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 if (gKernelArgs.kernel_image->elf_class != ELFCLASS64) 88 return; 89 90 fix_address(gKernelArgs.boot_volume); 91 fix_address(gKernelArgs.vesa_modes); 92 fix_address(gKernelArgs.edid_info); 93 fix_address(gKernelArgs.debug_output); 94 fix_address(gKernelArgs.boot_splash); 95 #if defined(__x86_64__) || defined(__x86__) 96 fix_address(gKernelArgs.ucode_data); 97 fix_address(gKernelArgs.arch_args.apic); 98 fix_address(gKernelArgs.arch_args.hpet); 99 #endif 100 101 convert_preloaded_image(static_cast<preloaded_elf64_image*>( 102 gKernelArgs.kernel_image.Pointer())); 103 fix_address(gKernelArgs.kernel_image); 104 105 // Iterate over the preloaded images. Must save the next address before 106 // converting, as the next pointer will be converted. 107 preloaded_image* image = gKernelArgs.preloaded_images; 108 fix_address(gKernelArgs.preloaded_images); 109 while (image != NULL) { 110 preloaded_image* next = image->next; 111 convert_preloaded_image(static_cast<preloaded_elf64_image*>(image)); 112 image = next; 113 } 114 115 // Fix driver settings files. 116 driver_settings_file* file = gKernelArgs.driver_settings; 117 fix_address(gKernelArgs.driver_settings); 118 while (file != NULL) { 119 driver_settings_file* next = file->next; 120 fix_address(file->next); 121 fix_address(file->buffer); 122 file = next; 123 } 124 } 125 126 127 static addr_t 128 get_kernel_entry(void) 129 { 130 if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { 131 preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 132 gKernelArgs.kernel_image.Pointer()); 133 return image->elf_header.e_entry; 134 } else if (gKernelArgs.kernel_image->elf_class == ELFCLASS32) { 135 preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( 136 gKernelArgs.kernel_image.Pointer()); 137 return image->elf_header.e_entry; 138 } 139 panic("Unknown kernel format! Not 32-bit or 64-bit!"); 140 return 0; 141 } 142 143 144 extern "C" void 145 platform_start_kernel(void) 146 { 147 smp_init_other_cpus(); 148 149 addr_t kernelEntry = get_kernel_entry(); 150 151 arch_mmu_init(); 152 convert_kernel_args(); 153 154 // Save the kernel entry point address. 155 dprintf("kernel entry at %#lx\n", kernelEntry); 156 157 // map in a kernel stack 158 void *stack_address = NULL; 159 if (platform_allocate_region(&stack_address, 160 KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) 161 != B_OK) { 162 panic("Unabled to allocate a stack"); 163 } 164 gKernelArgs.cpu_kstack[0].start = fix_address((addr_t)stack_address); 165 gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE 166 + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; 167 dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start); 168 169 // Apply any weird EFI quirks 170 quirks_init(); 171 172 // Begin architecture-centric kernel entry. 173 arch_start_kernel(kernelEntry); 174 175 panic("Shouldn't get here!"); 176 } 177 178 179 extern "C" void 180 platform_exit(void) 181 { 182 return; 183 } 184 185 186 /** 187 * efi_main - The entry point for the EFI application 188 * @image: firmware-allocated handle that identifies the image 189 * @systemTable: EFI system table 190 */ 191 extern "C" efi_status 192 efi_main(efi_handle image, efi_system_table *systemTable) 193 { 194 stage2_args args; 195 196 memset(&args, 0, sizeof(stage2_args)); 197 198 kImage = image; 199 kSystemTable = systemTable; 200 kBootServices = systemTable->BootServices; 201 kRuntimeServices = systemTable->RuntimeServices; 202 203 call_ctors(); 204 205 console_init(); 206 serial_init(); 207 serial_enable(); 208 209 sBootOptions = console_check_boot_keys(); 210 211 // disable apm in case we ever load a 32-bit kernel... 212 gKernelArgs.platform_args.apm.version = 0; 213 214 cpu_init(); 215 acpi_init(); 216 timer_init(); 217 smp_init(); 218 219 main(&args); 220 221 return EFI_SUCCESS; 222 } 223