1 /* 2 * Copyright 2014-2016 Haiku, Inc. All rights reserved. 3 * Copyright 2013-2014, Fredrik Holmqvist, fredrik.holmqvist@gmail.com. 4 * Copyright 2014, Henry Harrington, henry.harrington@gmail.com. 5 * All rights reserved. 6 * Distributed under the terms of the MIT License. 7 */ 8 9 10 #include <string.h> 11 12 #include <KernelExport.h> 13 14 #include <arch/cpu.h> 15 #include <arch_cpu_defs.h> 16 #include <kernel.h> 17 18 #include <boot/kernel_args.h> 19 #include <boot/platform.h> 20 #include <boot/stage2.h> 21 #include <boot/stdio.h> 22 23 #include "arch_mmu.h" 24 #include "arch_start.h" 25 #include "acpi.h" 26 #include "console.h" 27 #include "cpu.h" 28 #include "debug.h" 29 #ifdef _BOOT_FDT_SUPPORT 30 #include "dtb.h" 31 #endif 32 #include "efi_platform.h" 33 #include "mmu.h" 34 #include "quirks.h" 35 #include "serial.h" 36 #include "smp.h" 37 #include "timer.h" 38 39 40 extern void (*__ctor_list)(void); 41 extern void (*__ctor_end)(void); 42 43 44 const efi_system_table *kSystemTable; 45 const efi_boot_services *kBootServices; 46 const efi_runtime_services *kRuntimeServices; 47 efi_handle kImage; 48 49 50 static uint32 sBootOptions; 51 52 extern "C" int main(stage2_args *args); 53 extern "C" void _start(void); 54 extern "C" void efi_enter_kernel(uint64 pml4, uint64 entry_point, uint64 stack); 55 56 57 static void 58 call_ctors(void) 59 { 60 void (**f)(void); 61 62 for (f = &__ctor_list; f < &__ctor_end; f++) 63 (**f)(); 64 } 65 66 67 extern "C" uint32 68 platform_boot_options() 69 { 70 return sBootOptions; 71 } 72 73 74 static void 75 convert_preloaded_image(preloaded_elf64_image* image) 76 { 77 fix_address(image->next); 78 fix_address(image->name); 79 fix_address(image->debug_string_table); 80 fix_address(image->syms); 81 fix_address(image->rel); 82 fix_address(image->rela); 83 fix_address(image->pltrel); 84 fix_address(image->debug_symbols); 85 } 86 87 88 /*! Convert all addresses in kernel_args to 64-bit addresses. */ 89 static void 90 convert_kernel_args() 91 { 92 if (gKernelArgs.kernel_image->elf_class != ELFCLASS64) 93 return; 94 95 fix_address(gKernelArgs.boot_volume); 96 fix_address(gKernelArgs.vesa_modes); 97 fix_address(gKernelArgs.edid_info); 98 fix_address(gKernelArgs.debug_output); 99 fix_address(gKernelArgs.boot_splash); 100 #if defined(__x86_64__) || defined(__x86__) 101 fix_address(gKernelArgs.ucode_data); 102 fix_address(gKernelArgs.arch_args.apic); 103 fix_address(gKernelArgs.arch_args.hpet); 104 #endif 105 106 convert_preloaded_image(static_cast<preloaded_elf64_image*>( 107 gKernelArgs.kernel_image.Pointer())); 108 fix_address(gKernelArgs.kernel_image); 109 110 // Iterate over the preloaded images. Must save the next address before 111 // converting, as the next pointer will be converted. 112 preloaded_image* image = gKernelArgs.preloaded_images; 113 fix_address(gKernelArgs.preloaded_images); 114 while (image != NULL) { 115 preloaded_image* next = image->next; 116 convert_preloaded_image(static_cast<preloaded_elf64_image*>(image)); 117 image = next; 118 } 119 120 // Fix driver settings files. 121 driver_settings_file* file = gKernelArgs.driver_settings; 122 fix_address(gKernelArgs.driver_settings); 123 while (file != NULL) { 124 driver_settings_file* next = file->next; 125 fix_address(file->next); 126 fix_address(file->buffer); 127 file = next; 128 } 129 } 130 131 132 static addr_t 133 get_kernel_entry(void) 134 { 135 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 136 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 137 gKernelArgs.kernel_image.Pointer()); 138 return image->elf_header.e_entry; 139 } else if (gKernelArgs.kernel_image->elf_class == ELFCLASS32) { 140 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 141 gKernelArgs.kernel_image.Pointer()); 142 return image->elf_header.e_entry; 143 } 144 panic("Unknown kernel format! Not 32-bit or 64-bit!"); 145 return 0; 146 } 147 148 149 static void 150 get_kernel_regions(addr_range& text, addr_range& data) 151 { 152 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 153 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 154 gKernelArgs.kernel_image.Pointer()); 155 text.start = image->text_region.start; 156 text.size = image->text_region.size; 157 data.start = image->data_region.start; 158 data.size = image->data_region.size; 159 return; 160 } else if (gKernelArgs.kernel_image->elf_class == ELFCLASS32) { 161 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 162 gKernelArgs.kernel_image.Pointer()); 163 text.start = image->text_region.start; 164 text.size = image->text_region.size; 165 data.start = image->data_region.start; 166 data.size = image->data_region.size; 167 return; 168 } 169 panic("Unknown kernel format! Not 32-bit or 64-bit!"); 170 } 171 172 173 extern "C" void 174 platform_start_kernel(void) 175 { 176 smp_init_other_cpus(); 177 #ifdef _BOOT_FDT_SUPPORT 178 dtb_set_kernel_args(); 179 #endif 180 181 addr_t kernelEntry = get_kernel_entry(); 182 183 addr_range textRegion = {.start = 0, .size = 0}, dataRegion = {.start = 0, .size = 0}; 184 get_kernel_regions(textRegion, dataRegion); 185 dprintf("kernel:\n"); 186 dprintf(" text: %#" B_PRIx64 ", %#" B_PRIx64 "\n", textRegion.start, textRegion.size); 187 dprintf(" data: %#" B_PRIx64 ", %#" B_PRIx64 "\n", dataRegion.start, dataRegion.size); 188 dprintf(" entry: %#lx\n", kernelEntry); 189 190 debug_cleanup(); 191 192 arch_mmu_init(); 193 convert_kernel_args(); 194 195 // map in a kernel stack 196 void *stack_address = NULL; 197 if (platform_allocate_region(&stack_address, 198 KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) 199 != B_OK) { 200 panic("Unabled to allocate a stack"); 201 } 202 gKernelArgs.cpu_kstack[0].start = fix_address((addr_t)stack_address); 203 gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE 204 + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; 205 dprintf("Kernel stack at %#" B_PRIx64 "\n", gKernelArgs.cpu_kstack[0].start); 206 207 // Apply any weird EFI quirks 208 quirks_init(); 209 210 // Begin architecture-centric kernel entry. 211 arch_start_kernel(kernelEntry); 212 213 panic("Shouldn't get here!"); 214 } 215 216 217 extern "C" void 218 platform_exit(void) 219 { 220 kRuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); 221 return; 222 } 223 224 225 /** 226 * efi_main - The entry point for the EFI application 227 * @image: firmware-allocated handle that identifies the image 228 * @systemTable: EFI system table 229 */ 230 extern "C" efi_status 231 efi_main(efi_handle image, efi_system_table *systemTable) 232 { 233 stage2_args args; 234 235 memset(&args, 0, sizeof(stage2_args)); 236 237 kImage = image; 238 kSystemTable = systemTable; 239 kBootServices = systemTable->BootServices; 240 kRuntimeServices = systemTable->RuntimeServices; 241 242 call_ctors(); 243 244 console_init(); 245 serial_init(); 246 serial_enable(); 247 248 sBootOptions = console_check_boot_keys(); 249 250 // disable apm in case we ever load a 32-bit kernel... 251 gKernelArgs.platform_args.apm.version = 0; 252 253 cpu_init(); 254 acpi_init(); 255 #ifdef _BOOT_FDT_SUPPORT 256 dtb_init(); 257 #endif 258 timer_init(); 259 smp_init(); 260 261 main(&args); 262 263 return EFI_SUCCESS; 264 } 265