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 <kernel.h> 16 17 #include <boot/kernel_args.h> 18 #include <boot/platform.h> 19 #include <boot/stage2.h> 20 #include <boot/stdio.h> 21 22 #include "arch_mmu.h" 23 #include "arch_start.h" 24 #include "acpi.h" 25 #include "console.h" 26 #include "cpu.h" 27 #include "efi_platform.h" 28 #include "mmu.h" 29 #include "quirks.h" 30 #include "serial.h" 31 #include "smp.h" 32 #include "timer.h" 33 34 35 extern void (*__ctor_list)(void); 36 extern void (*__ctor_end)(void); 37 38 39 const efi_system_table *kSystemTable; 40 const efi_boot_services *kBootServices; 41 const efi_runtime_services *kRuntimeServices; 42 efi_handle kImage; 43 44 45 static uint32 sBootOptions; 46 47 extern "C" int main(stage2_args *args); 48 extern "C" void _start(void); 49 extern "C" void efi_enter_kernel(uint64 pml4, uint64 entry_point, uint64 stack); 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 extern "C" uint32 63 platform_boot_options() 64 { 65 return sBootOptions; 66 } 67 68 69 static void 70 convert_preloaded_image(preloaded_elf64_image* image) 71 { 72 fix_address(image->next); 73 fix_address(image->name); 74 fix_address(image->debug_string_table); 75 fix_address(image->syms); 76 fix_address(image->rel); 77 fix_address(image->rela); 78 fix_address(image->pltrel); 79 fix_address(image->debug_symbols); 80 } 81 82 83 /*! Convert all addresses in kernel_args to 64-bit addresses. */ 84 static void 85 convert_kernel_args() 86 { 87 fix_address(gKernelArgs.boot_volume); 88 fix_address(gKernelArgs.vesa_modes); 89 fix_address(gKernelArgs.edid_info); 90 fix_address(gKernelArgs.debug_output); 91 fix_address(gKernelArgs.boot_splash); 92 #if defined(__x86_64__) || defined(__x86__) 93 fix_address(gKernelArgs.ucode_data); 94 fix_address(gKernelArgs.arch_args.apic); 95 fix_address(gKernelArgs.arch_args.hpet); 96 #endif 97 98 convert_preloaded_image(static_cast<preloaded_elf64_image*>( 99 gKernelArgs.kernel_image.Pointer())); 100 fix_address(gKernelArgs.kernel_image); 101 102 // Iterate over the preloaded images. Must save the next address before 103 // converting, as the next pointer will be converted. 104 preloaded_image* image = gKernelArgs.preloaded_images; 105 fix_address(gKernelArgs.preloaded_images); 106 while (image != NULL) { 107 preloaded_image* next = image->next; 108 convert_preloaded_image(static_cast<preloaded_elf64_image*>(image)); 109 image = next; 110 } 111 112 // Fix driver settings files. 113 driver_settings_file* file = gKernelArgs.driver_settings; 114 fix_address(gKernelArgs.driver_settings); 115 while (file != NULL) { 116 driver_settings_file* next = file->next; 117 fix_address(file->next); 118 fix_address(file->buffer); 119 file = next; 120 } 121 } 122 123 124 extern "C" void 125 platform_start_kernel(void) 126 { 127 if (gKernelArgs.kernel_image->elf_class != ELFCLASS64) 128 panic("32-bit kernels not supported with EFI"); 129 130 smp_init_other_cpus(); 131 132 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 133 gKernelArgs.kernel_image.Pointer()); 134 135 arch_mmu_init(); 136 convert_kernel_args(); 137 138 // Save the kernel entry point address. 139 addr_t kernelEntry = image->elf_header.e_entry; 140 dprintf("kernel entry at %#lx\n", kernelEntry); 141 142 // map in a kernel stack 143 void *stack_address = NULL; 144 if (platform_allocate_region(&stack_address, 145 KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) 146 != B_OK) { 147 panic("Unabled to allocate a stack"); 148 } 149 gKernelArgs.cpu_kstack[0].start = fix_address((uint64_t)stack_address); 150 gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE 151 + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; 152 dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start); 153 154 // Apply any weird EFI quirks 155 quirks_init(); 156 157 // Begin architecture-centric kernel entry. 158 arch_start_kernel(kernelEntry); 159 160 panic("Shouldn't get here!"); 161 } 162 163 164 extern "C" void 165 platform_exit(void) 166 { 167 return; 168 } 169 170 171 /** 172 * efi_main - The entry point for the EFI application 173 * @image: firmware-allocated handle that identifies the image 174 * @systemTable: EFI system table 175 */ 176 extern "C" efi_status 177 efi_main(efi_handle image, efi_system_table *systemTable) 178 { 179 stage2_args args; 180 181 memset(&args, 0, sizeof(stage2_args)); 182 183 kImage = image; 184 kSystemTable = systemTable; 185 kBootServices = systemTable->BootServices; 186 kRuntimeServices = systemTable->RuntimeServices; 187 188 call_ctors(); 189 190 console_init(); 191 serial_init(); 192 serial_enable(); 193 194 sBootOptions = console_check_boot_keys(); 195 196 // disable apm in case we ever load a 32-bit kernel... 197 gKernelArgs.platform_args.apm.version = 0; 198 199 cpu_init(); 200 acpi_init(); 201 timer_init(); 202 smp_init(); 203 204 main(&args); 205 206 return EFI_SUCCESS; 207 } 208