4 * Copyright (c) 1998 Doug Rabson
5 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.37 2009/08/25 20:35:57 jhb Exp $
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: acpi.c,v 1.4 2008/02/13 18:59:18 drochner Exp $");
35 #include <sys/param.h>
36 #include <sys/endian.h>
52 #define BEGIN_COMMENT "/*\n"
53 #define END_COMMENT " */\n"
55 static void acpi_print_string(char *s
, size_t length
);
56 static void acpi_print_gas(ACPI_GENERIC_ADDRESS
*gas
);
57 static void acpi_print_pci(uint16_t vendorid
, uint16_t deviceid
,
58 uint8_t seg
, uint8_t bus
, uint8_t device
, uint8_t func
);
59 static void acpi_print_pci_sbfd(uint8_t seg
, uint8_t bus
, uint8_t device
,
62 static void acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS
*);
63 static void acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA
*);
65 static void acpi_print_whea(ACPI_WHEA_HEADER
*whea
,
66 void (*print_action
)(ACPI_WHEA_HEADER
*),
67 void (*print_ins
)(ACPI_WHEA_HEADER
*),
68 void (*print_flags
)(ACPI_WHEA_HEADER
*));
69 static int acpi_get_fadt_revision(ACPI_TABLE_FADT
*fadt
);
70 static void acpi_handle_fadt(ACPI_TABLE_HEADER
*fadt
);
71 static void acpi_print_cpu(u_char cpu_id
);
72 static void acpi_print_cpu_uid(uint32_t uid
, char *uid_string
);
73 static void acpi_print_local_apic(uint32_t apic_id
, uint32_t flags
);
74 static void acpi_print_io_apic(uint32_t apic_id
, uint32_t int_base
,
76 static void acpi_print_mps_flags(uint16_t flags
);
77 static void acpi_print_intr(uint32_t intr
, uint16_t mps_flags
);
78 static void acpi_print_local_nmi(u_int lint
, uint16_t mps_flags
);
79 static void acpi_print_madt(ACPI_SUBTABLE_HEADER
*mp
);
80 static void acpi_handle_bert(ACPI_TABLE_HEADER
*sdp
);
81 static void acpi_handle_boot(ACPI_TABLE_HEADER
*sdp
);
82 static void acpi_handle_cpep(ACPI_TABLE_HEADER
*sdp
);
83 static void acpi_handle_dbgp(ACPI_TABLE_HEADER
*sdp
);
84 static void acpi_handle_einj(ACPI_TABLE_HEADER
*sdp
);
85 static void acpi_handle_erst(ACPI_TABLE_HEADER
*sdp
);
86 static void acpi_handle_hest(ACPI_TABLE_HEADER
*sdp
);
87 static void acpi_handle_madt(ACPI_TABLE_HEADER
*sdp
);
88 static void acpi_handle_msct(ACPI_TABLE_HEADER
*sdp
);
89 static void acpi_handle_ecdt(ACPI_TABLE_HEADER
*sdp
);
90 static void acpi_handle_hpet(ACPI_TABLE_HEADER
*sdp
);
91 static void acpi_handle_mcfg(ACPI_TABLE_HEADER
*sdp
);
92 static void acpi_handle_sbst(ACPI_TABLE_HEADER
*sdp
);
93 static void acpi_handle_slit(ACPI_TABLE_HEADER
*sdp
);
94 static void acpi_handle_spcr(ACPI_TABLE_HEADER
*sdp
);
95 static void acpi_print_srat_cpu(uint32_t apic_id
,
96 uint32_t proximity_domain
,
97 uint32_t flags
, uint32_t clockdomain
);
98 static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY
*mp
);
99 static void acpi_print_srat(ACPI_SUBTABLE_HEADER
*srat
);
100 static void acpi_handle_srat(ACPI_TABLE_HEADER
*sdp
);
101 static void acpi_handle_tcpa(ACPI_TABLE_HEADER
*sdp
);
102 static void acpi_handle_waet(ACPI_TABLE_HEADER
*sdp
);
103 static void acpi_handle_wdat(ACPI_TABLE_HEADER
*sdp
);
104 static void acpi_handle_wdrt(ACPI_TABLE_HEADER
*sdp
);
105 static void acpi_print_sdt(ACPI_TABLE_HEADER
*sdp
);
106 static void acpi_print_fadt(ACPI_TABLE_HEADER
*sdp
);
107 static void acpi_print_facs(ACPI_TABLE_FACS
*facs
);
108 static void acpi_print_dsdt(ACPI_TABLE_HEADER
*dsdp
);
109 static ACPI_TABLE_HEADER
*acpi_map_sdt(vm_offset_t pa
);
110 static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP
*rp
);
111 static void acpi_handle_rsdt(ACPI_TABLE_HEADER
*rsdp
);
112 static void acpi_walk_subtables(ACPI_TABLE_HEADER
*table
, void *first
,
113 void (*action
)(ACPI_SUBTABLE_HEADER
*));
115 /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
116 static int addr_size
;
119 acpi_print_string(char *s
, size_t length
)
123 /* Trim trailing spaces and NULLs */
124 while (length
> 0 && (s
[length
- 1] == ' ' || s
[length
- 1] == '\0'))
134 acpi_print_gas(ACPI_GENERIC_ADDRESS
*gas
)
136 switch(gas
->SpaceId
) {
137 case ACPI_GAS_MEMORY
:
138 printf("0x%08lx:%u[%u] (Memory)", (u_long
)gas
->Address
,
139 gas
->BitOffset
, gas
->BitWidth
);
142 printf("0x%02lx:%u[%u] (IO)", (u_long
)gas
->Address
,
143 gas
->BitOffset
, gas
->BitWidth
);
146 printf("%x:%x+0x%x (PCI)", (uint16_t)(gas
->Address
>> 32),
147 (uint16_t)((gas
->Address
>> 16) & 0xffff),
148 (uint16_t)gas
->Address
);
150 /* XXX How to handle these below? */
151 case ACPI_GAS_EMBEDDED
:
152 printf("0x%x:%u[%u] (EC)", (uint16_t)gas
->Address
,
153 gas
->BitOffset
, gas
->BitWidth
);
156 printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas
->Address
,
157 gas
->BitOffset
, gas
->BitWidth
);
160 case ACPI_GAS_PCIBAR
:
161 case ACPI_GAS_DATATABLE
:
164 printf("0x%08lx (?)", (u_long
)gas
->Address
);
170 acpi_print_pci(uint16_t vendorid
, uint16_t deviceid
,
171 uint8_t seg
, uint8_t bus
, uint8_t device
, uint8_t func
)
173 if (vendorid
== 0xffff && deviceid
== 0xffff) {
174 printf("\tPCI Device=NONE\n");
178 printf("\tPCI device={\n");
179 printf("\t\tVendor=0x%x\n", vendorid
);
180 printf("\t\tDevice=0x%x\n", deviceid
);
182 printf("\t\tSegment Group=%d\n", seg
);
183 printf("\t\tBus=%d\n", bus
);
184 printf("\t\tDevice=%d\n", device
);
185 printf("\t\tFunction=%d\n", func
);
190 acpi_print_pci_sbfd(uint8_t seg
, uint8_t bus
, uint8_t device
, uint8_t func
)
192 if (bus
== 0xff && device
== 0xff && func
== 0xff) {
193 printf("\tPCI Device=NONE\n");
197 printf("\tPCI device={\n");
198 printf("\t\tSegment Group=%d\n", seg
);
199 printf("\t\tBus=%d\n", bus
);
200 printf("\t\tDevice=%d\n", device
);
201 printf("\t\tFunction=%d\n", func
);
207 acpi_print_hest_errorseverity(uint32_t error
)
209 printf("\tError Severity={ ");
212 printf("Recoverable");
224 printf("%d (reserved)", error
);
232 acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK
*bank
)
235 printf("\tBank Number=%d\n", bank
->BankNumber
);
236 printf("\tClear Status On Init={ %s }\n",
237 bank
->ClearStatusOnInit
? "NO" : "YES");
238 printf("\tStatus Data Format={ ");
239 switch (bank
->StatusFormat
) {
252 if (bank
->ControlRegister
)
253 printf("\tControl Register=0x%x\n", bank
->ControlRegister
);
254 printf("\tControl Init Data=0x%"PRIx64
"\n", bank
->ControlData
);
255 printf("\tStatus MSR=0x%x\n", bank
->StatusRegister
);
256 printf("\tAddress MSR=0x%x\n", bank
->AddressRegister
);
257 printf("\tMisc MSR=0x%x\n", bank
->MiscRegister
);
261 acpi_print_hest_header(ACPI_HEST_HEADER
*hest
)
264 switch (hest
->Type
) {
265 case ACPI_HEST_TYPE_IA32_CHECK
:
266 printf("IA32 Machine Check Exception");
268 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK
:
269 printf("IA32 Corrected Machine Check\n");
271 case ACPI_HEST_TYPE_IA32_NMI
:
272 printf("IA32 Non-Maskable Interrupt\n");
274 case ACPI_HEST_TYPE_NOT_USED3
:
275 case ACPI_HEST_TYPE_NOT_USED4
:
276 case ACPI_HEST_TYPE_NOT_USED5
:
277 printf("unused type: %d\n", hest
->Type
);
279 case ACPI_HEST_TYPE_AER_ROOT_PORT
:
280 printf("PCI Express Root Port AER\n");
282 case ACPI_HEST_TYPE_AER_ENDPOINT
:
283 printf("PCI Express Endpoint AER\n");
285 case ACPI_HEST_TYPE_AER_BRIDGE
:
286 printf("PCI Express/PCI-X Bridge AER\n");
288 case ACPI_HEST_TYPE_GENERIC_ERROR
:
289 printf("Generic Hardware Error Source\n");
291 case ACPI_HEST_TYPE_RESERVED
:
293 printf("Reserved\n");
297 printf("\tSourceId=%d\n", hest
->SourceId
);
301 acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON
*data
)
303 printf("\tFlags={ ");
304 if (data
->Flags
& ACPI_HEST_FIRMWARE_FIRST
)
305 printf("FIRMWARE_FIRST");
306 if (data
->Flags
& ACPI_HEST_GLOBAL
)
309 printf("\tEnabled={ %s ", data
->Flags
? "YES" : "NO");
310 if (data
->Flags
& ACPI_HEST_FIRMWARE_FIRST
)
311 printf("(ignored) ");
313 printf("\tNumber of Record to pre-allocate=%d\n",
314 data
->RecordsToPreallocate
);
315 printf("\tMax. Sections per Record=%d\n", data
->MaxSectionsPerRecord
);
316 if (!(data
->Flags
& ACPI_HEST_GLOBAL
))
317 acpi_print_pci_sbfd(0, data
->Bus
, data
->Device
, data
->Function
);
318 printf("\tDevice Control=0x%x\n", data
->DeviceControl
);
319 printf("\tUncorrectable Error Mask Register=0x%x\n",
320 data
->UncorrectableMask
);
321 printf("\tUncorrectable Error Severity Register=0x%x\n",
322 data
->UncorrectableSeverity
);
323 printf("\tCorrectable Error Mask Register=0x%x\n",
324 data
->CorrectableMask
);
325 printf("\tAdvanced Capabilities Register=0x%x\n",
326 data
->AdvancedCapabilities
);
330 acpi_print_hest_notify(ACPI_HEST_NOTIFY
*notify
)
332 printf("\tHW Error Notification={\n");
333 printf("\t\tType={ ");
334 switch (notify
->Type
) {
335 case ACPI_HEST_NOTIFY_POLLED
:
338 case ACPI_HEST_NOTIFY_EXTERNAL
:
341 case ACPI_HEST_NOTIFY_LOCAL
:
344 case ACPI_HEST_NOTIFY_SCI
:
347 case ACPI_HEST_NOTIFY_NMI
:
350 case ACPI_HEST_NOTIFY_RESERVED
:
354 printf(" %d (reserved)", notify
->Type
);
359 printf("\t\tLength=%d\n", notify
->Length
);
360 printf("\t\tConfig Write Enable={\n");
361 if (notify
->ConfigWriteEnable
& ACPI_HEST_TYPE
)
363 if (notify
->ConfigWriteEnable
& ACPI_HEST_POLL_INTERVAL
)
364 printf("POLL INTERVAL");
365 if (notify
->ConfigWriteEnable
& ACPI_HEST_POLL_THRESHOLD_VALUE
)
366 printf("THRESHOLD VALUE");
367 if (notify
->ConfigWriteEnable
& ACPI_HEST_POLL_THRESHOLD_WINDOW
)
368 printf("THRESHOLD WINDOW");
369 if (notify
->ConfigWriteEnable
& ACPI_HEST_ERR_THRESHOLD_VALUE
)
370 printf("THRESHOLD VALUE");
371 if (notify
->ConfigWriteEnable
& ACPI_HEST_ERR_THRESHOLD_WINDOW
)
372 printf("THRESHOLD WINDOW");
375 printf("\t\tPoll Interval=%d msec\n", notify
->PollInterval
);
376 printf("\t\tInterrupt Vector=%d\n", notify
->Vector
);
377 printf("\t\tSwitch To Polling Threshold Value=%d\n",
378 notify
->PollingThresholdValue
);
379 printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
380 notify
->PollingThresholdWindow
);
381 printf("\t\tError Threshold Value=%d\n",
382 notify
->ErrorThresholdValue
);
383 printf("\t\tError Threshold Window=%d msec\n",
384 notify
->ErrorThresholdWindow
);
390 acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS
*data
)
392 uint32_t i
, pos
, entries
;
393 ACPI_HEST_GENERIC_DATA
*gen
;
395 entries
= data
->BlockStatus
& ACPI_HEST_ERROR_ENTRY_COUNT
;
397 printf("\tGeneric Error Status={\n");
398 printf("\t\tBlock Status={ ");
399 if (data
->BlockStatus
& ACPI_HEST_UNCORRECTABLE
)
400 printf("UNCORRECTABLE");
401 if (data
->BlockStatus
& ACPI_HEST_CORRECTABLE
)
402 printf("CORRECTABLE");
403 if (data
->BlockStatus
& ACPI_HEST_MULTIPLE_UNCORRECTABLE
)
404 printf("MULTIPLE UNCORRECTABLE");
405 if (data
->BlockStatus
& ACPI_HEST_MULTIPLE_CORRECTABLE
)
406 printf("MULTIPLE CORRECTABLE");
408 printf("\t\tEntry Count=%d\n", entries
);
409 printf("\t\tRaw Data Offset=%d\n", data
->RawDataOffset
);
410 printf("\t\tRaw Data Length=%d\n", data
->RawDataLength
);
411 printf("\t\tData Length=%d\n", data
->DataLength
);
413 acpi_print_hest_errorseverity(data
->ErrorSeverity
);
416 pos
= sizeof(ACPI_HEST_GENERIC_STATUS
);
417 for (i
= 0; i
< entries
; i
++) {
418 gen
= (ACPI_HEST_GENERIC_DATA
*)((char *)data
+ pos
);
419 acpi_print_hest_generic_data(gen
);
420 pos
+= sizeof(ACPI_HEST_GENERIC_DATA
);
427 acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA
*data
)
429 printf("\tGeneric Error Data={\n");
430 printf("\t\tSectionType=");
431 acpi_print_string((char *)data
->SectionType
, sizeof(data
->SectionType
));
433 acpi_print_hest_errorseverity(data
->ErrorSeverity
);
434 printf("\t\tRevision=0x%x\n", data
->Revision
);
435 printf("\t\tValidation Bits=0x%x\n", data
->ValidationBits
);
436 printf("\t\tFlags=0x%x\n", data
->Flags
);
437 printf("\t\tData Length=%d\n", data
->ErrorDataLength
);
438 printf("\t\tField Replication Unit Id=");
439 acpi_print_string((char *)data
->FruId
, sizeof(data
->FruId
));
441 printf("\t\tField Replication Unit=");
442 acpi_print_string((char *)data
->FruText
, sizeof(data
->FruText
));
449 acpi_print_whea(ACPI_WHEA_HEADER
*whea
,
450 void (*print_action
)(ACPI_WHEA_HEADER
*),
451 void (*print_ins
)(ACPI_WHEA_HEADER
*),
452 void (*print_flags
)(ACPI_WHEA_HEADER
*))
460 printf("\tRegisterRegion=");
461 acpi_print_gas(&whea
->RegisterRegion
);
463 printf("\tMASK=0x%08"PRIx64
"\n", whea
->Mask
);
467 acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK
*data
)
470 ACPI_HEST_IA_ERROR_BANK
*bank
;
472 acpi_print_hest_header(&data
->Header
);
473 printf("\tFlags={ ");
474 if (data
->Flags
& ACPI_HEST_FIRMWARE_FIRST
)
475 printf("FIRMWARE_FIRST");
477 printf("\tEnabled={ %s }\n", data
->Enabled
? "YES" : "NO");
478 printf("\tNumber of Record to pre-allocate=%d\n",
479 data
->RecordsToPreallocate
);
480 printf("\tMax Sections per Record=%d\n",
481 data
->MaxSectionsPerRecord
);
482 printf("\tGlobal Capability Init Data=0x%"PRIx64
"\n",
483 data
->GlobalCapabilityData
);
484 printf("\tGlobal Control Init Data=0x%"PRIx64
"\n",
485 data
->GlobalControlData
);
486 printf("\tNumber of Hardware Error Reporting Banks=%d\n",
487 data
->NumHardwareBanks
);
489 pos
= sizeof(ACPI_HEST_IA_MACHINE_CHECK
);
490 for (i
= 0; i
< data
->NumHardwareBanks
; i
++) {
491 bank
= (ACPI_HEST_IA_ERROR_BANK
*)((char *)data
+ pos
);
492 acpi_print_hest_errorbank(bank
);
493 pos
+= sizeof(ACPI_HEST_IA_ERROR_BANK
);
498 acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED
*data
)
501 ACPI_HEST_IA_ERROR_BANK
*bank
;
503 acpi_print_hest_header(&data
->Header
);
504 printf("\tFlags={ ");
505 if (data
->Flags
& ACPI_HEST_FIRMWARE_FIRST
)
506 printf("FIRMWARE_FIRST");
508 printf("\tEnabled={ %s }\n", data
->Enabled
? "YES" : "NO");
509 printf("\tNumber of Record to pre-allocate=%d\n",
510 data
->RecordsToPreallocate
);
511 printf("\tMax Sections per Record=%d\n",
512 data
->MaxSectionsPerRecord
);
513 acpi_print_hest_notify(&data
->Notify
);
515 printf("\tNumber of Hardware Error Reporting Banks=%d\n",
516 data
->NumHardwareBanks
);
518 pos
= sizeof(ACPI_HEST_IA_MACHINE_CHECK
);
519 for (i
= 0; i
< data
->NumHardwareBanks
; i
++) {
520 bank
= (ACPI_HEST_IA_ERROR_BANK
*)((char *)data
+ pos
);
521 acpi_print_hest_errorbank(bank
);
522 pos
+= sizeof(ACPI_HEST_IA_ERROR_BANK
);
527 acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI
*data
)
529 acpi_print_hest_header(&data
->Header
);
530 printf("\tNumber of Record to pre-allocate=%d\n",
531 data
->RecordsToPreallocate
);
532 printf("\tMax Sections per Record=%d\n",
533 data
->MaxSectionsPerRecord
);
534 printf("\tMax Raw Data Length=%d\n",
535 data
->MaxRawDataLength
);
539 acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT
*data
)
541 acpi_print_hest_header(&data
->Header
);
542 acpi_print_hest_aer_common(&data
->Aer
);
543 printf("Root Error Command Register=0x%x\n", data
->RootErrorCommand
);
547 acpi_print_hest_aer_endpoint(ACPI_HEST_AER
*data
)
549 acpi_print_hest_header(&data
->Header
);
550 acpi_print_hest_aer_common(&data
->Aer
);
554 acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE
*data
)
556 acpi_print_hest_header(&data
->Header
);
557 acpi_print_hest_aer_common(&data
->Aer
);
559 printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
560 data
->UncorrectableMask2
);
561 printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
562 data
->UncorrectableSeverity2
);
563 printf("\tSecondory Advanced Capabilities Register=0x%x\n",
564 data
->AdvancedCapabilities2
);
568 acpi_print_hest_generic(ACPI_HEST_GENERIC
*data
)
570 acpi_print_hest_header(&data
->Header
);
571 if (data
->RelatedSourceId
!= 0xffff)
572 printf("\tReleated SourceId=%d\n", data
->RelatedSourceId
);
573 printf("\tEnabled={ %s }\n", data
->Enabled
? "YES" : "NO");
574 printf("\tNumber of Records to pre-allocate=%d\n",
575 data
->RecordsToPreallocate
);
576 printf("\tMax Sections per Record=%d\n",
577 data
->MaxSectionsPerRecord
);
578 printf("\tMax Raw Data Length=%d\n", data
->MaxRawDataLength
);
579 printf("\tError Status Address=");
580 acpi_print_gas(&data
->ErrorStatusAddress
);
581 acpi_print_hest_notify(&data
->Notify
);
582 printf("\tError Block Length=%d\n", data
->ErrorBlockLength
);
586 acpi_handle_hest(ACPI_TABLE_HEADER
*sdp
)
588 ACPI_TABLE_HEST
*hest
;
589 ACPI_HEST_HEADER
*subhest
;
593 printf(BEGIN_COMMENT
);
595 hest
= (ACPI_TABLE_HEST
*)sdp
;
597 printf("\tError Source Count=%d\n", hest
->ErrorSourceCount
);
598 pos
= sizeof(ACPI_TABLE_HEST
);
599 for (i
= 0; i
< hest
->ErrorSourceCount
; i
++) {
600 subhest
= (ACPI_HEST_HEADER
*)((char *)hest
+ pos
);
601 subtable
= (void *)((char *)subhest
+ sizeof(ACPI_HEST_HEADER
));
605 switch (subhest
->Type
) {
606 case ACPI_HEST_TYPE_IA32_CHECK
:
607 acpi_print_hest_ia32_check(subtable
);
608 pos
+= sizeof(ACPI_HEST_IA_MACHINE_CHECK
);
611 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK
:
612 acpi_print_hest_ia32_correctedcheck(subtable
);
613 pos
+= sizeof(ACPI_HEST_IA_CORRECTED
);
616 case ACPI_HEST_TYPE_IA32_NMI
:
617 acpi_print_hest_ia32_nmi(subtable
);
618 pos
+= sizeof(ACPI_HEST_IA_NMI
);
621 case ACPI_HEST_TYPE_NOT_USED3
:
622 case ACPI_HEST_TYPE_NOT_USED4
:
623 case ACPI_HEST_TYPE_NOT_USED5
:
624 pos
+= sizeof(ACPI_HEST_HEADER
);
627 case ACPI_HEST_TYPE_AER_ROOT_PORT
:
628 acpi_print_hest_aer_root(subtable
);
629 pos
+= sizeof(ACPI_HEST_AER_ROOT
);
632 case ACPI_HEST_TYPE_AER_ENDPOINT
:
633 acpi_print_hest_aer_endpoint(subtable
);
634 pos
+= sizeof(ACPI_HEST_AER_ROOT
);
637 case ACPI_HEST_TYPE_AER_BRIDGE
:
638 acpi_print_hest_aer_bridge(subtable
);
639 pos
+= sizeof(ACPI_HEST_AER_BRIDGE
);
642 case ACPI_HEST_TYPE_GENERIC_ERROR
:
643 acpi_print_hest_generic(subtable
);
644 pos
+= sizeof(ACPI_HEST_GENERIC
);
647 case ACPI_HEST_TYPE_RESERVED
:
649 pos
+= sizeof(ACPI_HEST_HEADER
);
657 /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
659 acpi_get_fadt_revision(ACPI_TABLE_FADT
*fadt
)
663 /* Set the FADT revision separately from the RSDP version. */
664 if (addr_size
== 8) {
668 * A few systems (e.g., IBM T23) have an RSDP that claims
669 * revision 2 but the 64 bit addresses are invalid. If
670 * revision 2 and the 32 bit address is non-zero but the
671 * 32 and 64 bit versions don't match, prefer the 32 bit
672 * version for all subsequent tables.
674 if (fadt
->Facs
!= 0 &&
675 (fadt
->XFacs
& 0xffffffff) != fadt
->Facs
)
679 return (fadt_revision
);
683 acpi_handle_fadt(ACPI_TABLE_HEADER
*sdp
)
685 ACPI_TABLE_HEADER
*dsdp
;
686 ACPI_TABLE_FACS
*facs
;
687 ACPI_TABLE_FADT
*fadt
;
690 fadt
= (ACPI_TABLE_FADT
*)sdp
;
691 acpi_print_fadt(sdp
);
693 fadt_revision
= acpi_get_fadt_revision(fadt
);
694 if (fadt_revision
== 1)
695 facs
= (ACPI_TABLE_FACS
*)acpi_map_sdt(fadt
->Facs
);
697 facs
= (ACPI_TABLE_FACS
*)acpi_map_sdt(fadt
->XFacs
);
698 if (memcmp(facs
->Signature
, ACPI_SIG_FACS
, 4) != 0 || facs
->Length
< 64)
699 errx(EXIT_FAILURE
, "FACS is corrupt");
700 acpi_print_facs(facs
);
702 if (fadt_revision
== 1)
703 dsdp
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(fadt
->Dsdt
);
705 dsdp
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(fadt
->XDsdt
);
706 if (acpi_checksum(dsdp
, dsdp
->Length
))
707 errx(EXIT_FAILURE
, "DSDT is corrupt");
708 acpi_print_dsdt(dsdp
);
712 acpi_walk_subtables(ACPI_TABLE_HEADER
*table
, void *first
,
713 void (*action
)(ACPI_SUBTABLE_HEADER
*))
715 ACPI_SUBTABLE_HEADER
*subtable
;
719 end
= (char *)table
+ table
->Length
;
720 while ((char *)subtable
< end
) {
723 subtable
= (ACPI_SUBTABLE_HEADER
*)((char *)subtable
+
729 acpi_print_cpu(u_char cpu_id
)
732 printf("\tACPI CPU=");
736 printf("%d\n", (u_int
)cpu_id
);
740 acpi_print_cpu_uid(uint32_t uid
, char *uid_string
)
743 printf("\tUID=%d", uid
);
744 if (uid_string
!= NULL
)
745 printf(" (%s)", uid_string
);
750 acpi_print_local_apic(uint32_t apic_id
, uint32_t flags
)
754 if (flags
& ACPI_MADT_ENABLED
)
759 printf("\tAPIC ID=%d\n", apic_id
);
763 acpi_print_io_apic(uint32_t apic_id
, uint32_t int_base
, uint64_t apic_addr
)
766 printf("\tAPIC ID=%d\n", apic_id
);
767 printf("\tINT BASE=%d\n", int_base
);
768 printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr
);
772 acpi_print_mps_flags(uint16_t flags
)
775 printf("\tFlags={Polarity=");
776 switch (flags
& ACPI_MADT_POLARITY_MASK
) {
777 case ACPI_MADT_POLARITY_CONFORMS
:
778 printf("conforming");
780 case ACPI_MADT_POLARITY_ACTIVE_HIGH
:
783 case ACPI_MADT_POLARITY_ACTIVE_LOW
:
787 printf("0x%x", flags
& ACPI_MADT_POLARITY_MASK
);
790 printf(", Trigger=");
791 switch (flags
& ACPI_MADT_TRIGGER_MASK
) {
792 case ACPI_MADT_TRIGGER_CONFORMS
:
793 printf("conforming");
795 case ACPI_MADT_TRIGGER_EDGE
:
798 case ACPI_MADT_TRIGGER_LEVEL
:
802 printf("0x%x", (flags
& ACPI_MADT_TRIGGER_MASK
) >> 2);
808 acpi_print_intr(uint32_t intr
, uint16_t mps_flags
)
811 printf("\tINTR=%d\n", intr
);
812 acpi_print_mps_flags(mps_flags
);
816 acpi_print_local_nmi(u_int lint
, uint16_t mps_flags
)
819 printf("\tLINT Pin=%d\n", lint
);
820 acpi_print_mps_flags(mps_flags
);
823 const char *apic_types
[] = { "Local APIC", "IO APIC", "INT Override", "NMI",
824 "Local APIC NMI", "Local APIC Override",
825 "IO SAPIC", "Local SAPIC", "Platform Interrupt",
826 "Local X2APIC", "Local X2APIC NMI" };
827 const char *platform_int_types
[] = { "0 (unknown)", "PMI", "INIT",
828 "Corrected Platform Error" };
831 acpi_print_madt(ACPI_SUBTABLE_HEADER
*mp
)
833 ACPI_MADT_LOCAL_APIC
*lapic
;
834 ACPI_MADT_IO_APIC
*ioapic
;
835 ACPI_MADT_INTERRUPT_OVERRIDE
*over
;
836 ACPI_MADT_NMI_SOURCE
*nmi
;
837 ACPI_MADT_LOCAL_APIC_NMI
*lapic_nmi
;
838 ACPI_MADT_LOCAL_APIC_OVERRIDE
*lapic_over
;
839 ACPI_MADT_IO_SAPIC
*iosapic
;
840 ACPI_MADT_LOCAL_SAPIC
*lsapic
;
841 ACPI_MADT_INTERRUPT_SOURCE
*isrc
;
842 ACPI_MADT_LOCAL_X2APIC
*x2apic
;
843 ACPI_MADT_LOCAL_X2APIC_NMI
*x2apic_nmi
;
845 if (mp
->Type
< sizeof(apic_types
) / sizeof(apic_types
[0]))
846 printf("\tType=%s\n", apic_types
[mp
->Type
]);
848 printf("\tType=%d (unknown)\n", mp
->Type
);
850 case ACPI_MADT_TYPE_LOCAL_APIC
:
851 lapic
= (ACPI_MADT_LOCAL_APIC
*)mp
;
852 acpi_print_cpu(lapic
->ProcessorId
);
853 acpi_print_local_apic(lapic
->Id
, lapic
->LapicFlags
);
855 case ACPI_MADT_TYPE_IO_APIC
:
856 ioapic
= (ACPI_MADT_IO_APIC
*)mp
;
857 acpi_print_io_apic(ioapic
->Id
, ioapic
->GlobalIrqBase
,
860 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
:
861 over
= (ACPI_MADT_INTERRUPT_OVERRIDE
*)mp
;
862 printf("\tBUS=%d\n", (u_int
)over
->Bus
);
863 printf("\tIRQ=%d\n", (u_int
)over
->SourceIrq
);
864 acpi_print_intr(over
->GlobalIrq
, over
->IntiFlags
);
866 case ACPI_MADT_TYPE_NMI_SOURCE
:
867 nmi
= (ACPI_MADT_NMI_SOURCE
*)mp
;
868 acpi_print_intr(nmi
->GlobalIrq
, nmi
->IntiFlags
);
870 case ACPI_MADT_TYPE_LOCAL_APIC_NMI
:
871 lapic_nmi
= (ACPI_MADT_LOCAL_APIC_NMI
*)mp
;
872 acpi_print_cpu(lapic_nmi
->ProcessorId
);
873 acpi_print_local_nmi(lapic_nmi
->Lint
, lapic_nmi
->IntiFlags
);
875 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE
:
876 lapic_over
= (ACPI_MADT_LOCAL_APIC_OVERRIDE
*)mp
;
877 printf("\tLocal APIC ADDR=0x%016jx\n",
878 (uintmax_t)lapic_over
->Address
);
880 case ACPI_MADT_TYPE_IO_SAPIC
:
881 iosapic
= (ACPI_MADT_IO_SAPIC
*)mp
;
882 acpi_print_io_apic(iosapic
->Id
, iosapic
->GlobalIrqBase
,
885 case ACPI_MADT_TYPE_LOCAL_SAPIC
:
886 lsapic
= (ACPI_MADT_LOCAL_SAPIC
*)mp
;
887 acpi_print_cpu(lsapic
->ProcessorId
);
888 acpi_print_local_apic(lsapic
->Id
, lsapic
->LapicFlags
);
889 printf("\tAPIC EID=%d\n", (u_int
)lsapic
->Eid
);
890 if (mp
->Length
> offsetof(ACPI_MADT_LOCAL_SAPIC
, Uid
))
891 acpi_print_cpu_uid(lsapic
->Uid
, lsapic
->UidString
);
893 case ACPI_MADT_TYPE_INTERRUPT_SOURCE
:
894 isrc
= (ACPI_MADT_INTERRUPT_SOURCE
*)mp
;
895 if (isrc
->Type
< sizeof(platform_int_types
) /
896 sizeof(platform_int_types
[0]))
897 printf("\tType=%s\n", platform_int_types
[isrc
->Type
]);
899 printf("\tType=%d (unknown)\n", isrc
->Type
);
900 printf("\tAPIC ID=%d\n", (u_int
)isrc
->Id
);
901 printf("\tAPIC EID=%d\n", (u_int
)isrc
->Eid
);
902 printf("\tSAPIC Vector=%d\n", (u_int
)isrc
->IoSapicVector
);
903 acpi_print_intr(isrc
->GlobalIrq
, isrc
->IntiFlags
);
905 case ACPI_MADT_TYPE_LOCAL_X2APIC
:
906 x2apic
= (ACPI_MADT_LOCAL_X2APIC
*)mp
;
907 acpi_print_cpu_uid(x2apic
->Uid
, NULL
);
908 acpi_print_local_apic(x2apic
->LocalApicId
, x2apic
->LapicFlags
);
910 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI
:
911 x2apic_nmi
= (ACPI_MADT_LOCAL_X2APIC_NMI
*)mp
;
912 acpi_print_cpu_uid(x2apic_nmi
->Uid
, NULL
);
913 acpi_print_local_nmi(x2apic_nmi
->Lint
, x2apic_nmi
->IntiFlags
);
920 acpi_print_bert_region(ACPI_BERT_REGION
*region
)
922 uint32_t i
, pos
, entries
;
923 ACPI_HEST_GENERIC_DATA
*data
;
926 printf("\tBlockStatus={ ");
928 if (region
->BlockStatus
& ACPI_BERT_UNCORRECTABLE
)
929 printf("Uncorrectable");
930 if (region
->BlockStatus
& ACPI_BERT_CORRECTABLE
)
931 printf("Correctable");
932 if (region
->BlockStatus
& ACPI_BERT_MULTIPLE_UNCORRECTABLE
)
933 printf("Multiple Uncorrectable");
934 if (region
->BlockStatus
& ACPI_BERT_MULTIPLE_CORRECTABLE
)
935 printf("Multiple Correctable");
936 entries
= region
->BlockStatus
& ACPI_BERT_ERROR_ENTRY_COUNT
;
937 printf(", Error Entry Count=%d", entries
);
940 printf("\tRaw Data Offset=0x%x\n", region
->RawDataOffset
);
941 printf("\tRaw Data Length=0x%x\n", region
->RawDataLength
);
942 printf("\tData Length=0x%x\n", region
->DataLength
);
944 acpi_print_hest_errorseverity(region
->ErrorSeverity
);
946 pos
= sizeof(ACPI_BERT_REGION
);
947 for (i
= 0; i
< entries
; i
++) {
948 data
= (ACPI_HEST_GENERIC_DATA
*)((char *)region
+ pos
);
949 acpi_print_hest_generic_data(data
);
950 pos
+= sizeof(ACPI_HEST_GENERIC_DATA
);
956 acpi_handle_bert(ACPI_TABLE_HEADER
*sdp
)
958 ACPI_TABLE_BERT
*bert
;
960 printf(BEGIN_COMMENT
);
962 bert
= (ACPI_TABLE_BERT
*)sdp
;
964 printf("\tLength of Boot Error Region=%d bytes\n", bert
->RegionLength
);
965 printf("\tPhysical Address of Region=0x%"PRIx64
"\n", bert
->Address
);
971 acpi_handle_boot(ACPI_TABLE_HEADER
*sdp
)
973 ACPI_TABLE_BOOT
*boot
;
975 printf(BEGIN_COMMENT
);
977 boot
= (ACPI_TABLE_BOOT
*)sdp
;
978 printf("\tCMOS Index=0x%02x\n", boot
->CmosIndex
);
983 acpi_handle_cpep(ACPI_TABLE_HEADER
*sdp
)
985 ACPI_TABLE_CPEP
*cpep
;
986 ACPI_CPEP_POLLING
*poll
;
989 printf(BEGIN_COMMENT
);
991 cpep
= (ACPI_TABLE_CPEP
*)sdp
;
993 cpep_pos
= sizeof(ACPI_TABLE_CPEP
);
994 while (cpep_pos
< sdp
->Length
) {
995 poll
= (ACPI_CPEP_POLLING
*)((char *)cpep
+ cpep_pos
);
996 acpi_print_cpu(poll
->Id
);
997 printf("\tACPI CPU EId=%d\n", poll
->Eid
);
998 printf("\tPoll Interval=%d msec\n", poll
->Interval
);
999 cpep_pos
+= sizeof(ACPI_CPEP_POLLING
);
1001 printf(END_COMMENT
);
1005 acpi_handle_dbgp(ACPI_TABLE_HEADER
*sdp
)
1007 ACPI_TABLE_DBGP
*dbgp
;
1009 printf(BEGIN_COMMENT
);
1010 acpi_print_sdt(sdp
);
1011 dbgp
= (ACPI_TABLE_DBGP
*)sdp
;
1013 switch (dbgp
->Type
) {
1015 printf("full 16550");
1018 printf("subset of 16550");
1022 printf("DebugPort=");
1023 acpi_print_gas(&dbgp
->DebugPort
);
1024 printf(END_COMMENT
);
1028 acpi_print_einj_action(ACPI_WHEA_HEADER
*whea
)
1030 printf("\tACTION={");
1031 switch (whea
->Action
) {
1032 case ACPI_EINJ_BEGIN_OPERATION
:
1033 printf("Begin Operation");
1035 case ACPI_EINJ_GET_TRIGGER_TABLE
:
1036 printf("Get Trigger Table");
1038 case ACPI_EINJ_SET_ERROR_TYPE
:
1039 printf("Set Error Type");
1041 case ACPI_EINJ_GET_ERROR_TYPE
:
1042 printf("Get Error Type");
1044 case ACPI_EINJ_END_OPERATION
:
1045 printf("End Operation");
1047 case ACPI_EINJ_EXECUTE_OPERATION
:
1048 printf("Execute Operation");
1050 case ACPI_EINJ_CHECK_BUSY_STATUS
:
1051 printf("Check Busy Status");
1053 case ACPI_EINJ_GET_COMMAND_STATUS
:
1054 printf("Get Command Status");
1056 case ACPI_EINJ_ACTION_RESERVED
:
1057 printf("Preserved");
1059 case ACPI_EINJ_TRIGGER_ERROR
:
1060 printf("Trigger Error");
1063 printf("%d", whea
->Action
);
1070 acpi_print_einj_instruction(ACPI_WHEA_HEADER
*whea
)
1072 uint32_t ins
= whea
->Instruction
;
1074 printf("\tINSTRUCTION={");
1076 case ACPI_EINJ_READ_REGISTER
:
1077 printf("Read Register");
1079 case ACPI_EINJ_READ_REGISTER_VALUE
:
1080 printf("Read Register Value");
1082 case ACPI_EINJ_WRITE_REGISTER
:
1083 printf("Write Register");
1085 case ACPI_EINJ_WRITE_REGISTER_VALUE
:
1086 printf("Write Register Value");
1088 case ACPI_EINJ_NOOP
:
1091 case ACPI_EINJ_INSTRUCTION_RESERVED
:
1102 acpi_print_einj_flags(ACPI_WHEA_HEADER
*whea
)
1104 uint32_t flags
= whea
->Flags
;
1106 printf("\tFLAGS={ ");
1107 if (flags
& ACPI_EINJ_PRESERVE
)
1108 printf("PRESERVED");
1113 acpi_handle_einj(ACPI_TABLE_HEADER
*sdp
)
1115 ACPI_TABLE_EINJ
*einj
;
1116 ACPI_EINJ_ENTRY
*einj_entry
;
1120 printf(BEGIN_COMMENT
);
1121 acpi_print_sdt(sdp
);
1122 einj
= (ACPI_TABLE_EINJ
*)sdp
;
1124 printf("\tHeader Length=%d\n", einj
->HeaderLength
);
1125 printf("\tFlags=0x%x\n", einj
->Flags
);
1126 printf("\tEntries=%d\n", einj
->Entries
);
1128 einj_pos
= sizeof(ACPI_TABLE_EINJ
);
1129 for (i
= 0; i
< einj
->Entries
; i
++) {
1130 einj_entry
= (ACPI_EINJ_ENTRY
*)((char *)einj
+ einj_pos
);
1131 acpi_print_whea(&einj_entry
->WheaHeader
,
1132 acpi_print_einj_action
, acpi_print_einj_instruction
,
1133 acpi_print_einj_flags
);
1134 einj_pos
+= sizeof(ACPI_EINJ_ENTRY
);
1136 printf(END_COMMENT
);
1140 acpi_print_erst_action(ACPI_WHEA_HEADER
*whea
)
1142 printf("\tACTION={");
1143 switch (whea
->Action
) {
1144 case ACPI_ERST_BEGIN_WRITE
:
1145 printf("Begin Write");
1147 case ACPI_ERST_BEGIN_READ
:
1148 printf("Begin Read");
1150 case ACPI_ERST_BEGIN_CLEAR
:
1151 printf("Begin Clear");
1156 case ACPI_ERST_SET_RECORD_OFFSET
:
1157 printf("Set Record Offset");
1159 case ACPI_ERST_EXECUTE_OPERATION
:
1160 printf("Execute Operation");
1162 case ACPI_ERST_CHECK_BUSY_STATUS
:
1163 printf("Check Busy Status");
1165 case ACPI_ERST_GET_COMMAND_STATUS
:
1166 printf("Get Command Status");
1168 case ACPI_ERST_GET_RECORD_ID
:
1169 printf("Get Record ID");
1171 case ACPI_ERST_SET_RECORD_ID
:
1172 printf("Set Record ID");
1174 case ACPI_ERST_GET_RECORD_COUNT
:
1175 printf("Get Record Count");
1177 case ACPI_ERST_BEGIN_DUMMY_WRIITE
:
1178 printf("Begin Dummy Write");
1180 case ACPI_ERST_NOT_USED
:
1183 case ACPI_ERST_GET_ERROR_RANGE
:
1184 printf("Get Error Range");
1186 case ACPI_ERST_GET_ERROR_LENGTH
:
1187 printf("Get Error Length");
1189 case ACPI_ERST_GET_ERROR_ATTRIBUTES
:
1190 printf("Get Error Attributes");
1192 case ACPI_ERST_ACTION_RESERVED
:
1196 printf("%d", whea
->Action
);
1203 acpi_print_erst_instruction(ACPI_WHEA_HEADER
*whea
)
1205 printf("\tINSTRUCTION={");
1206 switch (whea
->Instruction
) {
1207 case ACPI_ERST_READ_REGISTER
:
1208 printf("Read Register");
1210 case ACPI_ERST_READ_REGISTER_VALUE
:
1211 printf("Read Register Value");
1213 case ACPI_ERST_WRITE_REGISTER
:
1214 printf("Write Register");
1216 case ACPI_ERST_WRITE_REGISTER_VALUE
:
1217 printf("Write Register Value");
1219 case ACPI_ERST_NOOP
:
1222 case ACPI_ERST_LOAD_VAR1
:
1223 printf("Load Var1");
1225 case ACPI_ERST_LOAD_VAR2
:
1226 printf("Load Var2");
1228 case ACPI_ERST_STORE_VAR1
:
1229 printf("Store Var1");
1234 case ACPI_ERST_SUBTRACT
:
1237 case ACPI_ERST_ADD_VALUE
:
1238 printf("Add Value");
1240 case ACPI_ERST_SUBTRACT_VALUE
:
1241 printf("Subtract Value");
1243 case ACPI_ERST_STALL
:
1246 case ACPI_ERST_STALL_WHILE_TRUE
:
1247 printf("Stall While True");
1249 case ACPI_ERST_SKIP_NEXT_IF_TRUE
:
1250 printf("Skip Next If True");
1252 case ACPI_ERST_GOTO
:
1255 case ACPI_ERST_SET_SRC_ADDRESS_BASE
:
1256 printf("Set Src Address Base");
1258 case ACPI_ERST_SET_DST_ADDRESS_BASE
:
1259 printf("Set Dst Address Base");
1261 case ACPI_ERST_MOVE_DATA
:
1262 printf("Move Data");
1264 case ACPI_ERST_INSTRUCTION_RESERVED
:
1268 printf("%d (reserved)", whea
->Instruction
);
1275 acpi_print_erst_flags(ACPI_WHEA_HEADER
*whea
)
1277 uint32_t flags
= whea
->Flags
;
1279 printf("\tFLAGS={ ");
1280 if (flags
& ACPI_ERST_PRESERVE
)
1281 printf("PRESERVED");
1286 acpi_handle_erst(ACPI_TABLE_HEADER
*sdp
)
1288 ACPI_TABLE_ERST
*erst
;
1289 ACPI_ERST_ENTRY
*erst_entry
;
1293 printf(BEGIN_COMMENT
);
1294 acpi_print_sdt(sdp
);
1295 erst
= (ACPI_TABLE_ERST
*)sdp
;
1297 printf("\tHeader Length=%d\n", erst
->HeaderLength
);
1298 printf("\tEntries=%d\n", erst
->Entries
);
1300 erst_pos
= sizeof(ACPI_TABLE_ERST
);
1301 for (i
= 0; i
< erst
->Entries
; i
++) {
1302 erst_entry
= (ACPI_ERST_ENTRY
*)((char *)erst
+ erst_pos
);
1303 acpi_print_whea(&erst_entry
->WheaHeader
,
1304 acpi_print_erst_action
, acpi_print_erst_instruction
,
1305 acpi_print_erst_flags
);
1306 erst_pos
+= sizeof(ACPI_ERST_ENTRY
);
1308 printf(END_COMMENT
);
1312 acpi_handle_madt(ACPI_TABLE_HEADER
*sdp
)
1314 ACPI_TABLE_MADT
*madt
;
1316 printf(BEGIN_COMMENT
);
1317 acpi_print_sdt(sdp
);
1318 madt
= (ACPI_TABLE_MADT
*)sdp
;
1319 printf("\tLocal APIC ADDR=0x%08x\n", madt
->Address
);
1320 printf("\tFlags={");
1321 if (madt
->Flags
& ACPI_MADT_PCAT_COMPAT
)
1324 acpi_walk_subtables(sdp
, (madt
+ 1), acpi_print_madt
);
1325 printf(END_COMMENT
);
1329 acpi_handle_hpet(ACPI_TABLE_HEADER
*sdp
)
1331 ACPI_TABLE_HPET
*hpet
;
1333 printf(BEGIN_COMMENT
);
1334 acpi_print_sdt(sdp
);
1335 hpet
= (ACPI_TABLE_HPET
*)sdp
;
1336 printf("\tHPET Number=%d\n", hpet
->Sequence
);
1338 acpi_print_gas(&hpet
->Address
);
1339 printf("\tHW Rev=0x%x\n", hpet
->Id
& ACPI_HPET_ID_HARDWARE_REV_ID
);
1340 printf("\tComparators=%d\n", (hpet
->Id
& ACPI_HPET_ID_COMPARATORS
) >>
1342 printf("\tCounter Size=%d\n", hpet
->Id
& ACPI_HPET_ID_COUNT_SIZE_CAP
?
1344 printf("\tLegacy IRQ routing capable={");
1345 if (hpet
->Id
& ACPI_HPET_ID_LEGACY_CAPABLE
)
1349 printf("\tPCI Vendor ID=0x%04x\n", hpet
->Id
>> 16);
1350 printf("\tMinimal Tick=%d\n", hpet
->MinimumTick
);
1351 printf(END_COMMENT
);
1355 acpi_handle_msct(ACPI_TABLE_HEADER
*sdp
)
1357 ACPI_TABLE_MSCT
*msct
;
1358 ACPI_MSCT_PROXIMITY
*msctentry
;
1361 printf(BEGIN_COMMENT
);
1362 acpi_print_sdt(sdp
);
1363 msct
= (ACPI_TABLE_MSCT
*)sdp
;
1365 printf("\tProximity Offset=0x%x\n", msct
->ProximityOffset
);
1366 printf("\tMax Proximity Domains=%d\n", msct
->MaxProximityDomains
);
1367 printf("\tMax Clock Domains=%d\n", msct
->MaxClockDomains
);
1368 printf("\tMax Physical Address=0x%"PRIx64
"\n", msct
->MaxAddress
);
1370 pos
= msct
->ProximityOffset
;
1371 while (pos
< msct
->Header
.Length
) {
1372 msctentry
= (ACPI_MSCT_PROXIMITY
*)((char *)msct
+ pos
);
1373 pos
+= msctentry
->Length
;
1376 printf("\tRevision=%d\n", msctentry
->Revision
);
1377 printf("\tLength=%d\n", msctentry
->Length
);
1378 printf("\tRange Start=%d\n", msctentry
->RangeStart
);
1379 printf("\tRange End=%d\n", msctentry
->RangeEnd
);
1380 printf("\tProcessor Capacity=%d\n",
1381 msctentry
->ProcessorCapacity
);
1382 printf("\tMemory Capacity=0x%"PRIx64
" byte\n",
1383 msctentry
->MemoryCapacity
);
1386 printf(END_COMMENT
);
1390 acpi_handle_ecdt(ACPI_TABLE_HEADER
*sdp
)
1392 ACPI_TABLE_ECDT
*ecdt
;
1394 printf(BEGIN_COMMENT
);
1395 acpi_print_sdt(sdp
);
1396 ecdt
= (ACPI_TABLE_ECDT
*)sdp
;
1397 printf("\tEC_CONTROL=");
1398 acpi_print_gas(&ecdt
->Control
);
1399 printf("\n\tEC_DATA=");
1400 acpi_print_gas(&ecdt
->Data
);
1401 printf("\n\tUID=%#x, ", ecdt
->Uid
);
1402 printf("GPE_BIT=%#x\n", ecdt
->Gpe
);
1403 printf("\tEC_ID=%s\n", ecdt
->Id
);
1404 printf(END_COMMENT
);
1408 acpi_handle_mcfg(ACPI_TABLE_HEADER
*sdp
)
1410 ACPI_TABLE_MCFG
*mcfg
;
1411 ACPI_MCFG_ALLOCATION
*alloc
;
1414 printf(BEGIN_COMMENT
);
1415 acpi_print_sdt(sdp
);
1416 mcfg
= (ACPI_TABLE_MCFG
*)sdp
;
1417 entries
= (sdp
->Length
- sizeof(ACPI_TABLE_MCFG
)) /
1418 sizeof(ACPI_MCFG_ALLOCATION
);
1419 alloc
= (ACPI_MCFG_ALLOCATION
*)(mcfg
+ 1);
1420 for (i
= 0; i
< entries
; i
++, alloc
++) {
1422 printf("\tBase Address=0x%016jx\n", alloc
->Address
);
1423 printf("\tSegment Group=0x%04x\n", alloc
->PciSegment
);
1424 printf("\tStart Bus=%d\n", alloc
->StartBusNumber
);
1425 printf("\tEnd Bus=%d\n", alloc
->EndBusNumber
);
1427 printf(END_COMMENT
);
1431 acpi_handle_sbst(ACPI_TABLE_HEADER
*sdp
)
1433 ACPI_TABLE_SBST
*sbst
;
1435 printf(BEGIN_COMMENT
);
1436 acpi_print_sdt(sdp
);
1437 sbst
= (ACPI_TABLE_SBST
*)sdp
;
1439 printf("\tWarning Level=%d mWh\n", sbst
->WarningLevel
);
1440 printf("\tLow Level=%d mWh\n", sbst
->LowLevel
);
1441 printf("\tCritical Level=%d mWh\n", sbst
->CriticalLevel
);
1443 printf(END_COMMENT
);
1447 acpi_handle_slit(ACPI_TABLE_HEADER
*sdp
)
1449 ACPI_TABLE_SLIT
*slit
;
1453 printf(BEGIN_COMMENT
);
1454 acpi_print_sdt(sdp
);
1455 slit
= (ACPI_TABLE_SLIT
*)sdp
;
1457 cnt
= slit
->LocalityCount
* slit
->LocalityCount
;
1458 printf("\tLocalityCount=%"PRIu64
"\n", slit
->LocalityCount
);
1459 printf("\tEntry=\n\t");
1460 for (idx
= 0; idx
< cnt
; idx
++) {
1461 printf("%u ", slit
->Entry
[idx
]);
1462 if ((idx
% slit
->LocalityCount
) == (slit
->LocalityCount
- 1)) {
1469 printf(END_COMMENT
);
1473 acpi_handle_spcr(ACPI_TABLE_HEADER
*sdp
)
1475 ACPI_TABLE_SPCR
*spcr
;
1477 printf(BEGIN_COMMENT
);
1478 acpi_print_sdt(sdp
);
1479 spcr
= (ACPI_TABLE_SPCR
*)sdp
;
1481 printf("\tSerial Port=");
1482 acpi_print_gas(&spcr
->SerialPort
);
1483 printf("\n\tInterrupt Type={");
1484 if (spcr
->InterruptType
& 0x1) {
1485 printf("\n\t\tdual-8259 IRQ=");
1486 switch (spcr
->PcInterrupt
) {
1490 printf("%d", spcr
->PcInterrupt
);
1493 printf("%d (invalid entry)", spcr
->PcInterrupt
);
1497 if (spcr
->InterruptType
& 0x2) {
1498 printf("\n\t\tIO APIC={ GSI=%d }", spcr
->Interrupt
);
1500 if (spcr
->InterruptType
& 0x4) {
1501 printf("\n\t\tIO SAPIC={ GSI=%d }", spcr
->Interrupt
);
1505 printf("\tBaud Rate=");
1506 switch (spcr
->BaudRate
) {
1520 printf("unknown speed index %d", spcr
->BaudRate
);
1523 printf("\n\tParity={");
1524 switch (spcr
->Parity
) {
1534 printf("\tStop Bits={");
1535 switch (spcr
->StopBits
) {
1545 printf("\tFlow Control={");
1546 if (spcr
->FlowControl
& 0x1)
1548 if (spcr
->FlowControl
& 0x2)
1549 printf("RTS/CTS hardware, ");
1550 if (spcr
->FlowControl
& 0x4)
1551 printf("XON/XOFF software");
1554 printf("\tTerminal=");
1555 switch (spcr
->TerminalType
) {
1569 printf("unknown type %d", spcr
->TerminalType
);
1574 acpi_print_pci(spcr
->PciVendorId
, spcr
->PciDeviceId
,
1575 spcr
->PciSegment
, spcr
->PciBus
, spcr
->PciDevice
, spcr
->PciFunction
);
1577 printf("\tPCI Flags={");
1578 if (spcr
->PciFlags
& ACPI_SPCR_DO_NOT_DISABLE
)
1579 printf("DONOT_DISABLE");
1582 printf(END_COMMENT
);
1586 acpi_print_srat_cpu(uint32_t apic_id
, uint32_t proximity_domain
,
1587 uint32_t flags
, uint32_t clockdomain
)
1590 printf("\tFlags={");
1591 if (flags
& ACPI_SRAT_CPU_ENABLED
)
1596 printf("\tAPIC ID=%d\n", apic_id
);
1597 printf("\tProximity Domain=%d\n", proximity_domain
);
1598 printf("\tClock Domain=%d\n", clockdomain
);
1602 acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY
*mp
)
1605 printf("\tFlags={");
1606 if (mp
->Flags
& ACPI_SRAT_MEM_ENABLED
)
1610 if (mp
->Flags
& ACPI_SRAT_MEM_HOT_PLUGGABLE
)
1611 printf(",HOT_PLUGGABLE");
1612 if (mp
->Flags
& ACPI_SRAT_MEM_NON_VOLATILE
)
1613 printf(",NON_VOLATILE");
1615 printf("\tBase Address=0x%016jx\n", (uintmax_t)mp
->BaseAddress
);
1616 printf("\tLength=0x%016jx\n", (uintmax_t)mp
->Length
);
1617 printf("\tProximity Domain=%d\n", mp
->ProximityDomain
);
1620 const char *srat_types
[] = { "CPU", "Memory", "X2APIC" };
1623 acpi_print_srat(ACPI_SUBTABLE_HEADER
*srat
)
1625 ACPI_SRAT_CPU_AFFINITY
*cpu
;
1626 ACPI_SRAT_X2APIC_CPU_AFFINITY
*x2apic
;
1628 if (srat
->Type
< sizeof(srat_types
) / sizeof(srat_types
[0]))
1629 printf("\tType=%s\n", srat_types
[srat
->Type
]);
1631 printf("\tType=%d (unknown)\n", srat
->Type
);
1632 switch (srat
->Type
) {
1633 case ACPI_SRAT_TYPE_CPU_AFFINITY
:
1634 cpu
= (ACPI_SRAT_CPU_AFFINITY
*)srat
;
1635 acpi_print_srat_cpu(cpu
->ApicId
,
1636 cpu
->ProximityDomainHi
[2] << 24 |
1637 cpu
->ProximityDomainHi
[1] << 16 |
1638 cpu
->ProximityDomainHi
[0] << 0 |
1639 cpu
->ProximityDomainLo
,
1640 cpu
->Flags
, cpu
->ClockDomain
);
1642 case ACPI_SRAT_TYPE_MEMORY_AFFINITY
:
1643 acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY
*)srat
);
1645 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY
:
1646 x2apic
= (ACPI_SRAT_X2APIC_CPU_AFFINITY
*)srat
;
1647 acpi_print_srat_cpu(x2apic
->ApicId
, x2apic
->ProximityDomain
,
1648 x2apic
->Flags
, x2apic
->ClockDomain
);
1654 acpi_handle_srat(ACPI_TABLE_HEADER
*sdp
)
1656 ACPI_TABLE_SRAT
*srat
;
1658 printf(BEGIN_COMMENT
);
1659 acpi_print_sdt(sdp
);
1660 srat
= (ACPI_TABLE_SRAT
*)sdp
;
1661 printf("\tTable Revision=%d\n", srat
->TableRevision
);
1662 acpi_walk_subtables(sdp
, (srat
+ 1), acpi_print_srat
);
1663 printf(END_COMMENT
);
1667 acpi_handle_tcpa(ACPI_TABLE_HEADER
*sdp
)
1669 ACPI_TABLE_TCPA
*tcpa
;
1671 printf(BEGIN_COMMENT
);
1672 acpi_print_sdt(sdp
);
1673 tcpa
= (ACPI_TABLE_TCPA
*)sdp
;
1675 printf("\tMaximum Length of Event Log Area=%d\n", tcpa
->MaxLogLength
);
1676 printf("\tPhysical Address of Log Area=0x%08"PRIx64
"\n",
1679 printf(END_COMMENT
);
1683 acpi_handle_waet(ACPI_TABLE_HEADER
*sdp
)
1685 ACPI_TABLE_WAET
*waet
;
1687 printf(BEGIN_COMMENT
);
1688 acpi_print_sdt(sdp
);
1689 waet
= (ACPI_TABLE_WAET
*)sdp
;
1691 printf("\tRTC Timer={");
1692 if (waet
->Flags
& ACPI_WAET_RTC_NO_ACK
)
1693 printf("No ACK required");
1695 printf("default behaviour");
1697 printf("\t ACPI PM Timer={");
1698 if (waet
->Flags
& ACPI_WAET_TIMER_ONE_READ
)
1699 printf("One Read sufficient");
1701 printf("default behaviour");
1704 printf(END_COMMENT
);
1708 acpi_print_wdat_action(ACPI_WHEA_HEADER
*whea
)
1710 printf("\tACTION={");
1711 switch (whea
->Action
) {
1712 case ACPI_WDAT_RESET
:
1715 case ACPI_WDAT_GET_CURRENT_COUNTDOWN
:
1716 printf("GET_CURRENT_COUNTDOWN");
1718 case ACPI_WDAT_GET_COUNTDOWN
:
1719 printf("GET_COUNTDOWN");
1721 case ACPI_WDAT_SET_COUNTDOWN
:
1722 printf("SET_COUNTDOWN");
1724 case ACPI_WDAT_GET_RUNNING_STATE
:
1725 printf("GET_RUNNING_STATE");
1727 case ACPI_WDAT_SET_RUNNING_STATE
:
1728 printf("SET_RUNNING_STATE");
1730 case ACPI_WDAT_GET_STOPPED_STATE
:
1731 printf("GET_STOPPED_STATE");
1733 case ACPI_WDAT_SET_STOPPED_STATE
:
1734 printf("SET_STOPPED_STATE");
1736 case ACPI_WDAT_GET_REBOOT
:
1737 printf("GET_REBOOT");
1739 case ACPI_WDAT_SET_REBOOT
:
1740 printf("SET_REBOOT");
1742 case ACPI_WDAT_GET_SHUTDOWN
:
1743 printf("GET_SHUTDOWN");
1745 case ACPI_WDAT_SET_SHUTDOWN
:
1746 printf("SET_SHUTDOWN");
1748 case ACPI_WDAT_GET_STATUS
:
1749 printf("GET_STATUS");
1751 case ACPI_WDAT_SET_STATUS
:
1752 printf("SET_STATUS");
1754 case ACPI_WDAT_ACTION_RESERVED
:
1755 printf("ACTION_RESERVED");
1758 printf("%d", whea
->Action
);
1765 acpi_print_wdat_instruction(ACPI_WHEA_HEADER
*whea
)
1769 ins
= whea
->Instruction
& ~ACPI_WDAT_PRESERVE_REGISTER
;
1771 printf("\tINSTRUCTION={");
1773 case ACPI_WDAT_READ_VALUE
:
1774 printf("READ_VALUE");
1776 case ACPI_WDAT_READ_COUNTDOWN
:
1777 printf("READ_COUNTDOWN");
1779 case ACPI_WDAT_WRITE_VALUE
:
1780 printf("WRITE_VALUE");
1782 case ACPI_WDAT_WRITE_COUNTDOWN
:
1783 printf("WRITE_COUNTDOWN");
1785 case ACPI_WDAT_INSTRUCTION_RESERVED
:
1786 printf("INSTRUCTION_RESERVED");
1793 if (whea
->Instruction
& ACPI_WDAT_PRESERVE_REGISTER
)
1794 printf(", Preserve Register ");
1800 acpi_handle_wdat(ACPI_TABLE_HEADER
*sdp
)
1802 ACPI_TABLE_WDAT
*wdat
;
1803 ACPI_WHEA_HEADER
*whea
;
1807 printf(BEGIN_COMMENT
);
1808 acpi_print_sdt(sdp
);
1809 wdat
= (ACPI_TABLE_WDAT
*)sdp
;
1811 printf("\tHeader Length=%d\n", wdat
->HeaderLength
);
1813 acpi_print_pci_sbfd(wdat
->PciSegment
, wdat
->PciBus
, wdat
->PciDevice
,
1815 printf("\n\tTimer Counter Period=%d msec\n", wdat
->TimerPeriod
);
1816 printf("\tTimer Maximum Counter Value=%d\n", wdat
->MaxCount
);
1817 printf("\tTimer Minimum Counter Value=%d\n", wdat
->MinCount
);
1819 printf("\tFlags={");
1820 if (wdat
->Flags
& ACPI_WDAT_ENABLED
)
1822 if (wdat
->Flags
& ACPI_WDAT_STOPPED
)
1823 printf(", STOPPED");
1826 wdat_pos
= ((char *)wdat
+ sizeof(ACPI_TABLE_HEADER
)
1827 + wdat
->HeaderLength
);
1829 for (i
= 0; i
< wdat
->Entries
; i
++) {
1830 whea
= (ACPI_WHEA_HEADER
*)wdat_pos
;
1831 acpi_print_whea(whea
,
1832 acpi_print_wdat_action
, acpi_print_wdat_instruction
,
1834 wdat_pos
+= sizeof(ACPI_WDAT_ENTRY
);
1836 printf(END_COMMENT
);
1840 acpi_handle_wdrt(ACPI_TABLE_HEADER
*sdp
)
1842 ACPI_TABLE_WDRT
*wdrt
;
1844 printf(BEGIN_COMMENT
);
1845 acpi_print_sdt(sdp
);
1846 wdrt
= (ACPI_TABLE_WDRT
*)sdp
;
1848 printf("\tControl Register=");
1849 acpi_print_gas(&wdrt
->ControlRegister
);
1850 printf("\tCount Register=");
1851 acpi_print_gas(&wdrt
->CountRegister
);
1852 acpi_print_pci(wdrt
->PciVendorId
, wdrt
->PciDeviceId
,
1853 wdrt
->PciSegment
, wdrt
->PciBus
, wdrt
->PciDevice
, wdrt
->PciFunction
);
1855 /* Value must be >= 511 and < 65535 */
1856 printf("\tMaxCount=%d", wdrt
->MaxCount
);
1857 if (wdrt
->MaxCount
< 511)
1858 printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
1862 switch (wdrt
->Units
) {
1864 printf("1 seconds/count");
1867 printf("100 milliseconds/count");
1870 printf("10 milliseconds/count");
1873 printf("%d", wdrt
->Units
);
1878 printf(END_COMMENT
);
1882 acpi_print_sdt(ACPI_TABLE_HEADER
*sdp
)
1885 acpi_print_string(sdp
->Signature
, ACPI_NAME_SIZE
);
1886 printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1887 sdp
->Length
, sdp
->Revision
, sdp
->Checksum
);
1889 acpi_print_string(sdp
->OemId
, ACPI_OEM_ID_SIZE
);
1890 printf(", OEM Table ID=");
1891 acpi_print_string(sdp
->OemTableId
, ACPI_OEM_TABLE_ID_SIZE
);
1892 printf(", OEM Revision=0x%x,\n", sdp
->OemRevision
);
1893 printf("\tCreator ID=");
1894 acpi_print_string(sdp
->AslCompilerId
, ACPI_NAME_SIZE
);
1895 printf(", Creator Revision=0x%x\n", sdp
->AslCompilerRevision
);
1899 acpi_print_rsdt(ACPI_TABLE_HEADER
*rsdp
)
1901 ACPI_TABLE_RSDT
*rsdt
;
1902 ACPI_TABLE_XSDT
*xsdt
;
1906 rsdt
= (ACPI_TABLE_RSDT
*)rsdp
;
1907 xsdt
= (ACPI_TABLE_XSDT
*)rsdp
;
1908 printf(BEGIN_COMMENT
);
1909 acpi_print_sdt(rsdp
);
1910 entries
= (rsdp
->Length
- sizeof(ACPI_TABLE_HEADER
)) / addr_size
;
1911 printf("\tEntries={ ");
1912 for (i
= 0; i
< entries
; i
++) {
1915 switch (addr_size
) {
1917 addr
= le32toh(rsdt
->TableOffsetEntry
[i
]);
1920 addr
= le64toh(xsdt
->TableOffsetEntry
[i
]);
1926 printf("0x%08lx", addr
);
1929 printf(END_COMMENT
);
1932 static const char *acpi_pm_profiles
[] = {
1933 "Unspecified", "Desktop", "Mobile", "Workstation",
1934 "Enterprise Server", "SOHO Server", "Appliance PC"
1938 acpi_print_fadt(ACPI_TABLE_HEADER
*sdp
)
1940 ACPI_TABLE_FADT
*fadt
;
1944 fadt
= (ACPI_TABLE_FADT
*)sdp
;
1945 printf(BEGIN_COMMENT
);
1946 acpi_print_sdt(sdp
);
1947 printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt
->Facs
,
1949 printf("\tINT_MODEL=%s\n", fadt
->Model
? "APIC" : "PIC");
1950 if (fadt
->PreferredProfile
>= sizeof(acpi_pm_profiles
) / sizeof(char *))
1953 pm
= acpi_pm_profiles
[fadt
->PreferredProfile
];
1954 printf("\tPreferred_PM_Profile=%s (%d)\n", pm
, fadt
->PreferredProfile
);
1955 printf("\tSCI_INT=%d\n", fadt
->SciInterrupt
);
1956 printf("\tSMI_CMD=0x%x, ", fadt
->SmiCommand
);
1957 printf("ACPI_ENABLE=0x%x, ", fadt
->AcpiEnable
);
1958 printf("ACPI_DISABLE=0x%x, ", fadt
->AcpiDisable
);
1959 printf("S4BIOS_REQ=0x%x\n", fadt
->S4BiosRequest
);
1960 printf("\tPSTATE_CNT=0x%x\n", fadt
->PstateControl
);
1961 printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1962 fadt
->Pm1aEventBlock
,
1963 fadt
->Pm1aEventBlock
+ fadt
->Pm1EventLength
- 1);
1964 if (fadt
->Pm1bEventBlock
!= 0)
1965 printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1966 fadt
->Pm1bEventBlock
,
1967 fadt
->Pm1bEventBlock
+ fadt
->Pm1EventLength
- 1);
1968 printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1969 fadt
->Pm1aControlBlock
,
1970 fadt
->Pm1aControlBlock
+ fadt
->Pm1ControlLength
- 1);
1971 if (fadt
->Pm1bControlBlock
!= 0)
1972 printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1973 fadt
->Pm1bControlBlock
,
1974 fadt
->Pm1bControlBlock
+ fadt
->Pm1ControlLength
- 1);
1975 if (fadt
->Pm2ControlBlock
!= 0)
1976 printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1977 fadt
->Pm2ControlBlock
,
1978 fadt
->Pm2ControlBlock
+ fadt
->Pm2ControlLength
- 1);
1979 printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1981 fadt
->PmTimerBlock
+ fadt
->PmTimerLength
- 1);
1982 if (fadt
->Gpe0Block
!= 0)
1983 printf("\tGPE0_BLK=0x%x-0x%x\n",
1985 fadt
->Gpe0Block
+ fadt
->Gpe0BlockLength
- 1);
1986 if (fadt
->Gpe1Block
!= 0)
1987 printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1989 fadt
->Gpe1Block
+ fadt
->Gpe1BlockLength
- 1,
1991 if (fadt
->CstControl
!= 0)
1992 printf("\tCST_CNT=0x%x\n", fadt
->CstControl
);
1993 printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1994 fadt
->C2Latency
, fadt
->C3Latency
);
1995 printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1996 fadt
->FlushSize
, fadt
->FlushStride
);
1997 printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1998 fadt
->DutyOffset
, fadt
->DutyWidth
);
1999 printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
2000 fadt
->DayAlarm
, fadt
->MonthAlarm
, fadt
->Century
);
2002 #define PRINTFLAG(var, flag) do { \
2003 if ((var) & ACPI_FADT_## flag) { \
2004 printf("%c%s", sep, #flag); sep = ','; \
2008 printf("\tIAPC_BOOT_ARCH=");
2010 PRINTFLAG(fadt
->BootFlags
, LEGACY_DEVICES
);
2011 PRINTFLAG(fadt
->BootFlags
, 8042);
2012 PRINTFLAG(fadt
->BootFlags
, NO_VGA
);
2013 PRINTFLAG(fadt
->BootFlags
, NO_MSI
);
2014 PRINTFLAG(fadt
->BootFlags
, NO_ASPM
);
2015 if (fadt
->BootFlags
!= 0)
2021 PRINTFLAG(fadt
->Flags
, WBINVD
);
2022 PRINTFLAG(fadt
->Flags
, WBINVD_FLUSH
);
2023 PRINTFLAG(fadt
->Flags
, C1_SUPPORTED
);
2024 PRINTFLAG(fadt
->Flags
, C2_MP_SUPPORTED
);
2025 PRINTFLAG(fadt
->Flags
, POWER_BUTTON
);
2026 PRINTFLAG(fadt
->Flags
, SLEEP_BUTTON
);
2027 PRINTFLAG(fadt
->Flags
, FIXED_RTC
);
2028 PRINTFLAG(fadt
->Flags
, S4_RTC_WAKE
);
2029 PRINTFLAG(fadt
->Flags
, 32BIT_TIMER
);
2030 PRINTFLAG(fadt
->Flags
, DOCKING_SUPPORTED
);
2031 PRINTFLAG(fadt
->Flags
, RESET_REGISTER
);
2032 PRINTFLAG(fadt
->Flags
, SEALED_CASE
);
2033 PRINTFLAG(fadt
->Flags
, HEADLESS
);
2034 PRINTFLAG(fadt
->Flags
, SLEEP_TYPE
);
2035 PRINTFLAG(fadt
->Flags
, PCI_EXPRESS_WAKE
);
2036 PRINTFLAG(fadt
->Flags
, PLATFORM_CLOCK
);
2037 PRINTFLAG(fadt
->Flags
, S4_RTC_VALID
);
2038 PRINTFLAG(fadt
->Flags
, REMOTE_POWER_ON
);
2039 PRINTFLAG(fadt
->Flags
, APIC_CLUSTER
);
2040 PRINTFLAG(fadt
->Flags
, APIC_PHYSICAL
);
2041 if (fadt
->Flags
!= 0)
2046 if (fadt
->Flags
& ACPI_FADT_RESET_REGISTER
) {
2047 printf("\tRESET_REG=");
2048 acpi_print_gas(&fadt
->ResetRegister
);
2049 printf(", RESET_VALUE=%#x\n", fadt
->ResetValue
);
2051 if (acpi_get_fadt_revision(fadt
) > 1) {
2052 printf("\tX_FACS=0x%08lx, ", (u_long
)fadt
->XFacs
);
2053 printf("X_DSDT=0x%08lx\n", (u_long
)fadt
->XDsdt
);
2054 printf("\tX_PM1a_EVT_BLK=");
2055 acpi_print_gas(&fadt
->XPm1aEventBlock
);
2056 if (fadt
->XPm1bEventBlock
.Address
!= 0) {
2057 printf("\n\tX_PM1b_EVT_BLK=");
2058 acpi_print_gas(&fadt
->XPm1bEventBlock
);
2060 printf("\n\tX_PM1a_CNT_BLK=");
2061 acpi_print_gas(&fadt
->XPm1aControlBlock
);
2062 if (fadt
->XPm1bControlBlock
.Address
!= 0) {
2063 printf("\n\tX_PM1b_CNT_BLK=");
2064 acpi_print_gas(&fadt
->XPm1bControlBlock
);
2066 if (fadt
->XPm2ControlBlock
.Address
!= 0) {
2067 printf("\n\tX_PM2_CNT_BLK=");
2068 acpi_print_gas(&fadt
->XPm2ControlBlock
);
2070 printf("\n\tX_PM_TMR_BLK=");
2071 acpi_print_gas(&fadt
->XPmTimerBlock
);
2072 if (fadt
->XGpe0Block
.Address
!= 0) {
2073 printf("\n\tX_GPE0_BLK=");
2074 acpi_print_gas(&fadt
->XGpe0Block
);
2076 if (fadt
->XGpe1Block
.Address
!= 0) {
2077 printf("\n\tX_GPE1_BLK=");
2078 acpi_print_gas(&fadt
->XGpe1Block
);
2083 printf(END_COMMENT
);
2087 acpi_print_facs(ACPI_TABLE_FACS
*facs
)
2089 printf(BEGIN_COMMENT
);
2090 printf(" FACS:\tLength=%u, ", facs
->Length
);
2091 printf("HwSig=0x%08x, ", facs
->HardwareSignature
);
2092 printf("Firm_Wake_Vec=0x%08x\n", facs
->FirmwareWakingVector
);
2094 printf("\tGlobal_Lock=");
2095 if (facs
->GlobalLock
!= 0) {
2096 if (facs
->GlobalLock
& ACPI_GLOCK_PENDING
)
2098 if (facs
->GlobalLock
& ACPI_GLOCK_OWNED
)
2104 if (facs
->Flags
& ACPI_FACS_S4_BIOS_PRESENT
)
2108 if (facs
->XFirmwareWakingVector
!= 0) {
2109 printf("\tX_Firm_Wake_Vec=%08lx\n",
2110 (u_long
)facs
->XFirmwareWakingVector
);
2112 printf("\tVersion=%u\n", facs
->Version
);
2114 printf(END_COMMENT
);
2118 acpi_print_dsdt(ACPI_TABLE_HEADER
*dsdp
)
2120 printf(BEGIN_COMMENT
);
2121 acpi_print_sdt(dsdp
);
2122 printf(END_COMMENT
);
2126 acpi_checksum(void *p
, size_t length
)
2139 static ACPI_TABLE_HEADER
*
2140 acpi_map_sdt(vm_offset_t pa
)
2142 ACPI_TABLE_HEADER
*sp
;
2144 sp
= acpi_map_physical(pa
, sizeof(ACPI_TABLE_HEADER
));
2145 sp
= acpi_map_physical(pa
, sp
->Length
);
2150 acpi_print_rsd_ptr(ACPI_TABLE_RSDP
*rp
)
2152 printf(BEGIN_COMMENT
);
2153 printf(" RSD PTR: OEM=");
2154 acpi_print_string(rp
->OemId
, ACPI_OEM_ID_SIZE
);
2155 printf(", ACPI_Rev=%s (%d)\n", rp
->Revision
< 2 ? "1.0x" : "2.0x",
2157 if (rp
->Revision
< 2) {
2158 printf("\tRSDT=0x%08x, cksum=%u\n", rp
->RsdtPhysicalAddress
,
2161 printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n",
2162 (u_long
)rp
->XsdtPhysicalAddress
, rp
->Length
,
2163 rp
->ExtendedChecksum
);
2165 printf(END_COMMENT
);
2169 acpi_handle_rsdt(ACPI_TABLE_HEADER
*rsdp
)
2171 ACPI_TABLE_HEADER
*sdp
;
2172 ACPI_TABLE_RSDT
*rsdt
;
2173 ACPI_TABLE_XSDT
*xsdt
;
2177 acpi_print_rsdt(rsdp
);
2178 rsdt
= (ACPI_TABLE_RSDT
*)rsdp
;
2179 xsdt
= (ACPI_TABLE_XSDT
*)rsdp
;
2180 entries
= (rsdp
->Length
- sizeof(ACPI_TABLE_HEADER
)) / addr_size
;
2181 for (i
= 0; i
< entries
; i
++) {
2182 switch (addr_size
) {
2184 addr
= le32toh(rsdt
->TableOffsetEntry
[i
]);
2187 addr
= le64toh(xsdt
->TableOffsetEntry
[i
]);
2193 sdp
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(addr
);
2194 if (acpi_checksum(sdp
, sdp
->Length
)) {
2195 warnx("RSDT entry %d (sig %.4s) is corrupt", i
,
2199 if (!memcmp(sdp
->Signature
, ACPI_SIG_FADT
, 4))
2200 acpi_handle_fadt(sdp
);
2201 else if (!memcmp(sdp
->Signature
, ACPI_SIG_BERT
, 4))
2202 acpi_handle_bert(sdp
);
2203 else if (!memcmp(sdp
->Signature
, ACPI_SIG_BOOT
, 4))
2204 acpi_handle_boot(sdp
);
2205 else if (!memcmp(sdp
->Signature
, ACPI_SIG_CPEP
, 4))
2206 acpi_handle_cpep(sdp
);
2207 else if (!memcmp(sdp
->Signature
, ACPI_SIG_DBGP
, 4))
2208 acpi_handle_dbgp(sdp
);
2209 else if (!memcmp(sdp
->Signature
, ACPI_SIG_EINJ
, 4))
2210 acpi_handle_einj(sdp
);
2211 else if (!memcmp(sdp
->Signature
, ACPI_SIG_ERST
, 4))
2212 acpi_handle_erst(sdp
);
2213 else if (!memcmp(sdp
->Signature
, ACPI_SIG_MADT
, 4))
2214 acpi_handle_madt(sdp
);
2215 else if (!memcmp(sdp
->Signature
, ACPI_SIG_MSCT
, 4))
2216 acpi_handle_msct(sdp
);
2217 else if (!memcmp(sdp
->Signature
, ACPI_SIG_HEST
, 4))
2218 acpi_handle_hest(sdp
);
2219 else if (!memcmp(sdp
->Signature
, ACPI_SIG_HPET
, 4))
2220 acpi_handle_hpet(sdp
);
2221 else if (!memcmp(sdp
->Signature
, ACPI_SIG_ECDT
, 4))
2222 acpi_handle_ecdt(sdp
);
2223 else if (!memcmp(sdp
->Signature
, ACPI_SIG_MCFG
, 4))
2224 acpi_handle_mcfg(sdp
);
2225 else if (!memcmp(sdp
->Signature
, ACPI_SIG_SBST
, 4))
2226 acpi_handle_sbst(sdp
);
2227 else if (!memcmp(sdp
->Signature
, ACPI_SIG_SLIT
, 4))
2228 acpi_handle_slit(sdp
);
2229 else if (!memcmp(sdp
->Signature
, ACPI_SIG_SPCR
, 4))
2230 acpi_handle_spcr(sdp
);
2231 else if (!memcmp(sdp
->Signature
, ACPI_SIG_SRAT
, 4))
2232 acpi_handle_srat(sdp
);
2233 else if (!memcmp(sdp
->Signature
, ACPI_SIG_TCPA
, 4))
2234 acpi_handle_tcpa(sdp
);
2235 else if (!memcmp(sdp
->Signature
, ACPI_SIG_WAET
, 4))
2236 acpi_handle_waet(sdp
);
2237 else if (!memcmp(sdp
->Signature
, ACPI_SIG_WDAT
, 4))
2238 acpi_handle_wdat(sdp
);
2239 else if (!memcmp(sdp
->Signature
, ACPI_SIG_WDRT
, 4))
2240 acpi_handle_wdrt(sdp
);
2242 printf(BEGIN_COMMENT
);
2243 acpi_print_sdt(sdp
);
2244 printf(END_COMMENT
);
2250 sdt_load_devmem(void)
2252 ACPI_TABLE_RSDP
*rp
;
2253 ACPI_TABLE_HEADER
*rsdp
;
2255 rp
= acpi_find_rsd_ptr();
2257 errx(EXIT_FAILURE
, "Can't find ACPI information");
2260 acpi_print_rsd_ptr(rp
);
2261 if (rp
->Revision
< 2) {
2262 rsdp
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(rp
->RsdtPhysicalAddress
);
2263 if (memcmp(rsdp
->Signature
, "RSDT", 4) != 0 ||
2264 acpi_checksum(rsdp
, rsdp
->Length
) != 0)
2265 errx(EXIT_FAILURE
, "RSDT is corrupted");
2266 addr_size
= sizeof(uint32_t);
2268 rsdp
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(rp
->XsdtPhysicalAddress
);
2269 if (memcmp(rsdp
->Signature
, "XSDT", 4) != 0 ||
2270 acpi_checksum(rsdp
, rsdp
->Length
) != 0)
2271 errx(EXIT_FAILURE
, "XSDT is corrupted");
2272 addr_size
= sizeof(uint64_t);
2277 /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2279 write_dsdt(int fd
, ACPI_TABLE_HEADER
*rsdt
, ACPI_TABLE_HEADER
*dsdt
)
2281 ACPI_TABLE_HEADER sdt
;
2282 ACPI_TABLE_HEADER
*ssdt
;
2285 /* Create a new checksum to account for the DSDT and any SSDTs. */
2289 sum
= acpi_checksum(dsdt
+ 1, dsdt
->Length
-
2290 sizeof(ACPI_TABLE_HEADER
));
2291 ssdt
= sdt_from_rsdt(rsdt
, ACPI_SIG_SSDT
, NULL
);
2292 while (ssdt
!= NULL
) {
2293 sdt
.Length
+= ssdt
->Length
- sizeof(ACPI_TABLE_HEADER
);
2294 sum
+= acpi_checksum(ssdt
+ 1,
2295 ssdt
->Length
- sizeof(ACPI_TABLE_HEADER
));
2296 ssdt
= sdt_from_rsdt(rsdt
, ACPI_SIG_SSDT
, ssdt
);
2298 sum
+= acpi_checksum(&sdt
, sizeof(ACPI_TABLE_HEADER
));
2299 sdt
.Checksum
-= sum
;
2302 /* Write out the DSDT header and body. */
2303 write(fd
, &sdt
, sizeof(ACPI_TABLE_HEADER
));
2304 write(fd
, dsdt
+ 1, dsdt
->Length
- sizeof(ACPI_TABLE_HEADER
));
2306 /* Write out any SSDTs (if present.) */
2308 ssdt
= sdt_from_rsdt(rsdt
, "SSDT", NULL
);
2309 while (ssdt
!= NULL
) {
2310 write(fd
, ssdt
+ 1, ssdt
->Length
-
2311 sizeof(ACPI_TABLE_HEADER
));
2312 ssdt
= sdt_from_rsdt(rsdt
, "SSDT", ssdt
);
2319 dsdt_save_file(char *outfile
, ACPI_TABLE_HEADER
*rsdt
, ACPI_TABLE_HEADER
*dsdp
)
2324 assert(outfile
!= NULL
);
2325 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
;
2326 fd
= open(outfile
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
2328 perror("dsdt_save_file");
2331 write_dsdt(fd
, rsdt
, dsdp
);
2336 aml_disassemble(ACPI_TABLE_HEADER
*rsdt
, ACPI_TABLE_HEADER
*dsdp
)
2338 char buf
[PATH_MAX
], tmpstr
[PATH_MAX
];
2346 errx(EXIT_FAILURE
, "aml_disassemble: invalid rsdt");
2348 errx(EXIT_FAILURE
, "aml_disassemble: invalid dsdp");
2350 tmpdir
= getenv("TMPDIR");
2353 strlcpy(tmpstr
, tmpdir
, sizeof(tmpstr
));
2354 if (realpath(tmpstr
, buf
) == NULL
) {
2355 perror("realpath tmp file");
2358 strlcpy(tmpstr
, buf
, sizeof(tmpstr
));
2359 strlcat(tmpstr
, "/acpidump.", sizeof(tmpstr
));
2360 len
= strlen(tmpstr
);
2361 tmpext
= tmpstr
+ len
;
2362 strlcpy(tmpext
, "XXXXXX", sizeof(tmpstr
) - len
);
2363 fd
= mkstemp(tmpstr
);
2365 perror("iasl tmp file");
2368 write_dsdt(fd
, rsdt
, dsdp
);
2371 /* Run iasl -d on the temp file */
2373 close(STDOUT_FILENO
);
2375 close(STDERR_FILENO
);
2376 execl("/usr/bin/iasl", "iasl", "-d", tmpstr
, NULL
);
2377 err(EXIT_FAILURE
, "exec");
2383 /* Dump iasl's output to stdout */
2384 strlcpy(tmpext
, "dsl", sizeof(tmpstr
) - len
);
2385 fp
= fopen(tmpstr
, "r");
2388 perror("iasl tmp file (read)");
2391 while ((len
= fread(buf
, 1, sizeof(buf
), fp
)) > 0)
2392 fwrite(buf
, 1, len
, stdout
);
2397 sdt_print_all(ACPI_TABLE_HEADER
*rsdp
)
2399 acpi_handle_rsdt(rsdp
);
2402 /* Fetch a table matching the given signature via the RSDT. */
2404 sdt_from_rsdt(ACPI_TABLE_HEADER
*rsdp
, const char *sig
, ACPI_TABLE_HEADER
*last
)
2406 ACPI_TABLE_HEADER
*sdt
;
2407 ACPI_TABLE_RSDT
*rsdt
;
2408 ACPI_TABLE_XSDT
*xsdt
;
2412 rsdt
= (ACPI_TABLE_RSDT
*)rsdp
;
2413 xsdt
= (ACPI_TABLE_XSDT
*)rsdp
;
2414 entries
= (rsdp
->Length
- sizeof(ACPI_TABLE_HEADER
)) / addr_size
;
2415 for (i
= 0; i
< entries
; i
++) {
2416 switch (addr_size
) {
2418 addr
= le32toh(rsdt
->TableOffsetEntry
[i
]);
2421 addr
= le64toh(xsdt
->TableOffsetEntry
[i
]);
2426 sdt
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(addr
);
2432 if (memcmp(sdt
->Signature
, sig
, strlen(sig
)))
2434 if (acpi_checksum(sdt
, sdt
->Length
))
2435 errx(EXIT_FAILURE
, "RSDT entry %d is corrupt", i
);
2443 dsdt_from_fadt(ACPI_TABLE_FADT
*fadt
)
2445 ACPI_TABLE_HEADER
*sdt
;
2447 /* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2448 if (acpi_get_fadt_revision(fadt
) == 1)
2449 sdt
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(fadt
->Dsdt
);
2451 sdt
= (ACPI_TABLE_HEADER
*)acpi_map_sdt(fadt
->XDsdt
);
2452 if (acpi_checksum(sdt
, sdt
->Length
))
2453 errx(EXIT_FAILURE
, "DSDT is corrupt\n");