Kernel/x86_64 - Fixed recursive page fault, wasn't enabling the NX bit
[tpg/acess2.git] / Kernel / arch / x86_64 / start32.asm
1 ;
2 ; Acess2 x86_64 port
3 ;
4
5 %include "arch/x86_64/include/common.inc.asm"
6
7 [BITS 32]
8
9 ;KERNEL_BASE    equ     0xFFFF800000000000
10 KERNEL_BASE     equ     0xFFFFFFFF80000000
11
12 [section .multiboot]
13 mboot:
14         ; Multiboot macros to make a few lines later more readable
15         MULTIBOOT_PAGE_ALIGN    equ 1<<0
16         MULTIBOOT_MEMORY_INFO   equ 1<<1
17         MULTIBOOT_AOUT_KLUDGE   equ 1<<16
18         MULTIBOOT_HEADER_MAGIC  equ 0x1BADB002
19         MULTIBOOT_HEADER_FLAGS  equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO; | MULTIBOOT_AOUT_KLUDGE
20         MULTIBOOT_CHECKSUM      equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
21         
22         ; This is the GRUB Multiboot header. A boot signature
23         dd MULTIBOOT_HEADER_MAGIC
24         dd MULTIBOOT_HEADER_FLAGS
25         dd MULTIBOOT_CHECKSUM
26         [extern __load_addr]
27         [extern __bss_start]
28         [extern gKernelEnd]
29         ; a.out kludge
30         dd mboot        ; Location of Multiboot Header
31         dd __load_addr  ; Load address
32         dd __bss_start - KERNEL_BASE    ; End of .data
33         dd gKernelEnd - KERNEL_BASE     ; End of .bss (and kernel)
34         dd start - KERNEL_BASE  ; Entrypoint
35
36 [extern start64]
37
38 [section .text]
39 [global start]
40 start:
41         mov [gMultibootMagic - KERNEL_BASE], eax
42         mov [gMultibootPtr - KERNEL_BASE], ebx
43
44         ; Check for Long Mode support
45         mov eax, 0x80000000
46         cpuid
47         cmp eax, 0x80000001     ; Compare the A-register with 0x80000001.
48         mov eax, 0x80000001
49         cpuid
50         jb .not64bitCapable
51         test edx, 1<<29
52         jz .not64bitCapable
53
54         ; Enable PGE (Page Global Enable)
55         ; + PAE (Physical Address Extension)
56         ; + PSE (Page Size Extensions)
57         mov eax, cr4
58         or eax, 0x80|0x20|0x10
59         mov cr4, eax
60
61         ; Initialise System Calls (SYSCALL/SYSRET)
62         ; Set IA32_EFER.(NXE|SCE)
63         mov ecx, 0xC0000080
64         rdmsr
65         or eax, (1 << 11)|(1 << 0)      ; NXE, SCE
66         wrmsr
67
68         ; Load PDP4
69         mov eax, gInitialPML4 - KERNEL_BASE
70         mov cr3, eax
71
72         ; Enable long/compatability mode
73         mov ecx, 0xC0000080
74         rdmsr
75         or ax, 0x100
76         wrmsr
77
78         ; Enable paging
79         mov eax, cr0
80         or eax, 0x80010000      ; PG & WP
81         mov cr0, eax
82
83         ; Load GDT
84         lgdt [gGDTPtr - KERNEL_BASE]
85         jmp 0x08:start64 - KERNEL_BASE
86
87 .not64bitCapable:
88         mov ah, 0x0F
89         mov edi, 0xB8000
90         mov esi, csNot64BitCapable - KERNEL_BASE
91
92 .loop:
93         lodsb
94         test al, al
95         jz .hlt
96         stosw
97         jmp .loop
98         
99 .hlt:
100         jmp .hlt
101
102 [section .data]
103 [global gGDT]
104 [global gGDTPtr]
105 gGDT:
106         dd      0,0
107         dd      0x00000000, 0x00209A00  ; 0x08: 64-bit Code
108         dd      0x00000000, 0x00009200  ; 0x10: 64-bit Data
109         dd      0x00000000, 0x0040FA00  ; 0x18: 32-bit User Code
110         dd      0x00000000, 0x0040F200  ; 0x20: User Data
111         dd      0x00000000, 0x0020FA00  ; 0x28: 64-bit User Code
112         dd      0x00000000, 0x0000F200  ; 0x30: User Data (64 version)
113         times MAX_CPUS  dd      0, 0x00008900, 0, 0     ; 0x38+16*n: TSS 0
114 gGDTPtr:
115         dw      $-gGDT-1
116         dd      gGDT-KERNEL_BASE
117         dd      0
118 [global gMultibootPtr]
119 [global gMultibootMagic]
120 gMultibootMagic:
121         dd      0
122 gMultibootPtr:
123         dd      0
124
125 [section .padata]
126 [global gInitialPML4]
127 gInitialPML4:   ; Covers 256 TiB (Full 48-bit Virtual Address Space)
128         dd      gInitialPDP - KERNEL_BASE + 3, 0        ; Identity Map Low 4Mb
129         times 0xA0*2-1  dq      0
130         dd      gStackPDP - KERNEL_BASE + 3, 0
131         times 512-4-($-gInitialPML4)/8  dq      0
132         dd      gInitialPML4 - KERNEL_BASE + 3, 0       ; Fractal Mapping
133         dq      0
134         dq      0
135         dd      gHighPDP - KERNEL_BASE + 3, 0   ; Map Low 4Mb to kernel base
136
137 gInitialPDP:    ; Covers 512 GiB
138         dd      gInitialPD - KERNEL_BASE + 3, 0
139         times 511       dq      0
140
141 gStackPDP:
142         dd      gStackPD - KERNEL_BASE + 3, 0
143         times 511       dq      0
144
145 gHighPDP:       ; Covers 512 GiB
146         times 510       dq      0
147         ;dq     0 + 0x143       ; 1 GiB Page from zero
148         dd      gInitialPD - KERNEL_BASE + 3, 0
149         dq      0
150
151 gInitialPD:     ; Covers 1 GiB
152 ;       dq      0 + 0x143       ; 1 GiB Page from zero
153         dd      gInitialPT1 - KERNEL_BASE + 3, 0
154         dd      gInitialPT2 - KERNEL_BASE + 3, 0
155         times 510       dq      0
156
157 gStackPD:
158         dd      gKStackPT - KERNEL_BASE + 3, 0
159         times 511       dq      0
160
161 gKStackPT:      ; Covers 2 MiB
162         ; Initial stack - 64KiB
163         dq      0
164         %assign i 0
165         %rep INITIAL_KSTACK_SIZE-1
166         dd      gInitialKernelStack - KERNEL_BASE + i*0x1000 + 0x103, 0
167         %assign i i+1
168         %endrep
169         times 512-INITIAL_KSTACK_SIZE   dq 0
170 gInitialPT1:    ; 2 MiB
171         %assign i 0
172         %rep 512
173         dq      i*4096+0x103
174         %assign i i+1
175         %endrep
176 gInitialPT2:    ; 2 MiB
177         %assign i 512
178         %rep 512
179         dq      i*4096+0x103
180         %assign i i+1
181         %endrep
182
183 [section .padata]
184 [global gInitialKernelStack]
185 gInitialKernelStack:
186         times 0x1000*(INITIAL_KSTACK_SIZE-1)    db 0    ; 8 Pages
187
188 [section .rodata]
189 csNot64BitCapable:
190         db "Not 64-bit Capable",0
191
192 ; vim: ft=nasm

UCC git Repository :: git.ucc.asn.au