acpi.c revision 1.15.8.1 1 1.15.8.1 martin /* $NetBSD: acpi.c,v 1.15.8.1 2017/11/22 15:54:09 martin Exp $ */
2 1.1 christos
3 1.1 christos /*-
4 1.1 christos * Copyright (c) 1998 Doug Rabson
5 1.1 christos * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
6 1.1 christos * All rights reserved.
7 1.1 christos *
8 1.1 christos * Redistribution and use in source and binary forms, with or without
9 1.1 christos * modification, are permitted provided that the following conditions
10 1.1 christos * are met:
11 1.1 christos * 1. Redistributions of source code must retain the above copyright
12 1.1 christos * notice, this list of conditions and the following disclaimer.
13 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 christos * notice, this list of conditions and the following disclaimer in the
15 1.1 christos * documentation and/or other materials provided with the distribution.
16 1.1 christos *
17 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.1 christos * SUCH DAMAGE.
28 1.1 christos *
29 1.15.8.1 martin * $FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 321299 2017-07-20 17:36:17Z emaste $
30 1.1 christos */
31 1.1 christos
32 1.5 cegger #include <sys/cdefs.h>
33 1.15.8.1 martin __RCSID("$NetBSD: acpi.c,v 1.15.8.1 2017/11/22 15:54:09 martin Exp $");
34 1.5 cegger
35 1.5 cegger #include <sys/param.h>
36 1.5 cegger #include <sys/endian.h>
37 1.5 cegger #include <sys/stat.h>
38 1.5 cegger #include <sys/wait.h>
39 1.5 cegger #include <assert.h>
40 1.5 cegger #include <err.h>
41 1.5 cegger #include <fcntl.h>
42 1.5 cegger #include <paths.h>
43 1.5 cegger #include <stdio.h>
44 1.5 cegger #include <stdint.h>
45 1.5 cegger #include <stdlib.h>
46 1.5 cegger #include <string.h>
47 1.5 cegger #include <unistd.h>
48 1.5 cegger #include <stddef.h>
49 1.15.8.1 martin #include <uuid.h>
50 1.5 cegger
51 1.5 cegger #include "acpidump.h"
52 1.5 cegger
53 1.5 cegger #define BEGIN_COMMENT "/*\n"
54 1.5 cegger #define END_COMMENT " */\n"
55 1.5 cegger
56 1.5 cegger static void acpi_print_string(char *s, size_t length);
57 1.5 cegger static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
58 1.5 cegger static void acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
59 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func);
60 1.15.8.1 martin static void acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device,
61 1.5 cegger uint8_t func);
62 1.5 cegger #ifdef notyet
63 1.5 cegger static void acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *);
64 1.5 cegger static void acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *);
65 1.5 cegger #endif
66 1.5 cegger static void acpi_print_whea(ACPI_WHEA_HEADER *whea,
67 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
68 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
69 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *));
70 1.15.8.1 martin static uint64_t acpi_select_address(uint32_t, uint64_t);
71 1.5 cegger static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
72 1.5 cegger static void acpi_print_cpu(u_char cpu_id);
73 1.5 cegger static void acpi_print_cpu_uid(uint32_t uid, char *uid_string);
74 1.5 cegger static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
75 1.5 cegger static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
76 1.5 cegger uint64_t apic_addr);
77 1.5 cegger static void acpi_print_mps_flags(uint16_t flags);
78 1.5 cegger static void acpi_print_intr(uint32_t intr, uint16_t mps_flags);
79 1.5 cegger static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
80 1.5 cegger static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
81 1.5 cegger static void acpi_handle_bert(ACPI_TABLE_HEADER *sdp);
82 1.5 cegger static void acpi_handle_boot(ACPI_TABLE_HEADER *sdp);
83 1.5 cegger static void acpi_handle_cpep(ACPI_TABLE_HEADER *sdp);
84 1.5 cegger static void acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp);
85 1.15.8.1 martin static void acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp);
86 1.5 cegger static void acpi_handle_einj(ACPI_TABLE_HEADER *sdp);
87 1.5 cegger static void acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
88 1.5 cegger static void acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
89 1.5 cegger static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
90 1.5 cegger static void acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
91 1.5 cegger static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
92 1.5 cegger static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
93 1.5 cegger static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
94 1.5 cegger static void acpi_handle_sbst(ACPI_TABLE_HEADER *sdp);
95 1.5 cegger static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
96 1.5 cegger static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp);
97 1.15.8.1 martin static void acpi_handle_spmi(ACPI_TABLE_HEADER *sdp);
98 1.5 cegger static void acpi_print_srat_cpu(uint32_t apic_id,
99 1.5 cegger uint32_t proximity_domain,
100 1.5 cegger uint32_t flags, uint32_t clockdomain);
101 1.5 cegger static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
102 1.5 cegger static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
103 1.5 cegger static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
104 1.5 cegger static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
105 1.15.8.1 martin static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
106 1.15.8.1 martin static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
107 1.15.8.1 martin static void acpi_handle_uefi(ACPI_TABLE_HEADER *sdp);
108 1.5 cegger static void acpi_handle_waet(ACPI_TABLE_HEADER *sdp);
109 1.5 cegger static void acpi_handle_wdat(ACPI_TABLE_HEADER *sdp);
110 1.15.8.1 martin static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
111 1.5 cegger static void acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp);
112 1.5 cegger static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
113 1.7 jmcneill static void acpi_dump_bytes(ACPI_TABLE_HEADER *sdp);
114 1.5 cegger static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
115 1.5 cegger static void acpi_print_facs(ACPI_TABLE_FACS *facs);
116 1.5 cegger static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
117 1.5 cegger static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
118 1.5 cegger static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
119 1.5 cegger static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
120 1.5 cegger static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
121 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *));
122 1.15.8.1 martin static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
123 1.15.8.1 martin void (*action)(ACPI_NFIT_HEADER *));
124 1.5 cegger
125 1.5 cegger /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
126 1.5 cegger static int addr_size;
127 1.5 cegger
128 1.15.8.1 martin /* Strings used in the TCPA table */
129 1.15.8.1 martin static const char *tcpa_event_type_strings[] = {
130 1.15.8.1 martin "PREBOOT Certificate",
131 1.15.8.1 martin "POST Code",
132 1.15.8.1 martin "Unused",
133 1.15.8.1 martin "No Action",
134 1.15.8.1 martin "Separator",
135 1.15.8.1 martin "Action",
136 1.15.8.1 martin "Event Tag",
137 1.15.8.1 martin "S-CRTM Contents",
138 1.15.8.1 martin "S-CRTM Version",
139 1.15.8.1 martin "CPU Microcode",
140 1.15.8.1 martin "Platform Config Flags",
141 1.15.8.1 martin "Table of Devices",
142 1.15.8.1 martin "Compact Hash",
143 1.15.8.1 martin "IPL",
144 1.15.8.1 martin "IPL Partition Data",
145 1.15.8.1 martin "Non-Host Code",
146 1.15.8.1 martin "Non-Host Config",
147 1.15.8.1 martin "Non-Host Info"
148 1.15.8.1 martin };
149 1.15.8.1 martin
150 1.15.8.1 martin static const char *TCPA_pcclient_strings[] = {
151 1.15.8.1 martin "<undefined>",
152 1.15.8.1 martin "SMBIOS",
153 1.15.8.1 martin "BIS Certificate",
154 1.15.8.1 martin "POST BIOS ROM Strings",
155 1.15.8.1 martin "ESCD",
156 1.15.8.1 martin "CMOS",
157 1.15.8.1 martin "NVRAM",
158 1.15.8.1 martin "Option ROM Execute",
159 1.15.8.1 martin "Option ROM Configurateion",
160 1.15.8.1 martin "<undefined>",
161 1.15.8.1 martin "Option ROM Microcode Update ",
162 1.15.8.1 martin "S-CRTM Version String",
163 1.15.8.1 martin "S-CRTM Contents",
164 1.15.8.1 martin "POST Contents",
165 1.15.8.1 martin "Table of Devices",
166 1.15.8.1 martin };
167 1.15.8.1 martin
168 1.15.8.1 martin #define PRINTFLAG_END() printflag_end()
169 1.15.8.1 martin
170 1.15.8.1 martin static char pf_sep = '{';
171 1.15.8.1 martin
172 1.15.8.1 martin static void
173 1.15.8.1 martin printflag_end(void)
174 1.15.8.1 martin {
175 1.15.8.1 martin
176 1.15.8.1 martin if (pf_sep == ',') {
177 1.15.8.1 martin printf("}");
178 1.15.8.1 martin } else if (pf_sep == '{') {
179 1.15.8.1 martin printf("{}");
180 1.15.8.1 martin }
181 1.15.8.1 martin pf_sep = '{';
182 1.15.8.1 martin printf("\n");
183 1.15.8.1 martin }
184 1.15.8.1 martin
185 1.15.8.1 martin static void
186 1.15.8.1 martin printflag(uint64_t var, uint64_t mask, const char *name)
187 1.15.8.1 martin {
188 1.15.8.1 martin
189 1.15.8.1 martin if (var & mask) {
190 1.15.8.1 martin printf("%c%s", pf_sep, name);
191 1.15.8.1 martin pf_sep = ',';
192 1.15.8.1 martin }
193 1.15.8.1 martin }
194 1.15.8.1 martin
195 1.5 cegger static void
196 1.5 cegger acpi_print_string(char *s, size_t length)
197 1.5 cegger {
198 1.5 cegger int c;
199 1.5 cegger
200 1.5 cegger /* Trim trailing spaces and NULLs */
201 1.5 cegger while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
202 1.5 cegger length--;
203 1.5 cegger
204 1.5 cegger while (length--) {
205 1.5 cegger c = *s++;
206 1.5 cegger putchar(c);
207 1.5 cegger }
208 1.5 cegger }
209 1.5 cegger
210 1.5 cegger static void
211 1.5 cegger acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
212 1.5 cegger {
213 1.5 cegger switch(gas->SpaceId) {
214 1.15.8.1 martin case ACPI_ADR_SPACE_SYSTEM_MEMORY:
215 1.15.8.1 martin if (gas->BitWidth <= 32)
216 1.15.8.1 martin printf("0x%08x:%u[%u] (Memory)",
217 1.15.8.1 martin (u_int)gas->Address, gas->BitOffset,
218 1.15.8.1 martin gas->BitWidth);
219 1.15.8.1 martin else
220 1.15.8.1 martin printf("0x%016jx:%u[%u] (Memory)",
221 1.15.8.1 martin (uintmax_t)gas->Address, gas->BitOffset,
222 1.15.8.1 martin gas->BitWidth);
223 1.15.8.1 martin break;
224 1.15.8.1 martin case ACPI_ADR_SPACE_SYSTEM_IO:
225 1.15.8.1 martin printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
226 1.15.8.1 martin gas->BitOffset, gas->BitWidth);
227 1.5 cegger break;
228 1.15.8.1 martin case ACPI_ADR_SPACE_PCI_CONFIG:
229 1.5 cegger printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
230 1.5 cegger (uint16_t)((gas->Address >> 16) & 0xffff),
231 1.5 cegger (uint16_t)gas->Address);
232 1.5 cegger break;
233 1.5 cegger /* XXX How to handle these below? */
234 1.15.8.1 martin case ACPI_ADR_SPACE_EC:
235 1.5 cegger printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
236 1.5 cegger gas->BitOffset, gas->BitWidth);
237 1.5 cegger break;
238 1.15.8.1 martin case ACPI_ADR_SPACE_SMBUS:
239 1.5 cegger printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
240 1.5 cegger gas->BitOffset, gas->BitWidth);
241 1.5 cegger break;
242 1.15.8.1 martin case ACPI_ADR_SPACE_CMOS:
243 1.15.8.1 martin case ACPI_ADR_SPACE_PCI_BAR_TARGET:
244 1.15.8.1 martin case ACPI_ADR_SPACE_IPMI:
245 1.15.8.1 martin case ACPI_ADR_SPACE_GPIO:
246 1.15.8.1 martin case ACPI_ADR_SPACE_GSBUS:
247 1.15.8.1 martin case ACPI_ADR_SPACE_PLATFORM_COMM:
248 1.15.8.1 martin case ACPI_ADR_SPACE_FIXED_HARDWARE:
249 1.5 cegger default:
250 1.15.8.1 martin printf("0x%016jx (SpaceID=%hhu)", (uintmax_t)gas->Address,
251 1.15.8.1 martin gas->SpaceId);
252 1.5 cegger break;
253 1.5 cegger }
254 1.5 cegger }
255 1.5 cegger
256 1.5 cegger static void
257 1.5 cegger acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
258 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
259 1.5 cegger {
260 1.5 cegger if (vendorid == 0xffff && deviceid == 0xffff) {
261 1.5 cegger printf("\tPCI Device=NONE\n");
262 1.5 cegger return;
263 1.5 cegger }
264 1.5 cegger
265 1.5 cegger printf("\tPCI device={\n");
266 1.5 cegger printf("\t\tVendor=0x%x\n", vendorid);
267 1.5 cegger printf("\t\tDevice=0x%x\n", deviceid);
268 1.5 cegger printf("\n");
269 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
270 1.5 cegger printf("\t\tBus=%d\n", bus);
271 1.5 cegger printf("\t\tDevice=%d\n", device);
272 1.5 cegger printf("\t\tFunction=%d\n", func);
273 1.5 cegger printf("\t}\n");
274 1.5 cegger }
275 1.5 cegger
276 1.5 cegger static void
277 1.15.8.1 martin acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
278 1.5 cegger {
279 1.5 cegger if (bus == 0xff && device == 0xff && func == 0xff) {
280 1.5 cegger printf("\tPCI Device=NONE\n");
281 1.5 cegger return;
282 1.5 cegger }
283 1.5 cegger
284 1.5 cegger printf("\tPCI device={\n");
285 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
286 1.5 cegger printf("\t\tBus=%d\n", bus);
287 1.5 cegger printf("\t\tDevice=%d\n", device);
288 1.5 cegger printf("\t\tFunction=%d\n", func);
289 1.5 cegger printf("\t}\n");
290 1.5 cegger }
291 1.5 cegger
292 1.5 cegger #ifdef notyet
293 1.5 cegger static void
294 1.5 cegger acpi_print_hest_errorseverity(uint32_t error)
295 1.5 cegger {
296 1.5 cegger printf("\tError Severity={ ");
297 1.5 cegger switch (error) {
298 1.5 cegger case 0:
299 1.5 cegger printf("Recoverable");
300 1.5 cegger break;
301 1.5 cegger case 1:
302 1.5 cegger printf("Fatal");
303 1.5 cegger break;
304 1.5 cegger case 2:
305 1.5 cegger printf("Corrected");
306 1.5 cegger break;
307 1.5 cegger case 3:
308 1.5 cegger printf("None");
309 1.5 cegger break;
310 1.5 cegger default:
311 1.5 cegger printf("%d (reserved)", error);
312 1.5 cegger break;
313 1.5 cegger }
314 1.5 cegger printf("}\n");
315 1.5 cegger }
316 1.5 cegger #endif
317 1.5 cegger
318 1.5 cegger static void
319 1.5 cegger acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK *bank)
320 1.5 cegger {
321 1.5 cegger printf("\n");
322 1.5 cegger printf("\tBank Number=%d\n", bank->BankNumber);
323 1.15.8.1 martin printf("\tClear Status On Init={%s}\n",
324 1.5 cegger bank->ClearStatusOnInit ? "NO" : "YES");
325 1.5 cegger printf("\tStatus Data Format={ ");
326 1.5 cegger switch (bank->StatusFormat) {
327 1.5 cegger case 0:
328 1.5 cegger printf("IA32 MCA");
329 1.5 cegger break;
330 1.5 cegger case 1:
331 1.5 cegger printf("EMT64 MCA");
332 1.5 cegger break;
333 1.5 cegger case 2:
334 1.5 cegger printf("AMD64 MCA");
335 1.5 cegger break;
336 1.5 cegger }
337 1.5 cegger printf(" }\n");
338 1.5 cegger
339 1.5 cegger if (bank->ControlRegister)
340 1.5 cegger printf("\tControl Register=0x%x\n", bank->ControlRegister);
341 1.5 cegger printf("\tControl Init Data=0x%"PRIx64"\n", bank->ControlData);
342 1.5 cegger printf("\tStatus MSR=0x%x\n", bank->StatusRegister);
343 1.5 cegger printf("\tAddress MSR=0x%x\n", bank->AddressRegister);
344 1.5 cegger printf("\tMisc MSR=0x%x\n", bank->MiscRegister);
345 1.5 cegger }
346 1.5 cegger
347 1.5 cegger static void
348 1.5 cegger acpi_print_hest_header(ACPI_HEST_HEADER *hest)
349 1.5 cegger {
350 1.15.8.1 martin printf("\tType={");
351 1.5 cegger switch (hest->Type) {
352 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
353 1.5 cegger printf("IA32 Machine Check Exception");
354 1.5 cegger break;
355 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
356 1.15.8.1 martin printf("IA32 Corrected Machine Check");
357 1.5 cegger break;
358 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
359 1.15.8.1 martin printf("IA32 Non-Maskable Interrupt");
360 1.5 cegger break;
361 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
362 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
363 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
364 1.15.8.1 martin printf("unused type: %d", hest->Type);
365 1.5 cegger break;
366 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
367 1.15.8.1 martin printf("PCI Express Root Port AER");
368 1.5 cegger break;
369 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
370 1.15.8.1 martin printf("PCI Express Endpoint AER");
371 1.5 cegger break;
372 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
373 1.15.8.1 martin printf("PCI Express/PCI-X Bridge AER");
374 1.5 cegger break;
375 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
376 1.15.8.1 martin printf("Generic Hardware Error Source");
377 1.15.8.1 martin break;
378 1.15.8.1 martin case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
379 1.15.8.1 martin printf("Generic Hardware Error Source version 2");
380 1.5 cegger break;
381 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
382 1.5 cegger default:
383 1.15.8.1 martin printf("Reserved (%d)", hest->Type);
384 1.5 cegger break;
385 1.5 cegger }
386 1.15.8.1 martin printf("}\n");
387 1.5 cegger printf("\tSourceId=%d\n", hest->SourceId);
388 1.5 cegger }
389 1.5 cegger
390 1.5 cegger static void
391 1.5 cegger acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON *data)
392 1.5 cegger {
393 1.5 cegger printf("\tFlags={ ");
394 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
395 1.5 cegger printf("FIRMWARE_FIRST");
396 1.5 cegger if (data->Flags & ACPI_HEST_GLOBAL)
397 1.5 cegger printf("GLOBAL");
398 1.5 cegger printf(" }\n");
399 1.5 cegger printf("\tEnabled={ %s ", data->Flags ? "YES" : "NO");
400 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
401 1.5 cegger printf("(ignored) ");
402 1.5 cegger printf("}\n");
403 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
404 1.5 cegger data->RecordsToPreallocate);
405 1.5 cegger printf("\tMax. Sections per Record=%d\n", data->MaxSectionsPerRecord);
406 1.5 cegger if (!(data->Flags & ACPI_HEST_GLOBAL))
407 1.15.8.1 martin acpi_print_pci_sbdf(0, data->Bus, data->Device, data->Function);
408 1.5 cegger printf("\tDevice Control=0x%x\n", data->DeviceControl);
409 1.5 cegger printf("\tUncorrectable Error Mask Register=0x%x\n",
410 1.5 cegger data->UncorrectableMask);
411 1.5 cegger printf("\tUncorrectable Error Severity Register=0x%x\n",
412 1.5 cegger data->UncorrectableSeverity);
413 1.5 cegger printf("\tCorrectable Error Mask Register=0x%x\n",
414 1.5 cegger data->CorrectableMask);
415 1.5 cegger printf("\tAdvanced Capabilities Register=0x%x\n",
416 1.5 cegger data->AdvancedCapabilities);
417 1.5 cegger }
418 1.5 cegger
419 1.5 cegger static void
420 1.5 cegger acpi_print_hest_notify(ACPI_HEST_NOTIFY *notify)
421 1.5 cegger {
422 1.5 cegger printf("\tHW Error Notification={\n");
423 1.15.8.1 martin printf("\t\tType={");
424 1.5 cegger switch (notify->Type) {
425 1.5 cegger case ACPI_HEST_NOTIFY_POLLED:
426 1.5 cegger printf("POLLED");
427 1.5 cegger break;
428 1.5 cegger case ACPI_HEST_NOTIFY_EXTERNAL:
429 1.5 cegger printf("EXTERN");
430 1.5 cegger break;
431 1.5 cegger case ACPI_HEST_NOTIFY_LOCAL:
432 1.5 cegger printf("LOCAL");
433 1.5 cegger break;
434 1.5 cegger case ACPI_HEST_NOTIFY_SCI:
435 1.5 cegger printf("SCI");
436 1.5 cegger break;
437 1.5 cegger case ACPI_HEST_NOTIFY_NMI:
438 1.5 cegger printf("NMI");
439 1.5 cegger break;
440 1.15.8.1 martin case ACPI_HEST_NOTIFY_CMCI:
441 1.15.8.1 martin printf("CMCI");
442 1.15.8.1 martin break;
443 1.15.8.1 martin case ACPI_HEST_NOTIFY_MCE:
444 1.15.8.1 martin printf("MCE");
445 1.15.8.1 martin break;
446 1.15.8.1 martin case ACPI_HEST_NOTIFY_GPIO:
447 1.15.8.1 martin printf("GPIO-Signal");
448 1.15.8.1 martin break;
449 1.15.8.1 martin case ACPI_HEST_NOTIFY_SEA:
450 1.15.8.1 martin printf("ARMv8 SEA");
451 1.15.8.1 martin break;
452 1.15.8.1 martin case ACPI_HEST_NOTIFY_SEI:
453 1.15.8.1 martin printf("ARMv8 SEI");
454 1.15.8.1 martin break;
455 1.15.8.1 martin case ACPI_HEST_NOTIFY_GSIV:
456 1.15.8.1 martin printf("External Interrupt - GSIV");
457 1.15.8.1 martin break;
458 1.5 cegger case ACPI_HEST_NOTIFY_RESERVED:
459 1.5 cegger printf("RESERVED");
460 1.5 cegger break;
461 1.5 cegger default:
462 1.15.8.1 martin printf("%d (reserved)", notify->Type);
463 1.5 cegger break;
464 1.5 cegger }
465 1.15.8.1 martin printf("}\n");
466 1.5 cegger
467 1.5 cegger printf("\t\tLength=%d\n", notify->Length);
468 1.15.8.1 martin
469 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_HEST_## flag, #flag)
470 1.15.8.1 martin
471 1.15.8.1 martin printf("\t\tConfig Write Enable=");
472 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, TYPE);
473 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_INTERVAL);
474 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_VALUE);
475 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_WINDOW);
476 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_VALUE);
477 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_WINDOW);
478 1.15.8.1 martin PRINTFLAG_END();
479 1.15.8.1 martin
480 1.15.8.1 martin #undef PRINTFLAG
481 1.5 cegger
482 1.5 cegger printf("\t\tPoll Interval=%d msec\n", notify->PollInterval);
483 1.5 cegger printf("\t\tInterrupt Vector=%d\n", notify->Vector);
484 1.5 cegger printf("\t\tSwitch To Polling Threshold Value=%d\n",
485 1.5 cegger notify->PollingThresholdValue);
486 1.5 cegger printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
487 1.5 cegger notify->PollingThresholdWindow);
488 1.5 cegger printf("\t\tError Threshold Value=%d\n",
489 1.5 cegger notify->ErrorThresholdValue);
490 1.5 cegger printf("\t\tError Threshold Window=%d msec\n",
491 1.5 cegger notify->ErrorThresholdWindow);
492 1.5 cegger printf("\t}\n");
493 1.5 cegger }
494 1.5 cegger
495 1.5 cegger #ifdef notyet
496 1.5 cegger static void
497 1.5 cegger acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *data)
498 1.5 cegger {
499 1.5 cegger uint32_t i, pos, entries;
500 1.5 cegger ACPI_HEST_GENERIC_DATA *gen;
501 1.5 cegger
502 1.5 cegger entries = data->BlockStatus & ACPI_HEST_ERROR_ENTRY_COUNT;
503 1.5 cegger
504 1.5 cegger printf("\tGeneric Error Status={\n");
505 1.5 cegger printf("\t\tBlock Status={ ");
506 1.5 cegger if (data->BlockStatus & ACPI_HEST_UNCORRECTABLE)
507 1.5 cegger printf("UNCORRECTABLE");
508 1.5 cegger if (data->BlockStatus & ACPI_HEST_CORRECTABLE)
509 1.5 cegger printf("CORRECTABLE");
510 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_UNCORRECTABLE)
511 1.5 cegger printf("MULTIPLE UNCORRECTABLE");
512 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_CORRECTABLE)
513 1.5 cegger printf("MULTIPLE CORRECTABLE");
514 1.5 cegger printf(" }\n");
515 1.5 cegger printf("\t\tEntry Count=%d\n", entries);
516 1.5 cegger printf("\t\tRaw Data Offset=%d\n", data->RawDataOffset);
517 1.5 cegger printf("\t\tRaw Data Length=%d\n", data->RawDataLength);
518 1.5 cegger printf("\t\tData Length=%d\n", data->DataLength);
519 1.5 cegger printf("\t");
520 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
521 1.5 cegger printf("\t}\n");
522 1.5 cegger
523 1.5 cegger pos = sizeof(ACPI_HEST_GENERIC_STATUS);
524 1.5 cegger for (i = 0; i < entries; i++) {
525 1.5 cegger gen = (ACPI_HEST_GENERIC_DATA *)((char *)data + pos);
526 1.5 cegger acpi_print_hest_generic_data(gen);
527 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
528 1.5 cegger }
529 1.5 cegger }
530 1.5 cegger #endif
531 1.5 cegger
532 1.5 cegger #ifdef notyet
533 1.5 cegger static void
534 1.5 cegger acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *data)
535 1.5 cegger {
536 1.5 cegger printf("\tGeneric Error Data={\n");
537 1.5 cegger printf("\t\tSectionType=");
538 1.5 cegger acpi_print_string((char *)data->SectionType, sizeof(data->SectionType));
539 1.5 cegger printf("\n\t");
540 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
541 1.5 cegger printf("\t\tRevision=0x%x\n", data->Revision);
542 1.5 cegger printf("\t\tValidation Bits=0x%x\n", data->ValidationBits);
543 1.5 cegger printf("\t\tFlags=0x%x\n", data->Flags);
544 1.5 cegger printf("\t\tData Length=%d\n", data->ErrorDataLength);
545 1.5 cegger printf("\t\tField Replication Unit Id=");
546 1.5 cegger acpi_print_string((char *)data->FruId, sizeof(data->FruId));
547 1.5 cegger printf("\n");
548 1.5 cegger printf("\t\tField Replication Unit=");
549 1.5 cegger acpi_print_string((char *)data->FruText, sizeof(data->FruText));
550 1.5 cegger printf("\n");
551 1.5 cegger printf("\t}\n");
552 1.5 cegger }
553 1.5 cegger #endif
554 1.5 cegger
555 1.5 cegger static void
556 1.5 cegger acpi_print_whea(ACPI_WHEA_HEADER *whea,
557 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
558 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
559 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *))
560 1.5 cegger {
561 1.5 cegger printf("\n");
562 1.5 cegger
563 1.5 cegger print_action(whea);
564 1.5 cegger print_ins(whea);
565 1.5 cegger if (print_flags)
566 1.5 cegger print_flags(whea);
567 1.5 cegger printf("\tRegisterRegion=");
568 1.5 cegger acpi_print_gas(&whea->RegisterRegion);
569 1.5 cegger printf("\n");
570 1.5 cegger printf("\tMASK=0x%08"PRIx64"\n", whea->Mask);
571 1.5 cegger }
572 1.5 cegger
573 1.5 cegger static void
574 1.5 cegger acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK *data)
575 1.5 cegger {
576 1.5 cegger uint32_t i, pos;
577 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
578 1.5 cegger
579 1.5 cegger acpi_print_hest_header(&data->Header);
580 1.5 cegger printf("\tFlags={ ");
581 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
582 1.5 cegger printf("FIRMWARE_FIRST");
583 1.5 cegger printf(" }\n");
584 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
585 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
586 1.5 cegger data->RecordsToPreallocate);
587 1.5 cegger printf("\tMax Sections per Record=%d\n",
588 1.5 cegger data->MaxSectionsPerRecord);
589 1.5 cegger printf("\tGlobal Capability Init Data=0x%"PRIx64"\n",
590 1.5 cegger data->GlobalCapabilityData);
591 1.5 cegger printf("\tGlobal Control Init Data=0x%"PRIx64"\n",
592 1.5 cegger data->GlobalControlData);
593 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
594 1.5 cegger data->NumHardwareBanks);
595 1.5 cegger
596 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
597 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
598 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
599 1.5 cegger acpi_print_hest_errorbank(bank);
600 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
601 1.5 cegger }
602 1.5 cegger }
603 1.5 cegger
604 1.5 cegger static void
605 1.5 cegger acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED *data)
606 1.5 cegger {
607 1.5 cegger uint32_t i, pos;
608 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
609 1.5 cegger
610 1.5 cegger acpi_print_hest_header(&data->Header);
611 1.5 cegger printf("\tFlags={ ");
612 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
613 1.5 cegger printf("FIRMWARE_FIRST");
614 1.5 cegger printf(" }\n");
615 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
616 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
617 1.5 cegger data->RecordsToPreallocate);
618 1.5 cegger printf("\tMax Sections per Record=%d\n",
619 1.5 cegger data->MaxSectionsPerRecord);
620 1.5 cegger acpi_print_hest_notify(&data->Notify);
621 1.5 cegger
622 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
623 1.5 cegger data->NumHardwareBanks);
624 1.5 cegger
625 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
626 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
627 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
628 1.5 cegger acpi_print_hest_errorbank(bank);
629 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
630 1.5 cegger }
631 1.5 cegger }
632 1.5 cegger
633 1.5 cegger static void
634 1.5 cegger acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI *data)
635 1.5 cegger {
636 1.5 cegger acpi_print_hest_header(&data->Header);
637 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
638 1.5 cegger data->RecordsToPreallocate);
639 1.5 cegger printf("\tMax Sections per Record=%d\n",
640 1.5 cegger data->MaxSectionsPerRecord);
641 1.5 cegger printf("\tMax Raw Data Length=%d\n",
642 1.5 cegger data->MaxRawDataLength);
643 1.5 cegger }
644 1.5 cegger
645 1.5 cegger static void
646 1.5 cegger acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT *data)
647 1.5 cegger {
648 1.5 cegger acpi_print_hest_header(&data->Header);
649 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
650 1.5 cegger printf("Root Error Command Register=0x%x\n", data->RootErrorCommand);
651 1.5 cegger }
652 1.5 cegger
653 1.5 cegger static void
654 1.5 cegger acpi_print_hest_aer_endpoint(ACPI_HEST_AER *data)
655 1.5 cegger {
656 1.5 cegger acpi_print_hest_header(&data->Header);
657 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
658 1.5 cegger }
659 1.5 cegger
660 1.5 cegger static void
661 1.5 cegger acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE *data)
662 1.5 cegger {
663 1.5 cegger acpi_print_hest_header(&data->Header);
664 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
665 1.5 cegger
666 1.5 cegger printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
667 1.5 cegger data->UncorrectableMask2);
668 1.5 cegger printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
669 1.5 cegger data->UncorrectableSeverity2);
670 1.5 cegger printf("\tSecondory Advanced Capabilities Register=0x%x\n",
671 1.5 cegger data->AdvancedCapabilities2);
672 1.5 cegger }
673 1.5 cegger
674 1.5 cegger static void
675 1.5 cegger acpi_print_hest_generic(ACPI_HEST_GENERIC *data)
676 1.5 cegger {
677 1.5 cegger acpi_print_hest_header(&data->Header);
678 1.5 cegger if (data->RelatedSourceId != 0xffff)
679 1.5 cegger printf("\tReleated SourceId=%d\n", data->RelatedSourceId);
680 1.15.8.1 martin printf("\tEnabled={%s}\n", data->Enabled ? "YES" : "NO");
681 1.15.8.1 martin printf("\tNumber of Records to pre-allocate=%u\n",
682 1.5 cegger data->RecordsToPreallocate);
683 1.15.8.1 martin printf("\tMax Sections per Record=%u\n", data->MaxSectionsPerRecord);
684 1.15.8.1 martin printf("\tMax Raw Data Length=%u\n", data->MaxRawDataLength);
685 1.5 cegger printf("\tError Status Address=");
686 1.5 cegger acpi_print_gas(&data->ErrorStatusAddress);
687 1.15.8.1 martin printf("\n");
688 1.5 cegger acpi_print_hest_notify(&data->Notify);
689 1.15.8.1 martin printf("\tError Block Length=%u\n", data->ErrorBlockLength);
690 1.15.8.1 martin }
691 1.15.8.1 martin
692 1.15.8.1 martin static void
693 1.15.8.1 martin acpi_print_hest_generic_v2(ACPI_HEST_GENERIC_V2 *data)
694 1.15.8.1 martin {
695 1.15.8.1 martin
696 1.15.8.1 martin /* The first 64 bytes are the same as ACPI_HEST_GENERIC */
697 1.15.8.1 martin acpi_print_hest_generic((ACPI_HEST_GENERIC *)data);
698 1.15.8.1 martin
699 1.15.8.1 martin printf("\tError Status Address");
700 1.15.8.1 martin acpi_print_gas(&data->ReadAckRegister);
701 1.15.8.1 martin printf("\tRead Ack Preserve=0x%016jx\n",
702 1.15.8.1 martin (uintmax_t)data->ReadAckPreserve);
703 1.15.8.1 martin printf("\tRead Ack Write=0x%016jx\n",
704 1.15.8.1 martin (uintmax_t)data->ReadAckWrite);
705 1.5 cegger }
706 1.5 cegger
707 1.5 cegger static void
708 1.5 cegger acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
709 1.5 cegger {
710 1.5 cegger ACPI_TABLE_HEST *hest;
711 1.5 cegger ACPI_HEST_HEADER *subhest;
712 1.5 cegger uint32_t i, pos;
713 1.5 cegger
714 1.5 cegger printf(BEGIN_COMMENT);
715 1.5 cegger acpi_print_sdt(sdp);
716 1.5 cegger hest = (ACPI_TABLE_HEST *)sdp;
717 1.5 cegger
718 1.5 cegger printf("\tError Source Count=%d\n", hest->ErrorSourceCount);
719 1.5 cegger pos = sizeof(ACPI_TABLE_HEST);
720 1.5 cegger for (i = 0; i < hest->ErrorSourceCount; i++) {
721 1.5 cegger subhest = (ACPI_HEST_HEADER *)((char *)hest + pos);
722 1.5 cegger printf("\n");
723 1.5 cegger
724 1.5 cegger switch (subhest->Type) {
725 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
726 1.15.8.1 martin acpi_print_hest_ia32_check(
727 1.15.8.1 martin (ACPI_HEST_IA_MACHINE_CHECK *)subhest);
728 1.5 cegger pos += sizeof(ACPI_HEST_IA_MACHINE_CHECK);
729 1.5 cegger break;
730 1.5 cegger
731 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
732 1.15.8.1 martin acpi_print_hest_ia32_correctedcheck(
733 1.15.8.1 martin (ACPI_HEST_IA_CORRECTED *)subhest);
734 1.5 cegger pos += sizeof(ACPI_HEST_IA_CORRECTED);
735 1.5 cegger break;
736 1.5 cegger
737 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
738 1.15.8.1 martin acpi_print_hest_ia32_nmi(
739 1.15.8.1 martin (ACPI_HEST_IA_NMI *)subhest);
740 1.5 cegger pos += sizeof(ACPI_HEST_IA_NMI);
741 1.5 cegger break;
742 1.5 cegger
743 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
744 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
745 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
746 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
747 1.5 cegger break;
748 1.5 cegger
749 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
750 1.15.8.1 martin acpi_print_hest_aer_root((ACPI_HEST_AER_ROOT *)subhest);
751 1.5 cegger pos += sizeof(ACPI_HEST_AER_ROOT);
752 1.5 cegger break;
753 1.5 cegger
754 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
755 1.15.8.1 martin acpi_print_hest_aer_endpoint((ACPI_HEST_AER *)subhest);
756 1.15.8.1 martin pos += sizeof(ACPI_HEST_AER);
757 1.5 cegger break;
758 1.5 cegger
759 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
760 1.15.8.1 martin acpi_print_hest_aer_bridge((ACPI_HEST_AER_BRIDGE *)subhest);
761 1.5 cegger pos += sizeof(ACPI_HEST_AER_BRIDGE);
762 1.5 cegger break;
763 1.5 cegger
764 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
765 1.15.8.1 martin acpi_print_hest_generic((ACPI_HEST_GENERIC *)subhest);
766 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC);
767 1.5 cegger break;
768 1.5 cegger
769 1.15.8.1 martin case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
770 1.15.8.1 martin acpi_print_hest_generic_v2(
771 1.15.8.1 martin (ACPI_HEST_GENERIC_V2 *)subhest);
772 1.15.8.1 martin pos += sizeof(ACPI_HEST_GENERIC_V2);
773 1.15.8.1 martin break;
774 1.15.8.1 martin
775 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
776 1.5 cegger default:
777 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
778 1.5 cegger break;
779 1.5 cegger }
780 1.5 cegger }
781 1.5 cegger
782 1.5 cegger printf(END_COMMENT);
783 1.5 cegger }
784 1.5 cegger
785 1.15.8.1 martin static uint64_t
786 1.15.8.1 martin acpi_select_address(uint32_t addr32, uint64_t addr64)
787 1.5 cegger {
788 1.5 cegger
789 1.15.8.1 martin if (addr64 == 0)
790 1.15.8.1 martin return addr32;
791 1.5 cegger
792 1.15.8.1 martin if ((addr32 != 0) && ((addr64 & 0xfffffff) != addr32)) {
793 1.5 cegger /*
794 1.5 cegger * A few systems (e.g., IBM T23) have an RSDP that claims
795 1.5 cegger * revision 2 but the 64 bit addresses are invalid. If
796 1.5 cegger * revision 2 and the 32 bit address is non-zero but the
797 1.5 cegger * 32 and 64 bit versions don't match, prefer the 32 bit
798 1.5 cegger * version for all subsequent tables.
799 1.5 cegger */
800 1.15.8.1 martin return addr32;
801 1.15.8.1 martin }
802 1.15.8.1 martin
803 1.15.8.1 martin return addr64;
804 1.5 cegger }
805 1.5 cegger
806 1.5 cegger static void
807 1.5 cegger acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
808 1.5 cegger {
809 1.5 cegger ACPI_TABLE_HEADER *dsdp;
810 1.5 cegger ACPI_TABLE_FACS *facs;
811 1.5 cegger ACPI_TABLE_FADT *fadt;
812 1.5 cegger
813 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
814 1.5 cegger acpi_print_fadt(sdp);
815 1.5 cegger
816 1.15.8.1 martin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(
817 1.15.8.1 martin acpi_select_address(fadt->Facs, fadt->XFacs));
818 1.5 cegger if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
819 1.5 cegger errx(EXIT_FAILURE, "FACS is corrupt");
820 1.5 cegger acpi_print_facs(facs);
821 1.5 cegger
822 1.15.8.1 martin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(
823 1.15.8.1 martin acpi_select_address(fadt->Dsdt, fadt->XDsdt));
824 1.15.8.1 martin if (memcmp(dsdp->Signature, ACPI_SIG_DSDT, 4) != 0)
825 1.15.8.1 martin errx(EXIT_FAILURE, "DSDT signature mismatch");
826 1.5 cegger if (acpi_checksum(dsdp, dsdp->Length))
827 1.5 cegger errx(EXIT_FAILURE, "DSDT is corrupt");
828 1.5 cegger acpi_print_dsdt(dsdp);
829 1.5 cegger }
830 1.5 cegger
831 1.5 cegger static void
832 1.5 cegger acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
833 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *))
834 1.5 cegger {
835 1.5 cegger ACPI_SUBTABLE_HEADER *subtable;
836 1.5 cegger char *end;
837 1.5 cegger
838 1.5 cegger subtable = first;
839 1.5 cegger end = (char *)table + table->Length;
840 1.5 cegger while ((char *)subtable < end) {
841 1.5 cegger printf("\n");
842 1.15.8.1 martin if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
843 1.15.8.1 martin warnx("invalid subtable length %u", subtable->Length);
844 1.15.8.1 martin return;
845 1.15.8.1 martin }
846 1.5 cegger action(subtable);
847 1.5 cegger subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
848 1.5 cegger subtable->Length);
849 1.5 cegger }
850 1.5 cegger }
851 1.5 cegger
852 1.5 cegger static void
853 1.15.8.1 martin acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
854 1.15.8.1 martin void (*action)(ACPI_NFIT_HEADER *))
855 1.15.8.1 martin {
856 1.15.8.1 martin ACPI_NFIT_HEADER *subtable;
857 1.15.8.1 martin char *end;
858 1.15.8.1 martin
859 1.15.8.1 martin subtable = first;
860 1.15.8.1 martin end = (char *)table + table->Length;
861 1.15.8.1 martin while ((char *)subtable < end) {
862 1.15.8.1 martin printf("\n");
863 1.15.8.1 martin if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
864 1.15.8.1 martin warnx("invalid subtable length %u", subtable->Length);
865 1.15.8.1 martin return;
866 1.15.8.1 martin }
867 1.15.8.1 martin action(subtable);
868 1.15.8.1 martin subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
869 1.15.8.1 martin subtable->Length);
870 1.15.8.1 martin }
871 1.15.8.1 martin }
872 1.15.8.1 martin
873 1.15.8.1 martin static void
874 1.5 cegger acpi_print_cpu(u_char cpu_id)
875 1.5 cegger {
876 1.5 cegger
877 1.5 cegger printf("\tACPI CPU=");
878 1.5 cegger if (cpu_id == 0xff)
879 1.5 cegger printf("ALL\n");
880 1.5 cegger else
881 1.5 cegger printf("%d\n", (u_int)cpu_id);
882 1.5 cegger }
883 1.5 cegger
884 1.5 cegger static void
885 1.5 cegger acpi_print_cpu_uid(uint32_t uid, char *uid_string)
886 1.5 cegger {
887 1.5 cegger
888 1.5 cegger printf("\tUID=%d", uid);
889 1.5 cegger if (uid_string != NULL)
890 1.5 cegger printf(" (%s)", uid_string);
891 1.5 cegger printf("\n");
892 1.5 cegger }
893 1.5 cegger
894 1.5 cegger static void
895 1.5 cegger acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
896 1.5 cegger {
897 1.5 cegger
898 1.5 cegger printf("\tFlags={");
899 1.5 cegger if (flags & ACPI_MADT_ENABLED)
900 1.5 cegger printf("ENABLED");
901 1.5 cegger else
902 1.5 cegger printf("DISABLED");
903 1.5 cegger printf("}\n");
904 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
905 1.5 cegger }
906 1.5 cegger
907 1.5 cegger static void
908 1.5 cegger acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
909 1.5 cegger {
910 1.5 cegger
911 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
912 1.5 cegger printf("\tINT BASE=%d\n", int_base);
913 1.5 cegger printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
914 1.5 cegger }
915 1.5 cegger
916 1.5 cegger static void
917 1.5 cegger acpi_print_mps_flags(uint16_t flags)
918 1.5 cegger {
919 1.5 cegger
920 1.5 cegger printf("\tFlags={Polarity=");
921 1.5 cegger switch (flags & ACPI_MADT_POLARITY_MASK) {
922 1.5 cegger case ACPI_MADT_POLARITY_CONFORMS:
923 1.5 cegger printf("conforming");
924 1.5 cegger break;
925 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_HIGH:
926 1.5 cegger printf("active-hi");
927 1.5 cegger break;
928 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_LOW:
929 1.5 cegger printf("active-lo");
930 1.5 cegger break;
931 1.5 cegger default:
932 1.5 cegger printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
933 1.5 cegger break;
934 1.5 cegger }
935 1.5 cegger printf(", Trigger=");
936 1.5 cegger switch (flags & ACPI_MADT_TRIGGER_MASK) {
937 1.5 cegger case ACPI_MADT_TRIGGER_CONFORMS:
938 1.5 cegger printf("conforming");
939 1.5 cegger break;
940 1.5 cegger case ACPI_MADT_TRIGGER_EDGE:
941 1.5 cegger printf("edge");
942 1.5 cegger break;
943 1.5 cegger case ACPI_MADT_TRIGGER_LEVEL:
944 1.5 cegger printf("level");
945 1.5 cegger break;
946 1.5 cegger default:
947 1.5 cegger printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
948 1.5 cegger }
949 1.5 cegger printf("}\n");
950 1.5 cegger }
951 1.5 cegger
952 1.5 cegger static void
953 1.15.8.1 martin acpi_print_gicc_flags(uint32_t flags)
954 1.15.8.1 martin {
955 1.15.8.1 martin
956 1.15.8.1 martin printf("\tFlags={Performance intr=");
957 1.15.8.1 martin if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
958 1.15.8.1 martin printf("edge");
959 1.15.8.1 martin else
960 1.15.8.1 martin printf("level");
961 1.15.8.1 martin printf(", VGIC intr=");
962 1.15.8.1 martin if (flags & ACPI_MADT_VGIC_IRQ_MODE)
963 1.15.8.1 martin printf("edge");
964 1.15.8.1 martin else
965 1.15.8.1 martin printf("level");
966 1.15.8.1 martin printf("}\n");
967 1.15.8.1 martin }
968 1.15.8.1 martin
969 1.15.8.1 martin static void
970 1.5 cegger acpi_print_intr(uint32_t intr, uint16_t mps_flags)
971 1.5 cegger {
972 1.5 cegger
973 1.5 cegger printf("\tINTR=%d\n", intr);
974 1.5 cegger acpi_print_mps_flags(mps_flags);
975 1.5 cegger }
976 1.5 cegger
977 1.5 cegger static void
978 1.5 cegger acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
979 1.5 cegger {
980 1.5 cegger
981 1.5 cegger printf("\tLINT Pin=%d\n", lint);
982 1.5 cegger acpi_print_mps_flags(mps_flags);
983 1.5 cegger }
984 1.5 cegger
985 1.15.8.1 martin static const char *apic_types[] = {
986 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
987 1.15.8.1 martin [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
988 1.15.8.1 martin [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
989 1.15.8.1 martin [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
990 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
991 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
992 1.15.8.1 martin [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
993 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
994 1.15.8.1 martin [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
995 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
996 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
997 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
998 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
999 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
1000 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
1001 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
1002 1.15.8.1 martin };
1003 1.15.8.1 martin
1004 1.15.8.1 martin static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
1005 1.15.8.1 martin "Corrected Platform Error" };
1006 1.15.8.1 martin
1007 1.15.8.1 martin static void
1008 1.15.8.1 martin acpi_print_gicm_flags(ACPI_MADT_GENERIC_MSI_FRAME *gicm)
1009 1.15.8.1 martin {
1010 1.15.8.1 martin uint32_t flags = gicm->Flags;
1011 1.15.8.1 martin
1012 1.15.8.1 martin printf("\tFLAGS={");
1013 1.15.8.1 martin if (flags & ACPI_MADT_OVERRIDE_SPI_VALUES)
1014 1.15.8.1 martin printf("SPI Count/Base Select");
1015 1.15.8.1 martin printf("}\n");
1016 1.15.8.1 martin }
1017 1.5 cegger
1018 1.5 cegger static void
1019 1.5 cegger acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
1020 1.5 cegger {
1021 1.5 cegger ACPI_MADT_LOCAL_APIC *lapic;
1022 1.5 cegger ACPI_MADT_IO_APIC *ioapic;
1023 1.5 cegger ACPI_MADT_INTERRUPT_OVERRIDE *over;
1024 1.5 cegger ACPI_MADT_NMI_SOURCE *nmi;
1025 1.5 cegger ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
1026 1.5 cegger ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
1027 1.5 cegger ACPI_MADT_IO_SAPIC *iosapic;
1028 1.5 cegger ACPI_MADT_LOCAL_SAPIC *lsapic;
1029 1.5 cegger ACPI_MADT_INTERRUPT_SOURCE *isrc;
1030 1.5 cegger ACPI_MADT_LOCAL_X2APIC *x2apic;
1031 1.5 cegger ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
1032 1.15.8.1 martin ACPI_MADT_GENERIC_INTERRUPT *gicc;
1033 1.15.8.1 martin ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
1034 1.15.8.1 martin ACPI_MADT_GENERIC_MSI_FRAME *gicm;
1035 1.15.8.1 martin ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
1036 1.15.8.1 martin ACPI_MADT_GENERIC_TRANSLATOR *gict;
1037 1.5 cegger
1038 1.15.8.1 martin if (mp->Type < __arraycount(apic_types))
1039 1.5 cegger printf("\tType=%s\n", apic_types[mp->Type]);
1040 1.5 cegger else
1041 1.5 cegger printf("\tType=%d (unknown)\n", mp->Type);
1042 1.5 cegger switch (mp->Type) {
1043 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC:
1044 1.5 cegger lapic = (ACPI_MADT_LOCAL_APIC *)mp;
1045 1.5 cegger acpi_print_cpu(lapic->ProcessorId);
1046 1.5 cegger acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
1047 1.5 cegger break;
1048 1.5 cegger case ACPI_MADT_TYPE_IO_APIC:
1049 1.5 cegger ioapic = (ACPI_MADT_IO_APIC *)mp;
1050 1.5 cegger acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
1051 1.5 cegger ioapic->Address);
1052 1.5 cegger break;
1053 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1054 1.5 cegger over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
1055 1.5 cegger printf("\tBUS=%d\n", (u_int)over->Bus);
1056 1.5 cegger printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
1057 1.5 cegger acpi_print_intr(over->GlobalIrq, over->IntiFlags);
1058 1.5 cegger break;
1059 1.5 cegger case ACPI_MADT_TYPE_NMI_SOURCE:
1060 1.5 cegger nmi = (ACPI_MADT_NMI_SOURCE *)mp;
1061 1.5 cegger acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
1062 1.5 cegger break;
1063 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1064 1.5 cegger lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
1065 1.5 cegger acpi_print_cpu(lapic_nmi->ProcessorId);
1066 1.5 cegger acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
1067 1.5 cegger break;
1068 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1069 1.5 cegger lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
1070 1.5 cegger printf("\tLocal APIC ADDR=0x%016jx\n",
1071 1.5 cegger (uintmax_t)lapic_over->Address);
1072 1.5 cegger break;
1073 1.5 cegger case ACPI_MADT_TYPE_IO_SAPIC:
1074 1.5 cegger iosapic = (ACPI_MADT_IO_SAPIC *)mp;
1075 1.5 cegger acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
1076 1.5 cegger iosapic->Address);
1077 1.5 cegger break;
1078 1.5 cegger case ACPI_MADT_TYPE_LOCAL_SAPIC:
1079 1.5 cegger lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
1080 1.5 cegger acpi_print_cpu(lsapic->ProcessorId);
1081 1.5 cegger acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
1082 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
1083 1.5 cegger if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
1084 1.5 cegger acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
1085 1.5 cegger break;
1086 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1087 1.5 cegger isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
1088 1.15.8.1 martin if (isrc->Type < __arraycount(platform_int_types))
1089 1.5 cegger printf("\tType=%s\n", platform_int_types[isrc->Type]);
1090 1.5 cegger else
1091 1.5 cegger printf("\tType=%d (unknown)\n", isrc->Type);
1092 1.5 cegger printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
1093 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
1094 1.5 cegger printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
1095 1.5 cegger acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
1096 1.5 cegger break;
1097 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC:
1098 1.5 cegger x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
1099 1.5 cegger acpi_print_cpu_uid(x2apic->Uid, NULL);
1100 1.5 cegger acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
1101 1.5 cegger break;
1102 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1103 1.5 cegger x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
1104 1.5 cegger acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
1105 1.5 cegger acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
1106 1.5 cegger break;
1107 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1108 1.15.8.1 martin gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
1109 1.15.8.1 martin acpi_print_cpu_uid(gicc->Uid, NULL);
1110 1.15.8.1 martin printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
1111 1.15.8.1 martin acpi_print_gicc_flags(gicc->Flags);
1112 1.15.8.1 martin printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
1113 1.15.8.1 martin printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
1114 1.15.8.1 martin printf("\tParked ADDR=%016jx\n",
1115 1.15.8.1 martin (uintmax_t)gicc->ParkedAddress);
1116 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
1117 1.15.8.1 martin printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
1118 1.15.8.1 martin printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
1119 1.15.8.1 martin printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
1120 1.15.8.1 martin printf("\tGICR ADDR=%016jx\n",
1121 1.15.8.1 martin (uintmax_t)gicc->GicrBaseAddress);
1122 1.15.8.1 martin printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
1123 1.15.8.1 martin printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
1124 1.15.8.1 martin break;
1125 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1126 1.15.8.1 martin gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
1127 1.15.8.1 martin printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
1128 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
1129 1.15.8.1 martin printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
1130 1.15.8.1 martin printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
1131 1.15.8.1 martin break;
1132 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1133 1.15.8.1 martin gicm = (ACPI_MADT_GENERIC_MSI_FRAME*)mp;
1134 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicm->BaseAddress);
1135 1.15.8.1 martin acpi_print_gicm_flags(gicm);
1136 1.15.8.1 martin printf("\tSPI Count=%u\n", gicm->SpiCount);
1137 1.15.8.1 martin printf("\tSPI Base=%u\n", gicm->SpiBase);
1138 1.15.8.1 martin break;
1139 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1140 1.15.8.1 martin gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
1141 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
1142 1.15.8.1 martin printf("\tLength=%08x\n", gicr->Length);
1143 1.15.8.1 martin break;
1144 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
1145 1.15.8.1 martin gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
1146 1.15.8.1 martin printf("\tGIC ITS ID=%d\n", gict->TranslationId);
1147 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
1148 1.15.8.1 martin break;
1149 1.5 cegger }
1150 1.5 cegger }
1151 1.5 cegger
1152 1.5 cegger #ifdef notyet
1153 1.5 cegger static void
1154 1.5 cegger acpi_print_bert_region(ACPI_BERT_REGION *region)
1155 1.5 cegger {
1156 1.5 cegger uint32_t i, pos, entries;
1157 1.5 cegger ACPI_HEST_GENERIC_DATA *data;
1158 1.5 cegger
1159 1.5 cegger printf("\n");
1160 1.5 cegger printf("\tBlockStatus={ ");
1161 1.5 cegger
1162 1.5 cegger if (region->BlockStatus & ACPI_BERT_UNCORRECTABLE)
1163 1.5 cegger printf("Uncorrectable");
1164 1.5 cegger if (region->BlockStatus & ACPI_BERT_CORRECTABLE)
1165 1.5 cegger printf("Correctable");
1166 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_UNCORRECTABLE)
1167 1.5 cegger printf("Multiple Uncorrectable");
1168 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_CORRECTABLE)
1169 1.5 cegger printf("Multiple Correctable");
1170 1.5 cegger entries = region->BlockStatus & ACPI_BERT_ERROR_ENTRY_COUNT;
1171 1.5 cegger printf(", Error Entry Count=%d", entries);
1172 1.5 cegger printf("}\n");
1173 1.5 cegger
1174 1.5 cegger printf("\tRaw Data Offset=0x%x\n", region->RawDataOffset);
1175 1.5 cegger printf("\tRaw Data Length=0x%x\n", region->RawDataLength);
1176 1.5 cegger printf("\tData Length=0x%x\n", region->DataLength);
1177 1.5 cegger
1178 1.5 cegger acpi_print_hest_errorseverity(region->ErrorSeverity);
1179 1.5 cegger
1180 1.5 cegger pos = sizeof(ACPI_BERT_REGION);
1181 1.5 cegger for (i = 0; i < entries; i++) {
1182 1.5 cegger data = (ACPI_HEST_GENERIC_DATA *)((char *)region + pos);
1183 1.5 cegger acpi_print_hest_generic_data(data);
1184 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
1185 1.5 cegger }
1186 1.5 cegger }
1187 1.5 cegger #endif
1188 1.5 cegger
1189 1.5 cegger static void
1190 1.5 cegger acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
1191 1.5 cegger {
1192 1.5 cegger ACPI_TABLE_BERT *bert;
1193 1.5 cegger
1194 1.5 cegger printf(BEGIN_COMMENT);
1195 1.5 cegger acpi_print_sdt(sdp);
1196 1.5 cegger bert = (ACPI_TABLE_BERT *)sdp;
1197 1.5 cegger
1198 1.5 cegger printf("\tLength of Boot Error Region=%d bytes\n", bert->RegionLength);
1199 1.5 cegger printf("\tPhysical Address of Region=0x%"PRIx64"\n", bert->Address);
1200 1.5 cegger
1201 1.5 cegger printf(END_COMMENT);
1202 1.5 cegger }
1203 1.5 cegger
1204 1.5 cegger static void
1205 1.5 cegger acpi_handle_boot(ACPI_TABLE_HEADER *sdp)
1206 1.5 cegger {
1207 1.5 cegger ACPI_TABLE_BOOT *boot;
1208 1.5 cegger
1209 1.5 cegger printf(BEGIN_COMMENT);
1210 1.5 cegger acpi_print_sdt(sdp);
1211 1.5 cegger boot = (ACPI_TABLE_BOOT *)sdp;
1212 1.5 cegger printf("\tCMOS Index=0x%02x\n", boot->CmosIndex);
1213 1.5 cegger printf(END_COMMENT);
1214 1.5 cegger }
1215 1.5 cegger
1216 1.5 cegger static void
1217 1.5 cegger acpi_handle_cpep(ACPI_TABLE_HEADER *sdp)
1218 1.5 cegger {
1219 1.5 cegger ACPI_TABLE_CPEP *cpep;
1220 1.5 cegger ACPI_CPEP_POLLING *poll;
1221 1.5 cegger uint32_t cpep_pos;
1222 1.5 cegger
1223 1.5 cegger printf(BEGIN_COMMENT);
1224 1.5 cegger acpi_print_sdt(sdp);
1225 1.5 cegger cpep = (ACPI_TABLE_CPEP *)sdp;
1226 1.5 cegger
1227 1.5 cegger cpep_pos = sizeof(ACPI_TABLE_CPEP);
1228 1.5 cegger while (cpep_pos < sdp->Length) {
1229 1.5 cegger poll = (ACPI_CPEP_POLLING *)((char *)cpep + cpep_pos);
1230 1.5 cegger acpi_print_cpu(poll->Id);
1231 1.5 cegger printf("\tACPI CPU EId=%d\n", poll->Eid);
1232 1.5 cegger printf("\tPoll Interval=%d msec\n", poll->Interval);
1233 1.5 cegger cpep_pos += sizeof(ACPI_CPEP_POLLING);
1234 1.5 cegger }
1235 1.5 cegger printf(END_COMMENT);
1236 1.5 cegger }
1237 1.5 cegger
1238 1.5 cegger static void
1239 1.5 cegger acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp)
1240 1.5 cegger {
1241 1.5 cegger ACPI_TABLE_DBGP *dbgp;
1242 1.5 cegger
1243 1.5 cegger printf(BEGIN_COMMENT);
1244 1.5 cegger acpi_print_sdt(sdp);
1245 1.5 cegger dbgp = (ACPI_TABLE_DBGP *)sdp;
1246 1.5 cegger printf("\tType={");
1247 1.5 cegger switch (dbgp->Type) {
1248 1.5 cegger case 0:
1249 1.5 cegger printf("full 16550");
1250 1.5 cegger break;
1251 1.5 cegger case 1:
1252 1.5 cegger printf("subset of 16550");
1253 1.5 cegger break;
1254 1.5 cegger }
1255 1.5 cegger printf("}\n");
1256 1.15.8.1 martin printf("\tDebugPort=");
1257 1.5 cegger acpi_print_gas(&dbgp->DebugPort);
1258 1.15.8.1 martin printf("\n");
1259 1.15.8.1 martin printf(END_COMMENT);
1260 1.15.8.1 martin }
1261 1.15.8.1 martin
1262 1.15.8.1 martin static void
1263 1.15.8.1 martin acpi_print_dbg2_device(ACPI_DBG2_DEVICE *dev)
1264 1.15.8.1 martin {
1265 1.15.8.1 martin
1266 1.15.8.1 martin printf("\t\tRevision=%u\n", dev->Revision);
1267 1.15.8.1 martin printf("\t\tLength=%u\n", dev->Length);
1268 1.15.8.1 martin printf("\t\tRegisterCount=%u\n", dev->RegisterCount);
1269 1.15.8.1 martin
1270 1.15.8.1 martin printf("\t\tNamepath=");
1271 1.15.8.1 martin acpi_print_string((char *)((vaddr_t)dev + dev->NamepathOffset),
1272 1.15.8.1 martin dev->NamepathLength);
1273 1.15.8.1 martin printf("\n");
1274 1.15.8.1 martin
1275 1.15.8.1 martin if (dev->OemDataLength) {
1276 1.15.8.1 martin printf("\t\tOemDataLength=%u\n", dev->OemDataLength);
1277 1.15.8.1 martin printf("\t\tOemDataOffset=%u\n", dev->OemDataOffset);
1278 1.15.8.1 martin /* XXX need dump */
1279 1.15.8.1 martin }
1280 1.15.8.1 martin
1281 1.15.8.1 martin printf("\t\tPortType=");
1282 1.15.8.1 martin switch (dev->PortType) {
1283 1.15.8.1 martin case ACPI_DBG2_SERIAL_PORT:
1284 1.15.8.1 martin printf("Serial\n" "\t\tPortSubtype=");
1285 1.15.8.1 martin switch (dev->PortSubtype) {
1286 1.15.8.1 martin case ACPI_DBG2_16550_COMPATIBLE:
1287 1.15.8.1 martin printf("Fully 16550 compatible\n");
1288 1.15.8.1 martin break;
1289 1.15.8.1 martin case ACPI_DBG2_16550_SUBSET:
1290 1.15.8.1 martin printf("16550 subset with DBGP Rev. 1\n");
1291 1.15.8.1 martin break;
1292 1.15.8.1 martin case ACPI_DBG2_ARM_PL011:
1293 1.15.8.1 martin printf("ARM PL011\n");
1294 1.15.8.1 martin break;
1295 1.15.8.1 martin case ACPI_DBG2_ARM_SBSA_32BIT:
1296 1.15.8.1 martin printf("ARM SBSA 32bit only\n");
1297 1.15.8.1 martin break;
1298 1.15.8.1 martin case ACPI_DBG2_ARM_SBSA_GENERIC:
1299 1.15.8.1 martin printf("ARM SBSA Generic\n");
1300 1.15.8.1 martin break;
1301 1.15.8.1 martin case ACPI_DBG2_ARM_DCC:
1302 1.15.8.1 martin printf("ARM DCC\n");
1303 1.15.8.1 martin break;
1304 1.15.8.1 martin case ACPI_DBG2_BCM2835:
1305 1.15.8.1 martin printf("BCM2835\n");
1306 1.15.8.1 martin break;
1307 1.15.8.1 martin default:
1308 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortSubtype);
1309 1.15.8.1 martin break;
1310 1.15.8.1 martin }
1311 1.15.8.1 martin break;
1312 1.15.8.1 martin case ACPI_DBG2_1394_PORT:
1313 1.15.8.1 martin printf("IEEE1394\n" "\t\tPortSubtype=");
1314 1.15.8.1 martin if (dev->PortSubtype == ACPI_DBG2_1394_STANDARD)
1315 1.15.8.1 martin printf("Standard\n");
1316 1.15.8.1 martin else
1317 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortSubtype);
1318 1.15.8.1 martin break;
1319 1.15.8.1 martin case ACPI_DBG2_USB_PORT:
1320 1.15.8.1 martin printf("USB\n" "\t\tPortSubtype=");
1321 1.15.8.1 martin switch (dev->PortSubtype) {
1322 1.15.8.1 martin case ACPI_DBG2_USB_XHCI:
1323 1.15.8.1 martin printf("XHCIn");
1324 1.15.8.1 martin break;
1325 1.15.8.1 martin case ACPI_DBG2_USB_EHCI:
1326 1.15.8.1 martin printf("EHCI\n");
1327 1.15.8.1 martin break;
1328 1.15.8.1 martin default:
1329 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortSubtype);
1330 1.15.8.1 martin break;
1331 1.15.8.1 martin }
1332 1.15.8.1 martin break;
1333 1.15.8.1 martin case ACPI_DBG2_NET_PORT:
1334 1.15.8.1 martin printf("Net\n" "\t\tPciVendorID=%04x\n", dev->PortSubtype);
1335 1.15.8.1 martin break;
1336 1.15.8.1 martin default:
1337 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortType);
1338 1.15.8.1 martin printf("\t\tPortSubtype=reserved (%04hx)\n", dev->PortSubtype);
1339 1.15.8.1 martin break;
1340 1.15.8.1 martin }
1341 1.15.8.1 martin
1342 1.15.8.1 martin printf("\t\tBaseAddressOffset=0x%04x\n", dev->BaseAddressOffset);
1343 1.15.8.1 martin printf("\t\tAddressSizeOffset=0x%04x\n", dev->AddressSizeOffset);
1344 1.15.8.1 martin }
1345 1.15.8.1 martin
1346 1.15.8.1 martin static void
1347 1.15.8.1 martin acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp)
1348 1.15.8.1 martin {
1349 1.15.8.1 martin ACPI_TABLE_DBG2 *dbg2;
1350 1.15.8.1 martin ACPI_DBG2_DEVICE *device;
1351 1.15.8.1 martin unsigned int i;
1352 1.15.8.1 martin
1353 1.15.8.1 martin printf(BEGIN_COMMENT);
1354 1.15.8.1 martin acpi_print_sdt(sdp);
1355 1.15.8.1 martin dbg2 = (ACPI_TABLE_DBG2 *)sdp;
1356 1.15.8.1 martin
1357 1.15.8.1 martin printf("\tCount=%u\n", dbg2->InfoCount);
1358 1.15.8.1 martin device = (ACPI_DBG2_DEVICE *)((vaddr_t)sdp + dbg2->InfoOffset);
1359 1.15.8.1 martin for (i = 0; i < dbg2->InfoCount; i++) {
1360 1.15.8.1 martin printf("\tDevice %u={\n", i);
1361 1.15.8.1 martin acpi_print_dbg2_device(device);
1362 1.15.8.1 martin printf("\t}\n");
1363 1.15.8.1 martin device++;
1364 1.15.8.1 martin }
1365 1.15.8.1 martin
1366 1.5 cegger printf(END_COMMENT);
1367 1.5 cegger }
1368 1.5 cegger
1369 1.5 cegger static void
1370 1.5 cegger acpi_print_einj_action(ACPI_WHEA_HEADER *whea)
1371 1.5 cegger {
1372 1.5 cegger printf("\tACTION={");
1373 1.5 cegger switch (whea->Action) {
1374 1.5 cegger case ACPI_EINJ_BEGIN_OPERATION:
1375 1.5 cegger printf("Begin Operation");
1376 1.5 cegger break;
1377 1.5 cegger case ACPI_EINJ_GET_TRIGGER_TABLE:
1378 1.5 cegger printf("Get Trigger Table");
1379 1.5 cegger break;
1380 1.5 cegger case ACPI_EINJ_SET_ERROR_TYPE:
1381 1.5 cegger printf("Set Error Type");
1382 1.5 cegger break;
1383 1.5 cegger case ACPI_EINJ_GET_ERROR_TYPE:
1384 1.5 cegger printf("Get Error Type");
1385 1.5 cegger break;
1386 1.5 cegger case ACPI_EINJ_END_OPERATION:
1387 1.5 cegger printf("End Operation");
1388 1.5 cegger break;
1389 1.5 cegger case ACPI_EINJ_EXECUTE_OPERATION:
1390 1.5 cegger printf("Execute Operation");
1391 1.5 cegger break;
1392 1.5 cegger case ACPI_EINJ_CHECK_BUSY_STATUS:
1393 1.5 cegger printf("Check Busy Status");
1394 1.5 cegger break;
1395 1.5 cegger case ACPI_EINJ_GET_COMMAND_STATUS:
1396 1.5 cegger printf("Get Command Status");
1397 1.5 cegger break;
1398 1.15.8.1 martin case ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
1399 1.15.8.1 martin printf("Set Error Type With Address");
1400 1.15.8.1 martin break;
1401 1.15.8.1 martin case ACPI_EINJ_GET_EXECUTE_TIMINGS:
1402 1.15.8.1 martin printf("Get Execute Operation Timings");
1403 1.15.8.1 martin break;
1404 1.5 cegger case ACPI_EINJ_ACTION_RESERVED:
1405 1.5 cegger printf("Preserved");
1406 1.5 cegger break;
1407 1.5 cegger case ACPI_EINJ_TRIGGER_ERROR:
1408 1.5 cegger printf("Trigger Error");
1409 1.5 cegger break;
1410 1.5 cegger default:
1411 1.5 cegger printf("%d", whea->Action);
1412 1.5 cegger break;
1413 1.5 cegger }
1414 1.5 cegger printf("}\n");
1415 1.5 cegger }
1416 1.5 cegger
1417 1.5 cegger static void
1418 1.5 cegger acpi_print_einj_instruction(ACPI_WHEA_HEADER *whea)
1419 1.5 cegger {
1420 1.5 cegger uint32_t ins = whea->Instruction;
1421 1.5 cegger
1422 1.5 cegger printf("\tINSTRUCTION={");
1423 1.5 cegger switch (ins) {
1424 1.5 cegger case ACPI_EINJ_READ_REGISTER:
1425 1.5 cegger printf("Read Register");
1426 1.5 cegger break;
1427 1.5 cegger case ACPI_EINJ_READ_REGISTER_VALUE:
1428 1.5 cegger printf("Read Register Value");
1429 1.5 cegger break;
1430 1.5 cegger case ACPI_EINJ_WRITE_REGISTER:
1431 1.5 cegger printf("Write Register");
1432 1.5 cegger break;
1433 1.5 cegger case ACPI_EINJ_WRITE_REGISTER_VALUE:
1434 1.5 cegger printf("Write Register Value");
1435 1.5 cegger break;
1436 1.5 cegger case ACPI_EINJ_NOOP:
1437 1.5 cegger printf("Noop");
1438 1.5 cegger break;
1439 1.5 cegger case ACPI_EINJ_INSTRUCTION_RESERVED:
1440 1.5 cegger printf("Reserved");
1441 1.5 cegger break;
1442 1.5 cegger default:
1443 1.5 cegger printf("%d", ins);
1444 1.5 cegger break;
1445 1.5 cegger }
1446 1.5 cegger printf("}\n");
1447 1.5 cegger }
1448 1.5 cegger
1449 1.5 cegger static void
1450 1.5 cegger acpi_print_einj_flags(ACPI_WHEA_HEADER *whea)
1451 1.5 cegger {
1452 1.5 cegger uint32_t flags = whea->Flags;
1453 1.5 cegger
1454 1.15.8.1 martin printf("\tFLAGS={");
1455 1.5 cegger if (flags & ACPI_EINJ_PRESERVE)
1456 1.5 cegger printf("PRESERVED");
1457 1.5 cegger printf("}\n");
1458 1.5 cegger }
1459 1.5 cegger
1460 1.5 cegger static void
1461 1.5 cegger acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
1462 1.5 cegger {
1463 1.5 cegger ACPI_TABLE_EINJ *einj;
1464 1.5 cegger ACPI_EINJ_ENTRY *einj_entry;
1465 1.5 cegger uint32_t einj_pos;
1466 1.5 cegger u_int i;
1467 1.5 cegger
1468 1.5 cegger printf(BEGIN_COMMENT);
1469 1.5 cegger acpi_print_sdt(sdp);
1470 1.5 cegger einj = (ACPI_TABLE_EINJ *)sdp;
1471 1.5 cegger
1472 1.5 cegger printf("\tHeader Length=%d\n", einj->HeaderLength);
1473 1.5 cegger printf("\tFlags=0x%x\n", einj->Flags);
1474 1.5 cegger printf("\tEntries=%d\n", einj->Entries);
1475 1.5 cegger
1476 1.5 cegger einj_pos = sizeof(ACPI_TABLE_EINJ);
1477 1.5 cegger for (i = 0; i < einj->Entries; i++) {
1478 1.5 cegger einj_entry = (ACPI_EINJ_ENTRY *)((char *)einj + einj_pos);
1479 1.5 cegger acpi_print_whea(&einj_entry->WheaHeader,
1480 1.5 cegger acpi_print_einj_action, acpi_print_einj_instruction,
1481 1.5 cegger acpi_print_einj_flags);
1482 1.5 cegger einj_pos += sizeof(ACPI_EINJ_ENTRY);
1483 1.5 cegger }
1484 1.5 cegger printf(END_COMMENT);
1485 1.5 cegger }
1486 1.5 cegger
1487 1.5 cegger static void
1488 1.5 cegger acpi_print_erst_action(ACPI_WHEA_HEADER *whea)
1489 1.5 cegger {
1490 1.5 cegger printf("\tACTION={");
1491 1.5 cegger switch (whea->Action) {
1492 1.5 cegger case ACPI_ERST_BEGIN_WRITE:
1493 1.5 cegger printf("Begin Write");
1494 1.5 cegger break;
1495 1.5 cegger case ACPI_ERST_BEGIN_READ:
1496 1.5 cegger printf("Begin Read");
1497 1.5 cegger break;
1498 1.5 cegger case ACPI_ERST_BEGIN_CLEAR:
1499 1.5 cegger printf("Begin Clear");
1500 1.5 cegger break;
1501 1.5 cegger case ACPI_ERST_END:
1502 1.5 cegger printf("End");
1503 1.5 cegger break;
1504 1.5 cegger case ACPI_ERST_SET_RECORD_OFFSET:
1505 1.5 cegger printf("Set Record Offset");
1506 1.5 cegger break;
1507 1.5 cegger case ACPI_ERST_EXECUTE_OPERATION:
1508 1.5 cegger printf("Execute Operation");
1509 1.5 cegger break;
1510 1.5 cegger case ACPI_ERST_CHECK_BUSY_STATUS:
1511 1.5 cegger printf("Check Busy Status");
1512 1.5 cegger break;
1513 1.5 cegger case ACPI_ERST_GET_COMMAND_STATUS:
1514 1.5 cegger printf("Get Command Status");
1515 1.5 cegger break;
1516 1.5 cegger case ACPI_ERST_GET_RECORD_ID:
1517 1.5 cegger printf("Get Record ID");
1518 1.5 cegger break;
1519 1.5 cegger case ACPI_ERST_SET_RECORD_ID:
1520 1.5 cegger printf("Set Record ID");
1521 1.5 cegger break;
1522 1.5 cegger case ACPI_ERST_GET_RECORD_COUNT:
1523 1.5 cegger printf("Get Record Count");
1524 1.5 cegger break;
1525 1.5 cegger case ACPI_ERST_BEGIN_DUMMY_WRIITE:
1526 1.5 cegger printf("Begin Dummy Write");
1527 1.5 cegger break;
1528 1.5 cegger case ACPI_ERST_NOT_USED:
1529 1.5 cegger printf("Unused");
1530 1.5 cegger break;
1531 1.5 cegger case ACPI_ERST_GET_ERROR_RANGE:
1532 1.5 cegger printf("Get Error Range");
1533 1.5 cegger break;
1534 1.5 cegger case ACPI_ERST_GET_ERROR_LENGTH:
1535 1.5 cegger printf("Get Error Length");
1536 1.5 cegger break;
1537 1.5 cegger case ACPI_ERST_GET_ERROR_ATTRIBUTES:
1538 1.5 cegger printf("Get Error Attributes");
1539 1.5 cegger break;
1540 1.15.8.1 martin case ACPI_ERST_EXECUTE_TIMINGS:
1541 1.15.8.1 martin printf("Execute Operation Timings");
1542 1.15.8.1 martin break;
1543 1.5 cegger case ACPI_ERST_ACTION_RESERVED:
1544 1.5 cegger printf("Reserved");
1545 1.5 cegger break;
1546 1.5 cegger default:
1547 1.5 cegger printf("%d", whea->Action);
1548 1.5 cegger break;
1549 1.5 cegger }
1550 1.5 cegger printf("}\n");
1551 1.5 cegger }
1552 1.5 cegger
1553 1.5 cegger static void
1554 1.5 cegger acpi_print_erst_instruction(ACPI_WHEA_HEADER *whea)
1555 1.5 cegger {
1556 1.5 cegger printf("\tINSTRUCTION={");
1557 1.5 cegger switch (whea->Instruction) {
1558 1.5 cegger case ACPI_ERST_READ_REGISTER:
1559 1.5 cegger printf("Read Register");
1560 1.5 cegger break;
1561 1.5 cegger case ACPI_ERST_READ_REGISTER_VALUE:
1562 1.5 cegger printf("Read Register Value");
1563 1.5 cegger break;
1564 1.5 cegger case ACPI_ERST_WRITE_REGISTER:
1565 1.5 cegger printf("Write Register");
1566 1.5 cegger break;
1567 1.5 cegger case ACPI_ERST_WRITE_REGISTER_VALUE:
1568 1.5 cegger printf("Write Register Value");
1569 1.5 cegger break;
1570 1.5 cegger case ACPI_ERST_NOOP:
1571 1.5 cegger printf("Noop");
1572 1.5 cegger break;
1573 1.5 cegger case ACPI_ERST_LOAD_VAR1:
1574 1.5 cegger printf("Load Var1");
1575 1.5 cegger break;
1576 1.5 cegger case ACPI_ERST_LOAD_VAR2:
1577 1.5 cegger printf("Load Var2");
1578 1.5 cegger break;
1579 1.5 cegger case ACPI_ERST_STORE_VAR1:
1580 1.5 cegger printf("Store Var1");
1581 1.5 cegger break;
1582 1.5 cegger case ACPI_ERST_ADD:
1583 1.5 cegger printf("Add");
1584 1.5 cegger break;
1585 1.5 cegger case ACPI_ERST_SUBTRACT:
1586 1.5 cegger printf("Subtract");
1587 1.5 cegger break;
1588 1.5 cegger case ACPI_ERST_ADD_VALUE:
1589 1.5 cegger printf("Add Value");
1590 1.5 cegger break;
1591 1.5 cegger case ACPI_ERST_SUBTRACT_VALUE:
1592 1.5 cegger printf("Subtract Value");
1593 1.5 cegger break;
1594 1.5 cegger case ACPI_ERST_STALL:
1595 1.5 cegger printf("Stall");
1596 1.5 cegger break;
1597 1.5 cegger case ACPI_ERST_STALL_WHILE_TRUE:
1598 1.5 cegger printf("Stall While True");
1599 1.5 cegger break;
1600 1.5 cegger case ACPI_ERST_SKIP_NEXT_IF_TRUE:
1601 1.5 cegger printf("Skip Next If True");
1602 1.5 cegger break;
1603 1.5 cegger case ACPI_ERST_GOTO:
1604 1.5 cegger printf("Goto");
1605 1.5 cegger break;
1606 1.5 cegger case ACPI_ERST_SET_SRC_ADDRESS_BASE:
1607 1.5 cegger printf("Set Src Address Base");
1608 1.5 cegger break;
1609 1.5 cegger case ACPI_ERST_SET_DST_ADDRESS_BASE:
1610 1.5 cegger printf("Set Dst Address Base");
1611 1.5 cegger break;
1612 1.5 cegger case ACPI_ERST_MOVE_DATA:
1613 1.5 cegger printf("Move Data");
1614 1.5 cegger break;
1615 1.5 cegger case ACPI_ERST_INSTRUCTION_RESERVED:
1616 1.5 cegger printf("Reserved");
1617 1.5 cegger break;
1618 1.5 cegger default:
1619 1.5 cegger printf("%d (reserved)", whea->Instruction);
1620 1.5 cegger break;
1621 1.5 cegger }
1622 1.5 cegger printf("}\n");
1623 1.5 cegger }
1624 1.5 cegger
1625 1.5 cegger static void
1626 1.5 cegger acpi_print_erst_flags(ACPI_WHEA_HEADER *whea)
1627 1.5 cegger {
1628 1.5 cegger uint32_t flags = whea->Flags;
1629 1.5 cegger
1630 1.15.8.1 martin printf("\tFLAGS={");
1631 1.5 cegger if (flags & ACPI_ERST_PRESERVE)
1632 1.5 cegger printf("PRESERVED");
1633 1.5 cegger printf("}\n");
1634 1.5 cegger }
1635 1.5 cegger
1636 1.5 cegger static void
1637 1.5 cegger acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
1638 1.5 cegger {
1639 1.5 cegger ACPI_TABLE_ERST *erst;
1640 1.5 cegger ACPI_ERST_ENTRY *erst_entry;
1641 1.5 cegger uint32_t erst_pos;
1642 1.5 cegger u_int i;
1643 1.5 cegger
1644 1.5 cegger printf(BEGIN_COMMENT);
1645 1.5 cegger acpi_print_sdt(sdp);
1646 1.5 cegger erst = (ACPI_TABLE_ERST *)sdp;
1647 1.5 cegger
1648 1.5 cegger printf("\tHeader Length=%d\n", erst->HeaderLength);
1649 1.5 cegger printf("\tEntries=%d\n", erst->Entries);
1650 1.5 cegger
1651 1.5 cegger erst_pos = sizeof(ACPI_TABLE_ERST);
1652 1.5 cegger for (i = 0; i < erst->Entries; i++) {
1653 1.5 cegger erst_entry = (ACPI_ERST_ENTRY *)((char *)erst + erst_pos);
1654 1.5 cegger acpi_print_whea(&erst_entry->WheaHeader,
1655 1.5 cegger acpi_print_erst_action, acpi_print_erst_instruction,
1656 1.5 cegger acpi_print_erst_flags);
1657 1.5 cegger erst_pos += sizeof(ACPI_ERST_ENTRY);
1658 1.5 cegger }
1659 1.5 cegger printf(END_COMMENT);
1660 1.5 cegger }
1661 1.5 cegger
1662 1.5 cegger static void
1663 1.5 cegger acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
1664 1.5 cegger {
1665 1.5 cegger ACPI_TABLE_MADT *madt;
1666 1.5 cegger
1667 1.5 cegger printf(BEGIN_COMMENT);
1668 1.5 cegger acpi_print_sdt(sdp);
1669 1.5 cegger madt = (ACPI_TABLE_MADT *)sdp;
1670 1.5 cegger printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
1671 1.5 cegger printf("\tFlags={");
1672 1.5 cegger if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
1673 1.5 cegger printf("PC-AT");
1674 1.5 cegger printf("}\n");
1675 1.5 cegger acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
1676 1.5 cegger printf(END_COMMENT);
1677 1.5 cegger }
1678 1.5 cegger
1679 1.5 cegger static void
1680 1.5 cegger acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
1681 1.5 cegger {
1682 1.5 cegger ACPI_TABLE_HPET *hpet;
1683 1.5 cegger
1684 1.5 cegger printf(BEGIN_COMMENT);
1685 1.5 cegger acpi_print_sdt(sdp);
1686 1.5 cegger hpet = (ACPI_TABLE_HPET *)sdp;
1687 1.5 cegger printf("\tHPET Number=%d\n", hpet->Sequence);
1688 1.5 cegger printf("\tADDR=");
1689 1.5 cegger acpi_print_gas(&hpet->Address);
1690 1.5 cegger printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
1691 1.5 cegger printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
1692 1.5 cegger 8);
1693 1.5 cegger printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
1694 1.5 cegger 1 : 0);
1695 1.5 cegger printf("\tLegacy IRQ routing capable={");
1696 1.5 cegger if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
1697 1.5 cegger printf("TRUE}\n");
1698 1.5 cegger else
1699 1.5 cegger printf("FALSE}\n");
1700 1.5 cegger printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
1701 1.5 cegger printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
1702 1.15.8.1 martin printf("\tFlags=0x%02x\n", hpet->Flags);
1703 1.5 cegger printf(END_COMMENT);
1704 1.5 cegger }
1705 1.5 cegger
1706 1.5 cegger static void
1707 1.5 cegger acpi_handle_msct(ACPI_TABLE_HEADER *sdp)
1708 1.5 cegger {
1709 1.5 cegger ACPI_TABLE_MSCT *msct;
1710 1.5 cegger ACPI_MSCT_PROXIMITY *msctentry;
1711 1.5 cegger uint32_t pos;
1712 1.5 cegger
1713 1.5 cegger printf(BEGIN_COMMENT);
1714 1.5 cegger acpi_print_sdt(sdp);
1715 1.5 cegger msct = (ACPI_TABLE_MSCT *)sdp;
1716 1.5 cegger
1717 1.5 cegger printf("\tProximity Offset=0x%x\n", msct->ProximityOffset);
1718 1.5 cegger printf("\tMax Proximity Domains=%d\n", msct->MaxProximityDomains);
1719 1.5 cegger printf("\tMax Clock Domains=%d\n", msct->MaxClockDomains);
1720 1.5 cegger printf("\tMax Physical Address=0x%"PRIx64"\n", msct->MaxAddress);
1721 1.5 cegger
1722 1.5 cegger pos = msct->ProximityOffset;
1723 1.5 cegger while (pos < msct->Header.Length) {
1724 1.5 cegger msctentry = (ACPI_MSCT_PROXIMITY *)((char *)msct + pos);
1725 1.5 cegger pos += msctentry->Length;
1726 1.5 cegger
1727 1.5 cegger printf("\n");
1728 1.5 cegger printf("\tRevision=%d\n", msctentry->Revision);
1729 1.5 cegger printf("\tLength=%d\n", msctentry->Length);
1730 1.5 cegger printf("\tRange Start=%d\n", msctentry->RangeStart);
1731 1.5 cegger printf("\tRange End=%d\n", msctentry->RangeEnd);
1732 1.5 cegger printf("\tProcessor Capacity=%d\n",
1733 1.5 cegger msctentry->ProcessorCapacity);
1734 1.5 cegger printf("\tMemory Capacity=0x%"PRIx64" byte\n",
1735 1.5 cegger msctentry->MemoryCapacity);
1736 1.5 cegger }
1737 1.1 christos
1738 1.5 cegger printf(END_COMMENT);
1739 1.5 cegger }
1740 1.1 christos
1741 1.5 cegger static void
1742 1.5 cegger acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
1743 1.5 cegger {
1744 1.5 cegger ACPI_TABLE_ECDT *ecdt;
1745 1.1 christos
1746 1.5 cegger printf(BEGIN_COMMENT);
1747 1.5 cegger acpi_print_sdt(sdp);
1748 1.5 cegger ecdt = (ACPI_TABLE_ECDT *)sdp;
1749 1.5 cegger printf("\tEC_CONTROL=");
1750 1.5 cegger acpi_print_gas(&ecdt->Control);
1751 1.5 cegger printf("\n\tEC_DATA=");
1752 1.5 cegger acpi_print_gas(&ecdt->Data);
1753 1.5 cegger printf("\n\tUID=%#x, ", ecdt->Uid);
1754 1.5 cegger printf("GPE_BIT=%#x\n", ecdt->Gpe);
1755 1.5 cegger printf("\tEC_ID=%s\n", ecdt->Id);
1756 1.5 cegger printf(END_COMMENT);
1757 1.5 cegger }
1758 1.1 christos
1759 1.5 cegger static void
1760 1.5 cegger acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
1761 1.5 cegger {
1762 1.5 cegger ACPI_TABLE_MCFG *mcfg;
1763 1.5 cegger ACPI_MCFG_ALLOCATION *alloc;
1764 1.5 cegger u_int i, entries;
1765 1.1 christos
1766 1.5 cegger printf(BEGIN_COMMENT);
1767 1.5 cegger acpi_print_sdt(sdp);
1768 1.5 cegger mcfg = (ACPI_TABLE_MCFG *)sdp;
1769 1.5 cegger entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
1770 1.5 cegger sizeof(ACPI_MCFG_ALLOCATION);
1771 1.5 cegger alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
1772 1.5 cegger for (i = 0; i < entries; i++, alloc++) {
1773 1.5 cegger printf("\n");
1774 1.15.8.1 martin printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
1775 1.5 cegger printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
1776 1.5 cegger printf("\tStart Bus=%d\n", alloc->StartBusNumber);
1777 1.5 cegger printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
1778 1.5 cegger }
1779 1.5 cegger printf(END_COMMENT);
1780 1.5 cegger }
1781 1.1 christos
1782 1.1 christos static void
1783 1.5 cegger acpi_handle_sbst(ACPI_TABLE_HEADER *sdp)
1784 1.1 christos {
1785 1.5 cegger ACPI_TABLE_SBST *sbst;
1786 1.5 cegger
1787 1.5 cegger printf(BEGIN_COMMENT);
1788 1.5 cegger acpi_print_sdt(sdp);
1789 1.5 cegger sbst = (ACPI_TABLE_SBST *)sdp;
1790 1.5 cegger
1791 1.5 cegger printf("\tWarning Level=%d mWh\n", sbst->WarningLevel);
1792 1.5 cegger printf("\tLow Level=%d mWh\n", sbst->LowLevel);
1793 1.5 cegger printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel);
1794 1.1 christos
1795 1.5 cegger printf(END_COMMENT);
1796 1.1 christos }
1797 1.1 christos
1798 1.1 christos static void
1799 1.5 cegger acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
1800 1.1 christos {
1801 1.5 cegger ACPI_TABLE_SLIT *slit;
1802 1.5 cegger u_int idx;
1803 1.5 cegger uint64_t cnt;
1804 1.5 cegger
1805 1.5 cegger printf(BEGIN_COMMENT);
1806 1.5 cegger acpi_print_sdt(sdp);
1807 1.5 cegger slit = (ACPI_TABLE_SLIT *)sdp;
1808 1.1 christos
1809 1.5 cegger cnt = slit->LocalityCount * slit->LocalityCount;
1810 1.15.8.1 martin printf("\tLocalityCount=%ju\n", (uintmax_t)slit->LocalityCount);
1811 1.5 cegger printf("\tEntry=\n\t");
1812 1.5 cegger for (idx = 0; idx < cnt; idx++) {
1813 1.5 cegger printf("%u ", slit->Entry[idx]);
1814 1.5 cegger if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) {
1815 1.5 cegger printf("\n");
1816 1.5 cegger if (idx < cnt - 1)
1817 1.5 cegger printf("\t");
1818 1.5 cegger }
1819 1.5 cegger }
1820 1.1 christos
1821 1.5 cegger printf(END_COMMENT);
1822 1.1 christos }
1823 1.1 christos
1824 1.1 christos static void
1825 1.5 cegger acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
1826 1.1 christos {
1827 1.5 cegger ACPI_TABLE_SPCR *spcr;
1828 1.5 cegger
1829 1.5 cegger printf(BEGIN_COMMENT);
1830 1.5 cegger acpi_print_sdt(sdp);
1831 1.5 cegger spcr = (ACPI_TABLE_SPCR *)sdp;
1832 1.5 cegger
1833 1.5 cegger printf("\tSerial Port=");
1834 1.5 cegger acpi_print_gas(&spcr->SerialPort);
1835 1.5 cegger printf("\n\tInterrupt Type={");
1836 1.5 cegger if (spcr->InterruptType & 0x1) {
1837 1.5 cegger printf("\n\t\tdual-8259 IRQ=");
1838 1.5 cegger switch (spcr->PcInterrupt) {
1839 1.5 cegger case 2 ... 7:
1840 1.5 cegger case 9 ... 12:
1841 1.5 cegger case 14 ... 15:
1842 1.5 cegger printf("%d", spcr->PcInterrupt);
1843 1.5 cegger break;
1844 1.5 cegger default:
1845 1.5 cegger printf("%d (invalid entry)", spcr->PcInterrupt);
1846 1.5 cegger break;
1847 1.5 cegger }
1848 1.5 cegger }
1849 1.5 cegger if (spcr->InterruptType & 0x2) {
1850 1.5 cegger printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt);
1851 1.5 cegger }
1852 1.5 cegger if (spcr->InterruptType & 0x4) {
1853 1.5 cegger printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt);
1854 1.5 cegger }
1855 1.5 cegger printf("\n\t}\n");
1856 1.5 cegger
1857 1.5 cegger printf("\tBaud Rate=");
1858 1.5 cegger switch (spcr->BaudRate) {
1859 1.5 cegger case 3:
1860 1.5 cegger printf("9600");
1861 1.5 cegger break;
1862 1.5 cegger case 4:
1863 1.5 cegger printf("19200");
1864 1.5 cegger break;
1865 1.5 cegger case 6:
1866 1.5 cegger printf("57600");
1867 1.5 cegger break;
1868 1.5 cegger case 7:
1869 1.5 cegger printf("115200");
1870 1.5 cegger break;
1871 1.5 cegger default:
1872 1.5 cegger printf("unknown speed index %d", spcr->BaudRate);
1873 1.5 cegger break;
1874 1.5 cegger }
1875 1.5 cegger printf("\n\tParity={");
1876 1.5 cegger switch (spcr->Parity) {
1877 1.5 cegger case 0:
1878 1.5 cegger printf("OFF");
1879 1.5 cegger break;
1880 1.5 cegger default:
1881 1.5 cegger printf("ON");
1882 1.5 cegger break;
1883 1.5 cegger }
1884 1.5 cegger printf("}\n");
1885 1.5 cegger
1886 1.5 cegger printf("\tStop Bits={");
1887 1.5 cegger switch (spcr->StopBits) {
1888 1.5 cegger case 1:
1889 1.5 cegger printf("ON");
1890 1.5 cegger break;
1891 1.5 cegger default:
1892 1.5 cegger printf("OFF");
1893 1.5 cegger break;
1894 1.5 cegger }
1895 1.5 cegger printf("}\n");
1896 1.1 christos
1897 1.5 cegger printf("\tFlow Control={");
1898 1.5 cegger if (spcr->FlowControl & 0x1)
1899 1.5 cegger printf("DCD, ");
1900 1.5 cegger if (spcr->FlowControl & 0x2)
1901 1.5 cegger printf("RTS/CTS hardware, ");
1902 1.5 cegger if (spcr->FlowControl & 0x4)
1903 1.5 cegger printf("XON/XOFF software");
1904 1.5 cegger printf("}\n");
1905 1.1 christos
1906 1.5 cegger printf("\tTerminal=");
1907 1.5 cegger switch (spcr->TerminalType) {
1908 1.5 cegger case 0:
1909 1.5 cegger printf("VT100");
1910 1.5 cegger break;
1911 1.5 cegger case 1:
1912 1.5 cegger printf("VT100+");
1913 1.5 cegger break;
1914 1.5 cegger case 2:
1915 1.5 cegger printf("VT-UTF8");
1916 1.5 cegger break;
1917 1.5 cegger case 3:
1918 1.5 cegger printf("ANSI");
1919 1.5 cegger break;
1920 1.5 cegger default:
1921 1.5 cegger printf("unknown type %d", spcr->TerminalType);
1922 1.5 cegger break;
1923 1.1 christos }
1924 1.5 cegger printf("\n");
1925 1.5 cegger
1926 1.5 cegger acpi_print_pci(spcr->PciVendorId, spcr->PciDeviceId,
1927 1.5 cegger spcr->PciSegment, spcr->PciBus, spcr->PciDevice, spcr->PciFunction);
1928 1.5 cegger
1929 1.5 cegger printf("\tPCI Flags={");
1930 1.5 cegger if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE)
1931 1.5 cegger printf("DONOT_DISABLE");
1932 1.5 cegger printf("}\n");
1933 1.5 cegger
1934 1.5 cegger printf(END_COMMENT);
1935 1.5 cegger }
1936 1.5 cegger
1937 1.5 cegger static void
1938 1.15.8.1 martin acpi_handle_spmi(ACPI_TABLE_HEADER *sdp)
1939 1.15.8.1 martin {
1940 1.15.8.1 martin ACPI_TABLE_SPMI *spmi;
1941 1.15.8.1 martin
1942 1.15.8.1 martin printf(BEGIN_COMMENT);
1943 1.15.8.1 martin acpi_print_sdt(sdp);
1944 1.15.8.1 martin spmi = (ACPI_TABLE_SPMI *)sdp;
1945 1.15.8.1 martin
1946 1.15.8.1 martin printf("\tInterface Type=");
1947 1.15.8.1 martin switch (spmi->InterfaceType) {
1948 1.15.8.1 martin case ACPI_SPMI_KEYBOARD:
1949 1.15.8.1 martin printf("Keyboard Controller Stype (KCS)");
1950 1.15.8.1 martin break;
1951 1.15.8.1 martin case ACPI_SPMI_SMI:
1952 1.15.8.1 martin printf("Server Management Interface Chip (SMIC)");
1953 1.15.8.1 martin break;
1954 1.15.8.1 martin case ACPI_SPMI_BLOCK_TRANSFER:
1955 1.15.8.1 martin printf("Block Transfer (BT)");
1956 1.15.8.1 martin break;
1957 1.15.8.1 martin case ACPI_SPMI_SMBUS:
1958 1.15.8.1 martin printf("SMBus System Interface (SSIF)");
1959 1.15.8.1 martin break;
1960 1.15.8.1 martin default:
1961 1.15.8.1 martin printf("Reserved(%d)", spmi->InterfaceType);
1962 1.15.8.1 martin break;
1963 1.15.8.1 martin }
1964 1.15.8.1 martin printf("\n\tSpecRevision=%d.%d\n", spmi->SpecRevision >> 8,
1965 1.15.8.1 martin spmi->SpecRevision & 0xff);
1966 1.15.8.1 martin
1967 1.15.8.1 martin printf("\n\tInterrupt Type={");
1968 1.15.8.1 martin if (spmi->InterruptType & 0x1) {
1969 1.15.8.1 martin printf("\n\t\tSCI triggered GPE=%d", spmi->GpeNumber);
1970 1.15.8.1 martin }
1971 1.15.8.1 martin if (spmi->InterruptType & 0x2) {
1972 1.15.8.1 martin printf("\n\t\tIO APIC/SAPIC={ GSI=%d }", spmi->Interrupt);
1973 1.15.8.1 martin }
1974 1.15.8.1 martin printf("\n\t}\n");
1975 1.15.8.1 martin
1976 1.15.8.1 martin printf("\tBase Address=");
1977 1.15.8.1 martin acpi_print_gas(&spmi->IpmiRegister);
1978 1.15.8.1 martin printf("\n");
1979 1.15.8.1 martin
1980 1.15.8.1 martin if ((spmi->PciDeviceFlag & 0x01) != 0)
1981 1.15.8.1 martin acpi_print_pci_sbdf(spmi->PciSegment, spmi->PciBus,
1982 1.15.8.1 martin spmi->PciDevice, spmi->PciFunction);
1983 1.15.8.1 martin
1984 1.15.8.1 martin printf(END_COMMENT);
1985 1.15.8.1 martin }
1986 1.15.8.1 martin
1987 1.15.8.1 martin static void
1988 1.5 cegger acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1989 1.5 cegger uint32_t flags, uint32_t clockdomain)
1990 1.5 cegger {
1991 1.5 cegger
1992 1.5 cegger printf("\tFlags={");
1993 1.5 cegger if (flags & ACPI_SRAT_CPU_ENABLED)
1994 1.5 cegger printf("ENABLED");
1995 1.5 cegger else
1996 1.5 cegger printf("DISABLED");
1997 1.5 cegger printf("}\n");
1998 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
1999 1.5 cegger printf("\tProximity Domain=%d\n", proximity_domain);
2000 1.5 cegger printf("\tClock Domain=%d\n", clockdomain);
2001 1.5 cegger }
2002 1.5 cegger
2003 1.5 cegger static void
2004 1.5 cegger acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
2005 1.5 cegger {
2006 1.5 cegger
2007 1.5 cegger printf("\tFlags={");
2008 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
2009 1.5 cegger printf("ENABLED");
2010 1.5 cegger else
2011 1.5 cegger printf("DISABLED");
2012 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
2013 1.5 cegger printf(",HOT_PLUGGABLE");
2014 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
2015 1.5 cegger printf(",NON_VOLATILE");
2016 1.5 cegger printf("}\n");
2017 1.5 cegger printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
2018 1.5 cegger printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
2019 1.5 cegger printf("\tProximity Domain=%d\n", mp->ProximityDomain);
2020 1.1 christos }
2021 1.1 christos
2022 1.15.8.1 martin static const char *srat_types[] = {
2023 1.15.8.1 martin [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
2024 1.15.8.1 martin [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
2025 1.15.8.1 martin [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
2026 1.15.8.1 martin [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
2027 1.15.8.1 martin };
2028 1.5 cegger
2029 1.1 christos static void
2030 1.5 cegger acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
2031 1.1 christos {
2032 1.5 cegger ACPI_SRAT_CPU_AFFINITY *cpu;
2033 1.5 cegger ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
2034 1.15.8.1 martin ACPI_SRAT_GICC_AFFINITY *gic;
2035 1.5 cegger
2036 1.15.8.1 martin if (srat->Type < __arraycount(srat_types))
2037 1.5 cegger printf("\tType=%s\n", srat_types[srat->Type]);
2038 1.5 cegger else
2039 1.5 cegger printf("\tType=%d (unknown)\n", srat->Type);
2040 1.5 cegger switch (srat->Type) {
2041 1.5 cegger case ACPI_SRAT_TYPE_CPU_AFFINITY:
2042 1.5 cegger cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
2043 1.5 cegger acpi_print_srat_cpu(cpu->ApicId,
2044 1.5 cegger cpu->ProximityDomainHi[2] << 24 |
2045 1.5 cegger cpu->ProximityDomainHi[1] << 16 |
2046 1.5 cegger cpu->ProximityDomainHi[0] << 0 |
2047 1.5 cegger cpu->ProximityDomainLo,
2048 1.5 cegger cpu->Flags, cpu->ClockDomain);
2049 1.5 cegger break;
2050 1.5 cegger case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2051 1.5 cegger acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
2052 1.5 cegger break;
2053 1.5 cegger case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2054 1.5 cegger x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
2055 1.5 cegger acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
2056 1.5 cegger x2apic->Flags, x2apic->ClockDomain);
2057 1.5 cegger break;
2058 1.15.8.1 martin case ACPI_SRAT_TYPE_GICC_AFFINITY:
2059 1.15.8.1 martin gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
2060 1.15.8.1 martin acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
2061 1.15.8.1 martin gic->Flags, gic->ClockDomain);
2062 1.15.8.1 martin break;
2063 1.5 cegger }
2064 1.5 cegger }
2065 1.1 christos
2066 1.5 cegger static void
2067 1.5 cegger acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
2068 1.5 cegger {
2069 1.5 cegger ACPI_TABLE_SRAT *srat;
2070 1.1 christos
2071 1.5 cegger printf(BEGIN_COMMENT);
2072 1.5 cegger acpi_print_sdt(sdp);
2073 1.5 cegger srat = (ACPI_TABLE_SRAT *)sdp;
2074 1.5 cegger printf("\tTable Revision=%d\n", srat->TableRevision);
2075 1.5 cegger acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
2076 1.5 cegger printf(END_COMMENT);
2077 1.1 christos }
2078 1.1 christos
2079 1.15.8.1 martin static const char *nfit_types[] = {
2080 1.15.8.1 martin [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
2081 1.15.8.1 martin [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
2082 1.15.8.1 martin [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
2083 1.15.8.1 martin [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
2084 1.15.8.1 martin [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
2085 1.15.8.1 martin [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
2086 1.15.8.1 martin [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
2087 1.15.8.1 martin };
2088 1.15.8.1 martin
2089 1.15.8.1 martin
2090 1.15.8.1 martin static void
2091 1.15.8.1 martin acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
2092 1.15.8.1 martin {
2093 1.15.8.1 martin char *uuidstr;
2094 1.15.8.1 martin uint32_t status;
2095 1.15.8.1 martin
2096 1.15.8.1 martin ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
2097 1.15.8.1 martin ACPI_NFIT_MEMORY_MAP *mmap;
2098 1.15.8.1 martin ACPI_NFIT_INTERLEAVE *ileave;
2099 1.15.8.1 martin ACPI_NFIT_SMBIOS *smbios __unused;
2100 1.15.8.1 martin ACPI_NFIT_CONTROL_REGION *ctlreg;
2101 1.15.8.1 martin ACPI_NFIT_DATA_REGION *datareg;
2102 1.15.8.1 martin ACPI_NFIT_FLUSH_ADDRESS *fladdr;
2103 1.15.8.1 martin
2104 1.15.8.1 martin if (nfit->Type < __arraycount(nfit_types))
2105 1.15.8.1 martin printf("\tType=%s\n", nfit_types[nfit->Type]);
2106 1.15.8.1 martin else
2107 1.15.8.1 martin printf("\tType=%u (unknown)\n", nfit->Type);
2108 1.15.8.1 martin switch (nfit->Type) {
2109 1.15.8.1 martin case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2110 1.15.8.1 martin sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
2111 1.15.8.1 martin printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
2112 1.15.8.1 martin printf("\tProximityDomain=%u\n",
2113 1.15.8.1 martin (u_int)sysaddr->ProximityDomain);
2114 1.15.8.1 martin uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
2115 1.15.8.1 martin &uuidstr, &status);
2116 1.15.8.1 martin if (status != uuid_s_ok)
2117 1.15.8.1 martin errx(1, "uuid_to_string: status=%u", status);
2118 1.15.8.1 martin printf("\tRangeGuid=%s\n", uuidstr);
2119 1.15.8.1 martin free(uuidstr);
2120 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
2121 1.15.8.1 martin printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
2122 1.15.8.1 martin printf("\tMemoryMapping=0x%016jx\n",
2123 1.15.8.1 martin (uintmax_t)sysaddr->MemoryMapping);
2124 1.15.8.1 martin
2125 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2126 1.15.8.1 martin
2127 1.15.8.1 martin printf("\tFlags=");
2128 1.15.8.1 martin PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
2129 1.15.8.1 martin PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
2130 1.15.8.1 martin PRINTFLAG_END();
2131 1.15.8.1 martin
2132 1.15.8.1 martin #undef PRINTFLAG
2133 1.15.8.1 martin
2134 1.15.8.1 martin break;
2135 1.15.8.1 martin case ACPI_NFIT_TYPE_MEMORY_MAP:
2136 1.15.8.1 martin mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
2137 1.15.8.1 martin printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
2138 1.15.8.1 martin printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
2139 1.15.8.1 martin printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
2140 1.15.8.1 martin printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
2141 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
2142 1.15.8.1 martin printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
2143 1.15.8.1 martin printf("\tRegionOffset=0x%016jx\n",
2144 1.15.8.1 martin (uintmax_t)mmap->RegionOffset);
2145 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
2146 1.15.8.1 martin printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
2147 1.15.8.1 martin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
2148 1.15.8.1 martin
2149 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag)
2150 1.15.8.1 martin
2151 1.15.8.1 martin printf("\tFlags=");
2152 1.15.8.1 martin PRINTFLAG(mmap->Flags, SAVE_FAILED);
2153 1.15.8.1 martin PRINTFLAG(mmap->Flags, RESTORE_FAILED);
2154 1.15.8.1 martin PRINTFLAG(mmap->Flags, FLUSH_FAILED);
2155 1.15.8.1 martin PRINTFLAG(mmap->Flags, NOT_ARMED);
2156 1.15.8.1 martin PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
2157 1.15.8.1 martin PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
2158 1.15.8.1 martin PRINTFLAG(mmap->Flags, MAP_FAILED);
2159 1.15.8.1 martin PRINTFLAG_END();
2160 1.15.8.1 martin
2161 1.15.8.1 martin #undef PRINTFLAG
2162 1.15.8.1 martin
2163 1.15.8.1 martin break;
2164 1.15.8.1 martin case ACPI_NFIT_TYPE_INTERLEAVE:
2165 1.15.8.1 martin ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
2166 1.15.8.1 martin printf("\tInterleaveIndex=%u\n",
2167 1.15.8.1 martin (u_int)ileave->InterleaveIndex);
2168 1.15.8.1 martin printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
2169 1.15.8.1 martin printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
2170 1.15.8.1 martin /* XXX ileave->LineOffset[i] output is not supported */
2171 1.15.8.1 martin break;
2172 1.15.8.1 martin case ACPI_NFIT_TYPE_SMBIOS:
2173 1.15.8.1 martin smbios = (ACPI_NFIT_SMBIOS *)nfit;
2174 1.15.8.1 martin /* XXX smbios->Data[x] output is not supported */
2175 1.15.8.1 martin break;
2176 1.15.8.1 martin case ACPI_NFIT_TYPE_CONTROL_REGION:
2177 1.15.8.1 martin ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
2178 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
2179 1.15.8.1 martin printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
2180 1.15.8.1 martin printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
2181 1.15.8.1 martin printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
2182 1.15.8.1 martin printf("\tSubsystemVendorId=0x%04x\n",
2183 1.15.8.1 martin (u_int)ctlreg->SubsystemVendorId);
2184 1.15.8.1 martin printf("\tSubsystemDeviceId=0x%04x\n",
2185 1.15.8.1 martin (u_int)ctlreg->SubsystemDeviceId);
2186 1.15.8.1 martin printf("\tSubsystemRevisionId=%u\n",
2187 1.15.8.1 martin (u_int)ctlreg->SubsystemRevisionId);
2188 1.15.8.1 martin printf("\tValidFields=%02x\n", (u_int)ctlreg->ValidFields);
2189 1.15.8.1 martin printf("\tManufacturingLocation=%u\n",
2190 1.15.8.1 martin (u_int)ctlreg->ManufacturingLocation);
2191 1.15.8.1 martin printf("\tManufacturingDate=%u\n",
2192 1.15.8.1 martin (u_int)ctlreg->ManufacturingDate);
2193 1.15.8.1 martin printf("\tSerialNumber=%u\n",
2194 1.15.8.1 martin (u_int)ctlreg->SerialNumber);
2195 1.15.8.1 martin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
2196 1.15.8.1 martin printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
2197 1.15.8.1 martin printf("\tWindowSize=0x%016jx\n",
2198 1.15.8.1 martin (uintmax_t)ctlreg->WindowSize);
2199 1.15.8.1 martin printf("\tCommandOffset=0x%016jx\n",
2200 1.15.8.1 martin (uintmax_t)ctlreg->CommandOffset);
2201 1.15.8.1 martin printf("\tCommandSize=0x%016jx\n",
2202 1.15.8.1 martin (uintmax_t)ctlreg->CommandSize);
2203 1.15.8.1 martin printf("\tStatusOffset=0x%016jx\n",
2204 1.15.8.1 martin (uintmax_t)ctlreg->StatusOffset);
2205 1.15.8.1 martin printf("\tStatusSize=0x%016jx\n",
2206 1.15.8.1 martin (uintmax_t)ctlreg->StatusSize);
2207 1.15.8.1 martin
2208 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2209 1.15.8.1 martin
2210 1.15.8.1 martin printf("\tFlags=");
2211 1.15.8.1 martin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
2212 1.15.8.1 martin PRINTFLAG_END();
2213 1.15.8.1 martin
2214 1.15.8.1 martin #undef PRINTFLAG
2215 1.15.8.1 martin
2216 1.15.8.1 martin break;
2217 1.15.8.1 martin case ACPI_NFIT_TYPE_DATA_REGION:
2218 1.15.8.1 martin datareg = (ACPI_NFIT_DATA_REGION *)nfit;
2219 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
2220 1.15.8.1 martin printf("\tWindows=%u\n", (u_int)datareg->Windows);
2221 1.15.8.1 martin printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
2222 1.15.8.1 martin printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
2223 1.15.8.1 martin printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
2224 1.15.8.1 martin printf("\tStartAddress=0x%016jx\n",
2225 1.15.8.1 martin (uintmax_t)datareg->StartAddress);
2226 1.15.8.1 martin break;
2227 1.15.8.1 martin case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2228 1.15.8.1 martin fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
2229 1.15.8.1 martin printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
2230 1.15.8.1 martin printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
2231 1.15.8.1 martin /* XXX fladdr->HintAddress[i] output is not supported */
2232 1.15.8.1 martin break;
2233 1.15.8.1 martin }
2234 1.15.8.1 martin }
2235 1.15.8.1 martin
2236 1.15.8.1 martin static void
2237 1.15.8.1 martin acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
2238 1.15.8.1 martin {
2239 1.15.8.1 martin ACPI_TABLE_NFIT *nfit;
2240 1.15.8.1 martin
2241 1.15.8.1 martin printf(BEGIN_COMMENT);
2242 1.15.8.1 martin acpi_print_sdt(sdp);
2243 1.15.8.1 martin nfit = (ACPI_TABLE_NFIT *)sdp;
2244 1.15.8.1 martin acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
2245 1.15.8.1 martin printf(END_COMMENT);
2246 1.15.8.1 martin }
2247 1.15.8.1 martin
2248 1.15.8.1 martin static char *
2249 1.15.8.1 martin acpi_tcpa_evname(struct TCPAevent *event)
2250 1.15.8.1 martin {
2251 1.15.8.1 martin struct TCPApc_event *pc_event;
2252 1.15.8.1 martin char *eventname = NULL;
2253 1.15.8.1 martin
2254 1.15.8.1 martin pc_event = (struct TCPApc_event *)(event + 1);
2255 1.15.8.1 martin
2256 1.15.8.1 martin switch(event->event_type) {
2257 1.15.8.1 martin case PREBOOT:
2258 1.15.8.1 martin case POST_CODE:
2259 1.15.8.1 martin case UNUSED:
2260 1.15.8.1 martin case NO_ACTION:
2261 1.15.8.1 martin case SEPARATOR:
2262 1.15.8.1 martin case SCRTM_CONTENTS:
2263 1.15.8.1 martin case SCRTM_VERSION:
2264 1.15.8.1 martin case CPU_MICROCODE:
2265 1.15.8.1 martin case PLATFORM_CONFIG_FLAGS:
2266 1.15.8.1 martin case TABLE_OF_DEVICES:
2267 1.15.8.1 martin case COMPACT_HASH:
2268 1.15.8.1 martin case IPL:
2269 1.15.8.1 martin case IPL_PARTITION_DATA:
2270 1.15.8.1 martin case NONHOST_CODE:
2271 1.15.8.1 martin case NONHOST_CONFIG:
2272 1.15.8.1 martin case NONHOST_INFO:
2273 1.15.8.1 martin asprintf(&eventname, "%s",
2274 1.15.8.1 martin tcpa_event_type_strings[event->event_type]);
2275 1.15.8.1 martin break;
2276 1.15.8.1 martin
2277 1.15.8.1 martin case ACTION:
2278 1.15.8.1 martin eventname = calloc(event->event_size + 1, sizeof(char));
2279 1.15.8.1 martin memcpy(eventname, pc_event, event->event_size);
2280 1.15.8.1 martin break;
2281 1.15.8.1 martin
2282 1.15.8.1 martin case EVENT_TAG:
2283 1.15.8.1 martin switch (pc_event->event_id) {
2284 1.15.8.1 martin case SMBIOS:
2285 1.15.8.1 martin case BIS_CERT:
2286 1.15.8.1 martin case CMOS:
2287 1.15.8.1 martin case NVRAM:
2288 1.15.8.1 martin case OPTION_ROM_EXEC:
2289 1.15.8.1 martin case OPTION_ROM_CONFIG:
2290 1.15.8.1 martin case S_CRTM_VERSION:
2291 1.15.8.1 martin case POST_BIOS_ROM:
2292 1.15.8.1 martin case ESCD:
2293 1.15.8.1 martin case OPTION_ROM_MICROCODE:
2294 1.15.8.1 martin case S_CRTM_CONTENTS:
2295 1.15.8.1 martin case POST_CONTENTS:
2296 1.15.8.1 martin asprintf(&eventname, "%s",
2297 1.15.8.1 martin TCPA_pcclient_strings[pc_event->event_id]);
2298 1.15.8.1 martin break;
2299 1.15.8.1 martin
2300 1.15.8.1 martin default:
2301 1.15.8.1 martin asprintf(&eventname, "<unknown tag 0x%02x>",
2302 1.15.8.1 martin pc_event->event_id);
2303 1.15.8.1 martin break;
2304 1.15.8.1 martin }
2305 1.15.8.1 martin break;
2306 1.15.8.1 martin
2307 1.15.8.1 martin default:
2308 1.15.8.1 martin asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
2309 1.15.8.1 martin break;
2310 1.15.8.1 martin }
2311 1.15.8.1 martin
2312 1.15.8.1 martin return eventname;
2313 1.15.8.1 martin }
2314 1.15.8.1 martin
2315 1.15.8.1 martin static void
2316 1.15.8.1 martin acpi_print_tcpa(struct TCPAevent *event)
2317 1.15.8.1 martin {
2318 1.15.8.1 martin int i;
2319 1.15.8.1 martin char *eventname;
2320 1.15.8.1 martin
2321 1.15.8.1 martin eventname = acpi_tcpa_evname(event);
2322 1.15.8.1 martin
2323 1.15.8.1 martin printf("\t%d", event->pcr_index);
2324 1.15.8.1 martin printf(" 0x");
2325 1.15.8.1 martin for (i = 0; i < 20; i++)
2326 1.15.8.1 martin printf("%02x", event->pcr_value[i]);
2327 1.15.8.1 martin printf(" [%s]\n", eventname ? eventname : "<unknown>");
2328 1.15.8.1 martin
2329 1.15.8.1 martin free(eventname);
2330 1.15.8.1 martin }
2331 1.15.8.1 martin
2332 1.1 christos static void
2333 1.5 cegger acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
2334 1.1 christos {
2335 1.15.8.1 martin struct TCPAbody *tcpa;
2336 1.15.8.1 martin struct TCPAevent *event;
2337 1.15.8.1 martin uintmax_t len, paddr;
2338 1.15.8.1 martin unsigned char *vaddr = NULL;
2339 1.15.8.1 martin unsigned char *vend = NULL;
2340 1.5 cegger
2341 1.5 cegger printf(BEGIN_COMMENT);
2342 1.5 cegger acpi_print_sdt(sdp);
2343 1.15.8.1 martin tcpa = (struct TCPAbody *) sdp;
2344 1.15.8.1 martin
2345 1.15.8.1 martin switch (tcpa->platform_class) {
2346 1.15.8.1 martin case ACPI_TCPA_BIOS_CLIENT:
2347 1.15.8.1 martin len = tcpa->client.log_max_len;
2348 1.15.8.1 martin paddr = tcpa->client.log_start_addr;
2349 1.13 christos break;
2350 1.13 christos
2351 1.15.8.1 martin case ACPI_TCPA_BIOS_SERVER:
2352 1.15.8.1 martin len = tcpa->server.log_max_len;
2353 1.15.8.1 martin paddr = tcpa->server.log_start_addr;
2354 1.13 christos break;
2355 1.13 christos
2356 1.13 christos default:
2357 1.15.8.1 martin printf("XXX");
2358 1.15.8.1 martin printf(END_COMMENT);
2359 1.15.8.1 martin return;
2360 1.15.8.1 martin }
2361 1.15.8.1 martin printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
2362 1.15.8.1 martin tcpa->platform_class, paddr, len);
2363 1.15.8.1 martin
2364 1.15.8.1 martin if (len == 0) {
2365 1.15.8.1 martin printf("\tEmpty TCPA table\n");
2366 1.15.8.1 martin printf(END_COMMENT);
2367 1.15.8.1 martin return;
2368 1.15.8.1 martin }
2369 1.15.8.1 martin if(sdp->Revision == 1) {
2370 1.15.8.1 martin printf("\tOLD TCPA spec log found. Dumping not supported.\n");
2371 1.15.8.1 martin printf(END_COMMENT);
2372 1.15.8.1 martin return;
2373 1.15.8.1 martin }
2374 1.15.8.1 martin
2375 1.15.8.1 martin vaddr = (unsigned char *)acpi_map_physical(paddr, len);
2376 1.15.8.1 martin vend = vaddr + len;
2377 1.15.8.1 martin
2378 1.15.8.1 martin while (vaddr != NULL) {
2379 1.15.8.1 martin if ((vaddr + sizeof(struct TCPAevent) >= vend)||
2380 1.15.8.1 martin (vaddr + sizeof(struct TCPAevent) < vaddr))
2381 1.15.8.1 martin break;
2382 1.15.8.1 martin event = (struct TCPAevent *)(void *)vaddr;
2383 1.15.8.1 martin if (vaddr + event->event_size >= vend)
2384 1.15.8.1 martin break;
2385 1.15.8.1 martin if (vaddr + event->event_size < vaddr)
2386 1.15.8.1 martin break;
2387 1.15.8.1 martin if (event->event_type == 0 && event->event_size == 0)
2388 1.15.8.1 martin break;
2389 1.15.8.1 martin #if 0
2390 1.15.8.1 martin {
2391 1.15.8.1 martin unsigned int i, j, k;
2392 1.15.8.1 martin
2393 1.15.8.1 martin printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
2394 1.15.8.1 martin for (j = 0, i = 0; i <
2395 1.15.8.1 martin sizeof(struct TCPAevent) + event->event_size; i++) {
2396 1.15.8.1 martin printf("%02x ", vaddr[i]);
2397 1.15.8.1 martin if ((i+1) % 8 == 0) {
2398 1.15.8.1 martin for (k = 0; k < 8; k++)
2399 1.15.8.1 martin printf("%c", isprint(vaddr[j+k]) ?
2400 1.15.8.1 martin vaddr[j+k] : '.');
2401 1.15.8.1 martin printf("\n\t\t%p ", &vaddr[i + 1]);
2402 1.15.8.1 martin j = i + 1;
2403 1.15.8.1 martin }
2404 1.15.8.1 martin }
2405 1.15.8.1 martin printf("\n"); }
2406 1.15.8.1 martin #endif
2407 1.15.8.1 martin acpi_print_tcpa(event);
2408 1.15.8.1 martin
2409 1.15.8.1 martin vaddr += sizeof(struct TCPAevent) + event->event_size;
2410 1.15.8.1 martin }
2411 1.15.8.1 martin
2412 1.15.8.1 martin printf(END_COMMENT);
2413 1.15.8.1 martin }
2414 1.15.8.1 martin
2415 1.15.8.1 martin static const char *
2416 1.15.8.1 martin devscope_type2str(int type)
2417 1.15.8.1 martin {
2418 1.15.8.1 martin static char typebuf[16];
2419 1.15.8.1 martin
2420 1.15.8.1 martin switch (type) {
2421 1.15.8.1 martin case 1:
2422 1.15.8.1 martin return ("PCI Endpoint Device");
2423 1.15.8.1 martin case 2:
2424 1.15.8.1 martin return ("PCI Sub-Hierarchy");
2425 1.15.8.1 martin case 3:
2426 1.15.8.1 martin return ("IOAPIC");
2427 1.15.8.1 martin case 4:
2428 1.15.8.1 martin return ("HPET");
2429 1.15.8.1 martin default:
2430 1.15.8.1 martin snprintf(typebuf, sizeof(typebuf), "%d", type);
2431 1.15.8.1 martin return (typebuf);
2432 1.15.8.1 martin }
2433 1.15.8.1 martin }
2434 1.15.8.1 martin
2435 1.15.8.1 martin static int
2436 1.15.8.1 martin acpi_handle_dmar_devscope(void *addr, int remaining)
2437 1.15.8.1 martin {
2438 1.15.8.1 martin char sep;
2439 1.15.8.1 martin int pathlen;
2440 1.15.8.1 martin ACPI_DMAR_PCI_PATH *path, *pathend;
2441 1.15.8.1 martin ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
2442 1.15.8.1 martin
2443 1.15.8.1 martin if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
2444 1.15.8.1 martin return (-1);
2445 1.15.8.1 martin
2446 1.15.8.1 martin if (remaining < devscope->Length)
2447 1.15.8.1 martin return (-1);
2448 1.15.8.1 martin
2449 1.15.8.1 martin printf("\n");
2450 1.15.8.1 martin printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
2451 1.15.8.1 martin printf("\t\tLength=%d\n", devscope->Length);
2452 1.15.8.1 martin printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
2453 1.15.8.1 martin printf("\t\tStartBusNumber=%d\n", devscope->Bus);
2454 1.15.8.1 martin
2455 1.15.8.1 martin path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
2456 1.15.8.1 martin pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
2457 1.15.8.1 martin pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
2458 1.15.8.1 martin if (path < pathend) {
2459 1.15.8.1 martin sep = '{';
2460 1.15.8.1 martin printf("\t\tPath=");
2461 1.15.8.1 martin do {
2462 1.15.8.1 martin printf("%c%d:%d", sep, path->Device, path->Function);
2463 1.15.8.1 martin sep=',';
2464 1.15.8.1 martin path++;
2465 1.15.8.1 martin } while (path < pathend);
2466 1.15.8.1 martin printf("}\n");
2467 1.15.8.1 martin }
2468 1.15.8.1 martin
2469 1.15.8.1 martin return (devscope->Length);
2470 1.15.8.1 martin }
2471 1.15.8.1 martin
2472 1.15.8.1 martin static void
2473 1.15.8.1 martin acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
2474 1.15.8.1 martin {
2475 1.15.8.1 martin char *cp;
2476 1.15.8.1 martin int remaining, consumed;
2477 1.15.8.1 martin
2478 1.15.8.1 martin printf("\n");
2479 1.15.8.1 martin printf("\tType=DRHD\n");
2480 1.15.8.1 martin printf("\tLength=%d\n", drhd->Header.Length);
2481 1.15.8.1 martin
2482 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2483 1.15.8.1 martin
2484 1.15.8.1 martin printf("\tFlags=");
2485 1.15.8.1 martin PRINTFLAG(drhd->Flags, INCLUDE_ALL);
2486 1.15.8.1 martin PRINTFLAG_END();
2487 1.15.8.1 martin
2488 1.15.8.1 martin #undef PRINTFLAG
2489 1.15.8.1 martin
2490 1.15.8.1 martin printf("\tSegment=%d\n", drhd->Segment);
2491 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
2492 1.15.8.1 martin
2493 1.15.8.1 martin remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
2494 1.15.8.1 martin if (remaining > 0)
2495 1.15.8.1 martin printf("\tDevice Scope:");
2496 1.15.8.1 martin while (remaining > 0) {
2497 1.15.8.1 martin cp = (char *)drhd + drhd->Header.Length - remaining;
2498 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2499 1.15.8.1 martin if (consumed <= 0)
2500 1.15.8.1 martin break;
2501 1.15.8.1 martin else
2502 1.15.8.1 martin remaining -= consumed;
2503 1.15.8.1 martin }
2504 1.15.8.1 martin }
2505 1.15.8.1 martin
2506 1.15.8.1 martin static void
2507 1.15.8.1 martin acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
2508 1.15.8.1 martin {
2509 1.15.8.1 martin char *cp;
2510 1.15.8.1 martin int remaining, consumed;
2511 1.15.8.1 martin
2512 1.15.8.1 martin printf("\n");
2513 1.15.8.1 martin printf("\tType=RMRR\n");
2514 1.15.8.1 martin printf("\tLength=%d\n", rmrr->Header.Length);
2515 1.15.8.1 martin printf("\tSegment=%d\n", rmrr->Segment);
2516 1.15.8.1 martin printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
2517 1.15.8.1 martin printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
2518 1.15.8.1 martin
2519 1.15.8.1 martin remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
2520 1.15.8.1 martin if (remaining > 0)
2521 1.15.8.1 martin printf("\tDevice Scope:");
2522 1.15.8.1 martin while (remaining > 0) {
2523 1.15.8.1 martin cp = (char *)rmrr + rmrr->Header.Length - remaining;
2524 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2525 1.15.8.1 martin if (consumed <= 0)
2526 1.15.8.1 martin break;
2527 1.15.8.1 martin else
2528 1.15.8.1 martin remaining -= consumed;
2529 1.15.8.1 martin }
2530 1.15.8.1 martin }
2531 1.15.8.1 martin
2532 1.15.8.1 martin static void
2533 1.15.8.1 martin acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
2534 1.15.8.1 martin {
2535 1.15.8.1 martin char *cp;
2536 1.15.8.1 martin int remaining, consumed;
2537 1.15.8.1 martin
2538 1.15.8.1 martin printf("\n");
2539 1.15.8.1 martin printf("\tType=ATSR\n");
2540 1.15.8.1 martin printf("\tLength=%d\n", atsr->Header.Length);
2541 1.15.8.1 martin
2542 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2543 1.15.8.1 martin
2544 1.15.8.1 martin printf("\tFlags=");
2545 1.15.8.1 martin PRINTFLAG(atsr->Flags, ALL_PORTS);
2546 1.15.8.1 martin PRINTFLAG_END();
2547 1.15.8.1 martin
2548 1.15.8.1 martin #undef PRINTFLAG
2549 1.15.8.1 martin
2550 1.15.8.1 martin printf("\tSegment=%d\n", atsr->Segment);
2551 1.15.8.1 martin
2552 1.15.8.1 martin remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
2553 1.15.8.1 martin if (remaining > 0)
2554 1.15.8.1 martin printf("\tDevice Scope:");
2555 1.15.8.1 martin while (remaining > 0) {
2556 1.15.8.1 martin cp = (char *)atsr + atsr->Header.Length - remaining;
2557 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2558 1.15.8.1 martin if (consumed <= 0)
2559 1.15.8.1 martin break;
2560 1.15.8.1 martin else
2561 1.15.8.1 martin remaining -= consumed;
2562 1.15.8.1 martin }
2563 1.15.8.1 martin }
2564 1.15.8.1 martin
2565 1.15.8.1 martin static void
2566 1.15.8.1 martin acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
2567 1.15.8.1 martin {
2568 1.15.8.1 martin
2569 1.15.8.1 martin printf("\n");
2570 1.15.8.1 martin printf("\tType=RHSA\n");
2571 1.15.8.1 martin printf("\tLength=%d\n", rhsa->Header.Length);
2572 1.15.8.1 martin printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
2573 1.15.8.1 martin printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
2574 1.15.8.1 martin }
2575 1.15.8.1 martin
2576 1.15.8.1 martin static int
2577 1.15.8.1 martin acpi_handle_dmar_remapping_structure(void *addr, int remaining)
2578 1.15.8.1 martin {
2579 1.15.8.1 martin ACPI_DMAR_HEADER *hdr = addr;
2580 1.15.8.1 martin
2581 1.15.8.1 martin if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
2582 1.15.8.1 martin return (-1);
2583 1.15.8.1 martin
2584 1.15.8.1 martin if (remaining < hdr->Length)
2585 1.15.8.1 martin return (-1);
2586 1.15.8.1 martin
2587 1.15.8.1 martin switch (hdr->Type) {
2588 1.15.8.1 martin case ACPI_DMAR_TYPE_HARDWARE_UNIT:
2589 1.15.8.1 martin acpi_handle_dmar_drhd(addr);
2590 1.15.8.1 martin break;
2591 1.15.8.1 martin case ACPI_DMAR_TYPE_RESERVED_MEMORY:
2592 1.15.8.1 martin acpi_handle_dmar_rmrr(addr);
2593 1.15.8.1 martin break;
2594 1.15.8.1 martin case ACPI_DMAR_TYPE_ROOT_ATS:
2595 1.15.8.1 martin acpi_handle_dmar_atsr(addr);
2596 1.15.8.1 martin break;
2597 1.15.8.1 martin case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
2598 1.15.8.1 martin acpi_handle_dmar_rhsa(addr);
2599 1.13 christos break;
2600 1.15.8.1 martin default:
2601 1.15.8.1 martin printf("\n");
2602 1.15.8.1 martin printf("\tType=%d\n", hdr->Type);
2603 1.15.8.1 martin printf("\tLength=%d\n", hdr->Length);
2604 1.15.8.1 martin break;
2605 1.15.8.1 martin }
2606 1.15.8.1 martin return (hdr->Length);
2607 1.15.8.1 martin }
2608 1.15.8.1 martin
2609 1.15.8.1 martin #ifndef ACPI_DMAR_X2APIC_OPT_OUT
2610 1.15.8.1 martin #define ACPI_DMAR_X2APIC_OPT_OUT (0x2)
2611 1.15.8.1 martin #endif
2612 1.15.8.1 martin
2613 1.15.8.1 martin static void
2614 1.15.8.1 martin acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
2615 1.15.8.1 martin {
2616 1.15.8.1 martin char *cp;
2617 1.15.8.1 martin int remaining, consumed;
2618 1.15.8.1 martin ACPI_TABLE_DMAR *dmar;
2619 1.15.8.1 martin
2620 1.15.8.1 martin printf(BEGIN_COMMENT);
2621 1.15.8.1 martin acpi_print_sdt(sdp);
2622 1.15.8.1 martin dmar = (ACPI_TABLE_DMAR *)sdp;
2623 1.15.8.1 martin printf("\tHost Address Width=%d\n", dmar->Width + 1);
2624 1.15.8.1 martin
2625 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2626 1.15.8.1 martin
2627 1.15.8.1 martin printf("\tFlags=");
2628 1.15.8.1 martin PRINTFLAG(dmar->Flags, INTR_REMAP);
2629 1.15.8.1 martin PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
2630 1.15.8.1 martin PRINTFLAG_END();
2631 1.15.8.1 martin
2632 1.15.8.1 martin #undef PRINTFLAG
2633 1.15.8.1 martin
2634 1.15.8.1 martin remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
2635 1.15.8.1 martin while (remaining > 0) {
2636 1.15.8.1 martin cp = (char *)sdp + sdp->Length - remaining;
2637 1.15.8.1 martin consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
2638 1.15.8.1 martin if (consumed <= 0)
2639 1.15.8.1 martin break;
2640 1.15.8.1 martin else
2641 1.15.8.1 martin remaining -= consumed;
2642 1.13 christos }
2643 1.1 christos
2644 1.12 christos printf(END_COMMENT);
2645 1.1 christos }
2646 1.1 christos
2647 1.1 christos static void
2648 1.15.8.1 martin acpi_handle_uefi(ACPI_TABLE_HEADER *sdp)
2649 1.15.8.1 martin {
2650 1.15.8.1 martin ACPI_TABLE_UEFI *uefi;
2651 1.15.8.1 martin char *uuidstr;
2652 1.15.8.1 martin uint32_t status;
2653 1.15.8.1 martin
2654 1.15.8.1 martin printf(BEGIN_COMMENT);
2655 1.15.8.1 martin acpi_print_sdt(sdp);
2656 1.15.8.1 martin uefi = (ACPI_TABLE_UEFI *)sdp;
2657 1.15.8.1 martin
2658 1.15.8.1 martin uuid_to_string((uuid_t *)(uefi->Identifier),
2659 1.15.8.1 martin &uuidstr, &status);
2660 1.15.8.1 martin if (status != uuid_s_ok)
2661 1.15.8.1 martin errx(1, "uuid_to_string: status=%u", status);
2662 1.15.8.1 martin printf("\tUUID=%s\n", uuidstr);
2663 1.15.8.1 martin free(uuidstr);
2664 1.15.8.1 martin
2665 1.15.8.1 martin printf("\tDataOffset=%04hx\n", uefi->DataOffset);
2666 1.15.8.1 martin /* XXX need write */
2667 1.15.8.1 martin
2668 1.15.8.1 martin printf(END_COMMENT);
2669 1.15.8.1 martin }
2670 1.15.8.1 martin
2671 1.15.8.1 martin static void
2672 1.5 cegger acpi_handle_waet(ACPI_TABLE_HEADER *sdp)
2673 1.1 christos {
2674 1.5 cegger ACPI_TABLE_WAET *waet;
2675 1.5 cegger
2676 1.5 cegger printf(BEGIN_COMMENT);
2677 1.5 cegger acpi_print_sdt(sdp);
2678 1.5 cegger waet = (ACPI_TABLE_WAET *)sdp;
2679 1.1 christos
2680 1.5 cegger printf("\tRTC Timer={");
2681 1.5 cegger if (waet->Flags & ACPI_WAET_RTC_NO_ACK)
2682 1.5 cegger printf("No ACK required");
2683 1.5 cegger else
2684 1.5 cegger printf("default behaviour");
2685 1.5 cegger printf("}\n");
2686 1.5 cegger printf("\t ACPI PM Timer={");
2687 1.5 cegger if (waet->Flags & ACPI_WAET_TIMER_ONE_READ)
2688 1.5 cegger printf("One Read sufficient");
2689 1.5 cegger else
2690 1.5 cegger printf("default behaviour");
2691 1.5 cegger printf("}\n");
2692 1.3 joerg
2693 1.5 cegger printf(END_COMMENT);
2694 1.1 christos }
2695 1.1 christos
2696 1.5 cegger static void
2697 1.5 cegger acpi_print_wdat_action(ACPI_WHEA_HEADER *whea)
2698 1.5 cegger {
2699 1.5 cegger printf("\tACTION={");
2700 1.5 cegger switch (whea->Action) {
2701 1.5 cegger case ACPI_WDAT_RESET:
2702 1.5 cegger printf("RESET");
2703 1.5 cegger break;
2704 1.5 cegger case ACPI_WDAT_GET_CURRENT_COUNTDOWN:
2705 1.5 cegger printf("GET_CURRENT_COUNTDOWN");
2706 1.5 cegger break;
2707 1.5 cegger case ACPI_WDAT_GET_COUNTDOWN:
2708 1.5 cegger printf("GET_COUNTDOWN");
2709 1.5 cegger break;
2710 1.5 cegger case ACPI_WDAT_SET_COUNTDOWN:
2711 1.5 cegger printf("SET_COUNTDOWN");
2712 1.5 cegger break;
2713 1.5 cegger case ACPI_WDAT_GET_RUNNING_STATE:
2714 1.5 cegger printf("GET_RUNNING_STATE");
2715 1.5 cegger break;
2716 1.5 cegger case ACPI_WDAT_SET_RUNNING_STATE:
2717 1.5 cegger printf("SET_RUNNING_STATE");
2718 1.5 cegger break;
2719 1.5 cegger case ACPI_WDAT_GET_STOPPED_STATE:
2720 1.5 cegger printf("GET_STOPPED_STATE");
2721 1.5 cegger break;
2722 1.5 cegger case ACPI_WDAT_SET_STOPPED_STATE:
2723 1.5 cegger printf("SET_STOPPED_STATE");
2724 1.5 cegger break;
2725 1.5 cegger case ACPI_WDAT_GET_REBOOT:
2726 1.5 cegger printf("GET_REBOOT");
2727 1.5 cegger break;
2728 1.5 cegger case ACPI_WDAT_SET_REBOOT:
2729 1.5 cegger printf("SET_REBOOT");
2730 1.5 cegger break;
2731 1.5 cegger case ACPI_WDAT_GET_SHUTDOWN:
2732 1.5 cegger printf("GET_SHUTDOWN");
2733 1.5 cegger break;
2734 1.5 cegger case ACPI_WDAT_SET_SHUTDOWN:
2735 1.5 cegger printf("SET_SHUTDOWN");
2736 1.5 cegger break;
2737 1.5 cegger case ACPI_WDAT_GET_STATUS:
2738 1.5 cegger printf("GET_STATUS");
2739 1.5 cegger break;
2740 1.5 cegger case ACPI_WDAT_SET_STATUS:
2741 1.5 cegger printf("SET_STATUS");
2742 1.5 cegger break;
2743 1.5 cegger case ACPI_WDAT_ACTION_RESERVED:
2744 1.5 cegger printf("ACTION_RESERVED");
2745 1.5 cegger break;
2746 1.5 cegger default:
2747 1.5 cegger printf("%d", whea->Action);
2748 1.5 cegger break;
2749 1.5 cegger }
2750 1.5 cegger printf("}\n");
2751 1.5 cegger }
2752 1.1 christos
2753 1.5 cegger static void
2754 1.5 cegger acpi_print_wdat_instruction(ACPI_WHEA_HEADER *whea)
2755 1.1 christos {
2756 1.5 cegger uint32_t ins;
2757 1.5 cegger
2758 1.5 cegger ins = whea->Instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
2759 1.5 cegger
2760 1.5 cegger printf("\tINSTRUCTION={");
2761 1.5 cegger switch (ins) {
2762 1.5 cegger case ACPI_WDAT_READ_VALUE:
2763 1.5 cegger printf("READ_VALUE");
2764 1.5 cegger break;
2765 1.5 cegger case ACPI_WDAT_READ_COUNTDOWN:
2766 1.5 cegger printf("READ_COUNTDOWN");
2767 1.5 cegger break;
2768 1.5 cegger case ACPI_WDAT_WRITE_VALUE:
2769 1.5 cegger printf("WRITE_VALUE");
2770 1.5 cegger break;
2771 1.5 cegger case ACPI_WDAT_WRITE_COUNTDOWN:
2772 1.5 cegger printf("WRITE_COUNTDOWN");
2773 1.5 cegger break;
2774 1.5 cegger case ACPI_WDAT_INSTRUCTION_RESERVED:
2775 1.5 cegger printf("INSTRUCTION_RESERVED");
2776 1.5 cegger break;
2777 1.5 cegger default:
2778 1.5 cegger printf("%d", ins);
2779 1.5 cegger break;
2780 1.5 cegger }
2781 1.5 cegger
2782 1.5 cegger if (whea->Instruction & ACPI_WDAT_PRESERVE_REGISTER)
2783 1.15.8.1 martin printf(", Preserve Register");
2784 1.5 cegger
2785 1.5 cegger printf("}\n");
2786 1.5 cegger }
2787 1.1 christos
2788 1.5 cegger static void
2789 1.5 cegger acpi_handle_wdat(ACPI_TABLE_HEADER *sdp)
2790 1.5 cegger {
2791 1.5 cegger ACPI_TABLE_WDAT *wdat;
2792 1.5 cegger ACPI_WHEA_HEADER *whea;
2793 1.15.8.1 martin ACPI_WDAT_ENTRY *wdat_pos;
2794 1.5 cegger u_int i;
2795 1.1 christos
2796 1.5 cegger printf(BEGIN_COMMENT);
2797 1.5 cegger acpi_print_sdt(sdp);
2798 1.5 cegger wdat = (ACPI_TABLE_WDAT *)sdp;
2799 1.1 christos
2800 1.5 cegger printf("\tHeader Length=%d\n", wdat->HeaderLength);
2801 1.1 christos
2802 1.15.8.1 martin acpi_print_pci_sbdf(wdat->PciSegment, wdat->PciBus, wdat->PciDevice,
2803 1.5 cegger wdat->PciFunction);
2804 1.5 cegger printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod);
2805 1.5 cegger printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount);
2806 1.5 cegger printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount);
2807 1.5 cegger
2808 1.5 cegger printf("\tFlags={");
2809 1.5 cegger if (wdat->Flags & ACPI_WDAT_ENABLED)
2810 1.5 cegger printf("ENABLED");
2811 1.5 cegger if (wdat->Flags & ACPI_WDAT_STOPPED)
2812 1.5 cegger printf(", STOPPED");
2813 1.5 cegger printf("}\n");
2814 1.1 christos
2815 1.15.8.1 martin wdat_pos = (ACPI_WDAT_ENTRY *)((char *)wdat + sizeof(ACPI_TABLE_WDAT));
2816 1.1 christos
2817 1.5 cegger for (i = 0; i < wdat->Entries; i++) {
2818 1.5 cegger whea = (ACPI_WHEA_HEADER *)wdat_pos;
2819 1.5 cegger acpi_print_whea(whea,
2820 1.5 cegger acpi_print_wdat_action, acpi_print_wdat_instruction,
2821 1.5 cegger NULL);
2822 1.15.8.1 martin wdat_pos++;
2823 1.5 cegger }
2824 1.5 cegger printf(END_COMMENT);
2825 1.1 christos }
2826 1.5 cegger
2827 1.5 cegger static void
2828 1.15.8.1 martin acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
2829 1.15.8.1 martin {
2830 1.15.8.1 martin ACPI_TABLE_WDDT *wddt;
2831 1.15.8.1 martin
2832 1.15.8.1 martin printf(BEGIN_COMMENT);
2833 1.15.8.1 martin acpi_print_sdt(sdp);
2834 1.15.8.1 martin wddt = (ACPI_TABLE_WDDT *)sdp;
2835 1.15.8.1 martin
2836 1.15.8.1 martin printf("\tSpecVersion=%04hx\n", wddt->SpecVersion);
2837 1.15.8.1 martin printf("\tTableVersion=%04hx\n", wddt->TableVersion);
2838 1.15.8.1 martin printf("\tPciVendorID=%04hx\n", wddt->PciVendorId);
2839 1.15.8.1 martin printf("\tAddress=");
2840 1.15.8.1 martin acpi_print_gas(&wddt->Address);
2841 1.15.8.1 martin printf("\n\tTimer Maximum Counter Value=%d\n", wddt->MaxCount);
2842 1.15.8.1 martin printf("\tTimer Minimum Counter Value=%d\n", wddt->MinCount);
2843 1.15.8.1 martin printf("\tTimer Counter Period=%d\n", wddt->Period);
2844 1.15.8.1 martin
2845 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag)
2846 1.15.8.1 martin
2847 1.15.8.1 martin printf("\tStatus=");
2848 1.15.8.1 martin PRINTFLAG(wddt->Status, AVAILABLE);
2849 1.15.8.1 martin PRINTFLAG(wddt->Status, ACTIVE);
2850 1.15.8.1 martin PRINTFLAG(wddt->Status, TCO_OS_OWNED);
2851 1.15.8.1 martin PRINTFLAG(wddt->Status, USER_RESET);
2852 1.15.8.1 martin PRINTFLAG(wddt->Status, WDT_RESET);
2853 1.15.8.1 martin PRINTFLAG(wddt->Status, POWER_FAIL);
2854 1.15.8.1 martin PRINTFLAG(wddt->Status, UNKNOWN_RESET);
2855 1.15.8.1 martin PRINTFLAG_END();
2856 1.15.8.1 martin
2857 1.15.8.1 martin printf("\tCapability=");
2858 1.15.8.1 martin PRINTFLAG(wddt->Capability, AUTO_RESET);
2859 1.15.8.1 martin PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
2860 1.15.8.1 martin PRINTFLAG_END();
2861 1.15.8.1 martin
2862 1.15.8.1 martin #undef PRINTFLAG
2863 1.15.8.1 martin
2864 1.15.8.1 martin printf(END_COMMENT);
2865 1.15.8.1 martin }
2866 1.15.8.1 martin
2867 1.15.8.1 martin static void
2868 1.5 cegger acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp)
2869 1.1 christos {
2870 1.5 cegger ACPI_TABLE_WDRT *wdrt;
2871 1.1 christos
2872 1.1 christos printf(BEGIN_COMMENT);
2873 1.5 cegger acpi_print_sdt(sdp);
2874 1.5 cegger wdrt = (ACPI_TABLE_WDRT *)sdp;
2875 1.5 cegger
2876 1.5 cegger printf("\tControl Register=");
2877 1.5 cegger acpi_print_gas(&wdrt->ControlRegister);
2878 1.5 cegger printf("\tCount Register=");
2879 1.5 cegger acpi_print_gas(&wdrt->CountRegister);
2880 1.5 cegger acpi_print_pci(wdrt->PciVendorId, wdrt->PciDeviceId,
2881 1.5 cegger wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, wdrt->PciFunction);
2882 1.5 cegger
2883 1.5 cegger /* Value must be >= 511 and < 65535 */
2884 1.5 cegger printf("\tMaxCount=%d", wdrt->MaxCount);
2885 1.5 cegger if (wdrt->MaxCount < 511)
2886 1.5 cegger printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
2887 1.5 cegger printf("\n");
2888 1.5 cegger
2889 1.5 cegger printf("\tUnit={");
2890 1.5 cegger switch (wdrt->Units) {
2891 1.5 cegger case 0:
2892 1.5 cegger printf("1 seconds/count");
2893 1.5 cegger break;
2894 1.5 cegger case 1:
2895 1.5 cegger printf("100 milliseconds/count");
2896 1.5 cegger break;
2897 1.5 cegger case 2:
2898 1.5 cegger printf("10 milliseconds/count");
2899 1.5 cegger break;
2900 1.5 cegger default:
2901 1.5 cegger printf("%d", wdrt->Units);
2902 1.5 cegger break;
2903 1.5 cegger }
2904 1.5 cegger printf("}\n");
2905 1.5 cegger
2906 1.5 cegger printf(END_COMMENT);
2907 1.5 cegger }
2908 1.5 cegger
2909 1.5 cegger static void
2910 1.5 cegger acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
2911 1.5 cegger {
2912 1.5 cegger printf(" ");
2913 1.5 cegger acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
2914 1.8 jmcneill printf(": Length=%d, Revision=%d, Checksum=%d",
2915 1.5 cegger sdp->Length, sdp->Revision, sdp->Checksum);
2916 1.8 jmcneill if (acpi_checksum(sdp, sdp->Length))
2917 1.8 jmcneill printf(" (Incorrect)");
2918 1.8 jmcneill printf(",\n\tOEMID=");
2919 1.5 cegger acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
2920 1.1 christos printf(", OEM Table ID=");
2921 1.5 cegger acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
2922 1.5 cegger printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
2923 1.1 christos printf("\tCreator ID=");
2924 1.5 cegger acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
2925 1.5 cegger printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
2926 1.1 christos }
2927 1.1 christos
2928 1.5 cegger static void
2929 1.7 jmcneill acpi_dump_bytes(ACPI_TABLE_HEADER *sdp)
2930 1.7 jmcneill {
2931 1.7 jmcneill unsigned int i;
2932 1.7 jmcneill uint8_t *p;
2933 1.7 jmcneill
2934 1.8 jmcneill p = (uint8_t *)sdp;
2935 1.7 jmcneill printf("\n\tData={");
2936 1.7 jmcneill for (i = 0; i < sdp->Length; i++) {
2937 1.7 jmcneill if (cflag) {
2938 1.7 jmcneill if (i % 64 == 0)
2939 1.7 jmcneill printf("\n\t ");
2940 1.7 jmcneill else if (i % 16 == 0)
2941 1.7 jmcneill printf(" ");
2942 1.7 jmcneill printf("%c", (p[i] >= ' ' && p[i] <= '~') ? p[i] : '.');
2943 1.7 jmcneill } else {
2944 1.7 jmcneill if (i % 16 == 0)
2945 1.7 jmcneill printf("\n\t\t");
2946 1.7 jmcneill else if (i % 8 == 0)
2947 1.7 jmcneill printf(" ");
2948 1.7 jmcneill printf(" %02x", p[i]);
2949 1.7 jmcneill }
2950 1.7 jmcneill }
2951 1.7 jmcneill printf("\n\t}\n");
2952 1.7 jmcneill }
2953 1.7 jmcneill
2954 1.7 jmcneill static void
2955 1.5 cegger acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
2956 1.1 christos {
2957 1.5 cegger ACPI_TABLE_RSDT *rsdt;
2958 1.5 cegger ACPI_TABLE_XSDT *xsdt;
2959 1.1 christos int i, entries;
2960 1.1 christos
2961 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
2962 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
2963 1.5 cegger printf(BEGIN_COMMENT);
2964 1.1 christos acpi_print_sdt(rsdp);
2965 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2966 1.1 christos printf("\tEntries={ ");
2967 1.1 christos for (i = 0; i < entries; i++) {
2968 1.1 christos if (i > 0)
2969 1.1 christos printf(", ");
2970 1.15.8.1 martin if (addr_size == 4)
2971 1.15.8.1 martin printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
2972 1.15.8.1 martin else
2973 1.15.8.1 martin printf("0x%016jx",
2974 1.15.8.1 martin (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
2975 1.1 christos }
2976 1.1 christos printf(" }\n");
2977 1.1 christos printf(END_COMMENT);
2978 1.1 christos }
2979 1.1 christos
2980 1.5 cegger static const char *acpi_pm_profiles[] = {
2981 1.5 cegger "Unspecified", "Desktop", "Mobile", "Workstation",
2982 1.15.8.1 martin "Enterprise Server", "SOHO Server", "Appliance PC",
2983 1.15.8.1 martin "Performance Server", "Tablet"
2984 1.5 cegger };
2985 1.5 cegger
2986 1.5 cegger static void
2987 1.5 cegger acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
2988 1.1 christos {
2989 1.5 cegger ACPI_TABLE_FADT *fadt;
2990 1.5 cegger const char *pm;
2991 1.1 christos
2992 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
2993 1.1 christos printf(BEGIN_COMMENT);
2994 1.5 cegger acpi_print_sdt(sdp);
2995 1.5 cegger printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
2996 1.5 cegger fadt->Dsdt);
2997 1.15.8.1 martin /* XXX ACPI 2.0 eliminated this */
2998 1.5 cegger printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
2999 1.5 cegger if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
3000 1.5 cegger pm = "Reserved";
3001 1.5 cegger else
3002 1.5 cegger pm = acpi_pm_profiles[fadt->PreferredProfile];
3003 1.5 cegger printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
3004 1.5 cegger printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
3005 1.5 cegger printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
3006 1.5 cegger printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
3007 1.5 cegger printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
3008 1.5 cegger printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
3009 1.5 cegger printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
3010 1.5 cegger printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
3011 1.5 cegger fadt->Pm1aEventBlock,
3012 1.5 cegger fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
3013 1.5 cegger if (fadt->Pm1bEventBlock != 0)
3014 1.1 christos printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
3015 1.5 cegger fadt->Pm1bEventBlock,
3016 1.5 cegger fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
3017 1.5 cegger printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
3018 1.5 cegger fadt->Pm1aControlBlock,
3019 1.5 cegger fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
3020 1.5 cegger if (fadt->Pm1bControlBlock != 0)
3021 1.1 christos printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
3022 1.5 cegger fadt->Pm1bControlBlock,
3023 1.5 cegger fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
3024 1.5 cegger if (fadt->Pm2ControlBlock != 0)
3025 1.1 christos printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
3026 1.5 cegger fadt->Pm2ControlBlock,
3027 1.5 cegger fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
3028 1.5 cegger printf("\tPM_TMR_BLK=0x%x-0x%x\n",
3029 1.5 cegger fadt->PmTimerBlock,
3030 1.5 cegger fadt->PmTimerBlock + fadt->PmTimerLength - 1);
3031 1.5 cegger if (fadt->Gpe0Block != 0)
3032 1.5 cegger printf("\tGPE0_BLK=0x%x-0x%x\n",
3033 1.5 cegger fadt->Gpe0Block,
3034 1.5 cegger fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
3035 1.5 cegger if (fadt->Gpe1Block != 0)
3036 1.5 cegger printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
3037 1.5 cegger fadt->Gpe1Block,
3038 1.5 cegger fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
3039 1.5 cegger fadt->Gpe1Base);
3040 1.5 cegger if (fadt->CstControl != 0)
3041 1.5 cegger printf("\tCST_CNT=0x%x\n", fadt->CstControl);
3042 1.5 cegger printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
3043 1.5 cegger fadt->C2Latency, fadt->C3Latency);
3044 1.1 christos printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
3045 1.5 cegger fadt->FlushSize, fadt->FlushStride);
3046 1.1 christos printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
3047 1.5 cegger fadt->DutyOffset, fadt->DutyWidth);
3048 1.1 christos printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
3049 1.5 cegger fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
3050 1.1 christos
3051 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag)
3052 1.1 christos
3053 1.5 cegger printf("\tIAPC_BOOT_ARCH=");
3054 1.5 cegger PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
3055 1.5 cegger PRINTFLAG(fadt->BootFlags, 8042);
3056 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_VGA);
3057 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_MSI);
3058 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_ASPM);
3059 1.15.8.1 martin PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
3060 1.15.8.1 martin PRINTFLAG_END();
3061 1.5 cegger
3062 1.5 cegger printf("\tFlags=");
3063 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD);
3064 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
3065 1.5 cegger PRINTFLAG(fadt->Flags, C1_SUPPORTED);
3066 1.5 cegger PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
3067 1.5 cegger PRINTFLAG(fadt->Flags, POWER_BUTTON);
3068 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
3069 1.5 cegger PRINTFLAG(fadt->Flags, FIXED_RTC);
3070 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
3071 1.5 cegger PRINTFLAG(fadt->Flags, 32BIT_TIMER);
3072 1.5 cegger PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
3073 1.5 cegger PRINTFLAG(fadt->Flags, RESET_REGISTER);
3074 1.5 cegger PRINTFLAG(fadt->Flags, SEALED_CASE);
3075 1.5 cegger PRINTFLAG(fadt->Flags, HEADLESS);
3076 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_TYPE);
3077 1.5 cegger PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
3078 1.5 cegger PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
3079 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_VALID);
3080 1.5 cegger PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
3081 1.5 cegger PRINTFLAG(fadt->Flags, APIC_CLUSTER);
3082 1.5 cegger PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
3083 1.15.8.1 martin PRINTFLAG(fadt->Flags, HW_REDUCED);
3084 1.15.8.1 martin PRINTFLAG(fadt->Flags, LOW_POWER_S0);
3085 1.15.8.1 martin PRINTFLAG_END();
3086 1.1 christos
3087 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V2_SIZE)
3088 1.15.8.1 martin goto out;
3089 1.1 christos
3090 1.5 cegger if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
3091 1.5 cegger printf("\tRESET_REG=");
3092 1.5 cegger acpi_print_gas(&fadt->ResetRegister);
3093 1.5 cegger printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
3094 1.5 cegger }
3095 1.15.8.1 martin
3096 1.15.8.1 martin printf("\tArmBootFlags=");
3097 1.15.8.1 martin PRINTFLAG(fadt->ArmBootFlags, PSCI_COMPLIANT);
3098 1.15.8.1 martin PRINTFLAG(fadt->ArmBootFlags, PSCI_USE_HVC);
3099 1.15.8.1 martin PRINTFLAG_END();
3100 1.15.8.1 martin
3101 1.15.8.1 martin #undef PRINTFLAG
3102 1.15.8.1 martin
3103 1.15.8.1 martin printf("\tMinorRevision=%u\n", fadt->MinorRevision);
3104 1.15.8.1 martin
3105 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V3_SIZE)
3106 1.15.8.1 martin goto out;
3107 1.15.8.1 martin
3108 1.15.8.1 martin printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
3109 1.15.8.1 martin printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
3110 1.15.8.1 martin printf("\tX_PM1a_EVT_BLK=");
3111 1.15.8.1 martin acpi_print_gas(&fadt->XPm1aEventBlock);
3112 1.15.8.1 martin if (fadt->XPm1bEventBlock.Address != 0) {
3113 1.15.8.1 martin printf("\n\tX_PM1b_EVT_BLK=");
3114 1.15.8.1 martin acpi_print_gas(&fadt->XPm1bEventBlock);
3115 1.15.8.1 martin }
3116 1.15.8.1 martin printf("\n\tX_PM1a_CNT_BLK=");
3117 1.15.8.1 martin acpi_print_gas(&fadt->XPm1aControlBlock);
3118 1.15.8.1 martin if (fadt->XPm1bControlBlock.Address != 0) {
3119 1.15.8.1 martin printf("\n\tX_PM1b_CNT_BLK=");
3120 1.15.8.1 martin acpi_print_gas(&fadt->XPm1bControlBlock);
3121 1.15.8.1 martin }
3122 1.15.8.1 martin if (fadt->XPm2ControlBlock.Address != 0) {
3123 1.15.8.1 martin printf("\n\tX_PM2_CNT_BLK=");
3124 1.15.8.1 martin acpi_print_gas(&fadt->XPm2ControlBlock);
3125 1.15.8.1 martin }
3126 1.15.8.1 martin printf("\n\tX_PM_TMR_BLK=");
3127 1.15.8.1 martin acpi_print_gas(&fadt->XPmTimerBlock);
3128 1.15.8.1 martin if (fadt->XGpe0Block.Address != 0) {
3129 1.15.8.1 martin printf("\n\tX_GPE0_BLK=");
3130 1.15.8.1 martin acpi_print_gas(&fadt->XGpe0Block);
3131 1.15.8.1 martin }
3132 1.15.8.1 martin if (fadt->XGpe1Block.Address != 0) {
3133 1.15.8.1 martin printf("\n\tX_GPE1_BLK=");
3134 1.15.8.1 martin acpi_print_gas(&fadt->XGpe1Block);
3135 1.15.8.1 martin }
3136 1.15.8.1 martin printf("\n");
3137 1.15.8.1 martin
3138 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V5_SIZE)
3139 1.15.8.1 martin goto out;
3140 1.15.8.1 martin
3141 1.15.8.1 martin if (fadt->SleepControl.Address != 0) {
3142 1.15.8.1 martin printf("\tSleepControl=");
3143 1.15.8.1 martin acpi_print_gas(&fadt->SleepControl);
3144 1.5 cegger printf("\n");
3145 1.5 cegger }
3146 1.15.8.1 martin if (fadt->SleepStatus.Address != 0) {
3147 1.15.8.1 martin printf("\n\tSleepStatus=");
3148 1.15.8.1 martin acpi_print_gas(&fadt->SleepStatus);
3149 1.15.8.1 martin printf("\n");
3150 1.15.8.1 martin }
3151 1.15.8.1 martin
3152 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V6_SIZE)
3153 1.15.8.1 martin goto out;
3154 1.5 cegger
3155 1.15.8.1 martin printf("\tHypervisorId=0x%016"PRIx64"\n", fadt->HypervisorId);
3156 1.15.8.1 martin
3157 1.15.8.1 martin out:
3158 1.1 christos printf(END_COMMENT);
3159 1.1 christos }
3160 1.1 christos
3161 1.5 cegger static void
3162 1.5 cegger acpi_print_facs(ACPI_TABLE_FACS *facs)
3163 1.1 christos {
3164 1.5 cegger printf(BEGIN_COMMENT);
3165 1.5 cegger printf(" FACS:\tLength=%u, ", facs->Length);
3166 1.5 cegger printf("HwSig=0x%08x, ", facs->HardwareSignature);
3167 1.5 cegger printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
3168 1.5 cegger
3169 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_GLOCK_## flag, #flag)
3170 1.15.8.1 martin
3171 1.5 cegger printf("\tGlobal_Lock=");
3172 1.15.8.1 martin PRINTFLAG(facs->GlobalLock, PENDING);
3173 1.15.8.1 martin PRINTFLAG(facs->GlobalLock, OWNED);
3174 1.15.8.1 martin PRINTFLAG_END();
3175 1.15.8.1 martin
3176 1.15.8.1 martin #undef PRINTFLAG
3177 1.15.8.1 martin
3178 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_FACS_## flag, #flag)
3179 1.5 cegger
3180 1.5 cegger printf("\tFlags=");
3181 1.15.8.1 martin PRINTFLAG(facs->Flags, S4_BIOS_PRESENT);
3182 1.15.8.1 martin PRINTFLAG(facs->Flags, 64BIT_WAKE);
3183 1.15.8.1 martin PRINTFLAG_END();
3184 1.5 cegger
3185 1.15.8.1 martin #undef PRINTFLAG
3186 1.15.8.1 martin
3187 1.15.8.1 martin if (facs->XFirmwareWakingVector != 0)
3188 1.15.8.1 martin printf("\tX_Firm_Wake_Vec=%016jx\n",
3189 1.15.8.1 martin (uintmax_t)facs->XFirmwareWakingVector);
3190 1.5 cegger printf("\tVersion=%u\n", facs->Version);
3191 1.5 cegger
3192 1.15.8.1 martin printf("\tOspmFlags={");
3193 1.15.8.1 martin if (facs->OspmFlags & ACPI_FACS_64BIT_ENVIRONMENT)
3194 1.15.8.1 martin printf("64BIT_WAKE");
3195 1.15.8.1 martin printf("}\n");
3196 1.15.8.1 martin
3197 1.5 cegger printf(END_COMMENT);
3198 1.5 cegger }
3199 1.1 christos
3200 1.5 cegger static void
3201 1.5 cegger acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
3202 1.5 cegger {
3203 1.5 cegger printf(BEGIN_COMMENT);
3204 1.1 christos acpi_print_sdt(dsdp);
3205 1.5 cegger printf(END_COMMENT);
3206 1.1 christos }
3207 1.1 christos
3208 1.1 christos int
3209 1.1 christos acpi_checksum(void *p, size_t length)
3210 1.1 christos {
3211 1.5 cegger uint8_t *bp;
3212 1.5 cegger uint8_t sum;
3213 1.1 christos
3214 1.1 christos bp = p;
3215 1.1 christos sum = 0;
3216 1.1 christos while (length--)
3217 1.1 christos sum += *bp++;
3218 1.1 christos
3219 1.1 christos return (sum);
3220 1.1 christos }
3221 1.1 christos
3222 1.5 cegger static ACPI_TABLE_HEADER *
3223 1.1 christos acpi_map_sdt(vm_offset_t pa)
3224 1.1 christos {
3225 1.5 cegger ACPI_TABLE_HEADER *sp;
3226 1.1 christos
3227 1.5 cegger sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
3228 1.5 cegger sp = acpi_map_physical(pa, sp->Length);
3229 1.1 christos return (sp);
3230 1.1 christos }
3231 1.1 christos
3232 1.5 cegger static void
3233 1.5 cegger acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
3234 1.1 christos {
3235 1.1 christos printf(BEGIN_COMMENT);
3236 1.5 cegger printf(" RSD PTR: OEM=");
3237 1.5 cegger acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
3238 1.5 cegger printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
3239 1.5 cegger rp->Revision);
3240 1.5 cegger if (rp->Revision < 2) {
3241 1.5 cegger printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
3242 1.5 cegger rp->Checksum);
3243 1.5 cegger } else {
3244 1.15.8.1 martin printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
3245 1.15.8.1 martin (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
3246 1.5 cegger rp->ExtendedChecksum);
3247 1.5 cegger }
3248 1.1 christos printf(END_COMMENT);
3249 1.1 christos }
3250 1.1 christos
3251 1.5 cegger static void
3252 1.5 cegger acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
3253 1.1 christos {
3254 1.5 cegger ACPI_TABLE_HEADER *sdp;
3255 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3256 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3257 1.15 christos vm_offset_t addr = 0;
3258 1.5 cegger int entries, i;
3259 1.1 christos
3260 1.1 christos acpi_print_rsdt(rsdp);
3261 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3262 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3263 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3264 1.1 christos for (i = 0; i < entries; i++) {
3265 1.15.8.1 martin if (addr_size == 4)
3266 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
3267 1.15.8.1 martin else
3268 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
3269 1.15.8.1 martin if (addr == 0)
3270 1.15.8.1 martin continue;
3271 1.5 cegger sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
3272 1.5 cegger if (acpi_checksum(sdp, sdp->Length)) {
3273 1.5 cegger warnx("RSDT entry %d (sig %.4s) is corrupt", i,
3274 1.5 cegger sdp->Signature);
3275 1.8 jmcneill if (sflag)
3276 1.8 jmcneill continue;
3277 1.4 drochner }
3278 1.5 cegger if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
3279 1.5 cegger acpi_handle_fadt(sdp);
3280 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
3281 1.5 cegger acpi_handle_bert(sdp);
3282 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4))
3283 1.5 cegger acpi_handle_boot(sdp);
3284 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_CPEP, 4))
3285 1.5 cegger acpi_handle_cpep(sdp);
3286 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4))
3287 1.5 cegger acpi_handle_dbgp(sdp);
3288 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_DBG2, 4))
3289 1.15.8.1 martin acpi_handle_dbg2(sdp);
3290 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
3291 1.15.8.1 martin acpi_handle_dmar(sdp);
3292 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
3293 1.5 cegger acpi_handle_einj(sdp);
3294 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
3295 1.5 cegger acpi_handle_erst(sdp);
3296 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
3297 1.5 cegger acpi_handle_madt(sdp);
3298 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MSCT, 4))
3299 1.5 cegger acpi_handle_msct(sdp);
3300 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
3301 1.5 cegger acpi_handle_hest(sdp);
3302 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
3303 1.5 cegger acpi_handle_hpet(sdp);
3304 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
3305 1.5 cegger acpi_handle_ecdt(sdp);
3306 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
3307 1.5 cegger acpi_handle_mcfg(sdp);
3308 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4))
3309 1.5 cegger acpi_handle_sbst(sdp);
3310 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
3311 1.5 cegger acpi_handle_slit(sdp);
3312 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
3313 1.5 cegger acpi_handle_spcr(sdp);
3314 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_SPMI, 4))
3315 1.15.8.1 martin acpi_handle_spmi(sdp);
3316 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
3317 1.5 cegger acpi_handle_srat(sdp);
3318 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
3319 1.5 cegger acpi_handle_tcpa(sdp);
3320 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
3321 1.15.8.1 martin acpi_handle_nfit(sdp);
3322 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_UEFI, 4))
3323 1.15.8.1 martin acpi_handle_uefi(sdp);
3324 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WAET, 4))
3325 1.5 cegger acpi_handle_waet(sdp);
3326 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4))
3327 1.5 cegger acpi_handle_wdat(sdp);
3328 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
3329 1.15.8.1 martin acpi_handle_wddt(sdp);
3330 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4))
3331 1.5 cegger acpi_handle_wdrt(sdp);
3332 1.5 cegger else {
3333 1.5 cegger printf(BEGIN_COMMENT);
3334 1.1 christos acpi_print_sdt(sdp);
3335 1.7 jmcneill acpi_dump_bytes(sdp);
3336 1.5 cegger printf(END_COMMENT);
3337 1.1 christos }
3338 1.1 christos }
3339 1.1 christos }
3340 1.1 christos
3341 1.5 cegger ACPI_TABLE_HEADER *
3342 1.5 cegger sdt_load_devmem(void)
3343 1.5 cegger {
3344 1.5 cegger ACPI_TABLE_RSDP *rp;
3345 1.5 cegger ACPI_TABLE_HEADER *rsdp;
3346 1.1 christos
3347 1.5 cegger rp = acpi_find_rsd_ptr();
3348 1.5 cegger if (!rp)
3349 1.5 cegger errx(EXIT_FAILURE, "Can't find ACPI information");
3350 1.5 cegger
3351 1.5 cegger if (tflag)
3352 1.5 cegger acpi_print_rsd_ptr(rp);
3353 1.5 cegger if (rp->Revision < 2) {
3354 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
3355 1.5 cegger if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
3356 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
3357 1.5 cegger errx(EXIT_FAILURE, "RSDT is corrupted");
3358 1.5 cegger addr_size = sizeof(uint32_t);
3359 1.5 cegger } else {
3360 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
3361 1.5 cegger if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
3362 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
3363 1.5 cegger errx(EXIT_FAILURE, "XSDT is corrupted");
3364 1.5 cegger addr_size = sizeof(uint64_t);
3365 1.5 cegger }
3366 1.5 cegger return (rsdp);
3367 1.1 christos }
3368 1.1 christos
3369 1.5 cegger /* Write the DSDT to a file, concatenating any SSDTs (if present). */
3370 1.5 cegger static int
3371 1.5 cegger write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
3372 1.5 cegger {
3373 1.5 cegger ACPI_TABLE_HEADER sdt;
3374 1.5 cegger ACPI_TABLE_HEADER *ssdt;
3375 1.5 cegger uint8_t sum;
3376 1.5 cegger
3377 1.5 cegger /* Create a new checksum to account for the DSDT and any SSDTs. */
3378 1.5 cegger sdt = *dsdt;
3379 1.5 cegger if (rsdt != NULL) {
3380 1.5 cegger sdt.Checksum = 0;
3381 1.5 cegger sum = acpi_checksum(dsdt + 1, dsdt->Length -
3382 1.5 cegger sizeof(ACPI_TABLE_HEADER));
3383 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
3384 1.5 cegger while (ssdt != NULL) {
3385 1.5 cegger sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
3386 1.5 cegger sum += acpi_checksum(ssdt + 1,
3387 1.5 cegger ssdt->Length - sizeof(ACPI_TABLE_HEADER));
3388 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
3389 1.5 cegger }
3390 1.5 cegger sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
3391 1.5 cegger sdt.Checksum -= sum;
3392 1.5 cegger }
3393 1.5 cegger
3394 1.5 cegger /* Write out the DSDT header and body. */
3395 1.5 cegger write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
3396 1.5 cegger write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
3397 1.5 cegger
3398 1.5 cegger /* Write out any SSDTs (if present.) */
3399 1.5 cegger if (rsdt != NULL) {
3400 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
3401 1.5 cegger while (ssdt != NULL) {
3402 1.5 cegger write(fd, ssdt + 1, ssdt->Length -
3403 1.5 cegger sizeof(ACPI_TABLE_HEADER));
3404 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
3405 1.5 cegger }
3406 1.5 cegger }
3407 1.1 christos return (0);
3408 1.1 christos }
3409 1.1 christos
3410 1.5 cegger void
3411 1.5 cegger dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
3412 1.1 christos {
3413 1.5 cegger int fd;
3414 1.5 cegger mode_t mode;
3415 1.5 cegger
3416 1.5 cegger assert(outfile != NULL);
3417 1.5 cegger mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
3418 1.5 cegger fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
3419 1.5 cegger if (fd == -1) {
3420 1.5 cegger perror("dsdt_save_file");
3421 1.5 cegger return;
3422 1.5 cegger }
3423 1.5 cegger write_dsdt(fd, rsdt, dsdp);
3424 1.5 cegger close(fd);
3425 1.1 christos }
3426 1.1 christos
3427 1.5 cegger void
3428 1.5 cegger aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
3429 1.1 christos {
3430 1.15.8.1 martin char buf[MAXPATHLEN], tmpstr[MAXPATHLEN], wrkdir[MAXPATHLEN];
3431 1.15.8.1 martin const char *iname = "/acpdump.din";
3432 1.15.8.1 martin const char *oname = "/acpdump.dsl";
3433 1.5 cegger const char *tmpdir;
3434 1.5 cegger FILE *fp;
3435 1.5 cegger size_t len;
3436 1.15.8.1 martin int fd, status;
3437 1.15.8.1 martin pid_t pid;
3438 1.5 cegger
3439 1.5 cegger if (rsdt == NULL)
3440 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt");
3441 1.5 cegger if (dsdp == NULL)
3442 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp");
3443 1.5 cegger
3444 1.5 cegger tmpdir = getenv("TMPDIR");
3445 1.5 cegger if (tmpdir == NULL)
3446 1.5 cegger tmpdir = _PATH_TMP;
3447 1.15.8.1 martin if (realpath(tmpdir, buf) == NULL) {
3448 1.15.8.1 martin perror("realpath tmp dir");
3449 1.15.8.1 martin return;
3450 1.15.8.1 martin }
3451 1.15.8.1 martin len = sizeof(wrkdir) - strlen(iname);
3452 1.15.8.1 martin if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
3453 1.15.8.1 martin fprintf(stderr, "$TMPDIR too long\n");
3454 1.15.8.1 martin return;
3455 1.15.8.1 martin }
3456 1.15.8.1 martin if (mkdtemp(wrkdir) == NULL) {
3457 1.15.8.1 martin perror("mkdtemp tmp working dir");
3458 1.5 cegger return;
3459 1.5 cegger }
3460 1.15.8.1 martin len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
3461 1.15.8.1 martin assert(len <= sizeof(tmpstr) - 1);
3462 1.15.8.1 martin fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
3463 1.5 cegger if (fd < 0) {
3464 1.5 cegger perror("iasl tmp file");
3465 1.5 cegger return;
3466 1.5 cegger }
3467 1.5 cegger write_dsdt(fd, rsdt, dsdp);
3468 1.5 cegger close(fd);
3469 1.5 cegger
3470 1.5 cegger /* Run iasl -d on the temp file */
3471 1.15.8.1 martin if ((pid = fork()) == 0) {
3472 1.5 cegger close(STDOUT_FILENO);
3473 1.5 cegger if (vflag == 0)
3474 1.5 cegger close(STDERR_FILENO);
3475 1.5 cegger execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL);
3476 1.5 cegger err(EXIT_FAILURE, "exec");
3477 1.5 cegger }
3478 1.15.8.1 martin if (pid > 0)
3479 1.15.8.1 martin wait(&status);
3480 1.15.8.1 martin if (unlink(tmpstr) < 0) {
3481 1.15.8.1 martin perror("unlink");
3482 1.15.8.1 martin goto out;
3483 1.15.8.1 martin }
3484 1.15.8.1 martin if (pid < 0) {
3485 1.15.8.1 martin perror("fork");
3486 1.15.8.1 martin goto out;
3487 1.15.8.1 martin }
3488 1.15.8.1 martin if (status != 0) {
3489 1.15.8.1 martin fprintf(stderr, "iast exit status = %d\n", status);
3490 1.15.8.1 martin }
3491 1.1 christos
3492 1.5 cegger /* Dump iasl's output to stdout */
3493 1.15.8.1 martin len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
3494 1.15.8.1 martin assert(len <= sizeof(tmpstr) - 1);
3495 1.5 cegger fp = fopen(tmpstr, "r");
3496 1.15.8.1 martin if (unlink(tmpstr) < 0) {
3497 1.15.8.1 martin perror("unlink");
3498 1.15.8.1 martin goto out;
3499 1.15.8.1 martin }
3500 1.5 cegger if (fp == NULL) {
3501 1.5 cegger perror("iasl tmp file (read)");
3502 1.15.8.1 martin goto out;
3503 1.5 cegger }
3504 1.5 cegger while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
3505 1.5 cegger fwrite(buf, 1, len, stdout);
3506 1.5 cegger fclose(fp);
3507 1.15.8.1 martin
3508 1.15.8.1 martin out:
3509 1.15.8.1 martin if (rmdir(wrkdir) < 0)
3510 1.15.8.1 martin perror("rmdir");
3511 1.1 christos }
3512 1.1 christos
3513 1.5 cegger void
3514 1.5 cegger sdt_print_all(ACPI_TABLE_HEADER *rsdp)
3515 1.1 christos {
3516 1.5 cegger acpi_handle_rsdt(rsdp);
3517 1.1 christos }
3518 1.1 christos
3519 1.5 cegger /* Fetch a table matching the given signature via the RSDT. */
3520 1.5 cegger ACPI_TABLE_HEADER *
3521 1.5 cegger sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
3522 1.1 christos {
3523 1.5 cegger ACPI_TABLE_HEADER *sdt;
3524 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3525 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3526 1.15 christos vm_offset_t addr = 0;
3527 1.5 cegger int entries, i;
3528 1.1 christos
3529 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3530 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3531 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3532 1.5 cegger for (i = 0; i < entries; i++) {
3533 1.15.8.1 martin if (addr_size == 4)
3534 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
3535 1.15.8.1 martin else
3536 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
3537 1.15.8.1 martin if (addr == 0)
3538 1.15.8.1 martin continue;
3539 1.5 cegger sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
3540 1.5 cegger if (last != NULL) {
3541 1.5 cegger if (sdt == last)
3542 1.5 cegger last = NULL;
3543 1.5 cegger continue;
3544 1.5 cegger }
3545 1.5 cegger if (memcmp(sdt->Signature, sig, strlen(sig)))
3546 1.5 cegger continue;
3547 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
3548 1.5 cegger errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i);
3549 1.5 cegger return (sdt);
3550 1.5 cegger }
3551 1.1 christos
3552 1.5 cegger return (NULL);
3553 1.1 christos }
3554 1.1 christos
3555 1.5 cegger ACPI_TABLE_HEADER *
3556 1.5 cegger dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
3557 1.1 christos {
3558 1.5 cegger ACPI_TABLE_HEADER *sdt;
3559 1.1 christos
3560 1.5 cegger /* Use the DSDT address if it is version 1, otherwise use XDSDT. */
3561 1.15.8.1 martin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(
3562 1.15.8.1 martin acpi_select_address(fadt->Dsdt, fadt->XDsdt));
3563 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
3564 1.10 christos errx(EXIT_FAILURE, "DSDT is corrupt");
3565 1.5 cegger return (sdt);
3566 1.1 christos }
3567