1 /* 2 * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright 2008, François Revol, revol@free.fr. All rights reserved. 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 "smp.h" 20 #include "traps.h" 21 #include "fdt.h" 22 #include "Htif.h" 23 #include "virtio.h" 24 #include "graphics.h" 25 26 27 #define HEAP_SIZE (1024*1024) 28 29 // GCC defined globals 30 extern void (*__ctor_list)(void); 31 extern void (*__ctor_end)(void); 32 extern uint8 __bss_start; 33 extern uint8 _end; 34 35 extern "C" int main(stage2_args* args); 36 extern "C" void _start(int hartId, void* fdt); 37 extern "C" status_t arch_enter_kernel(uint64 satp, 38 struct kernel_args* kernelArgs, addr_t kernelEntry, addr_t kernelStackTop); 39 40 41 static uint32 sBootOptions; 42 static bool sBootOptionsValid = false; 43 44 45 static void 46 clear_bss(void) 47 { 48 memset(&__bss_start, 0, &_end - &__bss_start); 49 } 50 51 52 static void 53 call_ctors(void) 54 { 55 void (**f)(void); 56 57 for (f = &__ctor_list; f < &__ctor_end; f++) 58 (**f)(); 59 } 60 61 62 static uint32 63 check_for_boot_keys() 64 { 65 uint32 options = 0; 66 bigtime_t t0 = system_time(); 67 while (system_time() - t0 < 100000) { 68 int key = virtio_input_get_key(); 69 switch(key) { 70 case 94 /* space */: 71 options |= BOOT_OPTION_MENU; 72 break; 73 } 74 } 75 return options; 76 } 77 78 79 extern "C" uint32 80 platform_boot_options(void) 81 { 82 if (!sBootOptionsValid) { 83 sBootOptions = check_for_boot_keys(); 84 sBootOptionsValid = true; 85 /* 86 if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT) 87 serial_enable(); 88 */ 89 } 90 91 return sBootOptions; 92 } 93 94 95 static void 96 convert_preloaded_image(preloaded_elf64_image* image) 97 { 98 fix_address(image->next); 99 fix_address(image->name); 100 fix_address(image->debug_string_table); 101 fix_address(image->syms); 102 fix_address(image->rel); 103 fix_address(image->rela); 104 fix_address(image->pltrel); 105 fix_address(image->debug_symbols); 106 } 107 108 109 static void 110 convert_kernel_args() 111 { 112 if (gKernelArgs.kernel_image->elf_class != ELFCLASS64) 113 return; 114 115 fix_address(gKernelArgs.boot_volume); 116 fix_address(gKernelArgs.vesa_modes); 117 fix_address(gKernelArgs.edid_info); 118 fix_address(gKernelArgs.debug_output); 119 fix_address(gKernelArgs.boot_splash); 120 #if defined(__x86_64__) || defined(__x86__) 121 fix_address(gKernelArgs.ucode_data); 122 fix_address(gKernelArgs.arch_args.apic); 123 fix_address(gKernelArgs.arch_args.hpet); 124 #endif 125 fix_address(gKernelArgs.arch_args.fdt); 126 127 convert_preloaded_image(static_cast<preloaded_elf64_image*>( 128 gKernelArgs.kernel_image.Pointer())); 129 fix_address(gKernelArgs.kernel_image); 130 131 // Iterate over the preloaded images. Must save the next address before 132 // converting, as the next pointer will be converted. 133 preloaded_image* image = gKernelArgs.preloaded_images; 134 fix_address(gKernelArgs.preloaded_images); 135 while (image != NULL) { 136 preloaded_image* next = image->next; 137 convert_preloaded_image(static_cast<preloaded_elf64_image*>(image)); 138 image = next; 139 } 140 141 // Fix driver settings files. 142 driver_settings_file* file = gKernelArgs.driver_settings; 143 fix_address(gKernelArgs.driver_settings); 144 while (file != NULL) { 145 driver_settings_file* next = file->next; 146 fix_address(file->next); 147 fix_address(file->buffer); 148 file = next; 149 } 150 } 151 152 153 extern "C" void 154 platform_start_kernel(void) 155 { 156 static struct kernel_args* args = &gKernelArgs; 157 // platform_bootloader_address_to_kernel_address(&gKernelArgs, (addr_t*)&args); 158 159 preloaded_elf64_image* image = static_cast<preloaded_elf64_image*>( 160 gKernelArgs.kernel_image.Pointer()); 161 162 smp_init_other_cpus(); 163 //serial_cleanup(); 164 165 // Avoid interrupts from virtio devices before kernel driver takes control. 166 virtio_fini(); 167 168 // The native, non-SBI bootloader manually installs mmode hooks 169 gKernelArgs.arch_args.machine_platform = kPlatformMNative; 170 171 fdt_set_kernel_args(); 172 173 convert_kernel_args(); 174 uint64 satp; 175 mmu_init_for_kernel(satp); 176 177 smp_boot_other_cpus(satp, image->elf_header.e_entry); 178 179 dprintf("kernel entry: %lx\n", image->elf_header.e_entry); 180 dprintf("args: %lx\n", (addr_t)args); 181 182 addr_t stackTop 183 = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; 184 arch_enter_kernel(satp, args, image->elf_header.e_entry, stackTop); 185 186 panic("kernel returned!\n"); 187 188 } 189 190 191 extern "C" void 192 platform_exit(void) 193 { 194 HtifShutdown(); 195 } 196 197 198 extern "C" void 199 _start(int hartId, void* fdt) 200 { 201 HtifOutString("haiku_loader entry point\n"); 202 203 clear_bss(); 204 fdt_init(fdt); 205 call_ctors(); 206 207 stage2_args args; 208 args.heap_size = HEAP_SIZE; 209 args.arguments = NULL; 210 211 traps_init(); 212 // console_init(); 213 // virtio_init(); 214 cpu_init(); 215 mmu_init(); 216 //apm_init(); 217 smp_init(); 218 219 main(&args); 220 } 221