4 * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
6 #include <linux/kernel.h>
7 #include <asm/system.h>
8 #include <asm/ptrace.h>
9 #include <asm/addrspace.h>
11 #include <asm/baget/baget.h>
13 #include "balo.h" /* Includes some kernel symbol values */
15 static char *banner = "\nBaget Linux Loader v0.2\n";
17 static void mem_move (long *to, long *from, long size)
25 static volatile int *mem_limit = (volatile int*)KSEG1;
26 static volatile int *mem_limit_dbe = (volatile int*)KSEG1;
28 static int can_write (volatile int* p) {
29 return p < (int*)(KSEG1+BALO_OFFSET) ||
30 p >= (int*)(KSEG1+BALO_OFFSET+BALO_SIZE);
33 static volatile enum balo_state_enum {
38 } balo_state = BALO_INIT;
41 static __inline__ void reset_and_jump(int start, int mem_upper)
52 "ori\t$1, $1, 0xff00\n\t"
53 "xori\t$1, $1, 0xff00\n\t"
64 : "Ir" (start), "Ir" (mem_upper)
68 static void start_kernel(void)
70 extern char _vmlinux_start, _vmlinux_end;
71 extern char _ramdisk_start, _ramdisk_end;
73 outs( "Relocating Linux... " );
74 mem_move((long*)KSEG0, (long*)&_vmlinux_start,
75 &_vmlinux_end-&_vmlinux_start);
78 if (&_ramdisk_start != &_ramdisk_end) {
79 outs("Setting up RAMDISK... ");
80 if (*(unsigned long*)RAMDISK_BASE != 0xBA) {
81 outs("Bad RAMDISK_BASE signature in system image.\n");
84 *(unsigned long*)RAMDISK_BASE = (unsigned long)&_ramdisk_start;
85 *(unsigned long*)RAMDISK_SIZE = &_ramdisk_end -&_ramdisk_start;
90 extern void flush_cache_low(int isize, int dsize);
91 flush_cache_low(256*1024,256*1024);
94 balo_printf( "Kernel entry: %x\n\n", START);
95 balo_state = START_KERNEL;
96 reset_and_jump(START, (int)mem_limit-KSEG1+KSEG0);
100 static void mem_probe(void)
102 balo_state = MEM_PROBE;
104 while(mem_limit < mem_limit_dbe) {
105 if (can_write(mem_limit) && *mem_limit != 0)
106 break; /* cycle found */
108 if (can_write(mem_limit))
109 *mem_limit = -1; /* mark */
110 mem_limit += 0x40000;
116 volatile unsigned int int_cause;
117 volatile unsigned int epc;
118 volatile unsigned int badvaddr;
120 static void print_regs(void)
122 balo_printf("CAUSE=%x EPC=%x BADVADDR=%x\n",
123 int_cause, epc, badvaddr);
126 void int_handler(struct pt_regs *regs)
128 switch (balo_state) {
130 balo_printf("\nBALO: trap in balo itself.\n");
135 if ((int_cause & CAUSE_MASK) != CAUSE_DBE) {
136 balo_printf("\nBALO: unexpected trap during memory init.\n");
144 balo_printf("\nBALO: unexpected trap during memory probe.\n");
149 balo_printf("\nBALO: unexpected kernel trap.\n");
154 balo_printf("\nBALO: unexpected return from handler.\n");
159 static void mem_init(void)
161 balo_state = MEM_INIT;
165 if (can_write(mem_limit_dbe))
168 mem_limit_dbe += 0x40000; /* +1M */
170 /* no return: must go to int_handler */
173 void balo_entry(void)
175 extern void except_vec3_generic(void);
179 memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
183 /* Needed for linking */
185 int vsprintf(char *buf, const char *fmt, va_list arg)
187 outs("BALO: vsprintf called.\n");