1 /* 2 * Copyright 2008-2020, François Revol, revol@free.fr. All rights reserved. 3 * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <KernelExport.h> 9 #include <boot/platform.h> 10 #include <boot/heap.h> 11 #include <boot/stage2.h> 12 #include <arch/cpu.h> 13 14 #include <string.h> 15 16 #include "console.h" 17 #include "cpu.h" 18 #include "mmu.h" 19 #include "keyboard.h" 20 #include "nextrom.h" 21 22 #define HEAP_SIZE 65536 23 24 // GCC defined globals 25 extern void (*__ctor_list)(void); 26 extern void (*__ctor_end)(void); 27 extern uint8 __bss_start; 28 extern uint8 _end; 29 30 extern "C" int main(stage2_args *args); 31 extern "C" void _start(void); 32 33 // the boot rom monitor entry point 34 struct mon_global *mg = NULL; 35 36 static uint32 sBootOptions; 37 38 39 static void 40 clear_bss(void) 41 { 42 memset(&__bss_start, 0, &_end - &__bss_start); 43 } 44 45 46 static void 47 call_ctors(void) 48 { 49 void (**f)(void); 50 51 for (f = &__ctor_list; f < &__ctor_end; f++) { 52 (**f)(); 53 } 54 } 55 56 57 extern "C" uint32 58 platform_boot_options(void) 59 { 60 #if 0 61 if (!gKernelArgs.fb.enabled) 62 sBootOptions |= check_for_boot_keys(); 63 #endif 64 return sBootOptions; 65 } 66 67 68 extern "C" void 69 platform_start_kernel(void) 70 { 71 #if 0 72 static struct kernel_args *args = &gKernelArgs; 73 // something goes wrong when we pass &gKernelArgs directly 74 // to the assembler inline below - might be a bug in GCC 75 // or I don't see something important... 76 addr_t stackTop 77 = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; 78 79 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 80 gKernelArgs.kernel_image.Pointer()); 81 82 //smp_init_other_cpus(); 83 //serial_cleanup(); 84 mmu_init_for_kernel(); 85 //smp_boot_other_cpus(); 86 87 #warning M68K: stop ints 88 89 dprintf("kernel entry at %lx\n", image->elf_header.e_entry); 90 91 asm volatile ( 92 "move.l %0,%%sp; " // move stack out of way 93 : : "m" (stackTop)); 94 95 asm volatile ( 96 "or #0x0700,%%sr; " : : ); // disable interrupts 97 98 asm volatile ( 99 "move.l #0x0,-(%%sp); " // we're the BSP cpu (0) 100 "move.l %0,-(%%sp); " // kernel args 101 "move.l #0x0,-(%%sp);" // dummy retval for call to main 102 "move.l %1,-(%%sp); " // this is the start address 103 "rts; " // jump. 104 : : "g" (args), "g" (image->elf_header.e_entry)); 105 106 // Huston, we have a problem! 107 108 asm volatile ( 109 "and #0xf8ff,%%sr; " : : ); // reenable interrupts 110 111 panic("kernel returned!\n"); 112 #endif 113 114 } 115 116 117 extern "C" void 118 platform_exit(void) 119 { 120 // TODO 121 while (true); 122 } 123 124 inline void dump_mg(struct mon_global *mg) 125 { 126 int i; 127 dprintf("mg@ %p\n", (void*)mg); 128 129 dprintf("mg_flags\t%x\n", (unsigned char)mg->mg_flags); 130 dprintf("mg_sid\t%x\n", mg->mg_sid); 131 dprintf("mg_pagesize\t%x\n", mg->mg_pagesize); 132 dprintf("mg_mon_stack\t%x\n", mg->mg_mon_stack); 133 dprintf("mg_vbr\t%x\n", mg->mg_vbr); 134 dprintf("mg_console_i\t%x\n", mg->mg_console_i); 135 dprintf("mg_console_o\t%x\n", mg->mg_console_o); 136 137 for (i = 0; i < N_SIMM; i++) { 138 dprintf("mg_region[%d] = {%08lx, %08lx}\n", i, 139 mg->mg_region[i].first_phys_addr, 140 mg->mg_region[i].last_phys_addr); 141 } 142 143 dprintf("mg_boot_dev\t%s\n", mg->mg_boot_dev); 144 dprintf("mg_boot_arg\t%s\n", mg->mg_boot_arg); 145 dprintf("mg_boot_info\t%s\n", mg->mg_boot_info); 146 dprintf("mg_boot_file\t%s\n", mg->mg_boot_file); 147 dprintf("mg_boot_dev\t%s\n", mg->mg_boot_dev); 148 dprintf("mg_boot_how\t%d\n", mg->mg_boot_how); 149 150 dprintf("mg_sddp\t%p\n", mg->mg_sddp); 151 dprintf("mg_dgp\t%p\n", mg->mg_dgp); 152 // "dlV3" (disk label signature ?) SCSI boot gives "@dlV3" 153 dprintf("mg_fdgp\t%p\n", mg->mg_fdgp); // "A" ?? SCSI: "to become ready" 154 dprintf("mg_s5cp\t%p\n", mg->mg_s5cp); 155 dprintf("mg_odc\t%p\n", mg->mg_odc); 156 dprintf("mg_odd\t%p\n", mg->mg_odd); 157 158 #if 0 159 for (int i = 0; i < sizeof(struct mon_global); i++) { 160 uint8 *p = ((uint8 *)mg)+i; 161 if (i % 32 == 0) 162 dprintf("%04x", i); 163 if (i % 4 == 0) 164 dprintf(" "); 165 if (i % 8 == 0) 166 dprintf(" "); 167 dprintf("%02x", *p); 168 if (i % 32 == 31 || i == sizeof(struct mon_global) - 1) 169 dprintf("\n"); 170 } 171 //while(true); 172 #endif 173 174 175 dprintf("mg_si\t%p\n", mg->mg_si); 176 /* XXX:the pointer seems completely random, sadly. 177 * Possibly the kernel is supposed to set it? 178 */ 179 #if 0 180 for (int i = 0; i < sizeof(struct sio); i++) { 181 uint8 *p = ((uint8 *)mg->mg_si)+i; 182 if (i % 32 == 0) 183 dprintf("%04x", i); 184 if (i % 4 == 0) 185 dprintf(" "); 186 if (i % 8 == 0) 187 dprintf(" "); 188 dprintf("%02x", *p); 189 if (i % 32 == 31 || i == sizeof(struct sio) - 1) 190 dprintf("\n"); 191 } 192 for (i = 0; i < 5; i++) { 193 struct sio *s = &mg->mg_si[i]; 194 dprintf("sio[%d] = {%08x, %u, %u, %u, %p, %u, %u, %p, %p, %p}\n", i, 195 s->si_args, s->si_ctrl, s->si_unit, s->si_part, 196 s->si_dev, s->si_blklen, s->si_lastlba, 197 s->si_sadmem, s->si_protomem, s->si_devmem); 198 s++; 199 } 200 #endif 201 202 //dprintf("test_msg\t%p\n", mg->test_msg); 203 /* Framebuffer info */ 204 #if 1 205 dprintf("km_coni = {%d, %d, %d, %d, %d, ... %d, %d, %d, ...%d}\n", 206 mg->km_coni.pixels_per_word, 207 mg->km_coni.bytes_per_scanline, 208 mg->km_coni.dspy_w, 209 mg->km_coni.dspy_max_w, 210 mg->km_coni.dspy_h, 211 //... 212 mg->km_coni.slot_num, 213 mg->km_coni.fb_num, 214 mg->km_coni.byte_lane_id, 215 mg->km_coni.access_stack); 216 for (i = 0; i < KM_CON_MAP_ENTRIES; i++) { 217 dprintf("km_coni.map_addr[%d] = {%08lx, %08lx, %08lx}\n", i, 218 mg->km_coni.map_addr[i].phys_addr, 219 mg->km_coni.map_addr[i].virt_addr, 220 mg->km_coni.map_addr[i].size); 221 } 222 #endif 223 224 //XXX: this one crashes on older ROMs 225 //dprintf("mg_cpu_clk\t%d\n", mg->mg_cpu_clk); 226 } 227 228 229 extern "C" void * 230 start_next(const char *boot_args, struct mon_global *monitor) 231 { 232 stage2_args args; 233 234 monitor->mg_putc('H'); 235 236 //asm("cld"); // Ain't nothing but a GCC thang. 237 //asm("fninit"); // initialize floating point unit 238 239 //clear_bss(); 240 /* save monitor ROM entry */ 241 mg = monitor; 242 // DEBUG 243 mg->mg_putc('A'); 244 245 call_ctors(); 246 // call C++ constructors before doing anything else 247 mg->mg_putc('I'); 248 249 args.heap_size = HEAP_SIZE; 250 args.arguments = NULL; 251 252 //serial_init(); 253 mg->mg_putc('K'); 254 console_init(); 255 mg->mg_putc('U'); 256 mg->mg_putc('\n'); 257 258 dump_mg(mg); 259 //while(1); 260 //return NULL; 261 cpu_init(); 262 #if 0 263 // TODO 264 mmu_init(); 265 266 // wait a bit to give the user the opportunity to press a key 267 spin(750000); 268 269 // reading the keyboard doesn't seem to work in graphics mode (maybe a bochs problem) 270 sBootOptions = check_for_boot_keys(); 271 //if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT) 272 //serial_enable(); 273 274 //apm_init(); 275 //smp_init(); 276 #endif 277 main(&args); 278 return NULL; 279 } 280