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