-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathcpu.asm
More file actions
337 lines (302 loc) · 10.4 KB
/
cpu.asm
File metadata and controls
337 lines (302 loc) · 10.4 KB
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
; =============================================================================
; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2025 Return Infinity -- see LICENSE.TXT
;
; INIT CPU - This code is called by all activated CPU cores in the system
; =============================================================================
init_cpu:
; Disable Cache
mov rax, cr0
btr rax, 29 ; Clear No Write Thru (Bit 29)
bts rax, 30 ; Set Cache Disable (Bit 30)
mov cr0, rax
; Flush Cache
wbinvd
; Flush TLB
mov rax, cr3
mov cr3, rax
; Read the MTRR Cap (IA32_MTRRCAP) Register - 64-bit
; SMRR (bit 11) — SMRR interface supported
; WC (bit 10) — Write-combining memory type supported
; FIX (bit 8) — Fixed range registers supported
; VCNT (bits 7:0)— Number of variable range registers
; mov ecx, IA32_MTRRCAP
; rdmsr ; Returns the 64-bit value in EDX:EAX
; Read/write the MTRR Default Type (IA32_MTRR_DEF_TYPE) Register - 64-bit
; E (bit 11) — MTRR enable/disable
; FE (bit 10) — Fixed-range MTRRs enable/disable
; Type (bits 7:0)— Default memory type
; mov ecx, IA32_MTRR_DEF_TYPE
; rdmsr
; btc eax, 11 ; Disable MTRR
; btc eax, 10 ; Disable Fixed-range MTRRs
; wrmsr ; Write the 64-bit value from EDX:EAX
; Configure Page Attribute Table (IA32_PAT)
;
; MTRR Memory Types
; 0x00 - Uncacheable (UC)
; 0x01 - Write Combining (WC)
; 0x04 - Write Through (WT)
; 0x05 - Write Protected (WP)
; 0x06 - Write Back (WB)
; 0x07 - Uncached (UC-)
;
; On system power-up/reset the PAT is configured as WB, WT, UC-, UC, WB, WT, UC-, UC for entries 0-7
; PA0-3 are left at system default
; PA4-7 are reconfigured to enable WP and WC
; The following table is used to set a mapped page to a specific PAT
; PAT = Bit 12, PCD = Bit 4, PWT = Bit 3
; PAT PCD PWT PAT Entry Type
; 0 0 0 PAT0 WB
; 0 0 1 PAT1 WT
; 0 1 0 PAT2 UC-
; 0 1 1 PAT3 UC
; 1 0 0 PAT4 WP
; 1 0 1 PAT5 WC
; 1 1 0 PAT6 UC
; 1 1 1 PAT7 UC
mov edx, 0x00000105 ; PA7 UC (00), PA6 UC (00), PA5 WC (01), PA4 WP (05)
mov eax, 0x00070406 ; PA3 UC (00), PA2 UC- (07), PA1 WT (04), PA0 WB (06)
mov ecx, IA32_PAT
wrmsr
; Enable MTRRs
; mov ecx, IA32_MTRR_DEF_TYPE
; rdmsr
; bts eax, 11 ; Set MTRR Enable (Bit 11), Only enables Variable Range MTRR's
; wrmsr
; Flush TLB
mov rax, cr3
mov cr3, rax
; Flush Cache
wbinvd
; Enable Cache
mov rax, cr0
btr rax, 29 ; Clear No Write Thru (Bit 29)
btr rax, 30 ; Clear CD (Bit 30)
mov cr0, rax
; Enable Floating Point
mov rax, cr0
bts rax, 1 ; Set Monitor co-processor (Bit 1)
btr rax, 2 ; Clear Emulation (Bit 2)
mov cr0, rax
; Enable SSE
mov rax, cr4
bts rax, 9 ; Set Operating System Support for FXSAVE and FXSTOR instructions (Bit 9)
bts rax, 10 ; Set Operating System Support for Unmasked SIMD Floating-Point Exceptions (Bit 10)
mov cr4, rax
; Enable Math Co-processor
finit
; Enable AVX-1 and AVX-2
mov eax, 1 ; CPUID Feature information 1
cpuid ; Sets info in ECX and EDX
bt ecx, 28 ; AVX-1 is supported if bit 28 is set in ECX
; AVX-2 is supported if bit 5 is set in EBX on CPUID (EAX=7, ECX=0)
jnc avx_not_supported ; Skip activating AVX if not supported
avx_supported:
mov rax, cr4
bts rax, 18 ; Enable OSXSAVE (Bit 18)
mov cr4, rax
xor ecx, ecx ; Set load XCR0
xgetbv ; Load XCR0 register
bts rax, 0 ; Set X87 enable (Bit 0)
bts rax, 1 ; Set SSE enable (Bit 1)
bts rax, 2 ; Set AVX enable (Bit 2)
xsetbv ; Save XCR0 register
avx_not_supported:
; Enable AVX-512
mov eax, 7 ; CPUID Feature information 7
xor ecx, ecx ; Extended Features 0
cpuid ; Sets info in EBX, ECX, and EDX
bt ebx, 16 ; AVX-512 is supported if bit 16 is set in EBX
jnc avx512_not_supported
avx512_supported:
xor ecx, ecx ; Set load XCR0
xgetbv ; Load XCR0 register
bts rax, 5 ; Set OPMASK (Bit 5)
bts rax, 6 ; Set ZMM_Hi256 (Bit 6)
bts rax, 7 ; Set Hi16_ZMM (Bit 7)
xsetbv ; Save XCR0 register
avx512_not_supported:
; Enable APIC
mov ecx, IA32_APIC_BASE
rdmsr
bts eax, 11 ; EN - xAPIC global enable/disable
cmp byte [p_x2APIC], 1
jne skip_x2APIC_enable
bts eax, 10 ; EXTD - Enable x2APIC mode
skip_x2APIC_enable:
wrmsr
mov r8d, eax ; Save MSR value as bit 8 is checked later
; Configure APIC
mov ecx, APIC_TPR
mov eax, 0x00000020
call apic_write ; Disable softint delivery
mov ecx, APIC_LVT_TMR
mov eax, 0x00010000
call apic_write ; Disable timer interrupts
mov ecx, APIC_LVT_PERF
mov eax, 0x00010000
call apic_write ; Disable performance counter interrupts
cmp byte [p_x2APIC], 1
je skip_APIC ; Next 2 registers are APIC only
mov ecx, APIC_LDR
xor eax, eax
call apic_write ; Set Logical Destination Register
mov ecx, APIC_DFR
not eax ; Set EAX to 0xFFFFFFFF; Bits 31-28 set for Flat Mode
call apic_write ; Set Destination Format Register
skip_APIC:
mov ecx, APIC_LVT_LINT0
mov eax, 0x00008700 ; Bit 15 (1 = Level), Bits 10:8 for Ext
call apic_write ; Enable normal external interrupts
mov ecx, APIC_LVT_LINT1
mov eax, 0x00000400
call apic_write ; Enable normal NMI processing
mov ecx, APIC_LVT_ERR
mov eax, 0x00010000
call apic_write ; Disable error interrupts
mov ecx, APIC_SPURIOUS
mov eax, 0x000001FF
call apic_write ; Enable the APIC (bit 8) and set spurious vector to 0xFF
lock inc word [p_cpu_activated]
mov ecx, APIC_ID
call apic_read
cmp byte [p_x2APIC], 1
je skip_shift
shr eax, 24 ; AL now holds the CPU's APIC ID (0 - 255)
skip_shift:
bt r8d, 8 ; Check for BSP bit
jnc skip_bsp
mov [p_BSP], eax
skip_bsp:
mov edi, IM_ActivedCoreIDs ; The location where the activated cores set their record to 1
add edi, eax ; RDI points to InfoMap CPU area + APIC ID. ex 0x5E01 would be APIC ID 1
mov al, 1
stosb ; Store a 1 as the core is activated
ret
; -----------------------------------------------------------------------------
; apic_read -- Read from a register in the APIC
; IN: ECX = Register to read
; OUT: RAX = Register value
; All other registers preserved
apic_read:
cmp byte [p_x2APIC], 1
je apic_read_x2
apic_read_x:
mov rax, [p_LocalAPICAddress]
mov eax, [rax + rcx]
ret
apic_read_x2:
push rdx
push rcx
shr ecx, 4 ; Convert xAPIC register to x2APIC
add ecx, 0x800 ; Add MSR base offset
rdmsr ; Read to EDX:EAX
shl rdx, 32 ; Shift to upper 32 bits
or rax, rdx ; Combine into RAX
pop rcx
pop rdx
ret
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; apic_write -- Write to a register in the APIC
; IN: ECX = Register to write
; RAX = Value to write
; OUT: All registers preserved
apic_write:
cmp byte [p_x2APIC], 1
je apic_write_x2
apic_write_x:
push rcx
add rcx, [p_LocalAPICAddress]
mov [rcx], eax
pop rcx
ret
apic_write_x2:
push rdx
push rcx
shr ecx, 4 ; Convert xAPIC register to x2APIC
add ecx, 0x800 ; Add MSR base offset
mov rdx, rax ; Copy RAX to RDX
shr rdx, 32 ; Shift upper 32 bits to lower 32
wrmsr ; Write as EDX:EAX
pop rcx
pop rdx
ret
; -----------------------------------------------------------------------------
; APIC Register list
; 0x000 - 0x010 are Reserved
APIC_ID equ 0x020 ; ID Register
APIC_VER equ 0x030 ; Version Register
; 0x040 - 0x070 are Reserved
APIC_TPR equ 0x080 ; Task Priority Register
APIC_APR equ 0x090 ; Arbitration Priority Register
APIC_PPR equ 0x0A0 ; Processor Priority Register
APIC_EOI equ 0x0B0 ; End Of Interrupt
APIC_RRD equ 0x0C0 ; Remote Read Register
APIC_LDR equ 0x0D0 ; Logical Destination Register
APIC_DFR equ 0x0E0 ; Destination Format Register
APIC_SPURIOUS equ 0x0F0 ; Spurious Interrupt Vector Register
APIC_ISR equ 0x100 ; In-Service Register (Starting Address)
APIC_TMR equ 0x180 ; Trigger Mode Register (Starting Address)
APIC_IRR equ 0x200 ; Interrupt Request Register (Starting Address)
APIC_ESR equ 0x280 ; Error Status Register
; 0x290 - 0x2E0 are Reserved
APIC_ICR equ 0x300 ; Interrupt Command Register (64-bit - x2APIC only)
APIC_ICRL equ 0x300 ; Interrupt Command Register (low 32 bits)
APIC_ICRH equ 0x310 ; Interrupt Command Register (high 32 bits)
APIC_LVT_TMR equ 0x320 ; LVT Timer Register
APIC_LVT_TSR equ 0x330 ; LVT Thermal Sensor Register
APIC_LVT_PERF equ 0x340 ; LVT Performance Monitoring Counters Register
APIC_LVT_LINT0 equ 0x350 ; LVT LINT0 Register
APIC_LVT_LINT1 equ 0x360 ; LVT LINT1 Register
APIC_LVT_ERR equ 0x370 ; LVT Error Register
APIC_TMRINITCNT equ 0x380 ; Initial Count Register (for Timer)
APIC_TMRCURRCNT equ 0x390 ; Current Count Register (for Timer)
; 0x3A0 - 0x3D0 are Reserved
APIC_TMRDIV equ 0x3E0 ; Divide Configuration Register (for Timer)
; 0x3F0 is Reserved
; MSR List
IA32_APIC_BASE equ 0x01B
IA32_MTRRCAP equ 0x0FE
IA32_MISC_ENABLE equ 0x1A0
IA32_MTRR_PHYSBASE0 equ 0x200
IA32_MTRR_PHYSMASK0 equ 0x201
IA32_MTRR_PHYSBASE1 equ 0x202
IA32_MTRR_PHYSMASK1 equ 0x203
IA32_PAT equ 0x277
IA32_MTRR_DEF_TYPE equ 0x2FF
; x2APIC MSR List
x2APIC_BASE equ 0x800
; 0x000 - 0x001 are Reserved
x2APIC_ID equ 0x002 ; ID Register
x2APIC_VER equ 0x003 ; Version Register
; 0x004 - 0x007 are Reserved
x2APIC_TPR equ 0x008 ; Task Priority Register - Bits 31:8 are Reserved.
; 0x009 is Reserved
x2APIC_PPR equ 0x00A ; Processor Priority Register
x2APIC_EOI equ 0x00B ; End Of Interrupt - Write 0 Only
; 0x00C is Reserved
x2APIC_LDR equ 0x00D ; Logical Destination Register - Read Only
; 0x00E is Reserved
x2APIC_SPURIOUS equ 0x00F ; Spurious Interrupt Vector Register
x2APIC_ISR equ 0x010 ; In-Service Register (Starting Address) - Read Only
x2APIC_TMR equ 0x018 ; Trigger Mode Register (Starting Address) - Read Only
x2APIC_IRR equ 0x020 ; Interrupt Request Register (Starting Address) - Read Only
x2APIC_ESR equ 0x028 ; Error Status Register
; 0x029 - 0x02E are Reserved
x2APIC_ICR equ 0x030 ; Interrupt Command Register
x2APIC_LVT_TMR equ 0x032 ; LVT Timer Register
x2APIC_LVT_TSR equ 0x033 ; LVT Thermal Sensor Register
x2APIC_LVT_PERF equ 0x034 ; LVT Performance Monitoring Counters Register
x2APIC_LVT_LINT0 equ 0x035 ; LVT LINT0 Register
x2APIC_LVT_LINT1 equ 0x036 ; LVT LINT1 Register
x2APIC_LVT_ERR equ 0x037 ; LVT Error Register
x2APIC_TMRINITCNT equ 0x038 ; Initial Count Register (for Timer)
x2APIC_TMRCURRCNT equ 0x039 ; Current Count Register (for Timer) - Read Only
; 0x03A - 0x03D are Reserved
x2APIC_TMRDIV equ 0x03E ; Divide Configuration Register (for Timer)
x2APIC_SELF_IPI equ 0x03F ; Self IPI - Write Only
; 0x040 - 0x3FF are Reserved
; =============================================================================
; EOF