#include <asm_defs.h>
#define __x86_64__
#include <arch/x86/descriptors.h>
#include "mmu.h"
#undef __x86_64__
#define GDT_LIMIT 0x800
.code32
FUNCTION(long_enter_kernel):
movl 4(%esp), %ebx
movl 8(%esp), %edi
movl 12(%esp), %esi
movl gLongLA57, %ecx
shl $12, %ecx
movl %cr0, %eax
andl $~(1 << 31), %eax
movl %eax, %cr0
movl %cr4, %eax
orl $(1 << 5) | (1 << 7), %eax
orl %ecx, %eax
movl %eax, %cr4
movl gLongPhysicalPMLTop, %eax
movl %eax, %cr3
movl $0xc0000080, %ecx
rdmsr
orl $(1 << 8), %eax
wrmsr
movl %cr0, %ecx
orl $(1 << 31), %ecx
movl %ecx, %cr0
lgdtl long_gdtr
ljmp $KERNEL_CODE_SELECTOR, $.Llmode
.align 8
.code64
.Llmode:
mov $KERNEL_DATA_SELECTOR, %ax
mov %ax, %ss
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
movl %edi, %esp
shl $32, %rsi
orq %rsi, %rsp
xorq %rbp, %rbp
push $0
popf
leaq gKernelArgs(%rip), %rdi
movl %ebx, %esi
movq gLongKernelEntry(%rip), %rax
call *%rax
.data
long_gdtr:
.word BOOT_GDT_SEGMENT_COUNT * 8 - 1
SYMBOL(gLongGDT):
.long 0
SYMBOL(gLongPhysicalPMLTop):
.long 0
SYMBOL(gLongLA57):
.long 0
SYMBOL(gLongKernelEntry):
.quad 0