1e1e9a4bfSMitsuru IWASAKI /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 31de7b4b8SPedro F. Giffuni * 4e1e9a4bfSMitsuru IWASAKI * Copyright (c) 1998 Doug Rabson 5e1e9a4bfSMitsuru IWASAKI * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 6*ebc22d04SAlexander Motin * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org> 7e1e9a4bfSMitsuru IWASAKI * All rights reserved. 8e1e9a4bfSMitsuru IWASAKI * 9e1e9a4bfSMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without 10e1e9a4bfSMitsuru IWASAKI * modification, are permitted provided that the following conditions 11e1e9a4bfSMitsuru IWASAKI * are met: 12e1e9a4bfSMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright 13e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer. 14e1e9a4bfSMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright 15e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the 16e1e9a4bfSMitsuru IWASAKI * documentation and/or other materials provided with the distribution. 17e1e9a4bfSMitsuru IWASAKI * 18e1e9a4bfSMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19e1e9a4bfSMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20e1e9a4bfSMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21e1e9a4bfSMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22e1e9a4bfSMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23e1e9a4bfSMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24e1e9a4bfSMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25e1e9a4bfSMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26e1e9a4bfSMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27e1e9a4bfSMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28e1e9a4bfSMitsuru IWASAKI * SUCH DAMAGE. 29e1e9a4bfSMitsuru IWASAKI * 30e1e9a4bfSMitsuru IWASAKI * $FreeBSD$ 31e1e9a4bfSMitsuru IWASAKI */ 32e1e9a4bfSMitsuru IWASAKI 33e1e9a4bfSMitsuru IWASAKI #include <sys/param.h> 34a74172abSNate Lawson #include <sys/endian.h> 35e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h> 36945137d9SNate Lawson #include <sys/wait.h> 37e1e9a4bfSMitsuru IWASAKI #include <assert.h> 38e1e9a4bfSMitsuru IWASAKI #include <err.h> 39e1e9a4bfSMitsuru IWASAKI #include <fcntl.h> 4099065116SJung-uk Kim #include <paths.h> 41e1e9a4bfSMitsuru IWASAKI #include <stdio.h> 42a0333ad1SJohn Baldwin #include <stdint.h> 4399065116SJung-uk Kim #include <stdlib.h> 44945137d9SNate Lawson #include <string.h> 45e1e9a4bfSMitsuru IWASAKI #include <unistd.h> 46340c0022SEd Maste #include <uuid.h> 47e1e9a4bfSMitsuru IWASAKI 48e1e9a4bfSMitsuru IWASAKI #include "acpidump.h" 49e1e9a4bfSMitsuru IWASAKI 50c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n" 51c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n" 52c62f1cccSMitsuru IWASAKI 53945137d9SNate Lawson static void acpi_print_string(char *s, size_t length); 54986dffafSJohn Baldwin static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas); 55986dffafSJohn Baldwin static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt); 56986dffafSJohn Baldwin static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt); 57945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id); 58986dffafSJohn Baldwin static void acpi_print_cpu_uid(uint32_t uid, char *uid_string); 59986dffafSJohn Baldwin static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags); 60986dffafSJohn Baldwin static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, 61986dffafSJohn Baldwin uint64_t apic_addr); 62986dffafSJohn Baldwin static void acpi_print_mps_flags(uint16_t flags); 63986dffafSJohn Baldwin static void acpi_print_intr(uint32_t intr, uint16_t mps_flags); 64986dffafSJohn Baldwin static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags); 65986dffafSJohn Baldwin static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp); 66986dffafSJohn Baldwin static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp); 67986dffafSJohn Baldwin static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); 68986dffafSJohn Baldwin static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); 69986dffafSJohn Baldwin static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); 7033866658SJohn Baldwin static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); 71ed26c389SScott Long static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp); 725857fba5SBen Widawsky static void acpi_handle_lpit(ACPI_TABLE_HEADER *sdp); 73a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 74a0333ad1SJohn Baldwin uint32_t flags); 75986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); 76986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); 77986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); 78c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); 79340c0022SEd Maste static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit); 80340c0022SEd Maste static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp); 81986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); 82986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); 83986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs); 84986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); 85986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); 86986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); 87986dffafSJohn Baldwin static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); 88986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 89986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)); 90340c0022SEd Maste static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 91340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)); 92c62f1cccSMitsuru IWASAKI 93773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 94a74172abSNate Lawson static int addr_size; 95a74172abSNate Lawson 96c031c93bSTakanori Watanabe /* Strings used in the TCPA table */ 97c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = { 98c031c93bSTakanori Watanabe "PREBOOT Certificate", 99c031c93bSTakanori Watanabe "POST Code", 100c031c93bSTakanori Watanabe "Unused", 101c031c93bSTakanori Watanabe "No Action", 102c031c93bSTakanori Watanabe "Separator", 103c031c93bSTakanori Watanabe "Action", 104c031c93bSTakanori Watanabe "Event Tag", 105c031c93bSTakanori Watanabe "S-CRTM Contents", 106c031c93bSTakanori Watanabe "S-CRTM Version", 107c031c93bSTakanori Watanabe "CPU Microcode", 108c031c93bSTakanori Watanabe "Platform Config Flags", 109c031c93bSTakanori Watanabe "Table of Devices", 110c031c93bSTakanori Watanabe "Compact Hash", 111c031c93bSTakanori Watanabe "IPL", 112c031c93bSTakanori Watanabe "IPL Partition Data", 113c031c93bSTakanori Watanabe "Non-Host Code", 114c031c93bSTakanori Watanabe "Non-Host Config", 115c031c93bSTakanori Watanabe "Non-Host Info" 116c031c93bSTakanori Watanabe }; 117c031c93bSTakanori Watanabe 118c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = { 119c031c93bSTakanori Watanabe "<undefined>", 120c031c93bSTakanori Watanabe "SMBIOS", 121c031c93bSTakanori Watanabe "BIS Certificate", 122c031c93bSTakanori Watanabe "POST BIOS ROM Strings", 123c031c93bSTakanori Watanabe "ESCD", 124c031c93bSTakanori Watanabe "CMOS", 125c031c93bSTakanori Watanabe "NVRAM", 126c031c93bSTakanori Watanabe "Option ROM Execute", 127c031c93bSTakanori Watanabe "Option ROM Configurateion", 128c031c93bSTakanori Watanabe "<undefined>", 129c031c93bSTakanori Watanabe "Option ROM Microcode Update ", 130c031c93bSTakanori Watanabe "S-CRTM Version String", 131c031c93bSTakanori Watanabe "S-CRTM Contents", 132c031c93bSTakanori Watanabe "POST Contents", 133c031c93bSTakanori Watanabe "Table of Devices", 134c031c93bSTakanori Watanabe }; 135c031c93bSTakanori Watanabe 136ec650989SNeel Natu #define PRINTFLAG_END() printflag_end() 137ec650989SNeel Natu 138ec650989SNeel Natu static char pf_sep = '{'; 139ec650989SNeel Natu 140ec650989SNeel Natu static void 141ec650989SNeel Natu printflag_end(void) 142ec650989SNeel Natu { 143ec650989SNeel Natu 144ec650989SNeel Natu if (pf_sep != '{') { 145ec650989SNeel Natu printf("}"); 146ec650989SNeel Natu pf_sep = '{'; 147ec650989SNeel Natu } 148ec650989SNeel Natu printf("\n"); 149ec650989SNeel Natu } 150ec650989SNeel Natu 151ec650989SNeel Natu static void 152ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name) 153ec650989SNeel Natu { 154ec650989SNeel Natu 155ec650989SNeel Natu if (var & mask) { 156ec650989SNeel Natu printf("%c%s", pf_sep, name); 157ec650989SNeel Natu pf_sep = ','; 158ec650989SNeel Natu } 159ec650989SNeel Natu } 160ec650989SNeel Natu 161e1e9a4bfSMitsuru IWASAKI static void 162e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 163e1e9a4bfSMitsuru IWASAKI { 164e1e9a4bfSMitsuru IWASAKI int c; 165e1e9a4bfSMitsuru IWASAKI 166e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 167e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 168e1e9a4bfSMitsuru IWASAKI length--; 169e1e9a4bfSMitsuru IWASAKI 170e1e9a4bfSMitsuru IWASAKI while (length--) { 171e1e9a4bfSMitsuru IWASAKI c = *s++; 172e1e9a4bfSMitsuru IWASAKI putchar(c); 173e1e9a4bfSMitsuru IWASAKI } 174e1e9a4bfSMitsuru IWASAKI } 175e1e9a4bfSMitsuru IWASAKI 176e1e9a4bfSMitsuru IWASAKI static void 177986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1788e6a8737SNate Lawson { 179986dffafSJohn Baldwin switch(gas->SpaceId) { 1808e6a8737SNate Lawson case ACPI_GAS_MEMORY: 181*ebc22d04SAlexander Motin printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address, 182*ebc22d04SAlexander Motin gas->BitOffset, gas->BitWidth); 1838e6a8737SNate Lawson break; 1848e6a8737SNate Lawson case ACPI_GAS_IO: 185*ebc22d04SAlexander Motin printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address, 186986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1878e6a8737SNate Lawson break; 1888e6a8737SNate Lawson case ACPI_GAS_PCI: 189*ebc22d04SAlexander Motin printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32), 190986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 191*ebc22d04SAlexander Motin (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth); 1928e6a8737SNate Lawson break; 1938e6a8737SNate Lawson /* XXX How to handle these below? */ 1948e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 195986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 196986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1978e6a8737SNate Lawson break; 1988e6a8737SNate Lawson case ACPI_GAS_SMBUS: 199986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 200986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 2018e6a8737SNate Lawson break; 202986dffafSJohn Baldwin case ACPI_GAS_CMOS: 203986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 204986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 2058e6a8737SNate Lawson case ACPI_GAS_FIXED: 2068e6a8737SNate Lawson default: 2077d369c6eSJung-uk Kim printf("0x%016jx (?)", (uintmax_t)gas->Address); 2088e6a8737SNate Lawson break; 2098e6a8737SNate Lawson } 2108e6a8737SNate Lawson } 2118e6a8737SNate Lawson 212c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 213c2962974SNate Lawson static int 214986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 215e1e9a4bfSMitsuru IWASAKI { 216c2962974SNate Lawson int fadt_revision; 217e1e9a4bfSMitsuru IWASAKI 218c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 219c83f0f99SNate Lawson if (addr_size == 8) { 220c83f0f99SNate Lawson fadt_revision = 2; 2218e6a8737SNate Lawson 222773b6454SNate Lawson /* 223c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 224c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 225c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 226c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 227c83f0f99SNate Lawson * version for all subsequent tables. 228773b6454SNate Lawson */ 229986dffafSJohn Baldwin if (fadt->Facs != 0 && 230986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 231c83f0f99SNate Lawson fadt_revision = 1; 232c2962974SNate Lawson } else 233c83f0f99SNate Lawson fadt_revision = 1; 234c2962974SNate Lawson return (fadt_revision); 235c83f0f99SNate Lawson } 236c2962974SNate Lawson 237c2962974SNate Lawson static void 238986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 239c2962974SNate Lawson { 240986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 241986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 242986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 243bc711181SAndrew Turner vm_offset_t addr; 244c2962974SNate Lawson int fadt_revision; 245c2962974SNate Lawson 246986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2472177d4e6SNate Lawson acpi_print_fadt(sdp); 248c83f0f99SNate Lawson 249c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 250c83f0f99SNate Lawson if (fadt_revision == 1) 251bc711181SAndrew Turner addr = fadt->Facs; 252773b6454SNate Lawson else 253bc711181SAndrew Turner addr = fadt->XFacs; 254bc711181SAndrew Turner if (addr != 0) { 255bc711181SAndrew Turner facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr); 256bc711181SAndrew Turner 257bc711181SAndrew Turner if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || 258bc711181SAndrew Turner facs->Length < 64) 2598e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2608e6a8737SNate Lawson acpi_print_facs(facs); 261bc711181SAndrew Turner } 2628e6a8737SNate Lawson 263c83f0f99SNate Lawson if (fadt_revision == 1) 264986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 265773b6454SNate Lawson else 266986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 267986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 268945137d9SNate Lawson errx(1, "DSDT is corrupt"); 269945137d9SNate Lawson acpi_print_dsdt(dsdp); 270c62f1cccSMitsuru IWASAKI } 271c62f1cccSMitsuru IWASAKI 272c62f1cccSMitsuru IWASAKI static void 273986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 274986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 275986dffafSJohn Baldwin { 276986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 277986dffafSJohn Baldwin char *end; 278986dffafSJohn Baldwin 279986dffafSJohn Baldwin subtable = first; 280986dffafSJohn Baldwin end = (char *)table + table->Length; 281986dffafSJohn Baldwin while ((char *)subtable < end) { 282986dffafSJohn Baldwin printf("\n"); 283f5d0a8f7SEd Maste if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) { 284f5d0a8f7SEd Maste warnx("invalid subtable length %u", subtable->Length); 285f5d0a8f7SEd Maste return; 286f5d0a8f7SEd Maste } 287986dffafSJohn Baldwin action(subtable); 288986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 289986dffafSJohn Baldwin subtable->Length); 290986dffafSJohn Baldwin } 291986dffafSJohn Baldwin } 292986dffafSJohn Baldwin 293986dffafSJohn Baldwin static void 294340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 295340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)) 296340c0022SEd Maste { 297340c0022SEd Maste ACPI_NFIT_HEADER *subtable; 298340c0022SEd Maste char *end; 299340c0022SEd Maste 300340c0022SEd Maste subtable = first; 301340c0022SEd Maste end = (char *)table + table->Length; 302340c0022SEd Maste while ((char *)subtable < end) { 303340c0022SEd Maste printf("\n"); 304340c0022SEd Maste if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) { 305340c0022SEd Maste warnx("invalid subtable length %u", subtable->Length); 306340c0022SEd Maste return; 307340c0022SEd Maste } 308340c0022SEd Maste action(subtable); 309340c0022SEd Maste subtable = (ACPI_NFIT_HEADER *)((char *)subtable + 310340c0022SEd Maste subtable->Length); 311340c0022SEd Maste } 312340c0022SEd Maste } 313340c0022SEd Maste 314340c0022SEd Maste static void 3150a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 3160a473124SJohn Baldwin { 3170a473124SJohn Baldwin 3180a473124SJohn Baldwin printf("\tACPI CPU="); 3190a473124SJohn Baldwin if (cpu_id == 0xff) 3200a473124SJohn Baldwin printf("ALL\n"); 3210a473124SJohn Baldwin else 3220a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 3230a473124SJohn Baldwin } 3240a473124SJohn Baldwin 3250a473124SJohn Baldwin static void 326986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 3270a473124SJohn Baldwin { 328986dffafSJohn Baldwin 329986dffafSJohn Baldwin printf("\tUID=%d", uid); 330986dffafSJohn Baldwin if (uid_string != NULL) 331986dffafSJohn Baldwin printf(" (%s)", uid_string); 332986dffafSJohn Baldwin printf("\n"); 333986dffafSJohn Baldwin } 334986dffafSJohn Baldwin 335986dffafSJohn Baldwin static void 336986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 337986dffafSJohn Baldwin { 338986dffafSJohn Baldwin 3390a473124SJohn Baldwin printf("\tFlags={"); 340986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 3410a473124SJohn Baldwin printf("ENABLED"); 3420a473124SJohn Baldwin else 3430a473124SJohn Baldwin printf("DISABLED"); 3440a473124SJohn Baldwin printf("}\n"); 345986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3460a473124SJohn Baldwin } 3470a473124SJohn Baldwin 3480a473124SJohn Baldwin static void 349986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 3500a473124SJohn Baldwin { 351986dffafSJohn Baldwin 352986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3530a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 354986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 3550a473124SJohn Baldwin } 3560a473124SJohn Baldwin 3570a473124SJohn Baldwin static void 358986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 3590a473124SJohn Baldwin { 3600a473124SJohn Baldwin 3610a473124SJohn Baldwin printf("\tFlags={Polarity="); 362986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 363986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 3640a473124SJohn Baldwin printf("conforming"); 3650a473124SJohn Baldwin break; 366986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3670a473124SJohn Baldwin printf("active-hi"); 3680a473124SJohn Baldwin break; 369986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3700a473124SJohn Baldwin printf("active-lo"); 3710a473124SJohn Baldwin break; 3720a473124SJohn Baldwin default: 373986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3740a473124SJohn Baldwin break; 3750a473124SJohn Baldwin } 3760a473124SJohn Baldwin printf(", Trigger="); 377986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 378986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3790a473124SJohn Baldwin printf("conforming"); 3800a473124SJohn Baldwin break; 381986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3820a473124SJohn Baldwin printf("edge"); 3830a473124SJohn Baldwin break; 384986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3850a473124SJohn Baldwin printf("level"); 3860a473124SJohn Baldwin break; 3870a473124SJohn Baldwin default: 388986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3890a473124SJohn Baldwin } 3900a473124SJohn Baldwin printf("}\n"); 3910a473124SJohn Baldwin } 3920a473124SJohn Baldwin 3930a473124SJohn Baldwin static void 3942b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags) 3952b2b1f42SAndrew Turner { 3962b2b1f42SAndrew Turner 3972b2b1f42SAndrew Turner printf("\tFlags={Performance intr="); 3982b2b1f42SAndrew Turner if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE) 3992b2b1f42SAndrew Turner printf("edge"); 4002b2b1f42SAndrew Turner else 4012b2b1f42SAndrew Turner printf("level"); 4022b2b1f42SAndrew Turner printf(", VGIC intr="); 4032b2b1f42SAndrew Turner if (flags & ACPI_MADT_VGIC_IRQ_MODE) 4042b2b1f42SAndrew Turner printf("edge"); 4052b2b1f42SAndrew Turner else 4062b2b1f42SAndrew Turner printf("level"); 4072b2b1f42SAndrew Turner printf("}\n"); 4082b2b1f42SAndrew Turner } 4092b2b1f42SAndrew Turner 4102b2b1f42SAndrew Turner static void 411986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 4120a473124SJohn Baldwin { 4130a473124SJohn Baldwin 414986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 415986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 416986dffafSJohn Baldwin } 417986dffafSJohn Baldwin 418986dffafSJohn Baldwin static void 419986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 420986dffafSJohn Baldwin { 421986dffafSJohn Baldwin 422986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 4230a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 4240a473124SJohn Baldwin } 4250a473124SJohn Baldwin 42627941afaSEd Maste static const char *apic_types[] = { 42727941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC", 42827941afaSEd Maste [ACPI_MADT_TYPE_IO_APIC] = "IO APIC", 42927941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override", 43027941afaSEd Maste [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI", 43127941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI", 43227941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override", 43327941afaSEd Maste [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC", 43427941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC", 43527941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt", 43627941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC", 43727941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI", 43827941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure", 43927941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure", 44027941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame", 44127941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure", 44227941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure" 44327941afaSEd Maste }; 44427941afaSEd Maste 445bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 4460a473124SJohn Baldwin "Corrected Platform Error" }; 4470a473124SJohn Baldwin 4480a473124SJohn Baldwin static void 449986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 4500a473124SJohn Baldwin { 451986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 452986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 453986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 454986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 455986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 456986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 457986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 458986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 459986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 460986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 461986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 4622b2b1f42SAndrew Turner ACPI_MADT_GENERIC_INTERRUPT *gicc; 4632b2b1f42SAndrew Turner ACPI_MADT_GENERIC_DISTRIBUTOR *gicd; 4642b2b1f42SAndrew Turner ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr; 4652b2b1f42SAndrew Turner ACPI_MADT_GENERIC_TRANSLATOR *gict; 4660a473124SJohn Baldwin 467c86932b6SMarcelo Araujo if (mp->Type < nitems(apic_types)) 468986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 469a0333ad1SJohn Baldwin else 470986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 471986dffafSJohn Baldwin switch (mp->Type) { 472986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 473986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 474986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 475986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 4760a473124SJohn Baldwin break; 477986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 478986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 479986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 480986dffafSJohn Baldwin ioapic->Address); 4810a473124SJohn Baldwin break; 482986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 483986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 484986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 485986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 486986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 4870a473124SJohn Baldwin break; 488986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 489986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 490986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 4910a473124SJohn Baldwin break; 492986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 493986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 494986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 495986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 4960a473124SJohn Baldwin break; 497986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 498986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 499945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 500986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 5010a473124SJohn Baldwin break; 502986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 503986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 504986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 505986dffafSJohn Baldwin iosapic->Address); 5060a473124SJohn Baldwin break; 507986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 508986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 509986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 510986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 511986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 512986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 513986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 5140a473124SJohn Baldwin break; 515986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 516986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 517c86932b6SMarcelo Araujo if (isrc->Type < nitems(platform_int_types)) 518986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 519986dffafSJohn Baldwin else 520986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 521986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 522986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 523986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 524986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 525986dffafSJohn Baldwin break; 526986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 527986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 528986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 529986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 530986dffafSJohn Baldwin break; 531986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 532986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 533986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 534986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 5350a473124SJohn Baldwin break; 5362b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 5372b2b1f42SAndrew Turner gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp; 5382b2b1f42SAndrew Turner acpi_print_cpu_uid(gicc->Uid, NULL); 5392b2b1f42SAndrew Turner printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber); 5402b2b1f42SAndrew Turner acpi_print_gicc_flags(gicc->Flags); 5412b2b1f42SAndrew Turner printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion); 5422b2b1f42SAndrew Turner printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt); 5432b2b1f42SAndrew Turner printf("\tParked ADDR=%016jx\n", 5442b2b1f42SAndrew Turner (uintmax_t)gicc->ParkedAddress); 5452b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress); 5462b2b1f42SAndrew Turner printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress); 5472b2b1f42SAndrew Turner printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress); 5482b2b1f42SAndrew Turner printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt); 5492b2b1f42SAndrew Turner printf("\tGICR ADDR=%016jx\n", 5502b2b1f42SAndrew Turner (uintmax_t)gicc->GicrBaseAddress); 5512b2b1f42SAndrew Turner printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr); 5522b2b1f42SAndrew Turner printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass); 5532b2b1f42SAndrew Turner break; 5542b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 5552b2b1f42SAndrew Turner gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp; 5562b2b1f42SAndrew Turner printf("\tGIC ID=%d\n", (u_int)gicd->GicId); 5572b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress); 5582b2b1f42SAndrew Turner printf("\tVector Base=%d\n", gicd->GlobalIrqBase); 5592b2b1f42SAndrew Turner printf("\tGIC VERSION=%d\n", (u_int)gicd->Version); 5602b2b1f42SAndrew Turner break; 5612b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 5622b2b1f42SAndrew Turner gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp; 5632b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress); 5642b2b1f42SAndrew Turner printf("\tLength=%08x\n", gicr->Length); 5652b2b1f42SAndrew Turner break; 5662b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 5672b2b1f42SAndrew Turner gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp; 5682b2b1f42SAndrew Turner printf("\tGIC ITS ID=%d\n", gict->TranslationId); 5692b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress); 5702b2b1f42SAndrew Turner break; 5710a473124SJohn Baldwin } 5720a473124SJohn Baldwin } 5730a473124SJohn Baldwin 5740a473124SJohn Baldwin static void 575986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 5760a473124SJohn Baldwin { 577986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 5780a473124SJohn Baldwin 579773b6454SNate Lawson printf(BEGIN_COMMENT); 580773b6454SNate Lawson acpi_print_sdt(sdp); 581986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 582986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 5830a473124SJohn Baldwin printf("\tFlags={"); 584986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 5850a473124SJohn Baldwin printf("PC-AT"); 5860a473124SJohn Baldwin printf("}\n"); 587986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 5880a473124SJohn Baldwin printf(END_COMMENT); 5890a473124SJohn Baldwin } 5900a473124SJohn Baldwin 5910a473124SJohn Baldwin static void 592*ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp) 593*ebc22d04SAlexander Motin { 594*ebc22d04SAlexander Motin ACPI_TABLE_BERT *bert; 595*ebc22d04SAlexander Motin 596*ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 597*ebc22d04SAlexander Motin acpi_print_sdt(sdp); 598*ebc22d04SAlexander Motin bert = (ACPI_TABLE_BERT *)sdp; 599*ebc22d04SAlexander Motin printf("\tRegionLength=%d\n", bert->RegionLength); 600*ebc22d04SAlexander Motin printf("\tAddress=0x%016jx\n", bert->Address); 601*ebc22d04SAlexander Motin printf(END_COMMENT); 602*ebc22d04SAlexander Motin } 603*ebc22d04SAlexander Motin 604*ebc22d04SAlexander Motin static void 605*ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w) 606*ebc22d04SAlexander Motin { 607*ebc22d04SAlexander Motin 608*ebc22d04SAlexander Motin printf("\n\tAction=%d\n", w->Action); 609*ebc22d04SAlexander Motin printf("\tInstruction=%d\n", w->Instruction); 610*ebc22d04SAlexander Motin printf("\tFlags=%02x\n", w->Flags); 611*ebc22d04SAlexander Motin printf("\tRegisterRegion="); 612*ebc22d04SAlexander Motin acpi_print_gas(&w->RegisterRegion); 613*ebc22d04SAlexander Motin printf("\n\tValue=0x%016jx\n", w->Value); 614*ebc22d04SAlexander Motin printf("\tMask=0x%016jx\n", w->Mask); 615*ebc22d04SAlexander Motin } 616*ebc22d04SAlexander Motin 617*ebc22d04SAlexander Motin static void 618*ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp) 619*ebc22d04SAlexander Motin { 620*ebc22d04SAlexander Motin ACPI_TABLE_EINJ *einj; 621*ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w; 622*ebc22d04SAlexander Motin u_int i; 623*ebc22d04SAlexander Motin 624*ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 625*ebc22d04SAlexander Motin acpi_print_sdt(sdp); 626*ebc22d04SAlexander Motin einj = (ACPI_TABLE_EINJ *)sdp; 627*ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", einj->HeaderLength); 628*ebc22d04SAlexander Motin printf("\tFlags=0x%02x\n", einj->Flags); 629*ebc22d04SAlexander Motin printf("\tEntries=%d\n", einj->Entries); 630*ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(einj + 1); 631*ebc22d04SAlexander Motin for (i = 0; i < MIN(einj->Entries, (sdp->Length - 632*ebc22d04SAlexander Motin sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++) 633*ebc22d04SAlexander Motin acpi_print_whea(w + i); 634*ebc22d04SAlexander Motin printf(END_COMMENT); 635*ebc22d04SAlexander Motin } 636*ebc22d04SAlexander Motin 637*ebc22d04SAlexander Motin static void 638*ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp) 639*ebc22d04SAlexander Motin { 640*ebc22d04SAlexander Motin ACPI_TABLE_ERST *erst; 641*ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w; 642*ebc22d04SAlexander Motin u_int i; 643*ebc22d04SAlexander Motin 644*ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 645*ebc22d04SAlexander Motin acpi_print_sdt(sdp); 646*ebc22d04SAlexander Motin erst = (ACPI_TABLE_ERST *)sdp; 647*ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", erst->HeaderLength); 648*ebc22d04SAlexander Motin printf("\tEntries=%d\n", erst->Entries); 649*ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(erst + 1); 650*ebc22d04SAlexander Motin for (i = 0; i < MIN(erst->Entries, (sdp->Length - 651*ebc22d04SAlexander Motin sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++) 652*ebc22d04SAlexander Motin acpi_print_whea(w + i); 653*ebc22d04SAlexander Motin printf(END_COMMENT); 654*ebc22d04SAlexander Motin } 655*ebc22d04SAlexander Motin 656*ebc22d04SAlexander Motin static void 657*ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b) 658*ebc22d04SAlexander Motin { 659*ebc22d04SAlexander Motin 660*ebc22d04SAlexander Motin printf("\tBank:\n"); 661*ebc22d04SAlexander Motin printf("\t\tBankNumber=%d\n", b->BankNumber); 662*ebc22d04SAlexander Motin printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit); 663*ebc22d04SAlexander Motin printf("\t\tStatusFormat=%d\n", b->StatusFormat); 664*ebc22d04SAlexander Motin printf("\t\tControlRegister=%x\n", b->ControlRegister); 665*ebc22d04SAlexander Motin printf("\t\tControlData=%jx\n", b->ControlData); 666*ebc22d04SAlexander Motin printf("\t\tStatusRegister=%x\n", b->StatusRegister); 667*ebc22d04SAlexander Motin printf("\t\tAddressRegister=%x\n", b->AddressRegister); 668*ebc22d04SAlexander Motin printf("\t\tMiscRegister=%x\n", b->MiscRegister); 669*ebc22d04SAlexander Motin } 670*ebc22d04SAlexander Motin 671*ebc22d04SAlexander Motin static void 672*ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n) 673*ebc22d04SAlexander Motin { 674*ebc22d04SAlexander Motin 675*ebc22d04SAlexander Motin printf("\t\tType=%d\n", n->Type); 676*ebc22d04SAlexander Motin printf("\t\tLength=%d\n", n->Length); 677*ebc22d04SAlexander Motin printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable); 678*ebc22d04SAlexander Motin printf("\t\tPollInterval=%d\n", n->PollInterval); 679*ebc22d04SAlexander Motin printf("\t\tVector=%d\n", n->Vector); 680*ebc22d04SAlexander Motin printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue); 681*ebc22d04SAlexander Motin printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow); 682*ebc22d04SAlexander Motin printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue); 683*ebc22d04SAlexander Motin printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow); 684*ebc22d04SAlexander Motin } 685*ebc22d04SAlexander Motin 686*ebc22d04SAlexander Motin static void 687*ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a) 688*ebc22d04SAlexander Motin { 689*ebc22d04SAlexander Motin 690*ebc22d04SAlexander Motin printf("\tFlags=%02x\n", a->Flags); 691*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", a->Enabled); 692*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate); 693*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord); 694*ebc22d04SAlexander Motin printf("\tBus=%d\n", a->Bus); 695*ebc22d04SAlexander Motin printf("\tDevice=%d\n", a->Device); 696*ebc22d04SAlexander Motin printf("\tFunction=%d\n", a->Function); 697*ebc22d04SAlexander Motin printf("\tDeviceControl=%d\n", a->DeviceControl); 698*ebc22d04SAlexander Motin printf("\tUncorrectableMask=%d\n", a->UncorrectableMask); 699*ebc22d04SAlexander Motin printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity); 700*ebc22d04SAlexander Motin printf("\tCorrectableMask=%d\n", a->CorrectableMask); 701*ebc22d04SAlexander Motin printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities); 702*ebc22d04SAlexander Motin } 703*ebc22d04SAlexander Motin 704*ebc22d04SAlexander Motin static int 705*ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining) 706*ebc22d04SAlexander Motin { 707*ebc22d04SAlexander Motin ACPI_HEST_HEADER *hdr = addr; 708*ebc22d04SAlexander Motin int i; 709*ebc22d04SAlexander Motin 710*ebc22d04SAlexander Motin if (remaining < (int)sizeof(ACPI_HEST_HEADER)) 711*ebc22d04SAlexander Motin return (-1); 712*ebc22d04SAlexander Motin 713*ebc22d04SAlexander Motin printf("\n\tType=%d\n", hdr->Type); 714*ebc22d04SAlexander Motin printf("\tSourceId=%d\n", hdr->SourceId); 715*ebc22d04SAlexander Motin switch (hdr->Type) { 716*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CHECK: { 717*ebc22d04SAlexander Motin ACPI_HEST_IA_MACHINE_CHECK *s = addr; 718*ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 719*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 720*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 721*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 722*ebc22d04SAlexander Motin printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData); 723*ebc22d04SAlexander Motin printf("\tGlobalControlData=%jd\n", s->GlobalControlData); 724*ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 725*ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 726*ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 727*ebc22d04SAlexander Motin (s + 1) + i); 728*ebc22d04SAlexander Motin } 729*ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 730*ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 731*ebc22d04SAlexander Motin } 732*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: { 733*ebc22d04SAlexander Motin ACPI_HEST_IA_CORRECTED *s = addr; 734*ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 735*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 736*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 737*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 738*ebc22d04SAlexander Motin printf("\tNotify:\n"); 739*ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 740*ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 741*ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 742*ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 743*ebc22d04SAlexander Motin (s + 1) + i); 744*ebc22d04SAlexander Motin } 745*ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 746*ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 747*ebc22d04SAlexander Motin } 748*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_NMI: { 749*ebc22d04SAlexander Motin ACPI_HEST_IA_NMI *s = addr; 750*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 751*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 752*ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 753*ebc22d04SAlexander Motin return (sizeof(*s)); 754*ebc22d04SAlexander Motin } 755*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ROOT_PORT: { 756*ebc22d04SAlexander Motin ACPI_HEST_AER_ROOT *s = addr; 757*ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 758*ebc22d04SAlexander Motin printf("\tRootErrorCommand=%d\n", s->RootErrorCommand); 759*ebc22d04SAlexander Motin return (sizeof(*s)); 760*ebc22d04SAlexander Motin } 761*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ENDPOINT: { 762*ebc22d04SAlexander Motin ACPI_HEST_AER *s = addr; 763*ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 764*ebc22d04SAlexander Motin return (sizeof(*s)); 765*ebc22d04SAlexander Motin } 766*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_BRIDGE: { 767*ebc22d04SAlexander Motin ACPI_HEST_AER_BRIDGE *s = addr; 768*ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 769*ebc22d04SAlexander Motin printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2); 770*ebc22d04SAlexander Motin printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2); 771*ebc22d04SAlexander Motin printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2); 772*ebc22d04SAlexander Motin return (sizeof(*s)); 773*ebc22d04SAlexander Motin } 774*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR: { 775*ebc22d04SAlexander Motin ACPI_HEST_GENERIC *s = addr; 776*ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId); 777*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 778*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 779*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 780*ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 781*ebc22d04SAlexander Motin printf("\tErrorStatusAddress="); 782*ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress); 783*ebc22d04SAlexander Motin printf("\n"); 784*ebc22d04SAlexander Motin printf("\tNotify:\n"); 785*ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 786*ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength); 787*ebc22d04SAlexander Motin return (sizeof(*s)); 788*ebc22d04SAlexander Motin } 789*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR_V2: { 790*ebc22d04SAlexander Motin ACPI_HEST_GENERIC_V2 *s = addr; 791*ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId); 792*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 793*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 794*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 795*ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 796*ebc22d04SAlexander Motin printf("\tErrorStatusAddress="); 797*ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress); 798*ebc22d04SAlexander Motin printf("\n"); 799*ebc22d04SAlexander Motin printf("\tNotify:\n"); 800*ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 801*ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength); 802*ebc22d04SAlexander Motin printf("\tReadAckRegister="); 803*ebc22d04SAlexander Motin acpi_print_gas(&s->ReadAckRegister); 804*ebc22d04SAlexander Motin printf("\n"); 805*ebc22d04SAlexander Motin printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve); 806*ebc22d04SAlexander Motin printf("\tReadAckWrite=%jd\n", s->ReadAckWrite); 807*ebc22d04SAlexander Motin return (sizeof(*s)); 808*ebc22d04SAlexander Motin } 809*ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: { 810*ebc22d04SAlexander Motin ACPI_HEST_IA_DEFERRED_CHECK *s = addr; 811*ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 812*ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 813*ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 814*ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 815*ebc22d04SAlexander Motin printf("\tNotify:\n"); 816*ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 817*ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 818*ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 819*ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 820*ebc22d04SAlexander Motin (s + 1) + i); 821*ebc22d04SAlexander Motin } 822*ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 823*ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 824*ebc22d04SAlexander Motin } 825*ebc22d04SAlexander Motin default: 826*ebc22d04SAlexander Motin return (-1); 827*ebc22d04SAlexander Motin } 828*ebc22d04SAlexander Motin } 829*ebc22d04SAlexander Motin 830*ebc22d04SAlexander Motin static void 831*ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp) 832*ebc22d04SAlexander Motin { 833*ebc22d04SAlexander Motin char *cp; 834*ebc22d04SAlexander Motin int remaining, consumed; 835*ebc22d04SAlexander Motin ACPI_TABLE_HEST *hest; 836*ebc22d04SAlexander Motin 837*ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 838*ebc22d04SAlexander Motin acpi_print_sdt(sdp); 839*ebc22d04SAlexander Motin hest = (ACPI_TABLE_HEST *)sdp; 840*ebc22d04SAlexander Motin printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount); 841*ebc22d04SAlexander Motin 842*ebc22d04SAlexander Motin remaining = sdp->Length - sizeof(ACPI_TABLE_HEST); 843*ebc22d04SAlexander Motin while (remaining > 0) { 844*ebc22d04SAlexander Motin cp = (char *)sdp + sdp->Length - remaining; 845*ebc22d04SAlexander Motin consumed = acpi_handle_hest_structure(cp, remaining); 846*ebc22d04SAlexander Motin if (consumed <= 0) 847*ebc22d04SAlexander Motin break; 848*ebc22d04SAlexander Motin else 849*ebc22d04SAlexander Motin remaining -= consumed; 850*ebc22d04SAlexander Motin } 851*ebc22d04SAlexander Motin printf(END_COMMENT); 852*ebc22d04SAlexander Motin } 853*ebc22d04SAlexander Motin 854*ebc22d04SAlexander Motin static void 855986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 85679d7565cSPeter Wemm { 857986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 85879d7565cSPeter Wemm 859773b6454SNate Lawson printf(BEGIN_COMMENT); 860773b6454SNate Lawson acpi_print_sdt(sdp); 861986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 862986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 86387f9f09aSTakanori Watanabe printf("\tADDR="); 864986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 865*ebc22d04SAlexander Motin printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 866986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 867986dffafSJohn Baldwin 8); 868986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 869986dffafSJohn Baldwin 1 : 0); 87079d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 871986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 87279d7565cSPeter Wemm printf("TRUE}\n"); 87379d7565cSPeter Wemm else 87479d7565cSPeter Wemm printf("FALSE}\n"); 875986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 876986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 8779785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags); 87879d7565cSPeter Wemm printf(END_COMMENT); 87979d7565cSPeter Wemm } 88079d7565cSPeter Wemm 88179d7565cSPeter Wemm static void 882986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 88355d7ff9eSNate Lawson { 884986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 88555d7ff9eSNate Lawson 88655d7ff9eSNate Lawson printf(BEGIN_COMMENT); 88755d7ff9eSNate Lawson acpi_print_sdt(sdp); 888986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 88955d7ff9eSNate Lawson printf("\tEC_CONTROL="); 890986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 89155d7ff9eSNate Lawson printf("\n\tEC_DATA="); 892986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 893986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 894986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 895986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 89655d7ff9eSNate Lawson printf(END_COMMENT); 89755d7ff9eSNate Lawson } 89855d7ff9eSNate Lawson 89955d7ff9eSNate Lawson static void 900986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 901a47e681bSScott Long { 902986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 903986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 904986dffafSJohn Baldwin u_int i, entries; 905a47e681bSScott Long 906a47e681bSScott Long printf(BEGIN_COMMENT); 907a47e681bSScott Long acpi_print_sdt(sdp); 908986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 909986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 910986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 911986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 912986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 913a47e681bSScott Long printf("\n"); 9140c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address); 915986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 916986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 917986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 918a47e681bSScott Long } 919a47e681bSScott Long printf(END_COMMENT); 920a47e681bSScott Long } 921a47e681bSScott Long 922a47e681bSScott Long static void 92333866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 92433866658SJohn Baldwin { 92533866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 92633866658SJohn Baldwin UINT64 i, j; 92733866658SJohn Baldwin 92833866658SJohn Baldwin printf(BEGIN_COMMENT); 92933866658SJohn Baldwin acpi_print_sdt(sdp); 93033866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 9310c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount); 93233866658SJohn Baldwin printf("\n\t "); 93333866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 9340c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i); 93533866658SJohn Baldwin printf("\n\t +"); 93633866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 93733866658SJohn Baldwin printf("----"); 93833866658SJohn Baldwin printf("\n"); 93933866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 9400c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i); 94133866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 94233866658SJohn Baldwin printf(" %3d", 94333866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 94433866658SJohn Baldwin printf("\n"); 94533866658SJohn Baldwin } 94633866658SJohn Baldwin printf(END_COMMENT); 94733866658SJohn Baldwin } 94833866658SJohn Baldwin 94933866658SJohn Baldwin static void 950ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp) 951ed26c389SScott Long { 952ed26c389SScott Long ACPI_TABLE_WDDT *wddt; 953ed26c389SScott Long 954ed26c389SScott Long printf(BEGIN_COMMENT); 955ed26c389SScott Long acpi_print_sdt(sdp); 956ed26c389SScott Long wddt = (ACPI_TABLE_WDDT *)sdp; 957ed26c389SScott Long printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n", 958ed26c389SScott Long wddt->SpecVersion, wddt->TableVersion); 959ed26c389SScott Long printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId); 960ed26c389SScott Long acpi_print_gas(&wddt->Address); 961ed26c389SScott Long printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n", 962ed26c389SScott Long wddt->MaxCount, wddt->MinCount, wddt->Period); 963ed26c389SScott Long 964ed26c389SScott Long #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag) 965ed26c389SScott Long printf("\tStatus="); 966ed26c389SScott Long PRINTFLAG(wddt->Status, AVAILABLE); 967ed26c389SScott Long PRINTFLAG(wddt->Status, ACTIVE); 968ed26c389SScott Long PRINTFLAG(wddt->Status, TCO_OS_OWNED); 969ed26c389SScott Long PRINTFLAG(wddt->Status, USER_RESET); 970ed26c389SScott Long PRINTFLAG(wddt->Status, WDT_RESET); 971ed26c389SScott Long PRINTFLAG(wddt->Status, POWER_FAIL); 972ed26c389SScott Long PRINTFLAG(wddt->Status, UNKNOWN_RESET); 973ed26c389SScott Long PRINTFLAG_END(); 974ed26c389SScott Long printf("\tCapability="); 975ed26c389SScott Long PRINTFLAG(wddt->Capability, AUTO_RESET); 976ed26c389SScott Long PRINTFLAG(wddt->Capability, ALERT_SUPPORT); 977ed26c389SScott Long PRINTFLAG_END(); 978ed26c389SScott Long #undef PRINTFLAG 979ed26c389SScott Long 980ed26c389SScott Long printf(END_COMMENT); 981ed26c389SScott Long } 982ed26c389SScott Long 983ed26c389SScott Long static void 9845857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl) 9855857fba5SBen Widawsky { 9865857fba5SBen Widawsky printf("\tEntryTrigger="); 9875857fba5SBen Widawsky acpi_print_gas(&nl->EntryTrigger); 988*ebc22d04SAlexander Motin printf("\n\tResidency=%u\n", nl->Residency); 9895857fba5SBen Widawsky printf("\tLatency=%u\n", nl->Latency); 9905857fba5SBen Widawsky if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER) 9915857fba5SBen Widawsky printf("\tResidencyCounter=Not Present"); 9925857fba5SBen Widawsky else { 9935857fba5SBen Widawsky printf("\tResidencyCounter="); 9945857fba5SBen Widawsky acpi_print_gas(&nl->ResidencyCounter); 995*ebc22d04SAlexander Motin printf("\n"); 9965857fba5SBen Widawsky } 9975857fba5SBen Widawsky if (nl->CounterFrequency) 9985857fba5SBen Widawsky printf("\tCounterFrequency=%ju\n", nl->CounterFrequency); 9995857fba5SBen Widawsky else 10005857fba5SBen Widawsky printf("\tCounterFrequency=TSC\n"); 10015857fba5SBen Widawsky } 10025857fba5SBen Widawsky 10035857fba5SBen Widawsky static void 10045857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit) 10055857fba5SBen Widawsky { 10065857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE) 10075857fba5SBen Widawsky printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n"); 10085857fba5SBen Widawsky else 10095857fba5SBen Widawsky warnx("unknown LPIT type %u", lpit->Type); 10105857fba5SBen Widawsky 10115857fba5SBen Widawsky printf("\tLength=%u\n", lpit->Length); 10125857fba5SBen Widawsky printf("\tUniqueId=0x%04x\n", lpit->UniqueId); 10135857fba5SBen Widawsky #define PRINTFLAG(var, flag) printflag((var), ACPI_LPIT_## flag, #flag) 10145857fba5SBen Widawsky printf("\tFlags="); 10155857fba5SBen Widawsky PRINTFLAG(lpit->Flags, STATE_DISABLED); 10165857fba5SBen Widawsky PRINTFLAG_END(); 10175857fba5SBen Widawsky #undef PRINTFLAG 10185857fba5SBen Widawsky 10195857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE) 10205857fba5SBen Widawsky return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit); 10215857fba5SBen Widawsky } 10225857fba5SBen Widawsky 10235857fba5SBen Widawsky static void 10245857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first, 10255857fba5SBen Widawsky void (*action)(ACPI_LPIT_HEADER *)) 10265857fba5SBen Widawsky { 10275857fba5SBen Widawsky ACPI_LPIT_HEADER *subtable; 10285857fba5SBen Widawsky char *end; 10295857fba5SBen Widawsky 10305857fba5SBen Widawsky subtable = first; 10315857fba5SBen Widawsky end = (char *)table + table->Length; 10325857fba5SBen Widawsky while ((char *)subtable < end) { 10335857fba5SBen Widawsky printf("\n"); 10345857fba5SBen Widawsky if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) { 10355857fba5SBen Widawsky warnx("invalid subtable length %u", subtable->Length); 10365857fba5SBen Widawsky return; 10375857fba5SBen Widawsky } 10385857fba5SBen Widawsky action(subtable); 10395857fba5SBen Widawsky subtable = (ACPI_LPIT_HEADER *)((char *)subtable + 10405857fba5SBen Widawsky subtable->Length); 10415857fba5SBen Widawsky } 10425857fba5SBen Widawsky } 10435857fba5SBen Widawsky 10445857fba5SBen Widawsky static void 10455857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp) 10465857fba5SBen Widawsky { 10475857fba5SBen Widawsky ACPI_TABLE_LPIT *lpit; 10485857fba5SBen Widawsky 10495857fba5SBen Widawsky printf(BEGIN_COMMENT); 10505857fba5SBen Widawsky acpi_print_sdt(sdp); 10515857fba5SBen Widawsky lpit = (ACPI_TABLE_LPIT *)sdp; 10525857fba5SBen Widawsky acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit); 10535857fba5SBen Widawsky 10545857fba5SBen Widawsky printf(END_COMMENT); 10555857fba5SBen Widawsky } 10565857fba5SBen Widawsky 10575857fba5SBen Widawsky static void 1058a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 1059a0333ad1SJohn Baldwin uint32_t flags) 1060a0333ad1SJohn Baldwin { 1061a0333ad1SJohn Baldwin 1062a0333ad1SJohn Baldwin printf("\tFlags={"); 1063a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 1064a0333ad1SJohn Baldwin printf("ENABLED"); 1065a0333ad1SJohn Baldwin else 1066a0333ad1SJohn Baldwin printf("DISABLED"); 1067a0333ad1SJohn Baldwin printf("}\n"); 1068a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 1069a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 1070a0333ad1SJohn Baldwin } 1071a0333ad1SJohn Baldwin 1072c031c93bSTakanori Watanabe static char * 1073c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 1074c031c93bSTakanori Watanabe { 1075c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 1076c031c93bSTakanori Watanabe char *eventname = NULL; 1077c031c93bSTakanori Watanabe 1078c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 1079c031c93bSTakanori Watanabe 1080c031c93bSTakanori Watanabe switch(event->event_type) { 1081c031c93bSTakanori Watanabe case PREBOOT: 1082c031c93bSTakanori Watanabe case POST_CODE: 1083c031c93bSTakanori Watanabe case UNUSED: 1084c031c93bSTakanori Watanabe case NO_ACTION: 1085c031c93bSTakanori Watanabe case SEPARATOR: 1086c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 1087c031c93bSTakanori Watanabe case SCRTM_VERSION: 1088c031c93bSTakanori Watanabe case CPU_MICROCODE: 1089c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 1090c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 1091c031c93bSTakanori Watanabe case COMPACT_HASH: 1092c031c93bSTakanori Watanabe case IPL: 1093c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 1094c031c93bSTakanori Watanabe case NONHOST_CODE: 1095c031c93bSTakanori Watanabe case NONHOST_CONFIG: 1096c031c93bSTakanori Watanabe case NONHOST_INFO: 1097c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 1098c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 1099c031c93bSTakanori Watanabe break; 1100c031c93bSTakanori Watanabe 1101c031c93bSTakanori Watanabe case ACTION: 1102c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 1103c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 1104c031c93bSTakanori Watanabe break; 1105c031c93bSTakanori Watanabe 1106c031c93bSTakanori Watanabe case EVENT_TAG: 1107c031c93bSTakanori Watanabe switch (pc_event->event_id) { 1108c031c93bSTakanori Watanabe case SMBIOS: 1109c031c93bSTakanori Watanabe case BIS_CERT: 1110c031c93bSTakanori Watanabe case CMOS: 1111c031c93bSTakanori Watanabe case NVRAM: 1112c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 1113c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 1114c031c93bSTakanori Watanabe case S_CRTM_VERSION: 1115c031c93bSTakanori Watanabe case POST_BIOS_ROM: 1116c031c93bSTakanori Watanabe case ESCD: 1117c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 1118c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 1119c031c93bSTakanori Watanabe case POST_CONTENTS: 1120c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 1121c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 1122c031c93bSTakanori Watanabe break; 1123c031c93bSTakanori Watanabe 1124c031c93bSTakanori Watanabe default: 1125c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 1126c031c93bSTakanori Watanabe pc_event->event_id); 1127c031c93bSTakanori Watanabe break; 1128c031c93bSTakanori Watanabe } 1129c031c93bSTakanori Watanabe break; 1130c031c93bSTakanori Watanabe 1131c031c93bSTakanori Watanabe default: 1132c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 1133c031c93bSTakanori Watanabe break; 1134c031c93bSTakanori Watanabe } 1135c031c93bSTakanori Watanabe 1136c031c93bSTakanori Watanabe return eventname; 1137c031c93bSTakanori Watanabe } 1138c031c93bSTakanori Watanabe 1139c031c93bSTakanori Watanabe static void 1140c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 1141c031c93bSTakanori Watanabe { 1142c031c93bSTakanori Watanabe int i; 1143c031c93bSTakanori Watanabe char *eventname; 1144c031c93bSTakanori Watanabe 1145c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 1146c031c93bSTakanori Watanabe 1147c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 1148c031c93bSTakanori Watanabe printf(" 0x"); 1149c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 1150c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 1151c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 1152c031c93bSTakanori Watanabe 1153c031c93bSTakanori Watanabe free(eventname); 1154c031c93bSTakanori Watanabe } 1155c031c93bSTakanori Watanabe 1156c031c93bSTakanori Watanabe static void 1157c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 1158c031c93bSTakanori Watanabe { 1159c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 1160c031c93bSTakanori Watanabe struct TCPAevent *event; 1161977fd9daSTakanori Watanabe uintmax_t len, paddr; 1162c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 1163c031c93bSTakanori Watanabe unsigned char *vend = NULL; 1164c031c93bSTakanori Watanabe 1165c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 1166c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 1167c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 1168c031c93bSTakanori Watanabe 1169c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 1170c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 1171c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 1172c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 1173c031c93bSTakanori Watanabe break; 1174c031c93bSTakanori Watanabe 1175c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 1176c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 1177c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 1178c031c93bSTakanori Watanabe break; 1179c031c93bSTakanori Watanabe 1180c031c93bSTakanori Watanabe default: 1181c031c93bSTakanori Watanabe printf("XXX"); 1182c031c93bSTakanori Watanabe printf(END_COMMENT); 1183c031c93bSTakanori Watanabe return; 1184c031c93bSTakanori Watanabe } 11850e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 1186c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 1187c031c93bSTakanori Watanabe 1188c031c93bSTakanori Watanabe if (len == 0) { 1189c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 1190c031c93bSTakanori Watanabe printf(END_COMMENT); 1191c031c93bSTakanori Watanabe return; 1192c031c93bSTakanori Watanabe } 11932ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 11942ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 11952ef23c6dSTakanori Watanabe printf(END_COMMENT); 11962ef23c6dSTakanori Watanabe return; 11972ef23c6dSTakanori Watanabe } 1198c031c93bSTakanori Watanabe 1199c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 1200c031c93bSTakanori Watanabe vend = vaddr + len; 1201c031c93bSTakanori Watanabe 1202c031c93bSTakanori Watanabe while (vaddr != NULL) { 12032ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 12042ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 1205c031c93bSTakanori Watanabe break; 12060e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 1207c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 1208c031c93bSTakanori Watanabe break; 12092ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 12102ef23c6dSTakanori Watanabe break; 1211c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 1212c031c93bSTakanori Watanabe break; 1213c031c93bSTakanori Watanabe #if 0 1214c031c93bSTakanori Watanabe { 1215c031c93bSTakanori Watanabe unsigned int i, j, k; 1216c031c93bSTakanori Watanabe 1217c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 1218c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 1219c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 1220c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 1221c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 1222c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 1223c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 1224c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 1225c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 1226c031c93bSTakanori Watanabe j = i + 1; 1227c031c93bSTakanori Watanabe } 1228c031c93bSTakanori Watanabe } 1229c031c93bSTakanori Watanabe printf("\n"); } 1230c031c93bSTakanori Watanabe #endif 1231c031c93bSTakanori Watanabe acpi_print_tcpa(event); 1232c031c93bSTakanori Watanabe 1233c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 1234c031c93bSTakanori Watanabe } 1235c031c93bSTakanori Watanabe 1236c031c93bSTakanori Watanabe printf(END_COMMENT); 1237c031c93bSTakanori Watanabe } 1238877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp) 1239877fc2e3STakanori Watanabe { 1240877fc2e3STakanori Watanabe ACPI_TABLE_TPM2 *tpm2; 1241877fc2e3STakanori Watanabe 1242877fc2e3STakanori Watanabe printf (BEGIN_COMMENT); 1243877fc2e3STakanori Watanabe acpi_print_sdt(sdp); 1244877fc2e3STakanori Watanabe tpm2 = (ACPI_TABLE_TPM2 *) sdp; 12457aef7138SCy Schubert printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress); 1246877fc2e3STakanori Watanabe printf ("\t\tStartMethod=%x\n", tpm2->StartMethod); 1247877fc2e3STakanori Watanabe printf (END_COMMENT); 1248877fc2e3STakanori Watanabe } 1249c031c93bSTakanori Watanabe 1250ec650989SNeel Natu static const char * 1251ec650989SNeel Natu devscope_type2str(int type) 1252ec650989SNeel Natu { 1253ec650989SNeel Natu static char typebuf[16]; 1254ec650989SNeel Natu 1255ec650989SNeel Natu switch (type) { 1256ec650989SNeel Natu case 1: 1257ec650989SNeel Natu return ("PCI Endpoint Device"); 1258ec650989SNeel Natu case 2: 1259ec650989SNeel Natu return ("PCI Sub-Hierarchy"); 1260ec650989SNeel Natu case 3: 1261ec650989SNeel Natu return ("IOAPIC"); 1262ec650989SNeel Natu case 4: 1263ec650989SNeel Natu return ("HPET"); 1264ec650989SNeel Natu default: 1265ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type); 1266ec650989SNeel Natu return (typebuf); 1267ec650989SNeel Natu } 1268ec650989SNeel Natu } 1269ec650989SNeel Natu 1270ec650989SNeel Natu static int 1271ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining) 1272ec650989SNeel Natu { 1273ec650989SNeel Natu char sep; 1274ec650989SNeel Natu int pathlen; 1275ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend; 1276ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr; 1277ec650989SNeel Natu 1278ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) 1279ec650989SNeel Natu return (-1); 1280ec650989SNeel Natu 1281ec650989SNeel Natu if (remaining < devscope->Length) 1282ec650989SNeel Natu return (-1); 1283ec650989SNeel Natu 1284ec650989SNeel Natu printf("\n"); 1285ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); 1286ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length); 1287ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); 1288ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus); 1289ec650989SNeel Natu 1290ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); 1291ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); 1292ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); 1293ec650989SNeel Natu if (path < pathend) { 1294ec650989SNeel Natu sep = '{'; 1295ec650989SNeel Natu printf("\t\tPath="); 1296ec650989SNeel Natu do { 1297ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function); 1298ec650989SNeel Natu sep=','; 1299ec650989SNeel Natu path++; 1300ec650989SNeel Natu } while (path < pathend); 1301ec650989SNeel Natu printf("}\n"); 1302ec650989SNeel Natu } 1303ec650989SNeel Natu 1304ec650989SNeel Natu return (devscope->Length); 1305ec650989SNeel Natu } 1306ec650989SNeel Natu 1307ec650989SNeel Natu static void 1308ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) 1309ec650989SNeel Natu { 1310ec650989SNeel Natu char *cp; 1311ec650989SNeel Natu int remaining, consumed; 1312ec650989SNeel Natu 1313ec650989SNeel Natu printf("\n"); 1314ec650989SNeel Natu printf("\tType=DRHD\n"); 1315ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length); 1316ec650989SNeel Natu 1317ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1318ec650989SNeel Natu 1319ec650989SNeel Natu printf("\tFlags="); 1320ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL); 1321ec650989SNeel Natu PRINTFLAG_END(); 1322ec650989SNeel Natu 1323ec650989SNeel Natu #undef PRINTFLAG 1324ec650989SNeel Natu 1325ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment); 13267d369c6eSJung-uk Kim printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address); 1327ec650989SNeel Natu 1328ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); 1329ec650989SNeel Natu if (remaining > 0) 1330ec650989SNeel Natu printf("\tDevice Scope:"); 1331ec650989SNeel Natu while (remaining > 0) { 1332ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining; 1333ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1334ec650989SNeel Natu if (consumed <= 0) 1335ec650989SNeel Natu break; 1336ec650989SNeel Natu else 1337ec650989SNeel Natu remaining -= consumed; 1338ec650989SNeel Natu } 1339ec650989SNeel Natu } 1340ec650989SNeel Natu 1341ec650989SNeel Natu static void 1342ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) 1343ec650989SNeel Natu { 1344ec650989SNeel Natu char *cp; 1345ec650989SNeel Natu int remaining, consumed; 1346ec650989SNeel Natu 1347ec650989SNeel Natu printf("\n"); 1348ec650989SNeel Natu printf("\tType=RMRR\n"); 1349ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length); 1350ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment); 13517d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress); 13527d369c6eSJung-uk Kim printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress); 1353ec650989SNeel Natu 1354ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); 1355ec650989SNeel Natu if (remaining > 0) 1356ec650989SNeel Natu printf("\tDevice Scope:"); 1357ec650989SNeel Natu while (remaining > 0) { 1358ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining; 1359ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1360ec650989SNeel Natu if (consumed <= 0) 1361ec650989SNeel Natu break; 1362ec650989SNeel Natu else 1363ec650989SNeel Natu remaining -= consumed; 1364ec650989SNeel Natu } 1365ec650989SNeel Natu } 1366ec650989SNeel Natu 1367ec650989SNeel Natu static void 1368ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) 1369ec650989SNeel Natu { 1370ec650989SNeel Natu char *cp; 1371ec650989SNeel Natu int remaining, consumed; 1372ec650989SNeel Natu 1373ec650989SNeel Natu printf("\n"); 1374ec650989SNeel Natu printf("\tType=ATSR\n"); 1375ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length); 1376ec650989SNeel Natu 1377ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1378ec650989SNeel Natu 1379ec650989SNeel Natu printf("\tFlags="); 1380ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS); 1381ec650989SNeel Natu PRINTFLAG_END(); 1382ec650989SNeel Natu 1383ec650989SNeel Natu #undef PRINTFLAG 1384ec650989SNeel Natu 1385ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment); 1386ec650989SNeel Natu 1387ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); 1388ec650989SNeel Natu if (remaining > 0) 1389ec650989SNeel Natu printf("\tDevice Scope:"); 1390ec650989SNeel Natu while (remaining > 0) { 1391ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining; 1392ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1393ec650989SNeel Natu if (consumed <= 0) 1394ec650989SNeel Natu break; 1395ec650989SNeel Natu else 1396ec650989SNeel Natu remaining -= consumed; 1397ec650989SNeel Natu } 1398ec650989SNeel Natu } 1399ec650989SNeel Natu 1400ec650989SNeel Natu static void 1401ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) 1402ec650989SNeel Natu { 1403ec650989SNeel Natu 1404ec650989SNeel Natu printf("\n"); 1405ec650989SNeel Natu printf("\tType=RHSA\n"); 1406ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length); 14077d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress); 1408ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); 1409ec650989SNeel Natu } 1410ec650989SNeel Natu 1411ec650989SNeel Natu static int 1412ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining) 1413ec650989SNeel Natu { 1414ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr; 1415ec650989SNeel Natu 1416ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) 1417ec650989SNeel Natu return (-1); 1418ec650989SNeel Natu 1419ec650989SNeel Natu if (remaining < hdr->Length) 1420ec650989SNeel Natu return (-1); 1421ec650989SNeel Natu 1422ec650989SNeel Natu switch (hdr->Type) { 1423ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1424ec650989SNeel Natu acpi_handle_dmar_drhd(addr); 1425ec650989SNeel Natu break; 1426ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1427ec650989SNeel Natu acpi_handle_dmar_rmrr(addr); 1428ec650989SNeel Natu break; 1429313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS: 1430ec650989SNeel Natu acpi_handle_dmar_atsr(addr); 1431ec650989SNeel Natu break; 1432313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1433ec650989SNeel Natu acpi_handle_dmar_rhsa(addr); 1434ec650989SNeel Natu break; 1435ec650989SNeel Natu default: 1436ec650989SNeel Natu printf("\n"); 1437ec650989SNeel Natu printf("\tType=%d\n", hdr->Type); 1438ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length); 1439ec650989SNeel Natu break; 1440ec650989SNeel Natu } 1441ec650989SNeel Natu return (hdr->Length); 1442ec650989SNeel Natu } 1443ec650989SNeel Natu 1444ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT 1445ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2) 1446ec650989SNeel Natu #endif 1447ec650989SNeel Natu 1448ec650989SNeel Natu static void 1449ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) 1450ec650989SNeel Natu { 1451ec650989SNeel Natu char *cp; 1452ec650989SNeel Natu int remaining, consumed; 1453ec650989SNeel Natu ACPI_TABLE_DMAR *dmar; 1454ec650989SNeel Natu 1455ec650989SNeel Natu printf(BEGIN_COMMENT); 1456ec650989SNeel Natu acpi_print_sdt(sdp); 1457ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp; 1458ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1); 1459ec650989SNeel Natu 1460ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1461ec650989SNeel Natu 1462ec650989SNeel Natu printf("\tFlags="); 1463ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP); 1464ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); 1465ec650989SNeel Natu PRINTFLAG_END(); 1466ec650989SNeel Natu 1467ec650989SNeel Natu #undef PRINTFLAG 1468ec650989SNeel Natu 1469ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); 1470ec650989SNeel Natu while (remaining > 0) { 1471ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining; 1472ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining); 1473ec650989SNeel Natu if (consumed <= 0) 1474ec650989SNeel Natu break; 1475ec650989SNeel Natu else 1476ec650989SNeel Natu remaining -= consumed; 1477ec650989SNeel Natu } 1478ec650989SNeel Natu 1479ec650989SNeel Natu printf(END_COMMENT); 1480ec650989SNeel Natu } 1481ec650989SNeel Natu 1482a0333ad1SJohn Baldwin static void 1483986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 1484a0333ad1SJohn Baldwin { 1485a0333ad1SJohn Baldwin 1486a0333ad1SJohn Baldwin printf("\tFlags={"); 1487986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 1488a0333ad1SJohn Baldwin printf("ENABLED"); 1489a0333ad1SJohn Baldwin else 1490a0333ad1SJohn Baldwin printf("DISABLED"); 1491986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 1492a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 1493986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 1494a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 1495a0333ad1SJohn Baldwin printf("}\n"); 1496986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 1497986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 1498986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 1499a0333ad1SJohn Baldwin } 1500a0333ad1SJohn Baldwin 150127941afaSEd Maste static const char *srat_types[] = { 150227941afaSEd Maste [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU", 150327941afaSEd Maste [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory", 150427941afaSEd Maste [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC", 1505cebb7b19SEd Maste [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC", 1506cebb7b19SEd Maste [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS", 150727941afaSEd Maste }; 1508a0333ad1SJohn Baldwin 1509a0333ad1SJohn Baldwin static void 1510986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 1511a0333ad1SJohn Baldwin { 1512986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 1513986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 15142b2b1f42SAndrew Turner ACPI_SRAT_GICC_AFFINITY *gic; 1515a0333ad1SJohn Baldwin 1516c86932b6SMarcelo Araujo if (srat->Type < nitems(srat_types)) 1517986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 1518a0333ad1SJohn Baldwin else 1519986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 1520986dffafSJohn Baldwin switch (srat->Type) { 1521a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 1522986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 1523986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 1524986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 1525986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 1526986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 1527986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 1528a0333ad1SJohn Baldwin break; 1529a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1530986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 1531a0333ad1SJohn Baldwin break; 1532a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1533986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 1534986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 1535986dffafSJohn Baldwin x2apic->Flags); 1536a0333ad1SJohn Baldwin break; 15372b2b1f42SAndrew Turner case ACPI_SRAT_TYPE_GICC_AFFINITY: 15382b2b1f42SAndrew Turner gic = (ACPI_SRAT_GICC_AFFINITY *)srat; 15392b2b1f42SAndrew Turner acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain, 15402b2b1f42SAndrew Turner gic->Flags); 15412b2b1f42SAndrew Turner break; 1542a0333ad1SJohn Baldwin } 1543a0333ad1SJohn Baldwin } 1544a0333ad1SJohn Baldwin 1545a0333ad1SJohn Baldwin static void 1546986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 1547a0333ad1SJohn Baldwin { 1548986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 1549a0333ad1SJohn Baldwin 1550a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 1551a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 1552986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 1553986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 1554986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 1555a0333ad1SJohn Baldwin printf(END_COMMENT); 1556a0333ad1SJohn Baldwin } 1557a0333ad1SJohn Baldwin 1558340c0022SEd Maste static const char *nfit_types[] = { 1559340c0022SEd Maste [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address", 1560340c0022SEd Maste [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map", 1561340c0022SEd Maste [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave", 1562340c0022SEd Maste [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS", 1563340c0022SEd Maste [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region", 1564340c0022SEd Maste [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region", 1565340c0022SEd Maste [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address" 1566340c0022SEd Maste }; 1567340c0022SEd Maste 1568340c0022SEd Maste 1569340c0022SEd Maste static void 1570340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit) 1571340c0022SEd Maste { 1572340c0022SEd Maste char *uuidstr; 1573340c0022SEd Maste uint32_t status; 1574340c0022SEd Maste 1575340c0022SEd Maste ACPI_NFIT_SYSTEM_ADDRESS *sysaddr; 1576340c0022SEd Maste ACPI_NFIT_MEMORY_MAP *mmap; 1577340c0022SEd Maste ACPI_NFIT_INTERLEAVE *ileave; 1578340c0022SEd Maste ACPI_NFIT_SMBIOS *smbios; 1579340c0022SEd Maste ACPI_NFIT_CONTROL_REGION *ctlreg; 1580340c0022SEd Maste ACPI_NFIT_DATA_REGION *datareg; 1581340c0022SEd Maste ACPI_NFIT_FLUSH_ADDRESS *fladdr; 1582340c0022SEd Maste 1583340c0022SEd Maste if (nfit->Type < nitems(nfit_types)) 1584340c0022SEd Maste printf("\tType=%s\n", nfit_types[nfit->Type]); 1585340c0022SEd Maste else 1586340c0022SEd Maste printf("\tType=%u (unknown)\n", nfit->Type); 1587340c0022SEd Maste switch (nfit->Type) { 1588340c0022SEd Maste case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 1589340c0022SEd Maste sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit; 1590340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex); 1591340c0022SEd Maste printf("\tProximityDomain=%u\n", 1592340c0022SEd Maste (u_int)sysaddr->ProximityDomain); 1593340c0022SEd Maste uuid_to_string((uuid_t *)(sysaddr->RangeGuid), 1594340c0022SEd Maste &uuidstr, &status); 1595340c0022SEd Maste if (status != uuid_s_ok) 1596340c0022SEd Maste errx(1, "uuid_to_string: status=%u", status); 1597340c0022SEd Maste printf("\tRangeGuid=%s\n", uuidstr); 1598340c0022SEd Maste free(uuidstr); 1599340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address); 1600340c0022SEd Maste printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length); 1601340c0022SEd Maste printf("\tMemoryMapping=0x%016jx\n", 1602340c0022SEd Maste (uintmax_t)sysaddr->MemoryMapping); 1603340c0022SEd Maste 1604340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 1605340c0022SEd Maste 1606340c0022SEd Maste printf("\tFlags="); 1607340c0022SEd Maste PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY); 1608340c0022SEd Maste PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID); 1609340c0022SEd Maste PRINTFLAG_END(); 1610340c0022SEd Maste 1611340c0022SEd Maste #undef PRINTFLAG 1612340c0022SEd Maste 1613340c0022SEd Maste break; 1614340c0022SEd Maste case ACPI_NFIT_TYPE_MEMORY_MAP: 1615340c0022SEd Maste mmap = (ACPI_NFIT_MEMORY_MAP *)nfit; 1616340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle); 1617340c0022SEd Maste printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId); 1618340c0022SEd Maste printf("\tRegionId=%u\n", (u_int)mmap->RegionId); 1619340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex); 1620340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex); 1621340c0022SEd Maste printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize); 1622340c0022SEd Maste printf("\tRegionOffset=0x%016jx\n", 1623340c0022SEd Maste (uintmax_t)mmap->RegionOffset); 1624340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address); 1625340c0022SEd Maste printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex); 1626fb1cf2a9SAlexander Motin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays); 1627340c0022SEd Maste 1628340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag) 1629340c0022SEd Maste 1630340c0022SEd Maste printf("\tFlags="); 1631340c0022SEd Maste PRINTFLAG(mmap->Flags, SAVE_FAILED); 1632340c0022SEd Maste PRINTFLAG(mmap->Flags, RESTORE_FAILED); 1633340c0022SEd Maste PRINTFLAG(mmap->Flags, FLUSH_FAILED); 1634340c0022SEd Maste PRINTFLAG(mmap->Flags, NOT_ARMED); 1635340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_OBSERVED); 1636340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_ENABLED); 1637340c0022SEd Maste PRINTFLAG(mmap->Flags, MAP_FAILED); 1638340c0022SEd Maste PRINTFLAG_END(); 1639340c0022SEd Maste 1640340c0022SEd Maste #undef PRINTFLAG 1641340c0022SEd Maste 1642340c0022SEd Maste break; 1643340c0022SEd Maste case ACPI_NFIT_TYPE_INTERLEAVE: 1644340c0022SEd Maste ileave = (ACPI_NFIT_INTERLEAVE *)nfit; 1645340c0022SEd Maste printf("\tInterleaveIndex=%u\n", 1646340c0022SEd Maste (u_int)ileave->InterleaveIndex); 1647340c0022SEd Maste printf("\tLineCount=%u\n", (u_int)ileave->LineCount); 1648340c0022SEd Maste printf("\tLineSize=%u\n", (u_int)ileave->LineSize); 1649340c0022SEd Maste /* XXX ileave->LineOffset[i] output is not supported */ 1650340c0022SEd Maste break; 1651340c0022SEd Maste case ACPI_NFIT_TYPE_SMBIOS: 1652340c0022SEd Maste smbios = (ACPI_NFIT_SMBIOS *)nfit; 1653340c0022SEd Maste /* XXX smbios->Data[x] output is not supported */ 1654340c0022SEd Maste break; 1655340c0022SEd Maste case ACPI_NFIT_TYPE_CONTROL_REGION: 1656340c0022SEd Maste ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit; 1657340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex); 1658340c0022SEd Maste printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId); 1659340c0022SEd Maste printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId); 1660340c0022SEd Maste printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId); 1661340c0022SEd Maste printf("\tSubsystemVendorId=0x%04x\n", 1662340c0022SEd Maste (u_int)ctlreg->SubsystemVendorId); 1663340c0022SEd Maste printf("\tSubsystemDeviceId=0x%04x\n", 1664340c0022SEd Maste (u_int)ctlreg->SubsystemDeviceId); 1665340c0022SEd Maste printf("\tSubsystemRevisionId=%u\n", 1666340c0022SEd Maste (u_int)ctlreg->SubsystemRevisionId); 1667d4c2de2eSAlexander Motin printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields); 1668340c0022SEd Maste printf("\tManufacturingLocation=%u\n", 1669340c0022SEd Maste (u_int)ctlreg->ManufacturingLocation); 1670340c0022SEd Maste printf("\tManufacturingDate=%u\n", 1671340c0022SEd Maste (u_int)ctlreg->ManufacturingDate); 1672340c0022SEd Maste printf("\tSerialNumber=%u\n", 1673340c0022SEd Maste (u_int)ctlreg->SerialNumber); 1674fb1cf2a9SAlexander Motin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code); 1675340c0022SEd Maste printf("\tWindows=%u\n", (u_int)ctlreg->Windows); 1676340c0022SEd Maste printf("\tWindowSize=0x%016jx\n", 1677340c0022SEd Maste (uintmax_t)ctlreg->WindowSize); 1678340c0022SEd Maste printf("\tCommandOffset=0x%016jx\n", 1679340c0022SEd Maste (uintmax_t)ctlreg->CommandOffset); 1680340c0022SEd Maste printf("\tCommandSize=0x%016jx\n", 1681340c0022SEd Maste (uintmax_t)ctlreg->CommandSize); 1682340c0022SEd Maste printf("\tStatusOffset=0x%016jx\n", 1683340c0022SEd Maste (uintmax_t)ctlreg->StatusOffset); 1684340c0022SEd Maste printf("\tStatusSize=0x%016jx\n", 1685340c0022SEd Maste (uintmax_t)ctlreg->StatusSize); 1686340c0022SEd Maste 1687340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 1688340c0022SEd Maste 1689340c0022SEd Maste printf("\tFlags="); 1690d4c2de2eSAlexander Motin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED); 1691340c0022SEd Maste PRINTFLAG_END(); 1692340c0022SEd Maste 1693340c0022SEd Maste #undef PRINTFLAG 1694340c0022SEd Maste 1695340c0022SEd Maste break; 1696340c0022SEd Maste case ACPI_NFIT_TYPE_DATA_REGION: 1697340c0022SEd Maste datareg = (ACPI_NFIT_DATA_REGION *)nfit; 1698340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex); 1699340c0022SEd Maste printf("\tWindows=%u\n", (u_int)datareg->Windows); 1700340c0022SEd Maste printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset); 1701340c0022SEd Maste printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size); 1702340c0022SEd Maste printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity); 1703340c0022SEd Maste printf("\tStartAddress=0x%016jx\n", 1704340c0022SEd Maste (uintmax_t)datareg->StartAddress); 1705340c0022SEd Maste break; 1706340c0022SEd Maste case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 1707340c0022SEd Maste fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit; 1708340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle); 1709340c0022SEd Maste printf("\tHintCount=%u\n", (u_int)fladdr->HintCount); 1710340c0022SEd Maste /* XXX fladdr->HintAddress[i] output is not supported */ 1711340c0022SEd Maste break; 1712340c0022SEd Maste } 1713340c0022SEd Maste } 1714340c0022SEd Maste 1715340c0022SEd Maste static void 1716340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp) 1717340c0022SEd Maste { 1718340c0022SEd Maste ACPI_TABLE_NFIT *nfit; 1719340c0022SEd Maste 1720340c0022SEd Maste printf(BEGIN_COMMENT); 1721340c0022SEd Maste acpi_print_sdt(sdp); 1722340c0022SEd Maste nfit = (ACPI_TABLE_NFIT *)sdp; 1723340c0022SEd Maste acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit); 1724340c0022SEd Maste printf(END_COMMENT); 1725340c0022SEd Maste } 1726340c0022SEd Maste 1727a0333ad1SJohn Baldwin static void 1728986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 1729c62f1cccSMitsuru IWASAKI { 1730773b6454SNate Lawson printf(" "); 1731278f0de6SJung-uk Kim acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE); 1732c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 1733986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 1734e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 1735986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 1736e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 1737986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 1738986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 1739e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 1740278f0de6SJung-uk Kim acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE); 1741986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 1742e1e9a4bfSMitsuru IWASAKI } 1743e1e9a4bfSMitsuru IWASAKI 1744945137d9SNate Lawson static void 1745986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 1746e1e9a4bfSMitsuru IWASAKI { 1747986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1748986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1749e1e9a4bfSMitsuru IWASAKI int i, entries; 1750e1e9a4bfSMitsuru IWASAKI 1751986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1752986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1753773b6454SNate Lawson printf(BEGIN_COMMENT); 1754773b6454SNate Lawson acpi_print_sdt(rsdp); 1755986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1756e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 1757e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1758e1e9a4bfSMitsuru IWASAKI if (i > 0) 1759e1e9a4bfSMitsuru IWASAKI printf(", "); 1760fe1d0c2dSJung-uk Kim if (addr_size == 4) 17617d369c6eSJung-uk Kim printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i])); 1762fe1d0c2dSJung-uk Kim else 17637d369c6eSJung-uk Kim printf("0x%016jx", 17647d369c6eSJung-uk Kim (uintmax_t)le64toh(xsdt->TableOffsetEntry[i])); 1765e1e9a4bfSMitsuru IWASAKI } 1766e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 1767c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1768e1e9a4bfSMitsuru IWASAKI } 1769e1e9a4bfSMitsuru IWASAKI 17708e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 17718e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 17728e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 17738e6a8737SNate Lawson }; 17748e6a8737SNate Lawson 1775945137d9SNate Lawson static void 1776986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 1777e1e9a4bfSMitsuru IWASAKI { 1778986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 17798e6a8737SNate Lawson const char *pm; 1780e1e9a4bfSMitsuru IWASAKI 1781986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 1782c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 17832177d4e6SNate Lawson acpi_print_sdt(sdp); 1784986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 1785986dffafSJohn Baldwin fadt->Dsdt); 1786986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 1787986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 17888e6a8737SNate Lawson pm = "Reserved"; 17898e6a8737SNate Lawson else 1790986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 1791986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 1792986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 1793986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 1794986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 1795986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 1796986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 1797986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 1798e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 1799986dffafSJohn Baldwin fadt->Pm1aEventBlock, 1800986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 1801986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 1802e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 1803986dffafSJohn Baldwin fadt->Pm1bEventBlock, 1804986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 1805e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 1806986dffafSJohn Baldwin fadt->Pm1aControlBlock, 1807986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 1808986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 1809e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 1810986dffafSJohn Baldwin fadt->Pm1bControlBlock, 1811986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 1812986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 1813e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 1814986dffafSJohn Baldwin fadt->Pm2ControlBlock, 1815986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 1816c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 1817986dffafSJohn Baldwin fadt->PmTimerBlock, 1818986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 1819986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 18208e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 1821986dffafSJohn Baldwin fadt->Gpe0Block, 1822986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 1823986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 18248e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 1825986dffafSJohn Baldwin fadt->Gpe1Block, 1826986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 1827986dffafSJohn Baldwin fadt->Gpe1Base); 1828986dffafSJohn Baldwin if (fadt->CstControl != 0) 1829986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 183051c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 1831986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 1832e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 1833986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 1834e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 1835986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 1836e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 1837986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 1838e1e9a4bfSMitsuru IWASAKI 1839ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) 1840e1e9a4bfSMitsuru IWASAKI 18418e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 1842986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 1843986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 1844986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 1845986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 1846986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 1847f6469ce1SAndrew Turner PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC); 1848ec650989SNeel Natu PRINTFLAG_END(); 18498e6a8737SNate Lawson 18508e6a8737SNate Lawson printf("\tFlags="); 1851986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 1852986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 1853986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 1854986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 1855986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 1856986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 1857986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 1858986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 1859986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 1860986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 1861986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 1862986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 1863986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 1864986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 1865986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 1866986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 1867986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 1868986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 1869986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 1870986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 1871f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, HW_REDUCED); 1872f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, LOW_POWER_S0); 1873ec650989SNeel Natu PRINTFLAG_END(); 1874e1e9a4bfSMitsuru IWASAKI 1875e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 1876e1e9a4bfSMitsuru IWASAKI 1877986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 18788e6a8737SNate Lawson printf("\tRESET_REG="); 1879986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 1880986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 18818e6a8737SNate Lawson } 1882c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 18837d369c6eSJung-uk Kim printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs); 18847d369c6eSJung-uk Kim printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt); 1885c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 1886986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 1887986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 1888c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 1889986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 1890c08c4e81SNate Lawson } 1891c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 1892986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 1893986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 1894c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 1895986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 1896c08c4e81SNate Lawson } 1897986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 1898773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 1899986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 1900c08c4e81SNate Lawson } 1901773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 1902986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 1903986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 1904773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 1905986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 1906c08c4e81SNate Lawson } 1907986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 1908773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 1909986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 1910c08c4e81SNate Lawson } 1911773b6454SNate Lawson printf("\n"); 1912773b6454SNate Lawson } 19138e6a8737SNate Lawson 19148e6a8737SNate Lawson printf(END_COMMENT); 19158e6a8737SNate Lawson } 19168e6a8737SNate Lawson 19178e6a8737SNate Lawson static void 1918986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 19198e6a8737SNate Lawson { 19208e6a8737SNate Lawson printf(BEGIN_COMMENT); 1921986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 1922986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 1923986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 19248e6a8737SNate Lawson 1925773b6454SNate Lawson printf("\tGlobal_Lock="); 1926986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 1927986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 19288e6a8737SNate Lawson printf("PENDING,"); 1929986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 19308e6a8737SNate Lawson printf("OWNED"); 19318e6a8737SNate Lawson } 1932773b6454SNate Lawson printf("\n"); 19338e6a8737SNate Lawson 1934773b6454SNate Lawson printf("\tFlags="); 1935986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 19368e6a8737SNate Lawson printf("S4BIOS"); 1937773b6454SNate Lawson printf("\n"); 19388e6a8737SNate Lawson 19397d369c6eSJung-uk Kim if (facs->XFirmwareWakingVector != 0) 19407d369c6eSJung-uk Kim printf("\tX_Firm_Wake_Vec=%016jx\n", 19417d369c6eSJung-uk Kim (uintmax_t)facs->XFirmwareWakingVector); 1942986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 19438e6a8737SNate Lawson 1944c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1945e1e9a4bfSMitsuru IWASAKI } 1946e1e9a4bfSMitsuru IWASAKI 1947945137d9SNate Lawson static void 1948986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 1949e1e9a4bfSMitsuru IWASAKI { 1950773b6454SNate Lawson printf(BEGIN_COMMENT); 1951773b6454SNate Lawson acpi_print_sdt(dsdp); 1952773b6454SNate Lawson printf(END_COMMENT); 1953e1e9a4bfSMitsuru IWASAKI } 1954e1e9a4bfSMitsuru IWASAKI 1955e1e9a4bfSMitsuru IWASAKI int 1956e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 1957e1e9a4bfSMitsuru IWASAKI { 1958986dffafSJohn Baldwin uint8_t *bp; 1959986dffafSJohn Baldwin uint8_t sum; 1960e1e9a4bfSMitsuru IWASAKI 1961e1e9a4bfSMitsuru IWASAKI bp = p; 1962e1e9a4bfSMitsuru IWASAKI sum = 0; 1963e1e9a4bfSMitsuru IWASAKI while (length--) 1964e1e9a4bfSMitsuru IWASAKI sum += *bp++; 1965e1e9a4bfSMitsuru IWASAKI 1966e1e9a4bfSMitsuru IWASAKI return (sum); 1967e1e9a4bfSMitsuru IWASAKI } 1968e1e9a4bfSMitsuru IWASAKI 1969986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 1970e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 1971e1e9a4bfSMitsuru IWASAKI { 1972986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 1973e1e9a4bfSMitsuru IWASAKI 1974986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 1975986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 1976e1e9a4bfSMitsuru IWASAKI return (sp); 1977e1e9a4bfSMitsuru IWASAKI } 1978e1e9a4bfSMitsuru IWASAKI 1979945137d9SNate Lawson static void 1980986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 1981e1e9a4bfSMitsuru IWASAKI { 1982c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 1983a74172abSNate Lawson printf(" RSD PTR: OEM="); 1984986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 1985986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 1986986dffafSJohn Baldwin rp->Revision); 1987986dffafSJohn Baldwin if (rp->Revision < 2) { 1988986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 1989986dffafSJohn Baldwin rp->Checksum); 1990a74172abSNate Lawson } else { 19917d369c6eSJung-uk Kim printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n", 19927d369c6eSJung-uk Kim (uintmax_t)rp->XsdtPhysicalAddress, rp->Length, 1993986dffafSJohn Baldwin rp->ExtendedChecksum); 1994a74172abSNate Lawson } 1995c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1996e1e9a4bfSMitsuru IWASAKI } 1997e1e9a4bfSMitsuru IWASAKI 1998945137d9SNate Lawson static void 1999986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 2000e1e9a4bfSMitsuru IWASAKI { 2001986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 2002986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 2003986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 2004a74172abSNate Lawson vm_offset_t addr; 2005a74172abSNate Lawson int entries, i; 2006e1e9a4bfSMitsuru IWASAKI 2007e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 2008986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 2009986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 2010986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 2011e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 2012fe1d0c2dSJung-uk Kim if (addr_size == 4) 2013986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 2014fe1d0c2dSJung-uk Kim else 2015986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 2016fe1d0c2dSJung-uk Kim if (addr == 0) 2017fe1d0c2dSJung-uk Kim continue; 2018986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 2019986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 20205cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 2021986dffafSJohn Baldwin sdp->Signature); 20225cf6d493SNate Lawson continue; 20235cf6d493SNate Lawson } 2024*ebc22d04SAlexander Motin if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4)) 2025*ebc22d04SAlexander Motin acpi_handle_bert(sdp); 2026*ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4)) 2027*ebc22d04SAlexander Motin acpi_handle_einj(sdp); 2028*ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4)) 2029*ebc22d04SAlexander Motin acpi_handle_erst(sdp); 2030*ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 20312177d4e6SNate Lawson acpi_handle_fadt(sdp); 2032986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 2033986dffafSJohn Baldwin acpi_handle_madt(sdp); 2034*ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4)) 2035*ebc22d04SAlexander Motin acpi_handle_hest(sdp); 2036986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 203779d7565cSPeter Wemm acpi_handle_hpet(sdp); 2038986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 203955d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 2040986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 2041a47e681bSScott Long acpi_handle_mcfg(sdp); 204233866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 204333866658SJohn Baldwin acpi_handle_slit(sdp); 2044986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 2045a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 2046c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 2047c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 2048ec650989SNeel Natu else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) 2049ec650989SNeel Natu acpi_handle_dmar(sdp); 2050340c0022SEd Maste else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4)) 2051340c0022SEd Maste acpi_handle_nfit(sdp); 2052ed26c389SScott Long else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4)) 2053ed26c389SScott Long acpi_handle_wddt(sdp); 20545857fba5SBen Widawsky else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4)) 20555857fba5SBen Widawsky acpi_handle_lpit(sdp); 2056877fc2e3STakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4)) 2057877fc2e3STakanori Watanabe acpi_handle_tpm2(sdp); 2058773b6454SNate Lawson else { 2059773b6454SNate Lawson printf(BEGIN_COMMENT); 2060773b6454SNate Lawson acpi_print_sdt(sdp); 2061773b6454SNate Lawson printf(END_COMMENT); 2062773b6454SNate Lawson } 2063e1e9a4bfSMitsuru IWASAKI } 2064e1e9a4bfSMitsuru IWASAKI } 2065c62f1cccSMitsuru IWASAKI 2066986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2067476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 2068945137d9SNate Lawson { 2069986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 2070986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 2071945137d9SNate Lawson 2072945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 2073945137d9SNate Lawson if (!rp) 2074945137d9SNate Lawson errx(1, "Can't find ACPI information"); 2075945137d9SNate Lawson 2076945137d9SNate Lawson if (tflag) 2077945137d9SNate Lawson acpi_print_rsd_ptr(rp); 2078986dffafSJohn Baldwin if (rp->Revision < 2) { 2079986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 2080986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 2081986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 2082945137d9SNate Lawson errx(1, "RSDT is corrupted"); 2083a74172abSNate Lawson addr_size = sizeof(uint32_t); 2084a74172abSNate Lawson } else { 2085986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 2086986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 2087986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 2088a74172abSNate Lawson errx(1, "XSDT is corrupted"); 2089a74172abSNate Lawson addr_size = sizeof(uint64_t); 2090a74172abSNate Lawson } 2091945137d9SNate Lawson return (rsdp); 2092945137d9SNate Lawson } 2093c62f1cccSMitsuru IWASAKI 209462c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 2095bfa3f012SMarcel Moolenaar static int 2096986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 2097bfa3f012SMarcel Moolenaar { 2098986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 2099986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 2100bfa3f012SMarcel Moolenaar uint8_t sum; 2101bfa3f012SMarcel Moolenaar 210262c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 2103bfa3f012SMarcel Moolenaar sdt = *dsdt; 2104bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 2105986dffafSJohn Baldwin sdt.Checksum = 0; 2106986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 2107986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 2108986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 2109f7675a56SNate Lawson while (ssdt != NULL) { 2110986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 2111986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 2112986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 2113986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 2114bfa3f012SMarcel Moolenaar } 2115986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 2116986dffafSJohn Baldwin sdt.Checksum -= sum; 2117bfa3f012SMarcel Moolenaar } 211862c7bde1SNate Lawson 211962c7bde1SNate Lawson /* Write out the DSDT header and body. */ 2120986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 2121986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 212262c7bde1SNate Lawson 2123b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 2124f7675a56SNate Lawson if (rsdt != NULL) { 2125bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 2126bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 2127986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 2128986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 2129bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 2130bfa3f012SMarcel Moolenaar } 2131bfa3f012SMarcel Moolenaar } 2132bfa3f012SMarcel Moolenaar return (0); 2133bfa3f012SMarcel Moolenaar } 2134bfa3f012SMarcel Moolenaar 2135c62f1cccSMitsuru IWASAKI void 2136986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 2137c62f1cccSMitsuru IWASAKI { 2138945137d9SNate Lawson int fd; 2139945137d9SNate Lawson mode_t mode; 2140945137d9SNate Lawson 2141945137d9SNate Lawson assert(outfile != NULL); 2142945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 2143945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 2144945137d9SNate Lawson if (fd == -1) { 2145945137d9SNate Lawson perror("dsdt_save_file"); 2146945137d9SNate Lawson return; 2147945137d9SNate Lawson } 2148bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 2149945137d9SNate Lawson close(fd); 2150c62f1cccSMitsuru IWASAKI } 2151c62f1cccSMitsuru IWASAKI 2152945137d9SNate Lawson void 2153986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 2154c62f1cccSMitsuru IWASAKI { 21557e2cc014SDon Lewis char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX]; 21567e2cc014SDon Lewis const char *iname = "/acpdump.din"; 21577e2cc014SDon Lewis const char *oname = "/acpdump.dsl"; 215899065116SJung-uk Kim const char *tmpdir; 2159945137d9SNate Lawson FILE *fp; 216099065116SJung-uk Kim size_t len; 21617e2cc014SDon Lewis int fd, status; 21627e2cc014SDon Lewis pid_t pid; 2163945137d9SNate Lawson 216499065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 216599065116SJung-uk Kim if (tmpdir == NULL) 216699065116SJung-uk Kim tmpdir = _PATH_TMP; 21677e2cc014SDon Lewis if (realpath(tmpdir, buf) == NULL) { 2168d6a6e590SJung-uk Kim perror("realpath tmp dir"); 216999065116SJung-uk Kim return; 217099065116SJung-uk Kim } 21717e2cc014SDon Lewis len = sizeof(wrkdir) - strlen(iname); 21727e2cc014SDon Lewis if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) { 21737e2cc014SDon Lewis fprintf(stderr, "$TMPDIR too long\n"); 21747e2cc014SDon Lewis return; 21757e2cc014SDon Lewis } 21767e2cc014SDon Lewis if (mkdtemp(wrkdir) == NULL) { 21777e2cc014SDon Lewis perror("mkdtemp tmp working dir"); 21787e2cc014SDon Lewis return; 21797e2cc014SDon Lewis } 218030bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname); 218130bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 21827e2cc014SDon Lewis fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 2183945137d9SNate Lawson if (fd < 0) { 2184945137d9SNate Lawson perror("iasl tmp file"); 2185945137d9SNate Lawson return; 2186c62f1cccSMitsuru IWASAKI } 2187bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 2188945137d9SNate Lawson close(fd); 2189945137d9SNate Lawson 2190945137d9SNate Lawson /* Run iasl -d on the temp file */ 21917e2cc014SDon Lewis if ((pid = fork()) == 0) { 2192945137d9SNate Lawson close(STDOUT_FILENO); 2193945137d9SNate Lawson if (vflag == 0) 2194945137d9SNate Lawson close(STDERR_FILENO); 219599065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 2196945137d9SNate Lawson err(1, "exec"); 2197c62f1cccSMitsuru IWASAKI } 21987e2cc014SDon Lewis if (pid > 0) 21997e2cc014SDon Lewis wait(&status); 22007e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 22017e2cc014SDon Lewis perror("unlink"); 22027e2cc014SDon Lewis goto out; 22037e2cc014SDon Lewis } 22047e2cc014SDon Lewis if (pid < 0) { 22057e2cc014SDon Lewis perror("fork"); 22067e2cc014SDon Lewis goto out; 22077e2cc014SDon Lewis } 22087e2cc014SDon Lewis if (status != 0) { 22097e2cc014SDon Lewis fprintf(stderr, "iast exit status = %d\n", status); 22107e2cc014SDon Lewis } 2211945137d9SNate Lawson 2212945137d9SNate Lawson /* Dump iasl's output to stdout */ 221330bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname); 221430bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 221599065116SJung-uk Kim fp = fopen(tmpstr, "r"); 22167e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 22177e2cc014SDon Lewis perror("unlink"); 22187e2cc014SDon Lewis goto out; 22197e2cc014SDon Lewis } 2220945137d9SNate Lawson if (fp == NULL) { 2221945137d9SNate Lawson perror("iasl tmp file (read)"); 22227e2cc014SDon Lewis goto out; 2223945137d9SNate Lawson } 2224945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 2225945137d9SNate Lawson fwrite(buf, 1, len, stdout); 2226945137d9SNate Lawson fclose(fp); 22277e2cc014SDon Lewis 22287e2cc014SDon Lewis out: 22297e2cc014SDon Lewis if (rmdir(wrkdir) < 0) 22307e2cc014SDon Lewis perror("rmdir"); 2231c62f1cccSMitsuru IWASAKI } 2232c62f1cccSMitsuru IWASAKI 2233945137d9SNate Lawson void 2234986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 2235c62f1cccSMitsuru IWASAKI { 2236945137d9SNate Lawson acpi_handle_rsdt(rsdp); 2237c62f1cccSMitsuru IWASAKI } 2238c62f1cccSMitsuru IWASAKI 2239bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 2240986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2241986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 2242c62f1cccSMitsuru IWASAKI { 2243986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 2244986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 2245986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 2246a74172abSNate Lawson vm_offset_t addr; 2247a74172abSNate Lawson int entries, i; 2248945137d9SNate Lawson 2249986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 2250986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 2251986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 2252945137d9SNate Lawson for (i = 0; i < entries; i++) { 2253fe1d0c2dSJung-uk Kim if (addr_size == 4) 2254986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 2255fe1d0c2dSJung-uk Kim else 2256986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 2257fe1d0c2dSJung-uk Kim if (addr == 0) 2258fe1d0c2dSJung-uk Kim continue; 2259986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 2260bfa3f012SMarcel Moolenaar if (last != NULL) { 2261bfa3f012SMarcel Moolenaar if (sdt == last) 2262bfa3f012SMarcel Moolenaar last = NULL; 2263bfa3f012SMarcel Moolenaar continue; 2264bfa3f012SMarcel Moolenaar } 2265986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 2266a74172abSNate Lawson continue; 2267986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 2268945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 2269945137d9SNate Lawson return (sdt); 2270c62f1cccSMitsuru IWASAKI } 2271c62f1cccSMitsuru IWASAKI 2272945137d9SNate Lawson return (NULL); 2273c62f1cccSMitsuru IWASAKI } 2274c62f1cccSMitsuru IWASAKI 2275986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2276986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 2277c62f1cccSMitsuru IWASAKI { 2278986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 2279c62f1cccSMitsuru IWASAKI 2280986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 2281c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 2282986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 22832e71eb12SNate Lawson else 2284986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 2285986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 2286945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 2287945137d9SNate Lawson return (sdt); 2288c62f1cccSMitsuru IWASAKI } 2289