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 13#define GDT_LIMIT 0x800 14 15 16.code64 17 18 19/*! void arch_enter_kernel(uint64 pml4, uint64 entry_point, uint64 stackTop); */ 20FUNCTION(arch_enter_kernel): 21 // Point CR3 to the kernel's PML4. 22 movq %rdi, %cr3 23 24 // Load 64-bit enabled GDT 25 lgdtq gLongGDTR(%rip) 26 27 // Jump into the 64-bit code segment. 28 push $KERNEL_CODE_SELECTOR 29 lea .Llmode(%rip), %rax 30 push %rax 31 lretq 32.align 8 33.code64 34.Llmode: 35 // Set data segments. 36 mov $KERNEL_DATA_SELECTOR, %ax 37 mov %ax, %ss 38 xor %ax, %ax 39 mov %ax, %ds 40 mov %ax, %es 41 mov %ax, %fs 42 mov %ax, %gs 43 44 // Set the stack pointer. 45 movq %rdx, %rsp 46 47 // Clear the stack frame/RFLAGS. 48 xorq %rbp, %rbp 49 push $2 50 popf 51 52 // Get arguments and call the kernel entry point. 53 mov %rsi, %rax // entry point 54 leaq gKernelArgs(%rip), %rdi 55 xorl %esi, %esi // current cpu 56 call *%rax 57 58 59.data 60 61 62SYMBOL(gLongGDTR): 63 .word BOOT_GDT_SEGMENT_COUNT * 8 - 1 64SYMBOL(gLongGDT): 65 .quad 0 66