-
Notifications
You must be signed in to change notification settings - Fork 47
/
code32.asm
198 lines (164 loc) · 3.78 KB
/
code32.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
; --------------------------------------- 32 bit Code ---------------------------------------
SEGMENT CODE32 USE32
ORG 0h
macro break32
{
xchg bx,bx
}
; --------------------------------------- One interrupt definition ---------------------------------------
intr00:
IRETD
INCLUDE 'acpi32.asm'
INCLUDE 'page32.asm'
include 'thread32.asm'
INCLUDE 'int32.asm'
; --------------------------------------- Entry Point ---------------------------------------
Start32:
mov ax,stack32_idx
mov ss,ax
mov esp,stack32_end
mov ax,data32_idx
mov ds,ax
mov es,ax
mov ax,data16_idx
mov gs,ax
mov fs,ax
;jmp ToBack16
; --------------------------------------- Data stuff ---------------------------------------
mov eax,1
mov [ds:d32],eax
mov ebx,[ds:d32]
; --------------------------------------- Interrupt Test ---------------------------------------
int 0x0;
; --------------------------------------- SIPI to real mode test ---------------------------------------
if TEST_PM_SIPI > 0
qlock32 mut_1
xor eax,eax
mov ax,data16_idx
mov ds,ax
linear eax,Thread16_3,CODE16
mov ebx,1
push cs
call SendSIPI32f
mov ax,mut_1
push cs
call qwait32
end if
; --------------------------------------- LLDT ---------------------------------------
mov ax,ldt_idx
lldt ax
mov ax,data32_ldt_idx
mov gs,ax
push ds
pop gs
; --------------------------------------- Page Tests---------------------------------------
call InitPageTable32a
mov ax,data16_idx
push gs
mov gs,ax
mov edx,[gs:PhysicalPagingOffset32]
pop gs
mov CR3,edx
mov eax,cr4
bts eax,4
mov cr4,eax
mov eax, cr0
or eax,80000000h
mov cr0, eax
; Paging is now enabled
nop
nop
nop
; Disable Paging
mov eax, cr0 ; Read CR0.
and eax,7FFFFFFFh; Set PE=0
mov cr0, eax ; Write CR0.
; jmp ToBack16
; --------------------------------------- Prepare Long Mode ---------------------------------------
if TEST_LONG > 0
if TEST_LM_SIPI > 0
mov ax,data16_idx
push gs
mov gs,ax
mov dl,[gs:Support1GBPaging]
mov dh,[gs:LongModeSupported]
pop gs
cmp dh,1
jnz ToBack16
cmp dl,1
jnz .no1GB
call InitPageTable643 ; 1gb pages, map entire 4gb
jmp .okPaging
.no1GB:
call InitPageTable642 ; Small pages
else
call InitPageTable642
end if
.okPaging:
; Enable PAE
mov eax, cr4
bts eax, 5
mov cr4, eax
; Load new page table
mov ax,data16_idx
push gs
mov gs,ax
mov edx,[gs:PhysicalPagingOffset64]
pop gs
mov cr3,edx
; Enable Long Mode
mov ecx, 0c0000080h ; EFER MSR number.
rdmsr ; Read EFER.
bts eax, 8 ; Set LME=1.
wrmsr ; Write EFER.
; Enable Paging to activate Long Mode
mov eax, cr0 ; Read CR0.
or eax,80000000h ; Set PE=1.
mov cr0, eax ; Write CR0.
nop
nop
nop
; We are now in Long Mode / Compatibility mode
; Jump to an 64-bit segment to enable 64-bit mode
db 0eah
PutLinearStart64 dd 0
dw code64_idx
else
jmp ToBack16
end if
; --------------------------------------- Back from Long Mode ---------------------------------------
Back32:
; We are now in Compatibility mode again
mov ax,stack32_idx
mov ss,ax
mov esp,stack32_end
mov ax,data32_idx
mov ds,ax
mov es,ax
mov ax,data16_idx
mov gs,ax
mov fs,ax
; Disable Paging to get out of Long Mode
mov eax, cr0
and eax,7fffffffh
mov cr0, eax
; Deactivate Long Mode
mov ecx, 0c0000080h
rdmsr
btc eax, 8
wrmsr
; Disable PAE
mov eax, cr4
btc eax, 5
mov cr4, eax
; --------------------------------------- Back to Real mode ---------------------------------------
ToBack16:
; = Give FS the abs32 segment
; To test unreal mode
mov ax,absd32_idx
mov fs,ax
; Go back
db 066h ; because we are in a 32bit segment
db 0eah
dw exit16
dw code16_idx