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