1e1e9a4bfSMitsuru IWASAKI /*- 2e1e9a4bfSMitsuru IWASAKI * Copyright (c) 1998 Doug Rabson 3e1e9a4bfSMitsuru IWASAKI * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 4e1e9a4bfSMitsuru IWASAKI * All rights reserved. 5e1e9a4bfSMitsuru IWASAKI * 6e1e9a4bfSMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without 7e1e9a4bfSMitsuru IWASAKI * modification, are permitted provided that the following conditions 8e1e9a4bfSMitsuru IWASAKI * are met: 9e1e9a4bfSMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright 10e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer. 11e1e9a4bfSMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright 12e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the 13e1e9a4bfSMitsuru IWASAKI * documentation and/or other materials provided with the distribution. 14e1e9a4bfSMitsuru IWASAKI * 15e1e9a4bfSMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e1e9a4bfSMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e1e9a4bfSMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e1e9a4bfSMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e1e9a4bfSMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e1e9a4bfSMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e1e9a4bfSMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e1e9a4bfSMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e1e9a4bfSMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e1e9a4bfSMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e1e9a4bfSMitsuru IWASAKI * SUCH DAMAGE. 26e1e9a4bfSMitsuru IWASAKI * 27e1e9a4bfSMitsuru IWASAKI * $FreeBSD$ 28e1e9a4bfSMitsuru IWASAKI */ 29e1e9a4bfSMitsuru IWASAKI 30e1e9a4bfSMitsuru IWASAKI #include <sys/param.h> 31a74172abSNate Lawson #include <sys/endian.h> 32e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h> 33945137d9SNate Lawson #include <sys/wait.h> 34e1e9a4bfSMitsuru IWASAKI #include <assert.h> 35e1e9a4bfSMitsuru IWASAKI #include <err.h> 36e1e9a4bfSMitsuru IWASAKI #include <fcntl.h> 3799065116SJung-uk Kim #include <paths.h> 38e1e9a4bfSMitsuru IWASAKI #include <stdio.h> 39a0333ad1SJohn Baldwin #include <stdint.h> 4099065116SJung-uk Kim #include <stdlib.h> 41945137d9SNate Lawson #include <string.h> 42e1e9a4bfSMitsuru IWASAKI #include <unistd.h> 43e1e9a4bfSMitsuru IWASAKI 44e1e9a4bfSMitsuru IWASAKI #include "acpidump.h" 45e1e9a4bfSMitsuru IWASAKI 46c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n" 47c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n" 48c62f1cccSMitsuru IWASAKI 49945137d9SNate Lawson static void acpi_print_string(char *s, size_t length); 50986dffafSJohn Baldwin static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas); 51986dffafSJohn Baldwin static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt); 52986dffafSJohn Baldwin static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt); 53945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id); 54986dffafSJohn Baldwin static void acpi_print_cpu_uid(uint32_t uid, char *uid_string); 55986dffafSJohn Baldwin static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags); 56986dffafSJohn Baldwin static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, 57986dffafSJohn Baldwin uint64_t apic_addr); 58986dffafSJohn Baldwin static void acpi_print_mps_flags(uint16_t flags); 59986dffafSJohn Baldwin static void acpi_print_intr(uint32_t intr, uint16_t mps_flags); 60986dffafSJohn Baldwin static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags); 61986dffafSJohn Baldwin static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp); 62986dffafSJohn Baldwin static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp); 63986dffafSJohn Baldwin static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); 64986dffafSJohn Baldwin static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); 65986dffafSJohn Baldwin static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); 66*33866658SJohn Baldwin static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); 67a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 68a0333ad1SJohn Baldwin uint32_t flags); 69986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); 70986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); 71986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); 72c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); 73986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); 74986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); 75986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs); 76986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); 77986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); 78986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); 79986dffafSJohn Baldwin static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); 80986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 81986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)); 82c62f1cccSMitsuru IWASAKI 83773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 84a74172abSNate Lawson static int addr_size; 85a74172abSNate Lawson 86c031c93bSTakanori Watanabe /* Strings used in the TCPA table */ 87c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = { 88c031c93bSTakanori Watanabe "PREBOOT Certificate", 89c031c93bSTakanori Watanabe "POST Code", 90c031c93bSTakanori Watanabe "Unused", 91c031c93bSTakanori Watanabe "No Action", 92c031c93bSTakanori Watanabe "Separator", 93c031c93bSTakanori Watanabe "Action", 94c031c93bSTakanori Watanabe "Event Tag", 95c031c93bSTakanori Watanabe "S-CRTM Contents", 96c031c93bSTakanori Watanabe "S-CRTM Version", 97c031c93bSTakanori Watanabe "CPU Microcode", 98c031c93bSTakanori Watanabe "Platform Config Flags", 99c031c93bSTakanori Watanabe "Table of Devices", 100c031c93bSTakanori Watanabe "Compact Hash", 101c031c93bSTakanori Watanabe "IPL", 102c031c93bSTakanori Watanabe "IPL Partition Data", 103c031c93bSTakanori Watanabe "Non-Host Code", 104c031c93bSTakanori Watanabe "Non-Host Config", 105c031c93bSTakanori Watanabe "Non-Host Info" 106c031c93bSTakanori Watanabe }; 107c031c93bSTakanori Watanabe 108c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = { 109c031c93bSTakanori Watanabe "<undefined>", 110c031c93bSTakanori Watanabe "SMBIOS", 111c031c93bSTakanori Watanabe "BIS Certificate", 112c031c93bSTakanori Watanabe "POST BIOS ROM Strings", 113c031c93bSTakanori Watanabe "ESCD", 114c031c93bSTakanori Watanabe "CMOS", 115c031c93bSTakanori Watanabe "NVRAM", 116c031c93bSTakanori Watanabe "Option ROM Execute", 117c031c93bSTakanori Watanabe "Option ROM Configurateion", 118c031c93bSTakanori Watanabe "<undefined>", 119c031c93bSTakanori Watanabe "Option ROM Microcode Update ", 120c031c93bSTakanori Watanabe "S-CRTM Version String", 121c031c93bSTakanori Watanabe "S-CRTM Contents", 122c031c93bSTakanori Watanabe "POST Contents", 123c031c93bSTakanori Watanabe "Table of Devices", 124c031c93bSTakanori Watanabe }; 125c031c93bSTakanori Watanabe 126e1e9a4bfSMitsuru IWASAKI static void 127e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 128e1e9a4bfSMitsuru IWASAKI { 129e1e9a4bfSMitsuru IWASAKI int c; 130e1e9a4bfSMitsuru IWASAKI 131e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 132e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 133e1e9a4bfSMitsuru IWASAKI length--; 134e1e9a4bfSMitsuru IWASAKI 135e1e9a4bfSMitsuru IWASAKI while (length--) { 136e1e9a4bfSMitsuru IWASAKI c = *s++; 137e1e9a4bfSMitsuru IWASAKI putchar(c); 138e1e9a4bfSMitsuru IWASAKI } 139e1e9a4bfSMitsuru IWASAKI } 140e1e9a4bfSMitsuru IWASAKI 141e1e9a4bfSMitsuru IWASAKI static void 142986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1438e6a8737SNate Lawson { 144986dffafSJohn Baldwin switch(gas->SpaceId) { 1458e6a8737SNate Lawson case ACPI_GAS_MEMORY: 146986dffafSJohn Baldwin printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address, 147986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1488e6a8737SNate Lawson break; 1498e6a8737SNate Lawson case ACPI_GAS_IO: 150986dffafSJohn Baldwin printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address, 151986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1528e6a8737SNate Lawson break; 1538e6a8737SNate Lawson case ACPI_GAS_PCI: 154986dffafSJohn Baldwin printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), 155986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 156986dffafSJohn Baldwin (uint16_t)gas->Address); 1578e6a8737SNate Lawson break; 1588e6a8737SNate Lawson /* XXX How to handle these below? */ 1598e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 160986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 161986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1628e6a8737SNate Lawson break; 1638e6a8737SNate Lawson case ACPI_GAS_SMBUS: 164986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 165986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1668e6a8737SNate Lawson break; 167986dffafSJohn Baldwin case ACPI_GAS_CMOS: 168986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 169986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 1708e6a8737SNate Lawson case ACPI_GAS_FIXED: 1718e6a8737SNate Lawson default: 172986dffafSJohn Baldwin printf("0x%08lx (?)", (u_long)gas->Address); 1738e6a8737SNate Lawson break; 1748e6a8737SNate Lawson } 1758e6a8737SNate Lawson } 1768e6a8737SNate Lawson 177c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 178c2962974SNate Lawson static int 179986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 180e1e9a4bfSMitsuru IWASAKI { 181c2962974SNate Lawson int fadt_revision; 182e1e9a4bfSMitsuru IWASAKI 183c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 184c83f0f99SNate Lawson if (addr_size == 8) { 185c83f0f99SNate Lawson fadt_revision = 2; 1868e6a8737SNate Lawson 187773b6454SNate Lawson /* 188c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 189c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 190c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 191c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 192c83f0f99SNate Lawson * version for all subsequent tables. 193773b6454SNate Lawson */ 194986dffafSJohn Baldwin if (fadt->Facs != 0 && 195986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 196c83f0f99SNate Lawson fadt_revision = 1; 197c2962974SNate Lawson } else 198c83f0f99SNate Lawson fadt_revision = 1; 199c2962974SNate Lawson return (fadt_revision); 200c83f0f99SNate Lawson } 201c2962974SNate Lawson 202c2962974SNate Lawson static void 203986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 204c2962974SNate Lawson { 205986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 206986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 207986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 208c2962974SNate Lawson int fadt_revision; 209c2962974SNate Lawson 210986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2112177d4e6SNate Lawson acpi_print_fadt(sdp); 212c83f0f99SNate Lawson 213c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 214c83f0f99SNate Lawson if (fadt_revision == 1) 215986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); 216773b6454SNate Lawson else 217986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); 218986dffafSJohn Baldwin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) 2198e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2208e6a8737SNate Lawson acpi_print_facs(facs); 2218e6a8737SNate Lawson 222c83f0f99SNate Lawson if (fadt_revision == 1) 223986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 224773b6454SNate Lawson else 225986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 226986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 227945137d9SNate Lawson errx(1, "DSDT is corrupt"); 228945137d9SNate Lawson acpi_print_dsdt(dsdp); 229c62f1cccSMitsuru IWASAKI } 230c62f1cccSMitsuru IWASAKI 231c62f1cccSMitsuru IWASAKI static void 232986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 233986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 234986dffafSJohn Baldwin { 235986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 236986dffafSJohn Baldwin char *end; 237986dffafSJohn Baldwin 238986dffafSJohn Baldwin subtable = first; 239986dffafSJohn Baldwin end = (char *)table + table->Length; 240986dffafSJohn Baldwin while ((char *)subtable < end) { 241986dffafSJohn Baldwin printf("\n"); 242986dffafSJohn Baldwin action(subtable); 243986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 244986dffafSJohn Baldwin subtable->Length); 245986dffafSJohn Baldwin } 246986dffafSJohn Baldwin } 247986dffafSJohn Baldwin 248986dffafSJohn Baldwin static void 2490a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 2500a473124SJohn Baldwin { 2510a473124SJohn Baldwin 2520a473124SJohn Baldwin printf("\tACPI CPU="); 2530a473124SJohn Baldwin if (cpu_id == 0xff) 2540a473124SJohn Baldwin printf("ALL\n"); 2550a473124SJohn Baldwin else 2560a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 2570a473124SJohn Baldwin } 2580a473124SJohn Baldwin 2590a473124SJohn Baldwin static void 260986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 2610a473124SJohn Baldwin { 262986dffafSJohn Baldwin 263986dffafSJohn Baldwin printf("\tUID=%d", uid); 264986dffafSJohn Baldwin if (uid_string != NULL) 265986dffafSJohn Baldwin printf(" (%s)", uid_string); 266986dffafSJohn Baldwin printf("\n"); 267986dffafSJohn Baldwin } 268986dffafSJohn Baldwin 269986dffafSJohn Baldwin static void 270986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 271986dffafSJohn Baldwin { 272986dffafSJohn Baldwin 2730a473124SJohn Baldwin printf("\tFlags={"); 274986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 2750a473124SJohn Baldwin printf("ENABLED"); 2760a473124SJohn Baldwin else 2770a473124SJohn Baldwin printf("DISABLED"); 2780a473124SJohn Baldwin printf("}\n"); 279986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 2800a473124SJohn Baldwin } 2810a473124SJohn Baldwin 2820a473124SJohn Baldwin static void 283986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 2840a473124SJohn Baldwin { 285986dffafSJohn Baldwin 286986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 2870a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 288986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 2890a473124SJohn Baldwin } 2900a473124SJohn Baldwin 2910a473124SJohn Baldwin static void 292986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 2930a473124SJohn Baldwin { 2940a473124SJohn Baldwin 2950a473124SJohn Baldwin printf("\tFlags={Polarity="); 296986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 297986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 2980a473124SJohn Baldwin printf("conforming"); 2990a473124SJohn Baldwin break; 300986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3010a473124SJohn Baldwin printf("active-hi"); 3020a473124SJohn Baldwin break; 303986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3040a473124SJohn Baldwin printf("active-lo"); 3050a473124SJohn Baldwin break; 3060a473124SJohn Baldwin default: 307986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3080a473124SJohn Baldwin break; 3090a473124SJohn Baldwin } 3100a473124SJohn Baldwin printf(", Trigger="); 311986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 312986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3130a473124SJohn Baldwin printf("conforming"); 3140a473124SJohn Baldwin break; 315986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3160a473124SJohn Baldwin printf("edge"); 3170a473124SJohn Baldwin break; 318986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3190a473124SJohn Baldwin printf("level"); 3200a473124SJohn Baldwin break; 3210a473124SJohn Baldwin default: 322986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3230a473124SJohn Baldwin } 3240a473124SJohn Baldwin printf("}\n"); 3250a473124SJohn Baldwin } 3260a473124SJohn Baldwin 3270a473124SJohn Baldwin static void 328986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 3290a473124SJohn Baldwin { 3300a473124SJohn Baldwin 331986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 332986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 333986dffafSJohn Baldwin } 334986dffafSJohn Baldwin 335986dffafSJohn Baldwin static void 336986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 337986dffafSJohn Baldwin { 338986dffafSJohn Baldwin 339986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 3400a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 3410a473124SJohn Baldwin } 3420a473124SJohn Baldwin 3430a473124SJohn Baldwin const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI", 344986dffafSJohn Baldwin "Local APIC NMI", "Local APIC Override", 345986dffafSJohn Baldwin "IO SAPIC", "Local SAPIC", "Platform Interrupt", 346986dffafSJohn Baldwin "Local X2APIC", "Local X2APIC NMI" }; 347986dffafSJohn Baldwin const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 3480a473124SJohn Baldwin "Corrected Platform Error" }; 3490a473124SJohn Baldwin 3500a473124SJohn Baldwin static void 351986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 3520a473124SJohn Baldwin { 353986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 354986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 355986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 356986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 357986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 358986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 359986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 360986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 361986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 362986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 363986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 3640a473124SJohn Baldwin 365986dffafSJohn Baldwin if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0])) 366986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 367a0333ad1SJohn Baldwin else 368986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 369986dffafSJohn Baldwin switch (mp->Type) { 370986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 371986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 372986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 373986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 3740a473124SJohn Baldwin break; 375986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 376986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 377986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 378986dffafSJohn Baldwin ioapic->Address); 3790a473124SJohn Baldwin break; 380986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 381986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 382986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 383986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 384986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 3850a473124SJohn Baldwin break; 386986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 387986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 388986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 3890a473124SJohn Baldwin break; 390986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 391986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 392986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 393986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 3940a473124SJohn Baldwin break; 395986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 396986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 397945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 398986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 3990a473124SJohn Baldwin break; 400986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 401986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 402986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 403986dffafSJohn Baldwin iosapic->Address); 4040a473124SJohn Baldwin break; 405986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 406986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 407986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 408986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 409986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 410986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 411986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 4120a473124SJohn Baldwin break; 413986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 414986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 415986dffafSJohn Baldwin if (isrc->Type < sizeof(platform_int_types) / 416986dffafSJohn Baldwin sizeof(platform_int_types[0])) 417986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 418986dffafSJohn Baldwin else 419986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 420986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 421986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 422986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 423986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 424986dffafSJohn Baldwin break; 425986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 426986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 427986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 428986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 429986dffafSJohn Baldwin break; 430986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 431986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 432986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 433986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 4340a473124SJohn Baldwin break; 4350a473124SJohn Baldwin } 4360a473124SJohn Baldwin } 4370a473124SJohn Baldwin 4380a473124SJohn Baldwin static void 439986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 4400a473124SJohn Baldwin { 441986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 4420a473124SJohn Baldwin 443773b6454SNate Lawson printf(BEGIN_COMMENT); 444773b6454SNate Lawson acpi_print_sdt(sdp); 445986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 446986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 4470a473124SJohn Baldwin printf("\tFlags={"); 448986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 4490a473124SJohn Baldwin printf("PC-AT"); 4500a473124SJohn Baldwin printf("}\n"); 451986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 4520a473124SJohn Baldwin printf(END_COMMENT); 4530a473124SJohn Baldwin } 4540a473124SJohn Baldwin 4550a473124SJohn Baldwin static void 456986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 45779d7565cSPeter Wemm { 458986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 45979d7565cSPeter Wemm 460773b6454SNate Lawson printf(BEGIN_COMMENT); 461773b6454SNate Lawson acpi_print_sdt(sdp); 462986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 463986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 46487f9f09aSTakanori Watanabe printf("\tADDR="); 465986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 466986dffafSJohn Baldwin printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 467986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 468986dffafSJohn Baldwin 8); 469986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 470986dffafSJohn Baldwin 1 : 0); 47179d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 472986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 47379d7565cSPeter Wemm printf("TRUE}\n"); 47479d7565cSPeter Wemm else 47579d7565cSPeter Wemm printf("FALSE}\n"); 476986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 477986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 47879d7565cSPeter Wemm printf(END_COMMENT); 47979d7565cSPeter Wemm } 48079d7565cSPeter Wemm 48179d7565cSPeter Wemm static void 482986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 48355d7ff9eSNate Lawson { 484986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 48555d7ff9eSNate Lawson 48655d7ff9eSNate Lawson printf(BEGIN_COMMENT); 48755d7ff9eSNate Lawson acpi_print_sdt(sdp); 488986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 48955d7ff9eSNate Lawson printf("\tEC_CONTROL="); 490986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 49155d7ff9eSNate Lawson printf("\n\tEC_DATA="); 492986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 493986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 494986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 495986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 49655d7ff9eSNate Lawson printf(END_COMMENT); 49755d7ff9eSNate Lawson } 49855d7ff9eSNate Lawson 49955d7ff9eSNate Lawson static void 500986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 501a47e681bSScott Long { 502986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 503986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 504986dffafSJohn Baldwin u_int i, entries; 505a47e681bSScott Long 506a47e681bSScott Long printf(BEGIN_COMMENT); 507a47e681bSScott Long acpi_print_sdt(sdp); 508986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 509986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 510986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 511986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 512986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 513a47e681bSScott Long printf("\n"); 514986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", alloc->Address); 515986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 516986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 517986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 518a47e681bSScott Long } 519a47e681bSScott Long printf(END_COMMENT); 520a47e681bSScott Long } 521a47e681bSScott Long 522a47e681bSScott Long static void 523*33866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 524*33866658SJohn Baldwin { 525*33866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 526*33866658SJohn Baldwin UINT64 i, j; 527*33866658SJohn Baldwin 528*33866658SJohn Baldwin printf(BEGIN_COMMENT); 529*33866658SJohn Baldwin acpi_print_sdt(sdp); 530*33866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 531*33866658SJohn Baldwin printf("\tLocality Count=%jd\n", slit->LocalityCount); 532*33866658SJohn Baldwin printf("\n\t "); 533*33866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 534*33866658SJohn Baldwin printf(" %3jd", i); 535*33866658SJohn Baldwin printf("\n\t +"); 536*33866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 537*33866658SJohn Baldwin printf("----"); 538*33866658SJohn Baldwin printf("\n"); 539*33866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 540*33866658SJohn Baldwin printf("\t %3jd |", i); 541*33866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 542*33866658SJohn Baldwin printf(" %3d", 543*33866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 544*33866658SJohn Baldwin printf("\n"); 545*33866658SJohn Baldwin } 546*33866658SJohn Baldwin printf(END_COMMENT); 547*33866658SJohn Baldwin } 548*33866658SJohn Baldwin 549*33866658SJohn Baldwin static void 550a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 551a0333ad1SJohn Baldwin uint32_t flags) 552a0333ad1SJohn Baldwin { 553a0333ad1SJohn Baldwin 554a0333ad1SJohn Baldwin printf("\tFlags={"); 555a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 556a0333ad1SJohn Baldwin printf("ENABLED"); 557a0333ad1SJohn Baldwin else 558a0333ad1SJohn Baldwin printf("DISABLED"); 559a0333ad1SJohn Baldwin printf("}\n"); 560a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 561a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 562a0333ad1SJohn Baldwin } 563a0333ad1SJohn Baldwin 564c031c93bSTakanori Watanabe static char * 565c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 566c031c93bSTakanori Watanabe { 567c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 568c031c93bSTakanori Watanabe char *eventname = NULL; 569c031c93bSTakanori Watanabe 570c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 571c031c93bSTakanori Watanabe 572c031c93bSTakanori Watanabe switch(event->event_type) { 573c031c93bSTakanori Watanabe case PREBOOT: 574c031c93bSTakanori Watanabe case POST_CODE: 575c031c93bSTakanori Watanabe case UNUSED: 576c031c93bSTakanori Watanabe case NO_ACTION: 577c031c93bSTakanori Watanabe case SEPARATOR: 578c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 579c031c93bSTakanori Watanabe case SCRTM_VERSION: 580c031c93bSTakanori Watanabe case CPU_MICROCODE: 581c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 582c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 583c031c93bSTakanori Watanabe case COMPACT_HASH: 584c031c93bSTakanori Watanabe case IPL: 585c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 586c031c93bSTakanori Watanabe case NONHOST_CODE: 587c031c93bSTakanori Watanabe case NONHOST_CONFIG: 588c031c93bSTakanori Watanabe case NONHOST_INFO: 589c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 590c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 591c031c93bSTakanori Watanabe break; 592c031c93bSTakanori Watanabe 593c031c93bSTakanori Watanabe case ACTION: 594c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 595c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 596c031c93bSTakanori Watanabe break; 597c031c93bSTakanori Watanabe 598c031c93bSTakanori Watanabe case EVENT_TAG: 599c031c93bSTakanori Watanabe switch (pc_event->event_id) { 600c031c93bSTakanori Watanabe case SMBIOS: 601c031c93bSTakanori Watanabe case BIS_CERT: 602c031c93bSTakanori Watanabe case CMOS: 603c031c93bSTakanori Watanabe case NVRAM: 604c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 605c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 606c031c93bSTakanori Watanabe case S_CRTM_VERSION: 607c031c93bSTakanori Watanabe case POST_BIOS_ROM: 608c031c93bSTakanori Watanabe case ESCD: 609c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 610c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 611c031c93bSTakanori Watanabe case POST_CONTENTS: 612c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 613c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 614c031c93bSTakanori Watanabe break; 615c031c93bSTakanori Watanabe 616c031c93bSTakanori Watanabe default: 617c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 618c031c93bSTakanori Watanabe pc_event->event_id); 619c031c93bSTakanori Watanabe break; 620c031c93bSTakanori Watanabe } 621c031c93bSTakanori Watanabe break; 622c031c93bSTakanori Watanabe 623c031c93bSTakanori Watanabe default: 624c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 625c031c93bSTakanori Watanabe break; 626c031c93bSTakanori Watanabe } 627c031c93bSTakanori Watanabe 628c031c93bSTakanori Watanabe return eventname; 629c031c93bSTakanori Watanabe } 630c031c93bSTakanori Watanabe 631c031c93bSTakanori Watanabe static void 632c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 633c031c93bSTakanori Watanabe { 634c031c93bSTakanori Watanabe int i; 635c031c93bSTakanori Watanabe char *eventname; 636c031c93bSTakanori Watanabe 637c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 638c031c93bSTakanori Watanabe 639c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 640c031c93bSTakanori Watanabe printf(" 0x"); 641c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 642c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 643c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 644c031c93bSTakanori Watanabe 645c031c93bSTakanori Watanabe free(eventname); 646c031c93bSTakanori Watanabe } 647c031c93bSTakanori Watanabe 648c031c93bSTakanori Watanabe static void 649c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 650c031c93bSTakanori Watanabe { 651c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 652c031c93bSTakanori Watanabe struct TCPAevent *event; 653977fd9daSTakanori Watanabe uintmax_t len, paddr; 654c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 655c031c93bSTakanori Watanabe unsigned char *vend = NULL; 656c031c93bSTakanori Watanabe 657c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 658c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 659c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 660c031c93bSTakanori Watanabe 661c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 662c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 663c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 664c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 665c031c93bSTakanori Watanabe break; 666c031c93bSTakanori Watanabe 667c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 668c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 669c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 670c031c93bSTakanori Watanabe break; 671c031c93bSTakanori Watanabe 672c031c93bSTakanori Watanabe default: 673c031c93bSTakanori Watanabe printf("XXX"); 674c031c93bSTakanori Watanabe printf(END_COMMENT); 675c031c93bSTakanori Watanabe return; 676c031c93bSTakanori Watanabe } 6770e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 678c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 679c031c93bSTakanori Watanabe 680c031c93bSTakanori Watanabe if (len == 0) { 681c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 682c031c93bSTakanori Watanabe printf(END_COMMENT); 683c031c93bSTakanori Watanabe return; 684c031c93bSTakanori Watanabe } 6852ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 6862ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 6872ef23c6dSTakanori Watanabe printf(END_COMMENT); 6882ef23c6dSTakanori Watanabe return; 6892ef23c6dSTakanori Watanabe } 690c031c93bSTakanori Watanabe 691c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 692c031c93bSTakanori Watanabe vend = vaddr + len; 693c031c93bSTakanori Watanabe 694c031c93bSTakanori Watanabe while (vaddr != NULL) { 6952ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 6962ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 697c031c93bSTakanori Watanabe break; 6980e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 699c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 700c031c93bSTakanori Watanabe break; 7012ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 7022ef23c6dSTakanori Watanabe break; 703c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 704c031c93bSTakanori Watanabe break; 705c031c93bSTakanori Watanabe #if 0 706c031c93bSTakanori Watanabe { 707c031c93bSTakanori Watanabe unsigned int i, j, k; 708c031c93bSTakanori Watanabe 709c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 710c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 711c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 712c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 713c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 714c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 715c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 716c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 717c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 718c031c93bSTakanori Watanabe j = i + 1; 719c031c93bSTakanori Watanabe } 720c031c93bSTakanori Watanabe } 721c031c93bSTakanori Watanabe printf("\n"); } 722c031c93bSTakanori Watanabe #endif 723c031c93bSTakanori Watanabe acpi_print_tcpa(event); 724c031c93bSTakanori Watanabe 725c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 726c031c93bSTakanori Watanabe } 727c031c93bSTakanori Watanabe 728c031c93bSTakanori Watanabe printf(END_COMMENT); 729c031c93bSTakanori Watanabe } 730c031c93bSTakanori Watanabe 731a0333ad1SJohn Baldwin static void 732986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 733a0333ad1SJohn Baldwin { 734a0333ad1SJohn Baldwin 735a0333ad1SJohn Baldwin printf("\tFlags={"); 736986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 737a0333ad1SJohn Baldwin printf("ENABLED"); 738a0333ad1SJohn Baldwin else 739a0333ad1SJohn Baldwin printf("DISABLED"); 740986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 741a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 742986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 743a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 744a0333ad1SJohn Baldwin printf("}\n"); 745986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 746986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 747986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 748a0333ad1SJohn Baldwin } 749a0333ad1SJohn Baldwin 750a0333ad1SJohn Baldwin const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; 751a0333ad1SJohn Baldwin 752a0333ad1SJohn Baldwin static void 753986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 754a0333ad1SJohn Baldwin { 755986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 756986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 757a0333ad1SJohn Baldwin 758986dffafSJohn Baldwin if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0])) 759986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 760a0333ad1SJohn Baldwin else 761986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 762986dffafSJohn Baldwin switch (srat->Type) { 763a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 764986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 765986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 766986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 767986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 768986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 769986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 770a0333ad1SJohn Baldwin break; 771a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 772986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 773a0333ad1SJohn Baldwin break; 774a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 775986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 776986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 777986dffafSJohn Baldwin x2apic->Flags); 778a0333ad1SJohn Baldwin break; 779a0333ad1SJohn Baldwin } 780a0333ad1SJohn Baldwin } 781a0333ad1SJohn Baldwin 782a0333ad1SJohn Baldwin static void 783986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 784a0333ad1SJohn Baldwin { 785986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 786a0333ad1SJohn Baldwin 787a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 788a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 789986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 790986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 791986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 792a0333ad1SJohn Baldwin printf(END_COMMENT); 793a0333ad1SJohn Baldwin } 794a0333ad1SJohn Baldwin 795a0333ad1SJohn Baldwin static void 796986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 797c62f1cccSMitsuru IWASAKI { 798773b6454SNate Lawson printf(" "); 799986dffafSJohn Baldwin acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); 800c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 801986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 802e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 803986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 804e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 805986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 806986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 807e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 808986dffafSJohn Baldwin acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); 809986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 810e1e9a4bfSMitsuru IWASAKI } 811e1e9a4bfSMitsuru IWASAKI 812945137d9SNate Lawson static void 813986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 814e1e9a4bfSMitsuru IWASAKI { 815986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 816986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 817e1e9a4bfSMitsuru IWASAKI int i, entries; 818a74172abSNate Lawson u_long addr; 819e1e9a4bfSMitsuru IWASAKI 820986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 821986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 822773b6454SNate Lawson printf(BEGIN_COMMENT); 823773b6454SNate Lawson acpi_print_sdt(rsdp); 824986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 825e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 826e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 827e1e9a4bfSMitsuru IWASAKI if (i > 0) 828e1e9a4bfSMitsuru IWASAKI printf(", "); 829a74172abSNate Lawson switch (addr_size) { 830a74172abSNate Lawson case 4: 831986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 832a74172abSNate Lawson break; 833a74172abSNate Lawson case 8: 834986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 835a74172abSNate Lawson break; 836a74172abSNate Lawson default: 837a74172abSNate Lawson addr = 0; 838a74172abSNate Lawson } 839a74172abSNate Lawson assert(addr != 0); 840a74172abSNate Lawson printf("0x%08lx", addr); 841e1e9a4bfSMitsuru IWASAKI } 842e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 843c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 844e1e9a4bfSMitsuru IWASAKI } 845e1e9a4bfSMitsuru IWASAKI 8468e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 8478e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 8488e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 8498e6a8737SNate Lawson }; 8508e6a8737SNate Lawson 851945137d9SNate Lawson static void 852986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 853e1e9a4bfSMitsuru IWASAKI { 854986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 8558e6a8737SNate Lawson const char *pm; 856e1e9a4bfSMitsuru IWASAKI char sep; 857e1e9a4bfSMitsuru IWASAKI 858986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 859c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 8602177d4e6SNate Lawson acpi_print_sdt(sdp); 861986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 862986dffafSJohn Baldwin fadt->Dsdt); 863986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 864986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 8658e6a8737SNate Lawson pm = "Reserved"; 8668e6a8737SNate Lawson else 867986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 868986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 869986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 870986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 871986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 872986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 873986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 874986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 875e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 876986dffafSJohn Baldwin fadt->Pm1aEventBlock, 877986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 878986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 879e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 880986dffafSJohn Baldwin fadt->Pm1bEventBlock, 881986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 882e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 883986dffafSJohn Baldwin fadt->Pm1aControlBlock, 884986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 885986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 886e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 887986dffafSJohn Baldwin fadt->Pm1bControlBlock, 888986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 889986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 890e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 891986dffafSJohn Baldwin fadt->Pm2ControlBlock, 892986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 893c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 894986dffafSJohn Baldwin fadt->PmTimerBlock, 895986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 896986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 8978e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 898986dffafSJohn Baldwin fadt->Gpe0Block, 899986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 900986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 9018e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 902986dffafSJohn Baldwin fadt->Gpe1Block, 903986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 904986dffafSJohn Baldwin fadt->Gpe1Base); 905986dffafSJohn Baldwin if (fadt->CstControl != 0) 906986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 90751c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 908986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 909e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 910986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 911e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 912986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 913e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 914986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 915e1e9a4bfSMitsuru IWASAKI 9168e6a8737SNate Lawson #define PRINTFLAG(var, flag) do { \ 917986dffafSJohn Baldwin if ((var) & ACPI_FADT_## flag) { \ 9188e6a8737SNate Lawson printf("%c%s", sep, #flag); sep = ','; \ 919e1e9a4bfSMitsuru IWASAKI } \ 920e1e9a4bfSMitsuru IWASAKI } while (0) 921e1e9a4bfSMitsuru IWASAKI 9228e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 9238e6a8737SNate Lawson sep = '{'; 924986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 925986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 926986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 927986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 928986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 929986dffafSJohn Baldwin if (fadt->BootFlags != 0) 9304e36f5a1SNate Lawson printf("}"); 9314e36f5a1SNate Lawson printf("\n"); 9328e6a8737SNate Lawson 9338e6a8737SNate Lawson printf("\tFlags="); 9348e6a8737SNate Lawson sep = '{'; 935986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 936986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 937986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 938986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 939986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 940986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 941986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 942986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 943986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 944986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 945986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 946986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 947986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 948986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 949986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 950986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 951986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 952986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 953986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 954986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 955986dffafSJohn Baldwin if (fadt->Flags != 0) 9568e6a8737SNate Lawson printf("}\n"); 957e1e9a4bfSMitsuru IWASAKI 958e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 959e1e9a4bfSMitsuru IWASAKI 960986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 9618e6a8737SNate Lawson printf("\tRESET_REG="); 962986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 963986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 9648e6a8737SNate Lawson } 965c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 966986dffafSJohn Baldwin printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs); 967986dffafSJohn Baldwin printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt); 968c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 969986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 970986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 971c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 972986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 973c08c4e81SNate Lawson } 974c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 975986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 976986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 977c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 978986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 979c08c4e81SNate Lawson } 980986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 981773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 982986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 983c08c4e81SNate Lawson } 984773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 985986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 986986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 987773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 988986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 989c08c4e81SNate Lawson } 990986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 991773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 992986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 993c08c4e81SNate Lawson } 994773b6454SNate Lawson printf("\n"); 995773b6454SNate Lawson } 9968e6a8737SNate Lawson 9978e6a8737SNate Lawson printf(END_COMMENT); 9988e6a8737SNate Lawson } 9998e6a8737SNate Lawson 10008e6a8737SNate Lawson static void 1001986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 10028e6a8737SNate Lawson { 10038e6a8737SNate Lawson printf(BEGIN_COMMENT); 1004986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 1005986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 1006986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 10078e6a8737SNate Lawson 1008773b6454SNate Lawson printf("\tGlobal_Lock="); 1009986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 1010986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 10118e6a8737SNate Lawson printf("PENDING,"); 1012986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 10138e6a8737SNate Lawson printf("OWNED"); 10148e6a8737SNate Lawson } 1015773b6454SNate Lawson printf("\n"); 10168e6a8737SNate Lawson 1017773b6454SNate Lawson printf("\tFlags="); 1018986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 10198e6a8737SNate Lawson printf("S4BIOS"); 1020773b6454SNate Lawson printf("\n"); 10218e6a8737SNate Lawson 1022986dffafSJohn Baldwin if (facs->XFirmwareWakingVector != 0) { 10238e6a8737SNate Lawson printf("\tX_Firm_Wake_Vec=%08lx\n", 1024986dffafSJohn Baldwin (u_long)facs->XFirmwareWakingVector); 10258e6a8737SNate Lawson } 1026986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 10278e6a8737SNate Lawson 1028c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1029e1e9a4bfSMitsuru IWASAKI } 1030e1e9a4bfSMitsuru IWASAKI 1031945137d9SNate Lawson static void 1032986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 1033e1e9a4bfSMitsuru IWASAKI { 1034773b6454SNate Lawson printf(BEGIN_COMMENT); 1035773b6454SNate Lawson acpi_print_sdt(dsdp); 1036773b6454SNate Lawson printf(END_COMMENT); 1037e1e9a4bfSMitsuru IWASAKI } 1038e1e9a4bfSMitsuru IWASAKI 1039e1e9a4bfSMitsuru IWASAKI int 1040e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 1041e1e9a4bfSMitsuru IWASAKI { 1042986dffafSJohn Baldwin uint8_t *bp; 1043986dffafSJohn Baldwin uint8_t sum; 1044e1e9a4bfSMitsuru IWASAKI 1045e1e9a4bfSMitsuru IWASAKI bp = p; 1046e1e9a4bfSMitsuru IWASAKI sum = 0; 1047e1e9a4bfSMitsuru IWASAKI while (length--) 1048e1e9a4bfSMitsuru IWASAKI sum += *bp++; 1049e1e9a4bfSMitsuru IWASAKI 1050e1e9a4bfSMitsuru IWASAKI return (sum); 1051e1e9a4bfSMitsuru IWASAKI } 1052e1e9a4bfSMitsuru IWASAKI 1053986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 1054e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 1055e1e9a4bfSMitsuru IWASAKI { 1056986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 1057e1e9a4bfSMitsuru IWASAKI 1058986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 1059986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 1060e1e9a4bfSMitsuru IWASAKI return (sp); 1061e1e9a4bfSMitsuru IWASAKI } 1062e1e9a4bfSMitsuru IWASAKI 1063945137d9SNate Lawson static void 1064986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 1065e1e9a4bfSMitsuru IWASAKI { 1066c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 1067a74172abSNate Lawson printf(" RSD PTR: OEM="); 1068986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 1069986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 1070986dffafSJohn Baldwin rp->Revision); 1071986dffafSJohn Baldwin if (rp->Revision < 2) { 1072986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 1073986dffafSJohn Baldwin rp->Checksum); 1074a74172abSNate Lawson } else { 1075a74172abSNate Lawson printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", 1076986dffafSJohn Baldwin (u_long)rp->XsdtPhysicalAddress, rp->Length, 1077986dffafSJohn Baldwin rp->ExtendedChecksum); 1078a74172abSNate Lawson } 1079c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1080e1e9a4bfSMitsuru IWASAKI } 1081e1e9a4bfSMitsuru IWASAKI 1082945137d9SNate Lawson static void 1083986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 1084e1e9a4bfSMitsuru IWASAKI { 1085986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 1086986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1087986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1088a74172abSNate Lawson vm_offset_t addr; 1089a74172abSNate Lawson int entries, i; 1090e1e9a4bfSMitsuru IWASAKI 1091e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 1092986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1093986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1094986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1095e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1096a74172abSNate Lawson switch (addr_size) { 1097a74172abSNate Lawson case 4: 1098986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1099a74172abSNate Lawson break; 1100a74172abSNate Lawson case 8: 1101986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1102a74172abSNate Lawson break; 1103a74172abSNate Lawson default: 1104a74172abSNate Lawson assert((addr = 0)); 1105a74172abSNate Lawson } 1106a74172abSNate Lawson 1107986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1108986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 11095cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 1110986dffafSJohn Baldwin sdp->Signature); 11115cf6d493SNate Lawson continue; 11125cf6d493SNate Lawson } 1113986dffafSJohn Baldwin if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 11142177d4e6SNate Lawson acpi_handle_fadt(sdp); 1115986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 1116986dffafSJohn Baldwin acpi_handle_madt(sdp); 1117986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 111879d7565cSPeter Wemm acpi_handle_hpet(sdp); 1119986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 112055d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 1121986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 1122a47e681bSScott Long acpi_handle_mcfg(sdp); 1123*33866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 1124*33866658SJohn Baldwin acpi_handle_slit(sdp); 1125986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 1126a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 1127c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 1128c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 1129773b6454SNate Lawson else { 1130773b6454SNate Lawson printf(BEGIN_COMMENT); 1131773b6454SNate Lawson acpi_print_sdt(sdp); 1132773b6454SNate Lawson printf(END_COMMENT); 1133773b6454SNate Lawson } 1134e1e9a4bfSMitsuru IWASAKI } 1135e1e9a4bfSMitsuru IWASAKI } 1136c62f1cccSMitsuru IWASAKI 1137986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1138476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 1139945137d9SNate Lawson { 1140986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 1141986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 1142945137d9SNate Lawson 1143945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 1144945137d9SNate Lawson if (!rp) 1145945137d9SNate Lawson errx(1, "Can't find ACPI information"); 1146945137d9SNate Lawson 1147945137d9SNate Lawson if (tflag) 1148945137d9SNate Lawson acpi_print_rsd_ptr(rp); 1149986dffafSJohn Baldwin if (rp->Revision < 2) { 1150986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 1151986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 1152986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1153945137d9SNate Lawson errx(1, "RSDT is corrupted"); 1154a74172abSNate Lawson addr_size = sizeof(uint32_t); 1155a74172abSNate Lawson } else { 1156986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 1157986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 1158986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1159a74172abSNate Lawson errx(1, "XSDT is corrupted"); 1160a74172abSNate Lawson addr_size = sizeof(uint64_t); 1161a74172abSNate Lawson } 1162945137d9SNate Lawson return (rsdp); 1163945137d9SNate Lawson } 1164c62f1cccSMitsuru IWASAKI 116562c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 1166bfa3f012SMarcel Moolenaar static int 1167986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 1168bfa3f012SMarcel Moolenaar { 1169986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 1170986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 1171bfa3f012SMarcel Moolenaar uint8_t sum; 1172bfa3f012SMarcel Moolenaar 117362c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 1174bfa3f012SMarcel Moolenaar sdt = *dsdt; 1175bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 1176986dffafSJohn Baldwin sdt.Checksum = 0; 1177986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 1178986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1179986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 1180f7675a56SNate Lawson while (ssdt != NULL) { 1181986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 1182986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 1183986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 1184986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 1185bfa3f012SMarcel Moolenaar } 1186986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 1187986dffafSJohn Baldwin sdt.Checksum -= sum; 1188bfa3f012SMarcel Moolenaar } 118962c7bde1SNate Lawson 119062c7bde1SNate Lawson /* Write out the DSDT header and body. */ 1191986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 1192986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 119362c7bde1SNate Lawson 1194b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 1195f7675a56SNate Lawson if (rsdt != NULL) { 1196bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 1197bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 1198986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 1199986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1200bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 1201bfa3f012SMarcel Moolenaar } 1202bfa3f012SMarcel Moolenaar } 1203bfa3f012SMarcel Moolenaar return (0); 1204bfa3f012SMarcel Moolenaar } 1205bfa3f012SMarcel Moolenaar 1206c62f1cccSMitsuru IWASAKI void 1207986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1208c62f1cccSMitsuru IWASAKI { 1209945137d9SNate Lawson int fd; 1210945137d9SNate Lawson mode_t mode; 1211945137d9SNate Lawson 1212945137d9SNate Lawson assert(outfile != NULL); 1213945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1214945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 1215945137d9SNate Lawson if (fd == -1) { 1216945137d9SNate Lawson perror("dsdt_save_file"); 1217945137d9SNate Lawson return; 1218945137d9SNate Lawson } 1219bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1220945137d9SNate Lawson close(fd); 1221c62f1cccSMitsuru IWASAKI } 1222c62f1cccSMitsuru IWASAKI 1223945137d9SNate Lawson void 1224986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1225c62f1cccSMitsuru IWASAKI { 122699065116SJung-uk Kim char buf[PATH_MAX], tmpstr[PATH_MAX]; 122799065116SJung-uk Kim const char *tmpdir; 122899065116SJung-uk Kim char *tmpext; 1229945137d9SNate Lawson FILE *fp; 123099065116SJung-uk Kim size_t len; 123199065116SJung-uk Kim int fd; 1232945137d9SNate Lawson 123399065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 123499065116SJung-uk Kim if (tmpdir == NULL) 123599065116SJung-uk Kim tmpdir = _PATH_TMP; 123699065116SJung-uk Kim strncpy(tmpstr, tmpdir, sizeof(tmpstr)); 123799065116SJung-uk Kim if (realpath(tmpstr, buf) == NULL) { 1238d6a6e590SJung-uk Kim perror("realpath tmp dir"); 123999065116SJung-uk Kim return; 124099065116SJung-uk Kim } 124199065116SJung-uk Kim strncpy(tmpstr, buf, sizeof(tmpstr)); 1242d6a6e590SJung-uk Kim strncat(tmpstr, "/acpidump.", sizeof(tmpstr) - strlen(buf)); 1243d6a6e590SJung-uk Kim len = strlen(tmpstr); 124499065116SJung-uk Kim tmpext = tmpstr + len; 124599065116SJung-uk Kim strncpy(tmpext, "XXXXXX", sizeof(tmpstr) - len); 1246945137d9SNate Lawson fd = mkstemp(tmpstr); 1247945137d9SNate Lawson if (fd < 0) { 1248945137d9SNate Lawson perror("iasl tmp file"); 1249945137d9SNate Lawson return; 1250c62f1cccSMitsuru IWASAKI } 1251bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1252945137d9SNate Lawson close(fd); 1253945137d9SNate Lawson 1254945137d9SNate Lawson /* Run iasl -d on the temp file */ 1255945137d9SNate Lawson if (fork() == 0) { 1256945137d9SNate Lawson close(STDOUT_FILENO); 1257945137d9SNate Lawson if (vflag == 0) 1258945137d9SNate Lawson close(STDERR_FILENO); 125999065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 1260945137d9SNate Lawson err(1, "exec"); 1261c62f1cccSMitsuru IWASAKI } 1262c62f1cccSMitsuru IWASAKI 1263945137d9SNate Lawson wait(NULL); 1264945137d9SNate Lawson unlink(tmpstr); 1265945137d9SNate Lawson 1266945137d9SNate Lawson /* Dump iasl's output to stdout */ 126799065116SJung-uk Kim strncpy(tmpext, "dsl", sizeof(tmpstr) - len); 126899065116SJung-uk Kim fp = fopen(tmpstr, "r"); 126999065116SJung-uk Kim unlink(tmpstr); 1270945137d9SNate Lawson if (fp == NULL) { 1271945137d9SNate Lawson perror("iasl tmp file (read)"); 1272945137d9SNate Lawson return; 1273945137d9SNate Lawson } 1274945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 1275945137d9SNate Lawson fwrite(buf, 1, len, stdout); 1276945137d9SNate Lawson fclose(fp); 1277c62f1cccSMitsuru IWASAKI } 1278c62f1cccSMitsuru IWASAKI 1279945137d9SNate Lawson void 1280986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 1281c62f1cccSMitsuru IWASAKI { 1282945137d9SNate Lawson acpi_handle_rsdt(rsdp); 1283c62f1cccSMitsuru IWASAKI } 1284c62f1cccSMitsuru IWASAKI 1285bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 1286986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1287986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 1288c62f1cccSMitsuru IWASAKI { 1289986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1290986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1291986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1292a74172abSNate Lawson vm_offset_t addr; 1293a74172abSNate Lawson int entries, i; 1294945137d9SNate Lawson 1295986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1296986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1297986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1298945137d9SNate Lawson for (i = 0; i < entries; i++) { 1299a74172abSNate Lawson switch (addr_size) { 1300a74172abSNate Lawson case 4: 1301986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1302a74172abSNate Lawson break; 1303a74172abSNate Lawson case 8: 1304986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1305a74172abSNate Lawson break; 1306a74172abSNate Lawson default: 1307a74172abSNate Lawson assert((addr = 0)); 1308a74172abSNate Lawson } 1309986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1310bfa3f012SMarcel Moolenaar if (last != NULL) { 1311bfa3f012SMarcel Moolenaar if (sdt == last) 1312bfa3f012SMarcel Moolenaar last = NULL; 1313bfa3f012SMarcel Moolenaar continue; 1314bfa3f012SMarcel Moolenaar } 1315986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 1316a74172abSNate Lawson continue; 1317986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1318945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 1319945137d9SNate Lawson return (sdt); 1320c62f1cccSMitsuru IWASAKI } 1321c62f1cccSMitsuru IWASAKI 1322945137d9SNate Lawson return (NULL); 1323c62f1cccSMitsuru IWASAKI } 1324c62f1cccSMitsuru IWASAKI 1325986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1326986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 1327c62f1cccSMitsuru IWASAKI { 1328986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1329c62f1cccSMitsuru IWASAKI 1330986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 1331c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 1332986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 13332e71eb12SNate Lawson else 1334986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 1335986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1336945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1337945137d9SNate Lawson return (sdt); 1338c62f1cccSMitsuru IWASAKI } 1339