1 /* 2 * Copyright 2014-2021 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 template<class T> static void 75 convert_preloaded_image(preloaded_image* _image) 76 { 77 T* image = static_cast<T*>(_image); 78 fix_address(image->next); 79 fix_address(image->name); 80 fix_address(image->debug_string_table); 81 fix_address(image->syms); 82 fix_address(image->rel); 83 fix_address(image->rela); 84 fix_address(image->pltrel); 85 fix_address(image->debug_symbols); 86 } 87 88 89 /*! Convert all addresses in kernel_args to virtual addresses. */ 90 static void 91 convert_kernel_args() 92 { 93 fix_address(gKernelArgs.boot_volume); 94 fix_address(gKernelArgs.vesa_modes); 95 fix_address(gKernelArgs.edid_info); 96 fix_address(gKernelArgs.debug_output); 97 fix_address(gKernelArgs.boot_splash); 98 99 arch_convert_kernel_args(); 100 101 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 102 convert_preloaded_image<preloaded_elf64_image>(gKernelArgs.kernel_image); 103 } else { 104 convert_preloaded_image<preloaded_elf32_image>(gKernelArgs.kernel_image); 105 } 106 fix_address(gKernelArgs.kernel_image); 107 108 // Iterate over the preloaded images. Must save the next address before 109 // converting, as the next pointer will be converted. 110 preloaded_image* image = gKernelArgs.preloaded_images; 111 fix_address(gKernelArgs.preloaded_images); 112 while (image != NULL) { 113 preloaded_image* next = image->next; 114 if (image->elf_class == ELFCLASS64) { 115 convert_preloaded_image<preloaded_elf64_image>(image); 116 } else { 117 convert_preloaded_image<preloaded_elf32_image>(image); 118 } 119 image = next; 120 } 121 122 // Fix driver settings files. 123 driver_settings_file* file = gKernelArgs.driver_settings; 124 fix_address(gKernelArgs.driver_settings); 125 while (file != NULL) { 126 driver_settings_file* next = file->next; 127 fix_address(file->next); 128 fix_address(file->buffer); 129 file = next; 130 } 131 } 132 133 134 static addr_t 135 get_kernel_entry(void) 136 { 137 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 138 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 139 gKernelArgs.kernel_image.Pointer()); 140 return image->elf_header.e_entry; 141 } else if (gKernelArgs.kernel_image->elf_class == ELFCLASS32) { 142 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 143 gKernelArgs.kernel_image.Pointer()); 144 return image->elf_header.e_entry; 145 } 146 panic("Unknown kernel format! Not 32-bit or 64-bit!"); 147 return 0; 148 } 149 150 151 static void 152 get_kernel_regions(addr_range& text, addr_range& data) 153 { 154 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 155 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 156 gKernelArgs.kernel_image.Pointer()); 157 text.start = image->text_region.start; 158 text.size = image->text_region.size; 159 data.start = image->data_region.start; 160 data.size = image->data_region.size; 161 return; 162 } else if (gKernelArgs.kernel_image->elf_class == ELFCLASS32) { 163 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 164 gKernelArgs.kernel_image.Pointer()); 165 text.start = image->text_region.start; 166 text.size = image->text_region.size; 167 data.start = image->data_region.start; 168 data.size = image->data_region.size; 169 return; 170 } 171 panic("Unknown kernel format! Not 32-bit or 64-bit!"); 172 } 173 174 175 extern "C" void 176 platform_start_kernel(void) 177 { 178 smp_init_other_cpus(); 179 #ifdef _BOOT_FDT_SUPPORT 180 dtb_set_kernel_args(); 181 #endif 182 183 addr_t kernelEntry = get_kernel_entry(); 184 185 addr_range textRegion = {.start = 0, .size = 0}, dataRegion = {.start = 0, .size = 0}; 186 get_kernel_regions(textRegion, dataRegion); 187 dprintf("kernel:\n"); 188 dprintf(" text: %#" B_PRIx64 ", %#" B_PRIx64 "\n", textRegion.start, textRegion.size); 189 dprintf(" data: %#" B_PRIx64 ", %#" B_PRIx64 "\n", dataRegion.start, dataRegion.size); 190 dprintf(" entry: %#lx\n", kernelEntry); 191 192 debug_cleanup(); 193 194 arch_mmu_init(); 195 convert_kernel_args(); 196 197 // map in a kernel stack 198 void *stack_address = NULL; 199 if (platform_allocate_region(&stack_address, 200 KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) 201 != B_OK) { 202 panic("Unabled to allocate a stack"); 203 } 204 gKernelArgs.cpu_kstack[0].start = fix_address((addr_t)stack_address); 205 gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE 206 + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; 207 dprintf("Kernel stack at %#" B_PRIx64 "\n", gKernelArgs.cpu_kstack[0].start); 208 209 // Apply any weird EFI quirks 210 quirks_init(); 211 212 // Begin architecture-centric kernel entry. 213 arch_start_kernel(kernelEntry); 214 215 panic("Shouldn't get here!"); 216 } 217 218 219 extern "C" void 220 platform_exit(void) 221 { 222 kRuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); 223 return; 224 } 225 226 227 /** 228 * efi_main - The entry point for the EFI application 229 * @image: firmware-allocated handle that identifies the image 230 * @systemTable: EFI system table 231 */ 232 extern "C" efi_status 233 efi_main(efi_handle image, efi_system_table *systemTable) 234 { 235 stage2_args args; 236 memset(&args, 0, sizeof(stage2_args)); 237 238 kImage = image; 239 kSystemTable = systemTable; 240 kBootServices = systemTable->BootServices; 241 kRuntimeServices = systemTable->RuntimeServices; 242 243 call_ctors(); 244 245 console_init(); 246 serial_init(); 247 serial_enable(); 248 249 sBootOptions = console_check_boot_keys(); 250 251 // disable apm in case we ever load a 32-bit kernel... 252 gKernelArgs.platform_args.apm.version = 0; 253 254 cpu_init(); 255 acpi_init(); 256 #ifdef _BOOT_FDT_SUPPORT 257 dtb_init(); 258 #endif 259 timer_init(); 260 smp_init(); 261 262 main(&args); 263 264 return EFI_SUCCESS; 265 } 266