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); 66a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 67a0333ad1SJohn Baldwin uint32_t flags); 68986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); 69986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); 70986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); 71c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); 72986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); 73986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); 74986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs); 75986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); 76986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); 77986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); 78986dffafSJohn Baldwin static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); 79986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 80986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)); 81c62f1cccSMitsuru IWASAKI 82773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 83a74172abSNate Lawson static int addr_size; 84a74172abSNate Lawson 85c031c93bSTakanori Watanabe /* Strings used in the TCPA table */ 86c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = { 87c031c93bSTakanori Watanabe "PREBOOT Certificate", 88c031c93bSTakanori Watanabe "POST Code", 89c031c93bSTakanori Watanabe "Unused", 90c031c93bSTakanori Watanabe "No Action", 91c031c93bSTakanori Watanabe "Separator", 92c031c93bSTakanori Watanabe "Action", 93c031c93bSTakanori Watanabe "Event Tag", 94c031c93bSTakanori Watanabe "S-CRTM Contents", 95c031c93bSTakanori Watanabe "S-CRTM Version", 96c031c93bSTakanori Watanabe "CPU Microcode", 97c031c93bSTakanori Watanabe "Platform Config Flags", 98c031c93bSTakanori Watanabe "Table of Devices", 99c031c93bSTakanori Watanabe "Compact Hash", 100c031c93bSTakanori Watanabe "IPL", 101c031c93bSTakanori Watanabe "IPL Partition Data", 102c031c93bSTakanori Watanabe "Non-Host Code", 103c031c93bSTakanori Watanabe "Non-Host Config", 104c031c93bSTakanori Watanabe "Non-Host Info" 105c031c93bSTakanori Watanabe }; 106c031c93bSTakanori Watanabe 107c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = { 108c031c93bSTakanori Watanabe "<undefined>", 109c031c93bSTakanori Watanabe "SMBIOS", 110c031c93bSTakanori Watanabe "BIS Certificate", 111c031c93bSTakanori Watanabe "POST BIOS ROM Strings", 112c031c93bSTakanori Watanabe "ESCD", 113c031c93bSTakanori Watanabe "CMOS", 114c031c93bSTakanori Watanabe "NVRAM", 115c031c93bSTakanori Watanabe "Option ROM Execute", 116c031c93bSTakanori Watanabe "Option ROM Configurateion", 117c031c93bSTakanori Watanabe "<undefined>", 118c031c93bSTakanori Watanabe "Option ROM Microcode Update ", 119c031c93bSTakanori Watanabe "S-CRTM Version String", 120c031c93bSTakanori Watanabe "S-CRTM Contents", 121c031c93bSTakanori Watanabe "POST Contents", 122c031c93bSTakanori Watanabe "Table of Devices", 123c031c93bSTakanori Watanabe }; 124c031c93bSTakanori Watanabe 125e1e9a4bfSMitsuru IWASAKI static void 126e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 127e1e9a4bfSMitsuru IWASAKI { 128e1e9a4bfSMitsuru IWASAKI int c; 129e1e9a4bfSMitsuru IWASAKI 130e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 131e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 132e1e9a4bfSMitsuru IWASAKI length--; 133e1e9a4bfSMitsuru IWASAKI 134e1e9a4bfSMitsuru IWASAKI while (length--) { 135e1e9a4bfSMitsuru IWASAKI c = *s++; 136e1e9a4bfSMitsuru IWASAKI putchar(c); 137e1e9a4bfSMitsuru IWASAKI } 138e1e9a4bfSMitsuru IWASAKI } 139e1e9a4bfSMitsuru IWASAKI 140e1e9a4bfSMitsuru IWASAKI static void 141986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1428e6a8737SNate Lawson { 143986dffafSJohn Baldwin switch(gas->SpaceId) { 1448e6a8737SNate Lawson case ACPI_GAS_MEMORY: 145986dffafSJohn Baldwin printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address, 146986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1478e6a8737SNate Lawson break; 1488e6a8737SNate Lawson case ACPI_GAS_IO: 149986dffafSJohn Baldwin printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address, 150986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1518e6a8737SNate Lawson break; 1528e6a8737SNate Lawson case ACPI_GAS_PCI: 153986dffafSJohn Baldwin printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), 154986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 155986dffafSJohn Baldwin (uint16_t)gas->Address); 1568e6a8737SNate Lawson break; 1578e6a8737SNate Lawson /* XXX How to handle these below? */ 1588e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 159986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 160986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1618e6a8737SNate Lawson break; 1628e6a8737SNate Lawson case ACPI_GAS_SMBUS: 163986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 164986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1658e6a8737SNate Lawson break; 166986dffafSJohn Baldwin case ACPI_GAS_CMOS: 167986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 168986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 1698e6a8737SNate Lawson case ACPI_GAS_FIXED: 1708e6a8737SNate Lawson default: 171986dffafSJohn Baldwin printf("0x%08lx (?)", (u_long)gas->Address); 1728e6a8737SNate Lawson break; 1738e6a8737SNate Lawson } 1748e6a8737SNate Lawson } 1758e6a8737SNate Lawson 176c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 177c2962974SNate Lawson static int 178986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 179e1e9a4bfSMitsuru IWASAKI { 180c2962974SNate Lawson int fadt_revision; 181e1e9a4bfSMitsuru IWASAKI 182c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 183c83f0f99SNate Lawson if (addr_size == 8) { 184c83f0f99SNate Lawson fadt_revision = 2; 1858e6a8737SNate Lawson 186773b6454SNate Lawson /* 187c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 188c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 189c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 190c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 191c83f0f99SNate Lawson * version for all subsequent tables. 192773b6454SNate Lawson */ 193986dffafSJohn Baldwin if (fadt->Facs != 0 && 194986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 195c83f0f99SNate Lawson fadt_revision = 1; 196c2962974SNate Lawson } else 197c83f0f99SNate Lawson fadt_revision = 1; 198c2962974SNate Lawson return (fadt_revision); 199c83f0f99SNate Lawson } 200c2962974SNate Lawson 201c2962974SNate Lawson static void 202986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 203c2962974SNate Lawson { 204986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 205986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 206986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 207c2962974SNate Lawson int fadt_revision; 208c2962974SNate Lawson 209986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2102177d4e6SNate Lawson acpi_print_fadt(sdp); 211c83f0f99SNate Lawson 212c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 213c83f0f99SNate Lawson if (fadt_revision == 1) 214986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); 215773b6454SNate Lawson else 216986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); 217986dffafSJohn Baldwin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) 2188e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2198e6a8737SNate Lawson acpi_print_facs(facs); 2208e6a8737SNate Lawson 221c83f0f99SNate Lawson if (fadt_revision == 1) 222986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 223773b6454SNate Lawson else 224986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 225986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 226945137d9SNate Lawson errx(1, "DSDT is corrupt"); 227945137d9SNate Lawson acpi_print_dsdt(dsdp); 228c62f1cccSMitsuru IWASAKI } 229c62f1cccSMitsuru IWASAKI 230c62f1cccSMitsuru IWASAKI static void 231986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 232986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 233986dffafSJohn Baldwin { 234986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 235986dffafSJohn Baldwin char *end; 236986dffafSJohn Baldwin 237986dffafSJohn Baldwin subtable = first; 238986dffafSJohn Baldwin end = (char *)table + table->Length; 239986dffafSJohn Baldwin while ((char *)subtable < end) { 240986dffafSJohn Baldwin printf("\n"); 241986dffafSJohn Baldwin action(subtable); 242986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 243986dffafSJohn Baldwin subtable->Length); 244986dffafSJohn Baldwin } 245986dffafSJohn Baldwin } 246986dffafSJohn Baldwin 247986dffafSJohn Baldwin static void 2480a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 2490a473124SJohn Baldwin { 2500a473124SJohn Baldwin 2510a473124SJohn Baldwin printf("\tACPI CPU="); 2520a473124SJohn Baldwin if (cpu_id == 0xff) 2530a473124SJohn Baldwin printf("ALL\n"); 2540a473124SJohn Baldwin else 2550a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 2560a473124SJohn Baldwin } 2570a473124SJohn Baldwin 2580a473124SJohn Baldwin static void 259986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 2600a473124SJohn Baldwin { 261986dffafSJohn Baldwin 262986dffafSJohn Baldwin printf("\tUID=%d", uid); 263986dffafSJohn Baldwin if (uid_string != NULL) 264986dffafSJohn Baldwin printf(" (%s)", uid_string); 265986dffafSJohn Baldwin printf("\n"); 266986dffafSJohn Baldwin } 267986dffafSJohn Baldwin 268986dffafSJohn Baldwin static void 269986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 270986dffafSJohn Baldwin { 271986dffafSJohn Baldwin 2720a473124SJohn Baldwin printf("\tFlags={"); 273986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 2740a473124SJohn Baldwin printf("ENABLED"); 2750a473124SJohn Baldwin else 2760a473124SJohn Baldwin printf("DISABLED"); 2770a473124SJohn Baldwin printf("}\n"); 278986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 2790a473124SJohn Baldwin } 2800a473124SJohn Baldwin 2810a473124SJohn Baldwin static void 282986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 2830a473124SJohn Baldwin { 284986dffafSJohn Baldwin 285986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 2860a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 287986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 2880a473124SJohn Baldwin } 2890a473124SJohn Baldwin 2900a473124SJohn Baldwin static void 291986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 2920a473124SJohn Baldwin { 2930a473124SJohn Baldwin 2940a473124SJohn Baldwin printf("\tFlags={Polarity="); 295986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 296986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 2970a473124SJohn Baldwin printf("conforming"); 2980a473124SJohn Baldwin break; 299986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3000a473124SJohn Baldwin printf("active-hi"); 3010a473124SJohn Baldwin break; 302986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3030a473124SJohn Baldwin printf("active-lo"); 3040a473124SJohn Baldwin break; 3050a473124SJohn Baldwin default: 306986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3070a473124SJohn Baldwin break; 3080a473124SJohn Baldwin } 3090a473124SJohn Baldwin printf(", Trigger="); 310986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 311986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3120a473124SJohn Baldwin printf("conforming"); 3130a473124SJohn Baldwin break; 314986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3150a473124SJohn Baldwin printf("edge"); 3160a473124SJohn Baldwin break; 317986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3180a473124SJohn Baldwin printf("level"); 3190a473124SJohn Baldwin break; 3200a473124SJohn Baldwin default: 321986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3220a473124SJohn Baldwin } 3230a473124SJohn Baldwin printf("}\n"); 3240a473124SJohn Baldwin } 3250a473124SJohn Baldwin 3260a473124SJohn Baldwin static void 327986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 3280a473124SJohn Baldwin { 3290a473124SJohn Baldwin 330986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 331986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 332986dffafSJohn Baldwin } 333986dffafSJohn Baldwin 334986dffafSJohn Baldwin static void 335986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 336986dffafSJohn Baldwin { 337986dffafSJohn Baldwin 338986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 3390a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 3400a473124SJohn Baldwin } 3410a473124SJohn Baldwin 3420a473124SJohn Baldwin const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI", 343986dffafSJohn Baldwin "Local APIC NMI", "Local APIC Override", 344986dffafSJohn Baldwin "IO SAPIC", "Local SAPIC", "Platform Interrupt", 345986dffafSJohn Baldwin "Local X2APIC", "Local X2APIC NMI" }; 346986dffafSJohn Baldwin const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 3470a473124SJohn Baldwin "Corrected Platform Error" }; 3480a473124SJohn Baldwin 3490a473124SJohn Baldwin static void 350986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 3510a473124SJohn Baldwin { 352986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 353986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 354986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 355986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 356986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 357986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 358986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 359986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 360986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 361986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 362986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 3630a473124SJohn Baldwin 364986dffafSJohn Baldwin if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0])) 365986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 366a0333ad1SJohn Baldwin else 367986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 368986dffafSJohn Baldwin switch (mp->Type) { 369986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 370986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 371986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 372986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 3730a473124SJohn Baldwin break; 374986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 375986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 376986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 377986dffafSJohn Baldwin ioapic->Address); 3780a473124SJohn Baldwin break; 379986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 380986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 381986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 382986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 383986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 3840a473124SJohn Baldwin break; 385986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 386986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 387986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 3880a473124SJohn Baldwin break; 389986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 390986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 391986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 392986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 3930a473124SJohn Baldwin break; 394986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 395986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 396945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 397986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 3980a473124SJohn Baldwin break; 399986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 400986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 401986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 402986dffafSJohn Baldwin iosapic->Address); 4030a473124SJohn Baldwin break; 404986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 405986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 406986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 407986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 408986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 409986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 410986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 4110a473124SJohn Baldwin break; 412986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 413986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 414986dffafSJohn Baldwin if (isrc->Type < sizeof(platform_int_types) / 415986dffafSJohn Baldwin sizeof(platform_int_types[0])) 416986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 417986dffafSJohn Baldwin else 418986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 419986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 420986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 421986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 422986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 423986dffafSJohn Baldwin break; 424986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 425986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 426986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 427986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 428986dffafSJohn Baldwin break; 429986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 430986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 431986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 432986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 4330a473124SJohn Baldwin break; 4340a473124SJohn Baldwin } 4350a473124SJohn Baldwin } 4360a473124SJohn Baldwin 4370a473124SJohn Baldwin static void 438986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 4390a473124SJohn Baldwin { 440986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 4410a473124SJohn Baldwin 442773b6454SNate Lawson printf(BEGIN_COMMENT); 443773b6454SNate Lawson acpi_print_sdt(sdp); 444986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 445986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 4460a473124SJohn Baldwin printf("\tFlags={"); 447986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 4480a473124SJohn Baldwin printf("PC-AT"); 4490a473124SJohn Baldwin printf("}\n"); 450986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 4510a473124SJohn Baldwin printf(END_COMMENT); 4520a473124SJohn Baldwin } 4530a473124SJohn Baldwin 4540a473124SJohn Baldwin static void 455986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 45679d7565cSPeter Wemm { 457986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 45879d7565cSPeter Wemm 459773b6454SNate Lawson printf(BEGIN_COMMENT); 460773b6454SNate Lawson acpi_print_sdt(sdp); 461986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 462986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 46387f9f09aSTakanori Watanabe printf("\tADDR="); 464986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 465986dffafSJohn Baldwin printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 466986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 467986dffafSJohn Baldwin 8); 468986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 469986dffafSJohn Baldwin 1 : 0); 47079d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 471986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 47279d7565cSPeter Wemm printf("TRUE}\n"); 47379d7565cSPeter Wemm else 47479d7565cSPeter Wemm printf("FALSE}\n"); 475986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 476986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 47779d7565cSPeter Wemm printf(END_COMMENT); 47879d7565cSPeter Wemm } 47979d7565cSPeter Wemm 48079d7565cSPeter Wemm static void 481986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 48255d7ff9eSNate Lawson { 483986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 48455d7ff9eSNate Lawson 48555d7ff9eSNate Lawson printf(BEGIN_COMMENT); 48655d7ff9eSNate Lawson acpi_print_sdt(sdp); 487986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 48855d7ff9eSNate Lawson printf("\tEC_CONTROL="); 489986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 49055d7ff9eSNate Lawson printf("\n\tEC_DATA="); 491986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 492986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 493986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 494986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 49555d7ff9eSNate Lawson printf(END_COMMENT); 49655d7ff9eSNate Lawson } 49755d7ff9eSNate Lawson 49855d7ff9eSNate Lawson static void 499986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 500a47e681bSScott Long { 501986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 502986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 503986dffafSJohn Baldwin u_int i, entries; 504a47e681bSScott Long 505a47e681bSScott Long printf(BEGIN_COMMENT); 506a47e681bSScott Long acpi_print_sdt(sdp); 507986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 508986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 509986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 510986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 511986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 512a47e681bSScott Long printf("\n"); 513986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", alloc->Address); 514986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 515986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 516986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 517a47e681bSScott Long } 518a47e681bSScott Long printf(END_COMMENT); 519a47e681bSScott Long } 520a47e681bSScott Long 521a47e681bSScott Long static void 522a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 523a0333ad1SJohn Baldwin uint32_t flags) 524a0333ad1SJohn Baldwin { 525a0333ad1SJohn Baldwin 526a0333ad1SJohn Baldwin printf("\tFlags={"); 527a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 528a0333ad1SJohn Baldwin printf("ENABLED"); 529a0333ad1SJohn Baldwin else 530a0333ad1SJohn Baldwin printf("DISABLED"); 531a0333ad1SJohn Baldwin printf("}\n"); 532a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 533a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 534a0333ad1SJohn Baldwin } 535a0333ad1SJohn Baldwin 536c031c93bSTakanori Watanabe static char * 537c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 538c031c93bSTakanori Watanabe { 539c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 540c031c93bSTakanori Watanabe char *eventname = NULL; 541c031c93bSTakanori Watanabe 542c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 543c031c93bSTakanori Watanabe 544c031c93bSTakanori Watanabe switch(event->event_type) { 545c031c93bSTakanori Watanabe case PREBOOT: 546c031c93bSTakanori Watanabe case POST_CODE: 547c031c93bSTakanori Watanabe case UNUSED: 548c031c93bSTakanori Watanabe case NO_ACTION: 549c031c93bSTakanori Watanabe case SEPARATOR: 550c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 551c031c93bSTakanori Watanabe case SCRTM_VERSION: 552c031c93bSTakanori Watanabe case CPU_MICROCODE: 553c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 554c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 555c031c93bSTakanori Watanabe case COMPACT_HASH: 556c031c93bSTakanori Watanabe case IPL: 557c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 558c031c93bSTakanori Watanabe case NONHOST_CODE: 559c031c93bSTakanori Watanabe case NONHOST_CONFIG: 560c031c93bSTakanori Watanabe case NONHOST_INFO: 561c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 562c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 563c031c93bSTakanori Watanabe break; 564c031c93bSTakanori Watanabe 565c031c93bSTakanori Watanabe case ACTION: 566c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 567c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 568c031c93bSTakanori Watanabe break; 569c031c93bSTakanori Watanabe 570c031c93bSTakanori Watanabe case EVENT_TAG: 571c031c93bSTakanori Watanabe switch (pc_event->event_id) { 572c031c93bSTakanori Watanabe case SMBIOS: 573c031c93bSTakanori Watanabe case BIS_CERT: 574c031c93bSTakanori Watanabe case CMOS: 575c031c93bSTakanori Watanabe case NVRAM: 576c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 577c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 578c031c93bSTakanori Watanabe case S_CRTM_VERSION: 579c031c93bSTakanori Watanabe case POST_BIOS_ROM: 580c031c93bSTakanori Watanabe case ESCD: 581c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 582c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 583c031c93bSTakanori Watanabe case POST_CONTENTS: 584c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 585c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 586c031c93bSTakanori Watanabe break; 587c031c93bSTakanori Watanabe 588c031c93bSTakanori Watanabe default: 589c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 590c031c93bSTakanori Watanabe pc_event->event_id); 591c031c93bSTakanori Watanabe break; 592c031c93bSTakanori Watanabe } 593c031c93bSTakanori Watanabe break; 594c031c93bSTakanori Watanabe 595c031c93bSTakanori Watanabe default: 596c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 597c031c93bSTakanori Watanabe break; 598c031c93bSTakanori Watanabe } 599c031c93bSTakanori Watanabe 600c031c93bSTakanori Watanabe return eventname; 601c031c93bSTakanori Watanabe } 602c031c93bSTakanori Watanabe 603c031c93bSTakanori Watanabe static void 604c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 605c031c93bSTakanori Watanabe { 606c031c93bSTakanori Watanabe int i; 607c031c93bSTakanori Watanabe char *eventname; 608c031c93bSTakanori Watanabe 609c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 610c031c93bSTakanori Watanabe 611c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 612c031c93bSTakanori Watanabe printf(" 0x"); 613c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 614c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 615c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 616c031c93bSTakanori Watanabe 617c031c93bSTakanori Watanabe free(eventname); 618c031c93bSTakanori Watanabe } 619c031c93bSTakanori Watanabe 620c031c93bSTakanori Watanabe static void 621c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 622c031c93bSTakanori Watanabe { 623c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 624c031c93bSTakanori Watanabe struct TCPAevent *event; 625*977fd9daSTakanori Watanabe uintmax_t len, paddr; 626c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 627c031c93bSTakanori Watanabe unsigned char *vend = NULL; 628c031c93bSTakanori Watanabe 629c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 630c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 631c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 632c031c93bSTakanori Watanabe 633c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 634c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 635c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 636c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 637c031c93bSTakanori Watanabe break; 638c031c93bSTakanori Watanabe 639c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 640c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 641c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 642c031c93bSTakanori Watanabe break; 643c031c93bSTakanori Watanabe 644c031c93bSTakanori Watanabe default: 645c031c93bSTakanori Watanabe printf("XXX"); 646c031c93bSTakanori Watanabe printf(END_COMMENT); 647c031c93bSTakanori Watanabe return; 648c031c93bSTakanori Watanabe } 6490e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 650c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 651c031c93bSTakanori Watanabe 652c031c93bSTakanori Watanabe if (len == 0) { 653c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 654c031c93bSTakanori Watanabe printf(END_COMMENT); 655c031c93bSTakanori Watanabe return; 656c031c93bSTakanori Watanabe } 657c031c93bSTakanori Watanabe 658c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 659c031c93bSTakanori Watanabe vend = vaddr + len; 660c031c93bSTakanori Watanabe 661c031c93bSTakanori Watanabe while (vaddr != NULL) { 662c031c93bSTakanori Watanabe if (vaddr + sizeof(struct TCPAevent) >= vend) 663c031c93bSTakanori Watanabe break; 6640e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 665c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 666c031c93bSTakanori Watanabe break; 667c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 668c031c93bSTakanori Watanabe break; 669c031c93bSTakanori Watanabe #if 0 670c031c93bSTakanori Watanabe { 671c031c93bSTakanori Watanabe unsigned int i, j, k; 672c031c93bSTakanori Watanabe 673c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 674c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 675c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 676c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 677c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 678c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 679c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 680c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 681c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 682c031c93bSTakanori Watanabe j = i + 1; 683c031c93bSTakanori Watanabe } 684c031c93bSTakanori Watanabe } 685c031c93bSTakanori Watanabe printf("\n"); } 686c031c93bSTakanori Watanabe #endif 687c031c93bSTakanori Watanabe acpi_print_tcpa(event); 688c031c93bSTakanori Watanabe 689c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 690c031c93bSTakanori Watanabe } 691c031c93bSTakanori Watanabe 692c031c93bSTakanori Watanabe printf(END_COMMENT); 693c031c93bSTakanori Watanabe } 694c031c93bSTakanori Watanabe 695a0333ad1SJohn Baldwin static void 696986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 697a0333ad1SJohn Baldwin { 698a0333ad1SJohn Baldwin 699a0333ad1SJohn Baldwin printf("\tFlags={"); 700986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 701a0333ad1SJohn Baldwin printf("ENABLED"); 702a0333ad1SJohn Baldwin else 703a0333ad1SJohn Baldwin printf("DISABLED"); 704986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 705a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 706986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 707a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 708a0333ad1SJohn Baldwin printf("}\n"); 709986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 710986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 711986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 712a0333ad1SJohn Baldwin } 713a0333ad1SJohn Baldwin 714a0333ad1SJohn Baldwin const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; 715a0333ad1SJohn Baldwin 716a0333ad1SJohn Baldwin static void 717986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 718a0333ad1SJohn Baldwin { 719986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 720986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 721a0333ad1SJohn Baldwin 722986dffafSJohn Baldwin if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0])) 723986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 724a0333ad1SJohn Baldwin else 725986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 726986dffafSJohn Baldwin switch (srat->Type) { 727a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 728986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 729986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 730986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 731986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 732986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 733986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 734a0333ad1SJohn Baldwin break; 735a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 736986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 737a0333ad1SJohn Baldwin break; 738a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 739986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 740986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 741986dffafSJohn Baldwin x2apic->Flags); 742a0333ad1SJohn Baldwin break; 743a0333ad1SJohn Baldwin } 744a0333ad1SJohn Baldwin } 745a0333ad1SJohn Baldwin 746a0333ad1SJohn Baldwin static void 747986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 748a0333ad1SJohn Baldwin { 749986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 750a0333ad1SJohn Baldwin 751a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 752a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 753986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 754986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 755986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 756a0333ad1SJohn Baldwin printf(END_COMMENT); 757a0333ad1SJohn Baldwin } 758a0333ad1SJohn Baldwin 759a0333ad1SJohn Baldwin static void 760986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 761c62f1cccSMitsuru IWASAKI { 762773b6454SNate Lawson printf(" "); 763986dffafSJohn Baldwin acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); 764c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 765986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 766e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 767986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 768e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 769986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 770986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 771e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 772986dffafSJohn Baldwin acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); 773986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 774e1e9a4bfSMitsuru IWASAKI } 775e1e9a4bfSMitsuru IWASAKI 776945137d9SNate Lawson static void 777986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 778e1e9a4bfSMitsuru IWASAKI { 779986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 780986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 781e1e9a4bfSMitsuru IWASAKI int i, entries; 782a74172abSNate Lawson u_long addr; 783e1e9a4bfSMitsuru IWASAKI 784986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 785986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 786773b6454SNate Lawson printf(BEGIN_COMMENT); 787773b6454SNate Lawson acpi_print_sdt(rsdp); 788986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 789e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 790e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 791e1e9a4bfSMitsuru IWASAKI if (i > 0) 792e1e9a4bfSMitsuru IWASAKI printf(", "); 793a74172abSNate Lawson switch (addr_size) { 794a74172abSNate Lawson case 4: 795986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 796a74172abSNate Lawson break; 797a74172abSNate Lawson case 8: 798986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 799a74172abSNate Lawson break; 800a74172abSNate Lawson default: 801a74172abSNate Lawson addr = 0; 802a74172abSNate Lawson } 803a74172abSNate Lawson assert(addr != 0); 804a74172abSNate Lawson printf("0x%08lx", addr); 805e1e9a4bfSMitsuru IWASAKI } 806e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 807c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 808e1e9a4bfSMitsuru IWASAKI } 809e1e9a4bfSMitsuru IWASAKI 8108e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 8118e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 8128e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 8138e6a8737SNate Lawson }; 8148e6a8737SNate Lawson 815945137d9SNate Lawson static void 816986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 817e1e9a4bfSMitsuru IWASAKI { 818986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 8198e6a8737SNate Lawson const char *pm; 820e1e9a4bfSMitsuru IWASAKI char sep; 821e1e9a4bfSMitsuru IWASAKI 822986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 823c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 8242177d4e6SNate Lawson acpi_print_sdt(sdp); 825986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 826986dffafSJohn Baldwin fadt->Dsdt); 827986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 828986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 8298e6a8737SNate Lawson pm = "Reserved"; 8308e6a8737SNate Lawson else 831986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 832986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 833986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 834986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 835986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 836986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 837986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 838986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 839e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 840986dffafSJohn Baldwin fadt->Pm1aEventBlock, 841986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 842986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 843e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 844986dffafSJohn Baldwin fadt->Pm1bEventBlock, 845986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 846e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 847986dffafSJohn Baldwin fadt->Pm1aControlBlock, 848986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 849986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 850e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 851986dffafSJohn Baldwin fadt->Pm1bControlBlock, 852986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 853986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 854e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 855986dffafSJohn Baldwin fadt->Pm2ControlBlock, 856986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 857c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 858986dffafSJohn Baldwin fadt->PmTimerBlock, 859986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 860986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 8618e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 862986dffafSJohn Baldwin fadt->Gpe0Block, 863986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 864986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 8658e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 866986dffafSJohn Baldwin fadt->Gpe1Block, 867986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 868986dffafSJohn Baldwin fadt->Gpe1Base); 869986dffafSJohn Baldwin if (fadt->CstControl != 0) 870986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 87151c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 872986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 873e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 874986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 875e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 876986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 877e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 878986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 879e1e9a4bfSMitsuru IWASAKI 8808e6a8737SNate Lawson #define PRINTFLAG(var, flag) do { \ 881986dffafSJohn Baldwin if ((var) & ACPI_FADT_## flag) { \ 8828e6a8737SNate Lawson printf("%c%s", sep, #flag); sep = ','; \ 883e1e9a4bfSMitsuru IWASAKI } \ 884e1e9a4bfSMitsuru IWASAKI } while (0) 885e1e9a4bfSMitsuru IWASAKI 8868e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 8878e6a8737SNate Lawson sep = '{'; 888986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 889986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 890986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 891986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 892986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 893986dffafSJohn Baldwin if (fadt->BootFlags != 0) 8944e36f5a1SNate Lawson printf("}"); 8954e36f5a1SNate Lawson printf("\n"); 8968e6a8737SNate Lawson 8978e6a8737SNate Lawson printf("\tFlags="); 8988e6a8737SNate Lawson sep = '{'; 899986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 900986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 901986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 902986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 903986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 904986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 905986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 906986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 907986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 908986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 909986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 910986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 911986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 912986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 913986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 914986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 915986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 916986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 917986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 918986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 919986dffafSJohn Baldwin if (fadt->Flags != 0) 9208e6a8737SNate Lawson printf("}\n"); 921e1e9a4bfSMitsuru IWASAKI 922e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 923e1e9a4bfSMitsuru IWASAKI 924986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 9258e6a8737SNate Lawson printf("\tRESET_REG="); 926986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 927986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 9288e6a8737SNate Lawson } 929c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 930986dffafSJohn Baldwin printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs); 931986dffafSJohn Baldwin printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt); 932c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 933986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 934986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 935c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 936986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 937c08c4e81SNate Lawson } 938c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 939986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 940986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 941c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 942986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 943c08c4e81SNate Lawson } 944986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 945773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 946986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 947c08c4e81SNate Lawson } 948773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 949986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 950986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 951773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 952986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 953c08c4e81SNate Lawson } 954986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 955773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 956986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 957c08c4e81SNate Lawson } 958773b6454SNate Lawson printf("\n"); 959773b6454SNate Lawson } 9608e6a8737SNate Lawson 9618e6a8737SNate Lawson printf(END_COMMENT); 9628e6a8737SNate Lawson } 9638e6a8737SNate Lawson 9648e6a8737SNate Lawson static void 965986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 9668e6a8737SNate Lawson { 9678e6a8737SNate Lawson printf(BEGIN_COMMENT); 968986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 969986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 970986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 9718e6a8737SNate Lawson 972773b6454SNate Lawson printf("\tGlobal_Lock="); 973986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 974986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 9758e6a8737SNate Lawson printf("PENDING,"); 976986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 9778e6a8737SNate Lawson printf("OWNED"); 9788e6a8737SNate Lawson } 979773b6454SNate Lawson printf("\n"); 9808e6a8737SNate Lawson 981773b6454SNate Lawson printf("\tFlags="); 982986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 9838e6a8737SNate Lawson printf("S4BIOS"); 984773b6454SNate Lawson printf("\n"); 9858e6a8737SNate Lawson 986986dffafSJohn Baldwin if (facs->XFirmwareWakingVector != 0) { 9878e6a8737SNate Lawson printf("\tX_Firm_Wake_Vec=%08lx\n", 988986dffafSJohn Baldwin (u_long)facs->XFirmwareWakingVector); 9898e6a8737SNate Lawson } 990986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 9918e6a8737SNate Lawson 992c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 993e1e9a4bfSMitsuru IWASAKI } 994e1e9a4bfSMitsuru IWASAKI 995945137d9SNate Lawson static void 996986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 997e1e9a4bfSMitsuru IWASAKI { 998773b6454SNate Lawson printf(BEGIN_COMMENT); 999773b6454SNate Lawson acpi_print_sdt(dsdp); 1000773b6454SNate Lawson printf(END_COMMENT); 1001e1e9a4bfSMitsuru IWASAKI } 1002e1e9a4bfSMitsuru IWASAKI 1003e1e9a4bfSMitsuru IWASAKI int 1004e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 1005e1e9a4bfSMitsuru IWASAKI { 1006986dffafSJohn Baldwin uint8_t *bp; 1007986dffafSJohn Baldwin uint8_t sum; 1008e1e9a4bfSMitsuru IWASAKI 1009e1e9a4bfSMitsuru IWASAKI bp = p; 1010e1e9a4bfSMitsuru IWASAKI sum = 0; 1011e1e9a4bfSMitsuru IWASAKI while (length--) 1012e1e9a4bfSMitsuru IWASAKI sum += *bp++; 1013e1e9a4bfSMitsuru IWASAKI 1014e1e9a4bfSMitsuru IWASAKI return (sum); 1015e1e9a4bfSMitsuru IWASAKI } 1016e1e9a4bfSMitsuru IWASAKI 1017986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 1018e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 1019e1e9a4bfSMitsuru IWASAKI { 1020986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 1021e1e9a4bfSMitsuru IWASAKI 1022986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 1023986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 1024e1e9a4bfSMitsuru IWASAKI return (sp); 1025e1e9a4bfSMitsuru IWASAKI } 1026e1e9a4bfSMitsuru IWASAKI 1027945137d9SNate Lawson static void 1028986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 1029e1e9a4bfSMitsuru IWASAKI { 1030c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 1031a74172abSNate Lawson printf(" RSD PTR: OEM="); 1032986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 1033986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 1034986dffafSJohn Baldwin rp->Revision); 1035986dffafSJohn Baldwin if (rp->Revision < 2) { 1036986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 1037986dffafSJohn Baldwin rp->Checksum); 1038a74172abSNate Lawson } else { 1039a74172abSNate Lawson printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", 1040986dffafSJohn Baldwin (u_long)rp->XsdtPhysicalAddress, rp->Length, 1041986dffafSJohn Baldwin rp->ExtendedChecksum); 1042a74172abSNate Lawson } 1043c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1044e1e9a4bfSMitsuru IWASAKI } 1045e1e9a4bfSMitsuru IWASAKI 1046945137d9SNate Lawson static void 1047986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 1048e1e9a4bfSMitsuru IWASAKI { 1049986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 1050986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1051986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1052a74172abSNate Lawson vm_offset_t addr; 1053a74172abSNate Lawson int entries, i; 1054e1e9a4bfSMitsuru IWASAKI 1055e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 1056986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1057986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1058986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1059e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1060a74172abSNate Lawson switch (addr_size) { 1061a74172abSNate Lawson case 4: 1062986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1063a74172abSNate Lawson break; 1064a74172abSNate Lawson case 8: 1065986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1066a74172abSNate Lawson break; 1067a74172abSNate Lawson default: 1068a74172abSNate Lawson assert((addr = 0)); 1069a74172abSNate Lawson } 1070a74172abSNate Lawson 1071986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1072986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 10735cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 1074986dffafSJohn Baldwin sdp->Signature); 10755cf6d493SNate Lawson continue; 10765cf6d493SNate Lawson } 1077986dffafSJohn Baldwin if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 10782177d4e6SNate Lawson acpi_handle_fadt(sdp); 1079986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 1080986dffafSJohn Baldwin acpi_handle_madt(sdp); 1081986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 108279d7565cSPeter Wemm acpi_handle_hpet(sdp); 1083986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 108455d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 1085986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 1086a47e681bSScott Long acpi_handle_mcfg(sdp); 1087986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 1088a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 1089c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 1090c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 1091773b6454SNate Lawson else { 1092773b6454SNate Lawson printf(BEGIN_COMMENT); 1093773b6454SNate Lawson acpi_print_sdt(sdp); 1094773b6454SNate Lawson printf(END_COMMENT); 1095773b6454SNate Lawson } 1096e1e9a4bfSMitsuru IWASAKI } 1097e1e9a4bfSMitsuru IWASAKI } 1098c62f1cccSMitsuru IWASAKI 1099986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1100476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 1101945137d9SNate Lawson { 1102986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 1103986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 1104945137d9SNate Lawson 1105945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 1106945137d9SNate Lawson if (!rp) 1107945137d9SNate Lawson errx(1, "Can't find ACPI information"); 1108945137d9SNate Lawson 1109945137d9SNate Lawson if (tflag) 1110945137d9SNate Lawson acpi_print_rsd_ptr(rp); 1111986dffafSJohn Baldwin if (rp->Revision < 2) { 1112986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 1113986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 1114986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1115945137d9SNate Lawson errx(1, "RSDT is corrupted"); 1116a74172abSNate Lawson addr_size = sizeof(uint32_t); 1117a74172abSNate Lawson } else { 1118986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 1119986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 1120986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1121a74172abSNate Lawson errx(1, "XSDT is corrupted"); 1122a74172abSNate Lawson addr_size = sizeof(uint64_t); 1123a74172abSNate Lawson } 1124945137d9SNate Lawson return (rsdp); 1125945137d9SNate Lawson } 1126c62f1cccSMitsuru IWASAKI 112762c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 1128bfa3f012SMarcel Moolenaar static int 1129986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 1130bfa3f012SMarcel Moolenaar { 1131986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 1132986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 1133bfa3f012SMarcel Moolenaar uint8_t sum; 1134bfa3f012SMarcel Moolenaar 113562c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 1136bfa3f012SMarcel Moolenaar sdt = *dsdt; 1137bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 1138986dffafSJohn Baldwin sdt.Checksum = 0; 1139986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 1140986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1141986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 1142f7675a56SNate Lawson while (ssdt != NULL) { 1143986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 1144986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 1145986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 1146986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 1147bfa3f012SMarcel Moolenaar } 1148986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 1149986dffafSJohn Baldwin sdt.Checksum -= sum; 1150bfa3f012SMarcel Moolenaar } 115162c7bde1SNate Lawson 115262c7bde1SNate Lawson /* Write out the DSDT header and body. */ 1153986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 1154986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 115562c7bde1SNate Lawson 1156b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 1157f7675a56SNate Lawson if (rsdt != NULL) { 1158bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 1159bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 1160986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 1161986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1162bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 1163bfa3f012SMarcel Moolenaar } 1164bfa3f012SMarcel Moolenaar } 1165bfa3f012SMarcel Moolenaar return (0); 1166bfa3f012SMarcel Moolenaar } 1167bfa3f012SMarcel Moolenaar 1168c62f1cccSMitsuru IWASAKI void 1169986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1170c62f1cccSMitsuru IWASAKI { 1171945137d9SNate Lawson int fd; 1172945137d9SNate Lawson mode_t mode; 1173945137d9SNate Lawson 1174945137d9SNate Lawson assert(outfile != NULL); 1175945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1176945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 1177945137d9SNate Lawson if (fd == -1) { 1178945137d9SNate Lawson perror("dsdt_save_file"); 1179945137d9SNate Lawson return; 1180945137d9SNate Lawson } 1181bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1182945137d9SNate Lawson close(fd); 1183c62f1cccSMitsuru IWASAKI } 1184c62f1cccSMitsuru IWASAKI 1185945137d9SNate Lawson void 1186986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1187c62f1cccSMitsuru IWASAKI { 118899065116SJung-uk Kim char buf[PATH_MAX], tmpstr[PATH_MAX]; 118999065116SJung-uk Kim const char *tmpdir; 119099065116SJung-uk Kim char *tmpext; 1191945137d9SNate Lawson FILE *fp; 119299065116SJung-uk Kim size_t len; 119399065116SJung-uk Kim int fd; 1194945137d9SNate Lawson 119599065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 119699065116SJung-uk Kim if (tmpdir == NULL) 119799065116SJung-uk Kim tmpdir = _PATH_TMP; 119899065116SJung-uk Kim strncpy(tmpstr, tmpdir, sizeof(tmpstr)); 119999065116SJung-uk Kim strncat(tmpstr, "/acpidump.", sizeof(tmpstr) - strlen(tmpdir)); 120099065116SJung-uk Kim if (realpath(tmpstr, buf) == NULL) { 120199065116SJung-uk Kim perror("realpath tmp file"); 120299065116SJung-uk Kim return; 120399065116SJung-uk Kim } 120499065116SJung-uk Kim strncpy(tmpstr, buf, sizeof(tmpstr)); 120599065116SJung-uk Kim len = strlen(buf); 120699065116SJung-uk Kim tmpext = tmpstr + len; 120799065116SJung-uk Kim strncpy(tmpext, "XXXXXX", sizeof(tmpstr) - len); 1208945137d9SNate Lawson fd = mkstemp(tmpstr); 1209945137d9SNate Lawson if (fd < 0) { 1210945137d9SNate Lawson perror("iasl tmp file"); 1211945137d9SNate Lawson return; 1212c62f1cccSMitsuru IWASAKI } 1213bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1214945137d9SNate Lawson close(fd); 1215945137d9SNate Lawson 1216945137d9SNate Lawson /* Run iasl -d on the temp file */ 1217945137d9SNate Lawson if (fork() == 0) { 1218945137d9SNate Lawson close(STDOUT_FILENO); 1219945137d9SNate Lawson if (vflag == 0) 1220945137d9SNate Lawson close(STDERR_FILENO); 122199065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 1222945137d9SNate Lawson err(1, "exec"); 1223c62f1cccSMitsuru IWASAKI } 1224c62f1cccSMitsuru IWASAKI 1225945137d9SNate Lawson wait(NULL); 1226945137d9SNate Lawson unlink(tmpstr); 1227945137d9SNate Lawson 1228945137d9SNate Lawson /* Dump iasl's output to stdout */ 122999065116SJung-uk Kim strncpy(tmpext, "dsl", sizeof(tmpstr) - len); 123099065116SJung-uk Kim fp = fopen(tmpstr, "r"); 123199065116SJung-uk Kim unlink(tmpstr); 1232945137d9SNate Lawson if (fp == NULL) { 1233945137d9SNate Lawson perror("iasl tmp file (read)"); 1234945137d9SNate Lawson return; 1235945137d9SNate Lawson } 1236945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 1237945137d9SNate Lawson fwrite(buf, 1, len, stdout); 1238945137d9SNate Lawson fclose(fp); 1239c62f1cccSMitsuru IWASAKI } 1240c62f1cccSMitsuru IWASAKI 1241945137d9SNate Lawson void 1242986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 1243c62f1cccSMitsuru IWASAKI { 1244945137d9SNate Lawson acpi_handle_rsdt(rsdp); 1245c62f1cccSMitsuru IWASAKI } 1246c62f1cccSMitsuru IWASAKI 1247bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 1248986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1249986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 1250c62f1cccSMitsuru IWASAKI { 1251986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1252986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1253986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1254a74172abSNate Lawson vm_offset_t addr; 1255a74172abSNate Lawson int entries, i; 1256945137d9SNate Lawson 1257986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1258986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1259986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1260945137d9SNate Lawson for (i = 0; i < entries; i++) { 1261a74172abSNate Lawson switch (addr_size) { 1262a74172abSNate Lawson case 4: 1263986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1264a74172abSNate Lawson break; 1265a74172abSNate Lawson case 8: 1266986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1267a74172abSNate Lawson break; 1268a74172abSNate Lawson default: 1269a74172abSNate Lawson assert((addr = 0)); 1270a74172abSNate Lawson } 1271986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1272bfa3f012SMarcel Moolenaar if (last != NULL) { 1273bfa3f012SMarcel Moolenaar if (sdt == last) 1274bfa3f012SMarcel Moolenaar last = NULL; 1275bfa3f012SMarcel Moolenaar continue; 1276bfa3f012SMarcel Moolenaar } 1277986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 1278a74172abSNate Lawson continue; 1279986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1280945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 1281945137d9SNate Lawson return (sdt); 1282c62f1cccSMitsuru IWASAKI } 1283c62f1cccSMitsuru IWASAKI 1284945137d9SNate Lawson return (NULL); 1285c62f1cccSMitsuru IWASAKI } 1286c62f1cccSMitsuru IWASAKI 1287986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1288986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 1289c62f1cccSMitsuru IWASAKI { 1290986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1291c62f1cccSMitsuru IWASAKI 1292986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 1293c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 1294986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 12952e71eb12SNate Lawson else 1296986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 1297986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1298945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1299945137d9SNate Lawson return (sdt); 1300c62f1cccSMitsuru IWASAKI } 1301