* mikeOS 16 bit and amd64 baremetal
[mascara-docs.git] / amd64 / pure64-0.5.0 / src / init_acpi.asm
blob701f98869a8d1de3656e24893fda8154b80d9414
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
5 ; INIT ACPI
6 ; =============================================================================
9 init_acpi:
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)
12 searchingforACPI:
13 lodsq ; Load a quad word from RSI and store in RAX, then increment RSI by 8
14 cmp rax, rbx
15 je foundACPI
16 cmp rsi, 0x00000000000FFFFF ; Keep looking until we get here
17 jge noACPI ; ACPI tables couldn't be found, Fail.
18 jmp searchingforACPI
20 foundACPI: ; Found a Pointer Structure, verify the checksum
21 push rsi
22 xor ebx, ebx
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
25 nextchecksum:
26 lodsb ; Get a byte
27 add bl, al ; Add it to the running total
28 sub cl, 1
29 cmp cl, 0
30 jne nextchecksum
31 pop rsi
32 cmp bl, 0
33 jne searchingforACPI ; Checksum didn't check out? Then keep looking.
35 lodsb ; Checksum
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)
39 add al, 49
40 mov [0x000B8098], al ; Print the ACPI version number
41 sub al, 49
42 cmp al, 0
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
46 foundACPIv1:
47 xor eax, eax
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
53 sub rsi, 4
54 mov [os_ACPITableAddress], rsi ; Save the RSDT Table Address
55 add rsi, 4
56 xor eax, eax
57 lodsd ; Length
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
62 xor ecx, ecx
63 foundACPIv1_nextentry:
64 lodsd
65 push rax
66 add ecx, 1
67 cmp ecx, edx
68 je findAPICTable
69 jmp foundACPIv1_nextentry
71 foundACPIv2:
72 lodsd ; RSDT Address
73 lodsd ; Length
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
79 sub rsi, 4
80 mov [os_ACPITableAddress], rsi ; Save the XSDT Table Address
81 add rsi, 4
82 xor eax, eax
83 lodsd ; Length
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
88 xor ecx, ecx
89 foundACPIv2_nextentry:
90 lodsq
91 push rax
92 add ecx, 1
93 cmp ecx, edx
94 jne foundACPIv2_nextentry
96 findAPICTable:
97 mov al, '3' ; Search for the APIC table
98 mov [0x000B809C], al
99 mov al, '4'
100 mov [0x000B809E], al
101 mov ebx, 'APIC' ; Signature for the Multiple APIC Description Table
102 xor ecx, ecx
103 searchingforAPIC:
104 pop rsi
105 lodsd
106 add ecx, 1
107 cmp eax, ebx
108 je foundAPICTable
109 cmp ecx, edx
110 jne searchingforAPIC
111 jmp noACPIAPIC
113 fixstack:
114 pop rax
115 add ecx, 1
117 foundAPICTable:
118 ; fix the stack
119 cmp ecx, edx
120 jne fixstack
122 lodsd ; Length of MADT in bytes
123 mov ecx, eax ; Store the length in ECX
124 xor ebx, ebx ; EBX is the counter
125 lodsb ; Revision
126 lodsb ; Checksum
127 lodsd ; OEMID (First 4 bytes)
128 lodsw ; OEMID (Last 2 bytes)
129 lodsq ; OEM Table ID
130 lodsd ; OEM Revision
131 lodsd ; Creator ID
132 lodsd ; Creator Revision
133 xor eax, eax
134 lodsd ; Local APIC Address
135 mov [os_LocalAPICAddress], rax ; Save the Address of the Local APIC
136 lodsd ; Flags
137 add ebx, 44
138 mov rdi, 0x0000000000005100 ; Valid CPU IDs
140 readAPICstructures:
141 cmp ebx, ecx
142 jge init_smp_acpi_done
143 ; mov al, ' '
144 ; call os_print_char
145 ; call os_print_char
146 lodsb ; APIC Structure Type
147 ; call os_debug_dump_al
148 ; push rax
149 ; mov al, ' '
150 ; call os_print_char
151 ; pop rax
152 cmp al, 0x00 ; Processor Local APIC
153 je APICapic
154 cmp al, 0x01 ; I/O APIC
155 je APICioapic
156 cmp al, 0x02 ; Interrupt Source Override
157 je APICinterruptsourceoverride
158 ; cmp al, 0x03 ; Non-maskable Interrupt Source (NMI)
159 ; je APICnmi
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
165 je APICx2apic
166 ; cmp al, 0x0A ; Local x2APIC NMI
167 ; je APICx2nmi
169 jmp APICignore
171 APICapic:
172 xor eax, eax
173 xor edx, edx
174 lodsb ; Length (will be set to 8)
175 add ebx, eax
176 lodsb ; ACPI Processor ID
177 lodsb ; APIC 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
184 stosb
185 jmp readAPICstructures ; Read the next structure
187 APICioapic:
188 xor eax, eax
189 lodsb ; Length (will be set to 12)
190 add ebx, eax
191 lodsb ; IO APIC ID
192 lodsb ; Reserved
193 xor eax, eax
194 lodsd ; IO APIC Address
195 push rdi
196 mov rdi, os_IOAPICAddress
197 xor ecx, ecx
198 mov cl, [os_IOAPICCount]
199 shl cx, 3 ; Quick multiply by 8
200 add rdi, rcx
201 stosd ; Store the IO APIC Address
202 lodsd ; System Vector Base
203 stosd ; Store the IO APIC Vector Base
204 pop rdi
205 inc byte [os_IOAPICCount]
206 jmp readAPICstructures ; Read the next structure
208 APICinterruptsourceoverride:
209 xor eax, eax
210 lodsb ; Length (will be set to 10)
211 add ebx, eax
212 lodsb ; Bus
213 lodsb ; Source
214 ; call os_debug_dump_al
215 ; mov al, ' '
216 ; call os_print_char
217 lodsd ; Global System Interrupt
218 ; call os_debug_dump_eax
219 lodsw ; Flags
220 jmp readAPICstructures ; Read the next structure
222 APICx2apic:
223 xor eax, eax
224 xor edx, edx
225 lodsb ; Length (will be set to 16)
226 lodsw ; Reserved; Must be Zero
227 lodsd
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
236 APICx2apicEnd:
237 lodsd ; ACPI Processor UID
238 jmp readAPICstructures ; Read the next structure
240 APICignore:
241 xor eax, eax
242 lodsb ; We have a type that we ignore, read the next byte
243 add ebx, eax
244 add rsi, rax
245 sub rsi, 2 ; For the two bytes just read
246 jmp readAPICstructures ; Read the next structure
248 init_smp_acpi_done:
251 noACPI:
252 noACPIAPIC:
253 novalidacpi:
254 mov al, 'X'
255 mov [0x000B809A], al
256 jmp $
257 ; =============================================================================
258 ; EOF