1/* 2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. 3 * Copyright 2014, Henry Harrington, henry.harrington@gmail.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include <asm_defs.h> 9 10#include <arch/x86/descriptors.h> 11 12#include "mmu.h" 13 14 15#define GDT_LIMIT 0x800 16 17 18.code64 19 20 21/*! void efi_enter_kernel(uint64 pml4, uint64 entry_point, uint64 stackTop); */ 22FUNCTION(efi_enter_kernel): 23 // Point CR3 to the kernel's PML4. 24 movq %rdi, %cr3 25 26 // Load 64-bit enabled GDT 27 lgdtq gLongGDTR(%rip) 28 29 // Jump into the 64-bit code segment. 30 push $KERNEL_CODE_SELECTOR 31 lea .Llmode(%rip), %rax 32 push %rax 33 lretq 34.align 8 35.code64 36.Llmode: 37 // Set data segments. 38 mov $KERNEL_DATA_SELECTOR, %ax 39 mov %ax, %ss 40 xor %ax, %ax 41 mov %ax, %ds 42 mov %ax, %es 43 mov %ax, %fs 44 mov %ax, %gs 45 46 // Set the stack pointer. 47 movq %rdx, %rsp 48 49 // Clear the stack frame/RFLAGS. 50 xorq %rbp, %rbp 51 push $2 52 popf 53 54 // Get arguments and call the kernel entry point. 55 mov %rsi, %rax // entry point 56 leaq gKernelArgs(%rip), %rdi 57 xorl %esi, %esi // current cpu 58 call *%rax 59 60 61.data 62 63 64SYMBOL(gLongGDTR): 65 .word BOOT_GDT_SEGMENT_COUNT * 8 - 1 66SYMBOL(gLongGDT): 67 .quad 0 68