1735f1daeSFredrik Holmqvist /* 2735f1daeSFredrik Holmqvist * Copyright 2014-2016 Haiku, Inc. All rights reserved. 3b3215a62SHenry Harrington * Copyright 2013-2014, Fredrik Holmqvist, fredrik.holmqvist@gmail.com. 4b3215a62SHenry Harrington * Copyright 2014, Henry Harrington, henry.harrington@gmail.com. 5b3215a62SHenry Harrington * All rights reserved. 647a21c5cSAugustin Cavalier * Distributed under the terms of the MIT License. 7735f1daeSFredrik Holmqvist */ 8735f1daeSFredrik Holmqvist 9735f1daeSFredrik Holmqvist 10b3215a62SHenry Harrington #include <string.h> 11b3215a62SHenry Harrington 12b3215a62SHenry Harrington #include <KernelExport.h> 13b3215a62SHenry Harrington 14b3215a62SHenry Harrington #include <arch/cpu.h> 157b4d924fSAndrej Antunovikj #include <kernel.h> 167b4d924fSAndrej Antunovikj 177b4d924fSAndrej Antunovikj #include <boot/arch/x86/arch_cpu.h> 186e6efaecSJessica Hamilton #include <boot/kernel_args.h> 19e2e1558aSJessica Hamilton #include <boot/platform.h> 20e2e1558aSJessica Hamilton #include <boot/stage2.h> 21e2e1558aSJessica Hamilton #include <boot/stdio.h> 22735f1daeSFredrik Holmqvist 23*04f1baa7SAlexander von Gluck IV #include "arch_start.h" 246e6efaecSJessica Hamilton #include "acpi.h" 25735f1daeSFredrik Holmqvist #include "console.h" 26735f1daeSFredrik Holmqvist #include "efi_platform.h" 27b3215a62SHenry Harrington #include "mmu.h" 28d38ba84dSAlexander von Gluck IV #include "quirks.h" 299e487d8dSFredrik Holmqvist #include "serial.h" 30a99a0c00SNick Smallbone #include "smp.h" 31b482adb1SAlexander von Gluck IV #include "timer.h" 32735f1daeSFredrik Holmqvist 33735f1daeSFredrik Holmqvist 34735f1daeSFredrik Holmqvist extern void (*__ctor_list)(void); 35735f1daeSFredrik Holmqvist extern void (*__ctor_end)(void); 36735f1daeSFredrik Holmqvist 37735f1daeSFredrik Holmqvist 38485b5cf8SAlexander von Gluck IV const efi_system_table *kSystemTable; 39485b5cf8SAlexander von Gluck IV const efi_boot_services *kBootServices; 40485b5cf8SAlexander von Gluck IV const efi_runtime_services *kRuntimeServices; 41485b5cf8SAlexander von Gluck IV efi_handle kImage; 42b3215a62SHenry Harrington 43735f1daeSFredrik Holmqvist 4496f4d68bSJessica Hamilton static uint32 sBootOptions; 45b3215a62SHenry Harrington 46b3215a62SHenry Harrington 47b3215a62SHenry Harrington extern "C" int main(stage2_args *args); 48b3215a62SHenry Harrington extern "C" void _start(void); 49b3215a62SHenry Harrington extern "C" void efi_enter_kernel(uint64 pml4, uint64 entry_point, uint64 stack); 5096f4d68bSJessica Hamilton 51735f1daeSFredrik Holmqvist 52735f1daeSFredrik Holmqvist static void 53735f1daeSFredrik Holmqvist call_ctors(void) 54735f1daeSFredrik Holmqvist { 55735f1daeSFredrik Holmqvist void (**f)(void); 56735f1daeSFredrik Holmqvist 57735f1daeSFredrik Holmqvist for (f = &__ctor_list; f < &__ctor_end; f++) 58735f1daeSFredrik Holmqvist (**f)(); 59735f1daeSFredrik Holmqvist } 60735f1daeSFredrik Holmqvist 61735f1daeSFredrik Holmqvist 62e2e1558aSJessica Hamilton extern "C" uint32 63e2e1558aSJessica Hamilton platform_boot_options() 64e2e1558aSJessica Hamilton { 6596f4d68bSJessica Hamilton return sBootOptions; 66e2e1558aSJessica Hamilton } 67e2e1558aSJessica Hamilton 68e2e1558aSJessica Hamilton 69b3215a62SHenry Harrington static void 70b3215a62SHenry Harrington convert_preloaded_image(preloaded_elf64_image* image) 71b3215a62SHenry Harrington { 72b3215a62SHenry Harrington fix_address(image->next); 73b3215a62SHenry Harrington fix_address(image->name); 74b3215a62SHenry Harrington fix_address(image->debug_string_table); 75b3215a62SHenry Harrington fix_address(image->syms); 76b3215a62SHenry Harrington fix_address(image->rel); 77b3215a62SHenry Harrington fix_address(image->rela); 78b3215a62SHenry Harrington fix_address(image->pltrel); 79b3215a62SHenry Harrington fix_address(image->debug_symbols); 80b3215a62SHenry Harrington } 81b3215a62SHenry Harrington 82b3215a62SHenry Harrington 83b3215a62SHenry Harrington /*! Convert all addresses in kernel_args to 64-bit addresses. */ 84b3215a62SHenry Harrington static void 85b3215a62SHenry Harrington convert_kernel_args() 86b3215a62SHenry Harrington { 87b3215a62SHenry Harrington fix_address(gKernelArgs.boot_volume); 88b3215a62SHenry Harrington fix_address(gKernelArgs.vesa_modes); 89b3215a62SHenry Harrington fix_address(gKernelArgs.edid_info); 90b3215a62SHenry Harrington fix_address(gKernelArgs.debug_output); 91b3215a62SHenry Harrington fix_address(gKernelArgs.boot_splash); 92b482adb1SAlexander von Gluck IV #if defined(__x86_64__) || defined(__x86__) 93b3215a62SHenry Harrington fix_address(gKernelArgs.arch_args.apic); 94b3215a62SHenry Harrington fix_address(gKernelArgs.arch_args.hpet); 95b482adb1SAlexander von Gluck IV #endif 96b3215a62SHenry Harrington 97b3215a62SHenry Harrington convert_preloaded_image(static_cast<preloaded_elf64_image*>( 98b3215a62SHenry Harrington gKernelArgs.kernel_image.Pointer())); 99b3215a62SHenry Harrington fix_address(gKernelArgs.kernel_image); 100b3215a62SHenry Harrington 101b3215a62SHenry Harrington // Iterate over the preloaded images. Must save the next address before 102b3215a62SHenry Harrington // converting, as the next pointer will be converted. 103b3215a62SHenry Harrington preloaded_image* image = gKernelArgs.preloaded_images; 104b3215a62SHenry Harrington fix_address(gKernelArgs.preloaded_images); 105b3215a62SHenry Harrington while (image != NULL) { 106b3215a62SHenry Harrington preloaded_image* next = image->next; 107b3215a62SHenry Harrington convert_preloaded_image(static_cast<preloaded_elf64_image*>(image)); 108b3215a62SHenry Harrington image = next; 109b3215a62SHenry Harrington } 110b3215a62SHenry Harrington 111b3215a62SHenry Harrington // Fix driver settings files. 112b3215a62SHenry Harrington driver_settings_file* file = gKernelArgs.driver_settings; 113b3215a62SHenry Harrington fix_address(gKernelArgs.driver_settings); 114b3215a62SHenry Harrington while (file != NULL) { 115b3215a62SHenry Harrington driver_settings_file* next = file->next; 116b3215a62SHenry Harrington fix_address(file->next); 117b3215a62SHenry Harrington fix_address(file->buffer); 118b3215a62SHenry Harrington file = next; 119b3215a62SHenry Harrington } 120b3215a62SHenry Harrington } 121b3215a62SHenry Harrington 122b3215a62SHenry Harrington 123e2e1558aSJessica Hamilton extern "C" void 124e2e1558aSJessica Hamilton platform_start_kernel(void) 125e2e1558aSJessica Hamilton { 126b3215a62SHenry Harrington if (gKernelArgs.kernel_image->elf_class != ELFCLASS64) 127b3215a62SHenry Harrington panic("32-bit kernels not supported with EFI"); 128b3215a62SHenry Harrington 129a99a0c00SNick Smallbone smp_init_other_cpus(); 130ec239abcSJessica Hamilton 131b3215a62SHenry Harrington preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>( 132b3215a62SHenry Harrington gKernelArgs.kernel_image.Pointer()); 133b3215a62SHenry Harrington 1347c32619cSAlexander von Gluck IV arch_mmu_init(); 135b3215a62SHenry Harrington convert_kernel_args(); 136b3215a62SHenry Harrington 137b3215a62SHenry Harrington // Save the kernel entry point address. 138*04f1baa7SAlexander von Gluck IV addr_t kernelEntry = image->elf_header.e_entry; 139*04f1baa7SAlexander von Gluck IV dprintf("kernel entry at %#lx\n", kernelEntry); 140b3215a62SHenry Harrington 141b3215a62SHenry Harrington // map in a kernel stack 142b3215a62SHenry Harrington void *stack_address = NULL; 143485b5cf8SAlexander von Gluck IV if (platform_allocate_region(&stack_address, 144485b5cf8SAlexander von Gluck IV KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) 145485b5cf8SAlexander von Gluck IV != B_OK) { 146b3215a62SHenry Harrington panic("Unabled to allocate a stack"); 147b3215a62SHenry Harrington } 148b3215a62SHenry Harrington gKernelArgs.cpu_kstack[0].start = fix_address((uint64_t)stack_address); 149485b5cf8SAlexander von Gluck IV gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE 150485b5cf8SAlexander von Gluck IV + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; 151b3215a62SHenry Harrington dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start); 152b3215a62SHenry Harrington 153d38ba84dSAlexander von Gluck IV // Apply any weird EFI quirks 154d38ba84dSAlexander von Gluck IV quirks_init(); 155d38ba84dSAlexander von Gluck IV 156*04f1baa7SAlexander von Gluck IV // Begin architecture-centric kernel entry. 157*04f1baa7SAlexander von Gluck IV arch_start_kernel(kernelEntry); 158b3215a62SHenry Harrington 159*04f1baa7SAlexander von Gluck IV panic("Shouldn't get here!"); 160e2e1558aSJessica Hamilton } 161e2e1558aSJessica Hamilton 162e2e1558aSJessica Hamilton 163e2e1558aSJessica Hamilton extern "C" void 164e2e1558aSJessica Hamilton platform_exit(void) 165e2e1558aSJessica Hamilton { 166e2e1558aSJessica Hamilton return; 167e2e1558aSJessica Hamilton } 168e2e1558aSJessica Hamilton 169e2e1558aSJessica Hamilton 170735f1daeSFredrik Holmqvist /** 171735f1daeSFredrik Holmqvist * efi_main - The entry point for the EFI application 172735f1daeSFredrik Holmqvist * @image: firmware-allocated handle that identifies the image 173735f1daeSFredrik Holmqvist * @systemTable: EFI system table 174735f1daeSFredrik Holmqvist */ 175485b5cf8SAlexander von Gluck IV extern "C" efi_status 176485b5cf8SAlexander von Gluck IV efi_main(efi_handle image, efi_system_table *systemTable) 177735f1daeSFredrik Holmqvist { 178e2e1558aSJessica Hamilton stage2_args args; 179e2e1558aSJessica Hamilton 180b3215a62SHenry Harrington memset(&args, 0, sizeof(stage2_args)); 181b3215a62SHenry Harrington 182b3215a62SHenry Harrington kImage = image; 183735f1daeSFredrik Holmqvist kSystemTable = systemTable; 184735f1daeSFredrik Holmqvist kBootServices = systemTable->BootServices; 185735f1daeSFredrik Holmqvist kRuntimeServices = systemTable->RuntimeServices; 186735f1daeSFredrik Holmqvist 187735f1daeSFredrik Holmqvist call_ctors(); 188735f1daeSFredrik Holmqvist 189735f1daeSFredrik Holmqvist console_init(); 1909e487d8dSFredrik Holmqvist serial_init(); 1919e487d8dSFredrik Holmqvist serial_enable(); 192735f1daeSFredrik Holmqvist 19396f4d68bSJessica Hamilton sBootOptions = console_check_boot_keys(); 19496f4d68bSJessica Hamilton 195b3215a62SHenry Harrington // disable apm in case we ever load a 32-bit kernel... 196b3215a62SHenry Harrington gKernelArgs.platform_args.apm.version = 0; 1976e6efaecSJessica Hamilton 198b3215a62SHenry Harrington gKernelArgs.num_cpus = 1; 199b482adb1SAlexander von Gluck IV #if defined(__x86_64__) || defined(__x86__) 200b3215a62SHenry Harrington gKernelArgs.arch_args.hpet_phys = 0; 201b3215a62SHenry Harrington gKernelArgs.arch_args.hpet = NULL; 202b482adb1SAlexander von Gluck IV #endif 203b3215a62SHenry Harrington 20486b12d85SJessica Hamilton cpu_init(); 20586b12d85SJessica Hamilton acpi_init(); 206b482adb1SAlexander von Gluck IV timer_init(); 20786b12d85SJessica Hamilton smp_init(); 20886b12d85SJessica Hamilton 209e2e1558aSJessica Hamilton main(&args); 210735f1daeSFredrik Holmqvist 211735f1daeSFredrik Holmqvist return EFI_SUCCESS; 212735f1daeSFredrik Holmqvist } 213