1 /* 2 * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "serial.h" 8 #include "console.h" 9 #include "cpu.h" 10 #include "mmu.h" 11 #include "smp.h" 12 #include "uimage.h" 13 #include "keyboard.h" 14 15 #include <KernelExport.h> 16 #include <boot/platform.h> 17 #include <boot/heap.h> 18 #include <boot/stage2.h> 19 #include <arch/cpu.h> 20 #include <platform_arch.h> 21 22 #include <string.h> 23 24 25 #define HEAP_SIZE (128 * 1024) 26 27 28 typedef struct uboot_gd { 29 // those are the only few members that we can trust 30 // others depend on compile-time config 31 struct board_data *bd; 32 uint32 flags; 33 uint32 baudrate; 34 // those are ARM-only 35 uint32 have_console; 36 uint32 reloc_off; 37 uint32 env_addr; 38 uint32 env_valid; 39 uint32 fb_base; 40 } uboot_gd; 41 42 43 // GCC defined globals 44 extern void (*__ctor_list)(void); 45 extern void (*__ctor_end)(void); 46 extern uint8 __bss_start; 47 extern uint8 _end; 48 49 extern "C" int main(stage2_args *args); 50 extern "C" void _start(void); 51 extern "C" int start_raw(int argc, const char **argv); 52 extern "C" void dump_uimage(struct image_header *image); 53 54 // declared in shell.S 55 // those are initialized to NULL but not in the BSS 56 extern struct image_header *gUImage; 57 extern uboot_gd *gUBootGlobalData; 58 extern uint32 gUBootOS; 59 extern void *gFDT; 60 61 static uint32 sBootOptions; 62 63 64 static void 65 clear_bss(void) 66 { 67 memset(&__bss_start, 0, &_end - &__bss_start); 68 } 69 70 71 static void 72 call_ctors(void) 73 { 74 void (**f)(void); 75 76 for (f = &__ctor_list; f < &__ctor_end; f++) { 77 (**f)(); 78 } 79 } 80 81 82 /* needed for libgcc unwind XXX */ 83 extern "C" void 84 abort(void) 85 { 86 panic("abort"); 87 } 88 89 90 extern "C" void 91 platform_start_kernel(void) 92 { 93 addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry; 94 addr_t stackTop 95 = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; 96 97 // smp_init_other_cpus(); 98 serial_cleanup(); 99 mmu_init_for_kernel(); 100 // smp_boot_other_cpus(); 101 102 dprintf("kernel entry at %lx\n", 103 gKernelArgs.kernel_image.elf_header.e_entry); 104 105 status_t error = arch_start_kernel(&gKernelArgs, kernelEntry, 106 stackTop); 107 108 panic("kernel returned!\n"); 109 } 110 111 112 extern "C" void 113 platform_exit(void) 114 { 115 } 116 117 118 extern "C" int 119 start_netbsd(struct board_info *bd, struct image_header *image, 120 const char *consdev, const char *cmdline) 121 { 122 const char *argv[] = { "haiku", cmdline }; 123 int argc = 1; 124 if (cmdline) 125 argc++; 126 gUImage = image; 127 return start_raw(argc, argv); 128 } 129 130 131 extern "C" int 132 start_linux(int argc, int archnum, void *atags) 133 { 134 return 1; 135 } 136 137 138 extern "C" int 139 start_linux_ppc_old(void */*board_info*/, 140 void */*initrd_start*/, void */*initrd_end*/, 141 const char */*cmdline_start*/, const char */*cmdline_end*/) 142 { 143 return 1; 144 } 145 146 147 extern "C" int 148 start_linux_ppc_fdt(void *fdt, long/*UNUSED*/, long/*UNUSED*/, 149 uint32 epapr_magic, uint32 initial_mem_size) 150 { 151 gFDT = fdt; //XXX: make a copy? 152 return start_raw(0, NULL); 153 } 154 155 156 extern "C" int 157 start_raw(int argc, const char **argv) 158 { 159 stage2_args args; 160 161 clear_bss(); 162 // call C++ constructors before doing anything else 163 call_ctors(); 164 args.heap_size = HEAP_SIZE; 165 args.arguments = NULL; 166 args.platform.boot_tgz_data = NULL; 167 args.platform.boot_tgz_size = 0; 168 169 serial_init(); 170 console_init(); 171 cpu_init(); 172 173 // if we get passed a uimage, try to find the second blob 174 if (gUImage != NULL 175 && image_multi_getimg(gUImage, 1, 176 (uint32*)&args.platform.boot_tgz_data, 177 &args.platform.boot_tgz_size)) { 178 dprintf("Found boot tgz @ %p, %" B_PRIu32 " bytes\n", 179 args.platform.boot_tgz_data, args.platform.boot_tgz_size); 180 } 181 182 { //DEBUG: 183 int i; 184 dprintf("argc = %d\n", argc); 185 for (i = 0; i < argc; i++) 186 dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]); 187 dprintf("os: %d\n", (int)gUBootOS); 188 dprintf("gd @ %p\n", gUBootGlobalData); 189 dprintf("gd->bd @ %p\n", gUBootGlobalData->bd); 190 //dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base); 191 dprintf("uimage @ %p\n", gUImage); 192 if (gUImage) 193 dump_uimage(gUImage); 194 } 195 196 mmu_init(); 197 198 // wait a bit to give the user the opportunity to press a key 199 // spin(750000); 200 201 // reading the keyboard doesn't seem to work in graphics mode 202 // (maybe a bochs problem) 203 // sBootOptions = check_for_boot_keys(); 204 //if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT) 205 serial_enable(); 206 207 main(&args); 208 return 0; 209 } 210 211 212 extern "C" uint32 213 platform_boot_options(void) 214 { 215 return sBootOptions; 216 } 217