1 ; =============================================================================
2 ; Pure64 -- a 64-bit OS loader written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2012 Return Infinity -- see LICENSE.TXT
6 ; =============================================================================
10 mov rsi
, 0x00000000000E0000 ; Start looking for the Root System Description Pointer Structure
11 mov rbx
, 'RSD PTR ' ; This in the Signature for the ACPI Structure Table (0x2052545020445352)
13 lodsq
; Load a quad word from RSI and store in RAX, then increment RSI by 8
16 cmp rsi
, 0x00000000000FFFFF ; Keep looking until we get here
17 jge noACPI
; ACPI tables couldn't be found, Fail.
20 foundACPI: ; Found a Pointer Structure, verify the checksum
23 mov ecx, 20 ; As per the spec only the first 20 bytes matter
24 sub rsi
, 8 ; Bytes 0 thru 19 must sum to zero
27 add bl, al ; Add it to the running total
33 jne searchingforACPI
; Checksum didn't check out? Then keep looking.
36 lodsd ; OEMID (First 4 bytes)
37 lodsw ; OEMID (Last 2 bytes)
38 lodsb ; Grab the Revision value (0 is v1.0, 1 is v2.0, 2 is v3.0, etc)
40 mov [0x000B8098], al ; Print the ACPI version number
43 je foundACPIv1
; If AL is 0 then the system is using ACPI v1.0
44 jmp foundACPIv2
; Otherwise it is v2.0 or higher
48 lodsd ; Grab the 32 bit physical address of the RSDT (Offset 16).
49 mov rsi
, rax
; RSI now points to the RSDT
50 lodsd ; Grab the Signiture
51 cmp eax, 'RSDT' ; Make sure the signiture is valid
52 jne novalidacpi
; Not the same? Bail out
54 mov [os_ACPITableAddress
], rsi
; Save the RSDT Table Address
58 add rsi
, 28 ; Skip to the Entry offset
59 sub eax, 36 ; EAX holds the table size. Subtract the preamble
60 shr eax, 2 ; Divide by 4
61 mov rdx
, rax
; RDX is the entry count
63 foundACPIv1_nextentry:
69 jmp foundACPIv1_nextentry
74 lodsq
; Grab the 64 bit physical address of the XSDT (Offset 24).
75 mov rsi
, rax
; RSI now points to the XSDT
76 lodsd ; Grab the Signiture
77 cmp eax, 'XSDT' ; Make sure the signiture is valid
78 jne novalidacpi
; Not the same? Bail out
80 mov [os_ACPITableAddress
], rsi
; Save the XSDT Table Address
84 add rsi
, 28 ; Skip to the start of the Entries (offset 36)
85 sub eax, 36 ; EAX holds the table size. Subtract the preamble
86 shr eax, 3 ; Divide by 8
87 mov rdx
, rax
; RDX is the entry count
89 foundACPIv2_nextentry:
94 jne foundACPIv2_nextentry
97 mov al, '3' ; Search for the APIC table
101 mov ebx, 'APIC' ; Signature for the Multiple APIC Description Table
122 lodsd ; Length of MADT in bytes
123 mov ecx, eax ; Store the length in ECX
124 xor ebx, ebx ; EBX is the counter
127 lodsd ; OEMID (First 4 bytes)
128 lodsw ; OEMID (Last 2 bytes)
132 lodsd ; Creator Revision
134 lodsd ; Local APIC Address
135 mov [os_LocalAPICAddress
], rax
; Save the Address of the Local APIC
138 mov rdi
, 0x0000000000005100 ; Valid CPU IDs
142 jge init_smp_acpi_done
146 lodsb ; APIC Structure Type
147 ; call os_debug_dump_al
152 cmp al, 0x00 ; Processor Local APIC
154 cmp al, 0x01 ; I/O APIC
156 cmp al, 0x02 ; Interrupt Source Override
157 je APICinterruptsourceoverride
158 ; cmp al, 0x03 ; Non-maskable Interrupt Source (NMI)
160 ; cmp al, 0x04 ; Local APIC NMI
161 ; je APIClocalapicnmi
162 ; cmp al, 0x05 ; Local APIC Address Override
163 ; je APICaddressoverride
164 cmp al, 0x09 ; Processor Local x2APIC
166 ; cmp al, 0x0A ; Local x2APIC NMI
174 lodsb ; Length (will be set to 8)
176 lodsb ; ACPI Processor ID
178 xchg eax, edx ; Save the APIC ID to EDX
179 lodsd ; Flags (Bit 0 set if enabled/usable)
180 bt eax, 0 ; Test to see if usable
181 jnc readAPICstructures
; Read the next structure if CPU not usable
182 inc word [cpu_detected
]
183 xchg eax, edx ; Restore the APIC ID back to EAX
185 jmp readAPICstructures
; Read the next structure
189 lodsb ; Length (will be set to 12)
194 lodsd ; IO APIC Address
196 mov rdi
, os_IOAPICAddress
198 mov cl, [os_IOAPICCount
]
199 shl cx, 3 ; Quick multiply by 8
201 stosd ; Store the IO APIC Address
202 lodsd ; System Vector Base
203 stosd ; Store the IO APIC Vector Base
205 inc byte [os_IOAPICCount
]
206 jmp readAPICstructures
; Read the next structure
208 APICinterruptsourceoverride:
210 lodsb ; Length (will be set to 10)
214 ; call os_debug_dump_al
217 lodsd ; Global System Interrupt
218 ; call os_debug_dump_eax
220 jmp readAPICstructures
; Read the next structure
225 lodsb ; Length (will be set to 16)
226 lodsw ; Reserved; Must be Zero
228 xchg eax, edx ; Save the x2APIC ID to EDX
229 lodsd ; Flags (Bit 0 set if enabled/usable)
230 bt eax, 0 ; Test to see if usable
231 jnc APICx2apicEnd
; Read the next structure if CPU not usable
232 xchg eax, edx ; Restore the x2APIC ID back to EAX
233 call os_debug_dump_eax
234 call os_print_newline
235 ; Save the ID's somewhere
237 lodsd ; ACPI Processor UID
238 jmp readAPICstructures
; Read the next structure
242 lodsb ; We have a type that we ignore, read the next byte
245 sub rsi
, 2 ; For the two bytes just read
246 jmp readAPICstructures
; Read the next structure
257 ; =============================================================================