Now with less fail
[tpg/acess2.git] / Kernel / arch / x86_64 / start32.asm
1
2 [BITS 32]
3
4 KERNEL_BASE     equ     0xFFFF800000000000
5
6 [section .multiboot]
7 mboot:
8         ; Multiboot macros to make a few lines later more readable
9         MULTIBOOT_PAGE_ALIGN    equ 1<<0
10         MULTIBOOT_MEMORY_INFO   equ 1<<1
11         MULTIBOOT_AOUT_KLUDGE   equ 1<<16
12         MULTIBOOT_HEADER_MAGIC  equ 0x1BADB002
13         MULTIBOOT_HEADER_FLAGS  equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO; | MULTIBOOT_AOUT_KLUDGE
14         MULTIBOOT_CHECKSUM      equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
15         
16         ; This is the GRUB Multiboot header. A boot signature
17         dd MULTIBOOT_HEADER_MAGIC
18         dd MULTIBOOT_HEADER_FLAGS
19         dd MULTIBOOT_CHECKSUM
20         [extern __load_addr]
21         [extern __bss_start]
22         [extern gKernelEnd]
23         ; a.out kludge
24         dd mboot        ; Location of Multiboot Header
25         dd __load_addr  ; Load address
26         dd __bss_start - KERNEL_BASE    ; End of .data
27         dd gKernelEnd - KERNEL_BASE     ; End of .bss (and kernel)
28         dd start - KERNEL_BASE  ; Entrypoint
29
30 [extern start64]
31
32 [section .text]
33 [global start]
34 start:
35         mov [gMultibootMagic - KERNEL_BASE], eax
36         mov [gMultibootPtr - KERNEL_BASE], ebx
37
38         ; Check for Long Mode support
39         mov eax, 0x80000000
40         cpuid
41         cmp eax, 0x80000001     ; Compare the A-register with 0x80000001.
42         mov eax, 0x80000001
43         cpuid
44     jb .not64bitCapable
45         test edx, 1<<29
46         jz .not64bitCapable
47
48         ; Enable PAE
49         mov eax, cr4
50         or eax, 0x80|0x20
51         mov cr4, eax
52
53         ; Load PDP4
54         mov eax, gInitialPML4 - KERNEL_BASE
55         mov cr3, eax
56
57         ; Enable long/compatability mode
58         mov ecx, 0xC0000080
59         rdmsr
60         or ax, 0x100
61         wrmsr
62
63         ; Enable paging
64         mov eax, cr0
65         or eax, 0x80000000
66         mov cr0, eax
67
68         ; Load GDT
69         lgdt [gGDTPtr - KERNEL_BASE]
70         jmp 0x08:start64 - KERNEL_BASE
71
72 .not64bitCapable:
73         mov ah, 0x0F
74         mov edi, 0xB8000
75         mov esi, csNot64BitCapable - KERNEL_BASE
76
77 .loop:
78         lodsb
79         test al, al
80         jz .hlt
81         stosw
82         jmp .loop
83         
84 .hlt:
85         jmp .hlt
86
87 [section .data]
88 [global gGDT]
89 gGDT:
90         dd      0,0
91         dd      0x00000000, 0x00209A00  ; 0x08: 64-bit Code
92         dd      0x00000000, 0x00009200  ; 0x10: 64-bit Data
93         dd      0x00000000, 0x0020FA00  ; 0x18: 64-bit User Code
94         dd      0x00000000, 0x0000F200  ; 0x20: 64-bit User Data
95         dd      0x00000000, 0x0040FA00  ; 0x38: 32-bit User Code
96         dd      0x00000000, 0x0040F200  ; 0x30: 32-bit User Data
97         times MAX_CPUS  dd      0, 0, 0, 0      ; 0x38+16*n: TSS 0
98 gGDTPtr:
99         dw      $-gGDT-1
100         dd      gGDT-KERNEL_BASE
101         dd      0
102 [global gMultibootPtr]
103 [global gMultibootMagic]
104 gMultibootMagic:
105         dd      0
106 gMultibootPtr:
107         dd      0
108
109 [section .padata]
110 [global gInitialPML4]
111 gInitialPML4:   ; Covers 256 TiB (Full 48-bit Virtual Address Space)
112         dd      gInitialPDP - KERNEL_BASE + 3, 0        ; Identity Map Low 4Mb
113         times 256-1 dq  0
114         dd      gInitialPDP - KERNEL_BASE + 3, 0        ; Map Low 4Mb to kernel base
115         times 256-1-4 dq 0
116         dd      gInitialPML4 - KERNEL_BASE + 3, 0       ; Fractal Mapping
117         dq      0
118         dq      0
119         dq      0
120
121 gInitialPDP:    ; Covers 512 GiB
122         dd      gInitialPD - KERNEL_BASE + 3, 0
123         times 511       dq      0
124
125 gInitialPD:     ; Covers 1 GiB
126         dd      gInitialPT1 - KERNEL_BASE + 3, 0
127         dd      gInitialPT2 - KERNEL_BASE + 3, 0
128         times 510       dq      0
129
130 gInitialPT1:    ; Covers 2 MiB
131         %assign i 0
132         %rep 512
133         dq      i*4096+3
134         %assign i i+1
135         %endrep
136 gInitialPT2:    ; 2 MiB
137         %assign i 512
138         %rep 512
139         dq      i*4096+3
140         %assign i i+1
141         %endrep
142
143
144 [section .rodata]
145 csNot64BitCapable:
146         db "Not 64-bit Capable",0

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