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); 6633866658SJohn 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 126ec650989SNeel Natu #define PRINTFLAG_END() printflag_end() 127ec650989SNeel Natu 128ec650989SNeel Natu static char pf_sep = '{'; 129ec650989SNeel Natu 130ec650989SNeel Natu static void 131ec650989SNeel Natu printflag_end(void) 132ec650989SNeel Natu { 133ec650989SNeel Natu 134ec650989SNeel Natu if (pf_sep != '{') { 135ec650989SNeel Natu printf("}"); 136ec650989SNeel Natu pf_sep = '{'; 137ec650989SNeel Natu } 138ec650989SNeel Natu printf("\n"); 139ec650989SNeel Natu } 140ec650989SNeel Natu 141ec650989SNeel Natu static void 142ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name) 143ec650989SNeel Natu { 144ec650989SNeel Natu 145ec650989SNeel Natu if (var & mask) { 146ec650989SNeel Natu printf("%c%s", pf_sep, name); 147ec650989SNeel Natu pf_sep = ','; 148ec650989SNeel Natu } 149ec650989SNeel Natu } 150ec650989SNeel Natu 151e1e9a4bfSMitsuru IWASAKI static void 152e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 153e1e9a4bfSMitsuru IWASAKI { 154e1e9a4bfSMitsuru IWASAKI int c; 155e1e9a4bfSMitsuru IWASAKI 156e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 157e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 158e1e9a4bfSMitsuru IWASAKI length--; 159e1e9a4bfSMitsuru IWASAKI 160e1e9a4bfSMitsuru IWASAKI while (length--) { 161e1e9a4bfSMitsuru IWASAKI c = *s++; 162e1e9a4bfSMitsuru IWASAKI putchar(c); 163e1e9a4bfSMitsuru IWASAKI } 164e1e9a4bfSMitsuru IWASAKI } 165e1e9a4bfSMitsuru IWASAKI 166e1e9a4bfSMitsuru IWASAKI static void 167986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1688e6a8737SNate Lawson { 169986dffafSJohn Baldwin switch(gas->SpaceId) { 1708e6a8737SNate Lawson case ACPI_GAS_MEMORY: 1717d369c6eSJung-uk Kim if (gas->BitWidth <= 32) 1727d369c6eSJung-uk Kim printf("0x%08x:%u[%u] (Memory)", 1737d369c6eSJung-uk Kim (u_int)gas->Address, gas->BitOffset, 1747d369c6eSJung-uk Kim gas->BitWidth); 1757d369c6eSJung-uk Kim else 1767d369c6eSJung-uk Kim printf("0x%016jx:%u[%u] (Memory)", 1777d369c6eSJung-uk Kim (uintmax_t)gas->Address, gas->BitOffset, 1787d369c6eSJung-uk Kim gas->BitWidth); 1798e6a8737SNate Lawson break; 1808e6a8737SNate Lawson case ACPI_GAS_IO: 1817d369c6eSJung-uk Kim printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address, 182986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1838e6a8737SNate Lawson break; 1848e6a8737SNate Lawson case ACPI_GAS_PCI: 185986dffafSJohn Baldwin printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), 186986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 187986dffafSJohn Baldwin (uint16_t)gas->Address); 1888e6a8737SNate Lawson break; 1898e6a8737SNate Lawson /* XXX How to handle these below? */ 1908e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 191986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 192986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1938e6a8737SNate Lawson break; 1948e6a8737SNate Lawson case ACPI_GAS_SMBUS: 195986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 196986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1978e6a8737SNate Lawson break; 198986dffafSJohn Baldwin case ACPI_GAS_CMOS: 199986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 200986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 2018e6a8737SNate Lawson case ACPI_GAS_FIXED: 2028e6a8737SNate Lawson default: 2037d369c6eSJung-uk Kim printf("0x%016jx (?)", (uintmax_t)gas->Address); 2048e6a8737SNate Lawson break; 2058e6a8737SNate Lawson } 2068e6a8737SNate Lawson } 2078e6a8737SNate Lawson 208c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 209c2962974SNate Lawson static int 210986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 211e1e9a4bfSMitsuru IWASAKI { 212c2962974SNate Lawson int fadt_revision; 213e1e9a4bfSMitsuru IWASAKI 214c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 215c83f0f99SNate Lawson if (addr_size == 8) { 216c83f0f99SNate Lawson fadt_revision = 2; 2178e6a8737SNate Lawson 218773b6454SNate Lawson /* 219c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 220c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 221c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 222c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 223c83f0f99SNate Lawson * version for all subsequent tables. 224773b6454SNate Lawson */ 225986dffafSJohn Baldwin if (fadt->Facs != 0 && 226986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 227c83f0f99SNate Lawson fadt_revision = 1; 228c2962974SNate Lawson } else 229c83f0f99SNate Lawson fadt_revision = 1; 230c2962974SNate Lawson return (fadt_revision); 231c83f0f99SNate Lawson } 232c2962974SNate Lawson 233c2962974SNate Lawson static void 234986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 235c2962974SNate Lawson { 236986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 237986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 238986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 239c2962974SNate Lawson int fadt_revision; 240c2962974SNate Lawson 241986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2422177d4e6SNate Lawson acpi_print_fadt(sdp); 243c83f0f99SNate Lawson 244c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 245c83f0f99SNate Lawson if (fadt_revision == 1) 246986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); 247773b6454SNate Lawson else 248986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); 249986dffafSJohn Baldwin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) 2508e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2518e6a8737SNate Lawson acpi_print_facs(facs); 2528e6a8737SNate Lawson 253c83f0f99SNate Lawson if (fadt_revision == 1) 254986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 255773b6454SNate Lawson else 256986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 257986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 258945137d9SNate Lawson errx(1, "DSDT is corrupt"); 259945137d9SNate Lawson acpi_print_dsdt(dsdp); 260c62f1cccSMitsuru IWASAKI } 261c62f1cccSMitsuru IWASAKI 262c62f1cccSMitsuru IWASAKI static void 263986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 264986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 265986dffafSJohn Baldwin { 266986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 267986dffafSJohn Baldwin char *end; 268986dffafSJohn Baldwin 269986dffafSJohn Baldwin subtable = first; 270986dffafSJohn Baldwin end = (char *)table + table->Length; 271986dffafSJohn Baldwin while ((char *)subtable < end) { 272986dffafSJohn Baldwin printf("\n"); 273986dffafSJohn Baldwin action(subtable); 274986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 275986dffafSJohn Baldwin subtable->Length); 276986dffafSJohn Baldwin } 277986dffafSJohn Baldwin } 278986dffafSJohn Baldwin 279986dffafSJohn Baldwin static void 2800a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 2810a473124SJohn Baldwin { 2820a473124SJohn Baldwin 2830a473124SJohn Baldwin printf("\tACPI CPU="); 2840a473124SJohn Baldwin if (cpu_id == 0xff) 2850a473124SJohn Baldwin printf("ALL\n"); 2860a473124SJohn Baldwin else 2870a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 2880a473124SJohn Baldwin } 2890a473124SJohn Baldwin 2900a473124SJohn Baldwin static void 291986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 2920a473124SJohn Baldwin { 293986dffafSJohn Baldwin 294986dffafSJohn Baldwin printf("\tUID=%d", uid); 295986dffafSJohn Baldwin if (uid_string != NULL) 296986dffafSJohn Baldwin printf(" (%s)", uid_string); 297986dffafSJohn Baldwin printf("\n"); 298986dffafSJohn Baldwin } 299986dffafSJohn Baldwin 300986dffafSJohn Baldwin static void 301986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 302986dffafSJohn Baldwin { 303986dffafSJohn Baldwin 3040a473124SJohn Baldwin printf("\tFlags={"); 305986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 3060a473124SJohn Baldwin printf("ENABLED"); 3070a473124SJohn Baldwin else 3080a473124SJohn Baldwin printf("DISABLED"); 3090a473124SJohn Baldwin printf("}\n"); 310986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3110a473124SJohn Baldwin } 3120a473124SJohn Baldwin 3130a473124SJohn Baldwin static void 314986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 3150a473124SJohn Baldwin { 316986dffafSJohn Baldwin 317986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3180a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 319986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 3200a473124SJohn Baldwin } 3210a473124SJohn Baldwin 3220a473124SJohn Baldwin static void 323986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 3240a473124SJohn Baldwin { 3250a473124SJohn Baldwin 3260a473124SJohn Baldwin printf("\tFlags={Polarity="); 327986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 328986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 3290a473124SJohn Baldwin printf("conforming"); 3300a473124SJohn Baldwin break; 331986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3320a473124SJohn Baldwin printf("active-hi"); 3330a473124SJohn Baldwin break; 334986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3350a473124SJohn Baldwin printf("active-lo"); 3360a473124SJohn Baldwin break; 3370a473124SJohn Baldwin default: 338986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3390a473124SJohn Baldwin break; 3400a473124SJohn Baldwin } 3410a473124SJohn Baldwin printf(", Trigger="); 342986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 343986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3440a473124SJohn Baldwin printf("conforming"); 3450a473124SJohn Baldwin break; 346986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3470a473124SJohn Baldwin printf("edge"); 3480a473124SJohn Baldwin break; 349986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3500a473124SJohn Baldwin printf("level"); 3510a473124SJohn Baldwin break; 3520a473124SJohn Baldwin default: 353986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3540a473124SJohn Baldwin } 3550a473124SJohn Baldwin printf("}\n"); 3560a473124SJohn Baldwin } 3570a473124SJohn Baldwin 3580a473124SJohn Baldwin static void 359986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 3600a473124SJohn Baldwin { 3610a473124SJohn Baldwin 362986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 363986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 364986dffafSJohn Baldwin } 365986dffafSJohn Baldwin 366986dffafSJohn Baldwin static void 367986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 368986dffafSJohn Baldwin { 369986dffafSJohn Baldwin 370986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 3710a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 3720a473124SJohn Baldwin } 3730a473124SJohn Baldwin 374bf70beceSEd Schouten static const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", 375bf70beceSEd Schouten "NMI", "Local APIC NMI", 376bf70beceSEd Schouten "Local APIC Override", "IO SAPIC", 377bf70beceSEd Schouten "Local SAPIC", "Platform Interrupt", 378986dffafSJohn Baldwin "Local X2APIC", "Local X2APIC NMI" }; 379bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 3800a473124SJohn Baldwin "Corrected Platform Error" }; 3810a473124SJohn Baldwin 3820a473124SJohn Baldwin static void 383986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 3840a473124SJohn Baldwin { 385986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 386986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 387986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 388986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 389986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 390986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 391986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 392986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 393986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 394986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 395986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 3960a473124SJohn Baldwin 397986dffafSJohn Baldwin if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0])) 398986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 399a0333ad1SJohn Baldwin else 400986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 401986dffafSJohn Baldwin switch (mp->Type) { 402986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 403986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 404986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 405986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 4060a473124SJohn Baldwin break; 407986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 408986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 409986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 410986dffafSJohn Baldwin ioapic->Address); 4110a473124SJohn Baldwin break; 412986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 413986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 414986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 415986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 416986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 4170a473124SJohn Baldwin break; 418986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 419986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 420986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 4210a473124SJohn Baldwin break; 422986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 423986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 424986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 425986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 4260a473124SJohn Baldwin break; 427986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 428986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 429945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 430986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 4310a473124SJohn Baldwin break; 432986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 433986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 434986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 435986dffafSJohn Baldwin iosapic->Address); 4360a473124SJohn Baldwin break; 437986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 438986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 439986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 440986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 441986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 442986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 443986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 4440a473124SJohn Baldwin break; 445986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 446986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 447986dffafSJohn Baldwin if (isrc->Type < sizeof(platform_int_types) / 448986dffafSJohn Baldwin sizeof(platform_int_types[0])) 449986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 450986dffafSJohn Baldwin else 451986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 452986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 453986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 454986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 455986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 456986dffafSJohn Baldwin break; 457986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 458986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 459986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 460986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 461986dffafSJohn Baldwin break; 462986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 463986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 464986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 465986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 4660a473124SJohn Baldwin break; 4670a473124SJohn Baldwin } 4680a473124SJohn Baldwin } 4690a473124SJohn Baldwin 4700a473124SJohn Baldwin static void 471986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 4720a473124SJohn Baldwin { 473986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 4740a473124SJohn Baldwin 475773b6454SNate Lawson printf(BEGIN_COMMENT); 476773b6454SNate Lawson acpi_print_sdt(sdp); 477986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 478986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 4790a473124SJohn Baldwin printf("\tFlags={"); 480986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 4810a473124SJohn Baldwin printf("PC-AT"); 4820a473124SJohn Baldwin printf("}\n"); 483986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 4840a473124SJohn Baldwin printf(END_COMMENT); 4850a473124SJohn Baldwin } 4860a473124SJohn Baldwin 4870a473124SJohn Baldwin static void 488986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 48979d7565cSPeter Wemm { 490986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 49179d7565cSPeter Wemm 492773b6454SNate Lawson printf(BEGIN_COMMENT); 493773b6454SNate Lawson acpi_print_sdt(sdp); 494986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 495986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 49687f9f09aSTakanori Watanabe printf("\tADDR="); 497986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 498986dffafSJohn Baldwin printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 499986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 500986dffafSJohn Baldwin 8); 501986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 502986dffafSJohn Baldwin 1 : 0); 50379d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 504986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 50579d7565cSPeter Wemm printf("TRUE}\n"); 50679d7565cSPeter Wemm else 50779d7565cSPeter Wemm printf("FALSE}\n"); 508986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 509986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 5109785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags); 51179d7565cSPeter Wemm printf(END_COMMENT); 51279d7565cSPeter Wemm } 51379d7565cSPeter Wemm 51479d7565cSPeter Wemm static void 515986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 51655d7ff9eSNate Lawson { 517986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 51855d7ff9eSNate Lawson 51955d7ff9eSNate Lawson printf(BEGIN_COMMENT); 52055d7ff9eSNate Lawson acpi_print_sdt(sdp); 521986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 52255d7ff9eSNate Lawson printf("\tEC_CONTROL="); 523986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 52455d7ff9eSNate Lawson printf("\n\tEC_DATA="); 525986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 526986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 527986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 528986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 52955d7ff9eSNate Lawson printf(END_COMMENT); 53055d7ff9eSNate Lawson } 53155d7ff9eSNate Lawson 53255d7ff9eSNate Lawson static void 533986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 534a47e681bSScott Long { 535986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 536986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 537986dffafSJohn Baldwin u_int i, entries; 538a47e681bSScott Long 539a47e681bSScott Long printf(BEGIN_COMMENT); 540a47e681bSScott Long acpi_print_sdt(sdp); 541986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 542986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 543986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 544986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 545986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 546a47e681bSScott Long printf("\n"); 5470c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address); 548986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 549986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 550986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 551a47e681bSScott Long } 552a47e681bSScott Long printf(END_COMMENT); 553a47e681bSScott Long } 554a47e681bSScott Long 555a47e681bSScott Long static void 55633866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 55733866658SJohn Baldwin { 55833866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 55933866658SJohn Baldwin UINT64 i, j; 56033866658SJohn Baldwin 56133866658SJohn Baldwin printf(BEGIN_COMMENT); 56233866658SJohn Baldwin acpi_print_sdt(sdp); 56333866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 5640c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount); 56533866658SJohn Baldwin printf("\n\t "); 56633866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 5670c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i); 56833866658SJohn Baldwin printf("\n\t +"); 56933866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 57033866658SJohn Baldwin printf("----"); 57133866658SJohn Baldwin printf("\n"); 57233866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 5730c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i); 57433866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 57533866658SJohn Baldwin printf(" %3d", 57633866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 57733866658SJohn Baldwin printf("\n"); 57833866658SJohn Baldwin } 57933866658SJohn Baldwin printf(END_COMMENT); 58033866658SJohn Baldwin } 58133866658SJohn Baldwin 58233866658SJohn Baldwin static void 583a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 584a0333ad1SJohn Baldwin uint32_t flags) 585a0333ad1SJohn Baldwin { 586a0333ad1SJohn Baldwin 587a0333ad1SJohn Baldwin printf("\tFlags={"); 588a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 589a0333ad1SJohn Baldwin printf("ENABLED"); 590a0333ad1SJohn Baldwin else 591a0333ad1SJohn Baldwin printf("DISABLED"); 592a0333ad1SJohn Baldwin printf("}\n"); 593a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 594a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 595a0333ad1SJohn Baldwin } 596a0333ad1SJohn Baldwin 597c031c93bSTakanori Watanabe static char * 598c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 599c031c93bSTakanori Watanabe { 600c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 601c031c93bSTakanori Watanabe char *eventname = NULL; 602c031c93bSTakanori Watanabe 603c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 604c031c93bSTakanori Watanabe 605c031c93bSTakanori Watanabe switch(event->event_type) { 606c031c93bSTakanori Watanabe case PREBOOT: 607c031c93bSTakanori Watanabe case POST_CODE: 608c031c93bSTakanori Watanabe case UNUSED: 609c031c93bSTakanori Watanabe case NO_ACTION: 610c031c93bSTakanori Watanabe case SEPARATOR: 611c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 612c031c93bSTakanori Watanabe case SCRTM_VERSION: 613c031c93bSTakanori Watanabe case CPU_MICROCODE: 614c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 615c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 616c031c93bSTakanori Watanabe case COMPACT_HASH: 617c031c93bSTakanori Watanabe case IPL: 618c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 619c031c93bSTakanori Watanabe case NONHOST_CODE: 620c031c93bSTakanori Watanabe case NONHOST_CONFIG: 621c031c93bSTakanori Watanabe case NONHOST_INFO: 622c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 623c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 624c031c93bSTakanori Watanabe break; 625c031c93bSTakanori Watanabe 626c031c93bSTakanori Watanabe case ACTION: 627c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 628c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 629c031c93bSTakanori Watanabe break; 630c031c93bSTakanori Watanabe 631c031c93bSTakanori Watanabe case EVENT_TAG: 632c031c93bSTakanori Watanabe switch (pc_event->event_id) { 633c031c93bSTakanori Watanabe case SMBIOS: 634c031c93bSTakanori Watanabe case BIS_CERT: 635c031c93bSTakanori Watanabe case CMOS: 636c031c93bSTakanori Watanabe case NVRAM: 637c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 638c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 639c031c93bSTakanori Watanabe case S_CRTM_VERSION: 640c031c93bSTakanori Watanabe case POST_BIOS_ROM: 641c031c93bSTakanori Watanabe case ESCD: 642c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 643c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 644c031c93bSTakanori Watanabe case POST_CONTENTS: 645c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 646c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 647c031c93bSTakanori Watanabe break; 648c031c93bSTakanori Watanabe 649c031c93bSTakanori Watanabe default: 650c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 651c031c93bSTakanori Watanabe pc_event->event_id); 652c031c93bSTakanori Watanabe break; 653c031c93bSTakanori Watanabe } 654c031c93bSTakanori Watanabe break; 655c031c93bSTakanori Watanabe 656c031c93bSTakanori Watanabe default: 657c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 658c031c93bSTakanori Watanabe break; 659c031c93bSTakanori Watanabe } 660c031c93bSTakanori Watanabe 661c031c93bSTakanori Watanabe return eventname; 662c031c93bSTakanori Watanabe } 663c031c93bSTakanori Watanabe 664c031c93bSTakanori Watanabe static void 665c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 666c031c93bSTakanori Watanabe { 667c031c93bSTakanori Watanabe int i; 668c031c93bSTakanori Watanabe char *eventname; 669c031c93bSTakanori Watanabe 670c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 671c031c93bSTakanori Watanabe 672c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 673c031c93bSTakanori Watanabe printf(" 0x"); 674c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 675c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 676c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 677c031c93bSTakanori Watanabe 678c031c93bSTakanori Watanabe free(eventname); 679c031c93bSTakanori Watanabe } 680c031c93bSTakanori Watanabe 681c031c93bSTakanori Watanabe static void 682c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 683c031c93bSTakanori Watanabe { 684c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 685c031c93bSTakanori Watanabe struct TCPAevent *event; 686977fd9daSTakanori Watanabe uintmax_t len, paddr; 687c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 688c031c93bSTakanori Watanabe unsigned char *vend = NULL; 689c031c93bSTakanori Watanabe 690c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 691c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 692c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 693c031c93bSTakanori Watanabe 694c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 695c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 696c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 697c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 698c031c93bSTakanori Watanabe break; 699c031c93bSTakanori Watanabe 700c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 701c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 702c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 703c031c93bSTakanori Watanabe break; 704c031c93bSTakanori Watanabe 705c031c93bSTakanori Watanabe default: 706c031c93bSTakanori Watanabe printf("XXX"); 707c031c93bSTakanori Watanabe printf(END_COMMENT); 708c031c93bSTakanori Watanabe return; 709c031c93bSTakanori Watanabe } 7100e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 711c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 712c031c93bSTakanori Watanabe 713c031c93bSTakanori Watanabe if (len == 0) { 714c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 715c031c93bSTakanori Watanabe printf(END_COMMENT); 716c031c93bSTakanori Watanabe return; 717c031c93bSTakanori Watanabe } 7182ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 7192ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 7202ef23c6dSTakanori Watanabe printf(END_COMMENT); 7212ef23c6dSTakanori Watanabe return; 7222ef23c6dSTakanori Watanabe } 723c031c93bSTakanori Watanabe 724c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 725c031c93bSTakanori Watanabe vend = vaddr + len; 726c031c93bSTakanori Watanabe 727c031c93bSTakanori Watanabe while (vaddr != NULL) { 7282ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 7292ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 730c031c93bSTakanori Watanabe break; 7310e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 732c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 733c031c93bSTakanori Watanabe break; 7342ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 7352ef23c6dSTakanori Watanabe break; 736c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 737c031c93bSTakanori Watanabe break; 738c031c93bSTakanori Watanabe #if 0 739c031c93bSTakanori Watanabe { 740c031c93bSTakanori Watanabe unsigned int i, j, k; 741c031c93bSTakanori Watanabe 742c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 743c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 744c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 745c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 746c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 747c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 748c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 749c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 750c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 751c031c93bSTakanori Watanabe j = i + 1; 752c031c93bSTakanori Watanabe } 753c031c93bSTakanori Watanabe } 754c031c93bSTakanori Watanabe printf("\n"); } 755c031c93bSTakanori Watanabe #endif 756c031c93bSTakanori Watanabe acpi_print_tcpa(event); 757c031c93bSTakanori Watanabe 758c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 759c031c93bSTakanori Watanabe } 760c031c93bSTakanori Watanabe 761c031c93bSTakanori Watanabe printf(END_COMMENT); 762c031c93bSTakanori Watanabe } 763c031c93bSTakanori Watanabe 764ec650989SNeel Natu static const char * 765ec650989SNeel Natu devscope_type2str(int type) 766ec650989SNeel Natu { 767ec650989SNeel Natu static char typebuf[16]; 768ec650989SNeel Natu 769ec650989SNeel Natu switch (type) { 770ec650989SNeel Natu case 1: 771ec650989SNeel Natu return ("PCI Endpoint Device"); 772ec650989SNeel Natu case 2: 773ec650989SNeel Natu return ("PCI Sub-Hierarchy"); 774ec650989SNeel Natu case 3: 775ec650989SNeel Natu return ("IOAPIC"); 776ec650989SNeel Natu case 4: 777ec650989SNeel Natu return ("HPET"); 778ec650989SNeel Natu default: 779ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type); 780ec650989SNeel Natu return (typebuf); 781ec650989SNeel Natu } 782ec650989SNeel Natu } 783ec650989SNeel Natu 784ec650989SNeel Natu static int 785ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining) 786ec650989SNeel Natu { 787ec650989SNeel Natu char sep; 788ec650989SNeel Natu int pathlen; 789ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend; 790ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr; 791ec650989SNeel Natu 792ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) 793ec650989SNeel Natu return (-1); 794ec650989SNeel Natu 795ec650989SNeel Natu if (remaining < devscope->Length) 796ec650989SNeel Natu return (-1); 797ec650989SNeel Natu 798ec650989SNeel Natu printf("\n"); 799ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); 800ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length); 801ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); 802ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus); 803ec650989SNeel Natu 804ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); 805ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); 806ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); 807ec650989SNeel Natu if (path < pathend) { 808ec650989SNeel Natu sep = '{'; 809ec650989SNeel Natu printf("\t\tPath="); 810ec650989SNeel Natu do { 811ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function); 812ec650989SNeel Natu sep=','; 813ec650989SNeel Natu path++; 814ec650989SNeel Natu } while (path < pathend); 815ec650989SNeel Natu printf("}\n"); 816ec650989SNeel Natu } 817ec650989SNeel Natu 818ec650989SNeel Natu return (devscope->Length); 819ec650989SNeel Natu } 820ec650989SNeel Natu 821ec650989SNeel Natu static void 822ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) 823ec650989SNeel Natu { 824ec650989SNeel Natu char *cp; 825ec650989SNeel Natu int remaining, consumed; 826ec650989SNeel Natu 827ec650989SNeel Natu printf("\n"); 828ec650989SNeel Natu printf("\tType=DRHD\n"); 829ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length); 830ec650989SNeel Natu 831ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 832ec650989SNeel Natu 833ec650989SNeel Natu printf("\tFlags="); 834ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL); 835ec650989SNeel Natu PRINTFLAG_END(); 836ec650989SNeel Natu 837ec650989SNeel Natu #undef PRINTFLAG 838ec650989SNeel Natu 839ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment); 8407d369c6eSJung-uk Kim printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address); 841ec650989SNeel Natu 842ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); 843ec650989SNeel Natu if (remaining > 0) 844ec650989SNeel Natu printf("\tDevice Scope:"); 845ec650989SNeel Natu while (remaining > 0) { 846ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining; 847ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 848ec650989SNeel Natu if (consumed <= 0) 849ec650989SNeel Natu break; 850ec650989SNeel Natu else 851ec650989SNeel Natu remaining -= consumed; 852ec650989SNeel Natu } 853ec650989SNeel Natu } 854ec650989SNeel Natu 855ec650989SNeel Natu static void 856ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) 857ec650989SNeel Natu { 858ec650989SNeel Natu char *cp; 859ec650989SNeel Natu int remaining, consumed; 860ec650989SNeel Natu 861ec650989SNeel Natu printf("\n"); 862ec650989SNeel Natu printf("\tType=RMRR\n"); 863ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length); 864ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment); 8657d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress); 8667d369c6eSJung-uk Kim printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress); 867ec650989SNeel Natu 868ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); 869ec650989SNeel Natu if (remaining > 0) 870ec650989SNeel Natu printf("\tDevice Scope:"); 871ec650989SNeel Natu while (remaining > 0) { 872ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining; 873ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 874ec650989SNeel Natu if (consumed <= 0) 875ec650989SNeel Natu break; 876ec650989SNeel Natu else 877ec650989SNeel Natu remaining -= consumed; 878ec650989SNeel Natu } 879ec650989SNeel Natu } 880ec650989SNeel Natu 881ec650989SNeel Natu static void 882ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) 883ec650989SNeel Natu { 884ec650989SNeel Natu char *cp; 885ec650989SNeel Natu int remaining, consumed; 886ec650989SNeel Natu 887ec650989SNeel Natu printf("\n"); 888ec650989SNeel Natu printf("\tType=ATSR\n"); 889ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length); 890ec650989SNeel Natu 891ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 892ec650989SNeel Natu 893ec650989SNeel Natu printf("\tFlags="); 894ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS); 895ec650989SNeel Natu PRINTFLAG_END(); 896ec650989SNeel Natu 897ec650989SNeel Natu #undef PRINTFLAG 898ec650989SNeel Natu 899ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment); 900ec650989SNeel Natu 901ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); 902ec650989SNeel Natu if (remaining > 0) 903ec650989SNeel Natu printf("\tDevice Scope:"); 904ec650989SNeel Natu while (remaining > 0) { 905ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining; 906ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 907ec650989SNeel Natu if (consumed <= 0) 908ec650989SNeel Natu break; 909ec650989SNeel Natu else 910ec650989SNeel Natu remaining -= consumed; 911ec650989SNeel Natu } 912ec650989SNeel Natu } 913ec650989SNeel Natu 914ec650989SNeel Natu static void 915ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) 916ec650989SNeel Natu { 917ec650989SNeel Natu 918ec650989SNeel Natu printf("\n"); 919ec650989SNeel Natu printf("\tType=RHSA\n"); 920ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length); 9217d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress); 922ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); 923ec650989SNeel Natu } 924ec650989SNeel Natu 925ec650989SNeel Natu static int 926ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining) 927ec650989SNeel Natu { 928ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr; 929ec650989SNeel Natu 930ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) 931ec650989SNeel Natu return (-1); 932ec650989SNeel Natu 933ec650989SNeel Natu if (remaining < hdr->Length) 934ec650989SNeel Natu return (-1); 935ec650989SNeel Natu 936ec650989SNeel Natu switch (hdr->Type) { 937ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT: 938ec650989SNeel Natu acpi_handle_dmar_drhd(addr); 939ec650989SNeel Natu break; 940ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY: 941ec650989SNeel Natu acpi_handle_dmar_rmrr(addr); 942ec650989SNeel Natu break; 943313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS: 944ec650989SNeel Natu acpi_handle_dmar_atsr(addr); 945ec650989SNeel Natu break; 946313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 947ec650989SNeel Natu acpi_handle_dmar_rhsa(addr); 948ec650989SNeel Natu break; 949ec650989SNeel Natu default: 950ec650989SNeel Natu printf("\n"); 951ec650989SNeel Natu printf("\tType=%d\n", hdr->Type); 952ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length); 953ec650989SNeel Natu break; 954ec650989SNeel Natu } 955ec650989SNeel Natu return (hdr->Length); 956ec650989SNeel Natu } 957ec650989SNeel Natu 958ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT 959ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2) 960ec650989SNeel Natu #endif 961ec650989SNeel Natu 962ec650989SNeel Natu static void 963ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) 964ec650989SNeel Natu { 965ec650989SNeel Natu char *cp; 966ec650989SNeel Natu int remaining, consumed; 967ec650989SNeel Natu ACPI_TABLE_DMAR *dmar; 968ec650989SNeel Natu 969ec650989SNeel Natu printf(BEGIN_COMMENT); 970ec650989SNeel Natu acpi_print_sdt(sdp); 971ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp; 972ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1); 973ec650989SNeel Natu 974ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 975ec650989SNeel Natu 976ec650989SNeel Natu printf("\tFlags="); 977ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP); 978ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); 979ec650989SNeel Natu PRINTFLAG_END(); 980ec650989SNeel Natu 981ec650989SNeel Natu #undef PRINTFLAG 982ec650989SNeel Natu 983ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); 984ec650989SNeel Natu while (remaining > 0) { 985ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining; 986ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining); 987ec650989SNeel Natu if (consumed <= 0) 988ec650989SNeel Natu break; 989ec650989SNeel Natu else 990ec650989SNeel Natu remaining -= consumed; 991ec650989SNeel Natu } 992ec650989SNeel Natu 993ec650989SNeel Natu printf(END_COMMENT); 994ec650989SNeel Natu } 995ec650989SNeel Natu 996a0333ad1SJohn Baldwin static void 997986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 998a0333ad1SJohn Baldwin { 999a0333ad1SJohn Baldwin 1000a0333ad1SJohn Baldwin printf("\tFlags={"); 1001986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 1002a0333ad1SJohn Baldwin printf("ENABLED"); 1003a0333ad1SJohn Baldwin else 1004a0333ad1SJohn Baldwin printf("DISABLED"); 1005986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 1006a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 1007986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 1008a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 1009a0333ad1SJohn Baldwin printf("}\n"); 1010986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 1011986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 1012986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 1013a0333ad1SJohn Baldwin } 1014a0333ad1SJohn Baldwin 1015bf70beceSEd Schouten static const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; 1016a0333ad1SJohn Baldwin 1017a0333ad1SJohn Baldwin static void 1018986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 1019a0333ad1SJohn Baldwin { 1020986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 1021986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 1022a0333ad1SJohn Baldwin 1023986dffafSJohn Baldwin if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0])) 1024986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 1025a0333ad1SJohn Baldwin else 1026986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 1027986dffafSJohn Baldwin switch (srat->Type) { 1028a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 1029986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 1030986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 1031986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 1032986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 1033986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 1034986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 1035a0333ad1SJohn Baldwin break; 1036a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1037986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 1038a0333ad1SJohn Baldwin break; 1039a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1040986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 1041986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 1042986dffafSJohn Baldwin x2apic->Flags); 1043a0333ad1SJohn Baldwin break; 1044a0333ad1SJohn Baldwin } 1045a0333ad1SJohn Baldwin } 1046a0333ad1SJohn Baldwin 1047a0333ad1SJohn Baldwin static void 1048986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 1049a0333ad1SJohn Baldwin { 1050986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 1051a0333ad1SJohn Baldwin 1052a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 1053a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 1054986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 1055986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 1056986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 1057a0333ad1SJohn Baldwin printf(END_COMMENT); 1058a0333ad1SJohn Baldwin } 1059a0333ad1SJohn Baldwin 1060a0333ad1SJohn Baldwin static void 1061986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 1062c62f1cccSMitsuru IWASAKI { 1063773b6454SNate Lawson printf(" "); 1064986dffafSJohn Baldwin acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); 1065c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 1066986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 1067e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 1068986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 1069e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 1070986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 1071986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 1072e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 1073986dffafSJohn Baldwin acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); 1074986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 1075e1e9a4bfSMitsuru IWASAKI } 1076e1e9a4bfSMitsuru IWASAKI 1077945137d9SNate Lawson static void 1078986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 1079e1e9a4bfSMitsuru IWASAKI { 1080986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1081986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1082e1e9a4bfSMitsuru IWASAKI int i, entries; 1083e1e9a4bfSMitsuru IWASAKI 1084986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1085986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1086773b6454SNate Lawson printf(BEGIN_COMMENT); 1087773b6454SNate Lawson acpi_print_sdt(rsdp); 1088986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1089e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 1090e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1091e1e9a4bfSMitsuru IWASAKI if (i > 0) 1092e1e9a4bfSMitsuru IWASAKI printf(", "); 1093fe1d0c2dSJung-uk Kim if (addr_size == 4) 10947d369c6eSJung-uk Kim printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i])); 1095fe1d0c2dSJung-uk Kim else 10967d369c6eSJung-uk Kim printf("0x%016jx", 10977d369c6eSJung-uk Kim (uintmax_t)le64toh(xsdt->TableOffsetEntry[i])); 1098e1e9a4bfSMitsuru IWASAKI } 1099e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 1100c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1101e1e9a4bfSMitsuru IWASAKI } 1102e1e9a4bfSMitsuru IWASAKI 11038e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 11048e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 11058e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 11068e6a8737SNate Lawson }; 11078e6a8737SNate Lawson 1108945137d9SNate Lawson static void 1109986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 1110e1e9a4bfSMitsuru IWASAKI { 1111986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 11128e6a8737SNate Lawson const char *pm; 1113e1e9a4bfSMitsuru IWASAKI 1114986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 1115c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 11162177d4e6SNate Lawson acpi_print_sdt(sdp); 1117986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 1118986dffafSJohn Baldwin fadt->Dsdt); 1119986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 1120986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 11218e6a8737SNate Lawson pm = "Reserved"; 11228e6a8737SNate Lawson else 1123986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 1124986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 1125986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 1126986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 1127986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 1128986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 1129986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 1130986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 1131e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 1132986dffafSJohn Baldwin fadt->Pm1aEventBlock, 1133986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 1134986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 1135e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 1136986dffafSJohn Baldwin fadt->Pm1bEventBlock, 1137986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 1138e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 1139986dffafSJohn Baldwin fadt->Pm1aControlBlock, 1140986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 1141986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 1142e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 1143986dffafSJohn Baldwin fadt->Pm1bControlBlock, 1144986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 1145986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 1146e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 1147986dffafSJohn Baldwin fadt->Pm2ControlBlock, 1148986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 1149c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 1150986dffafSJohn Baldwin fadt->PmTimerBlock, 1151986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 1152986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 11538e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 1154986dffafSJohn Baldwin fadt->Gpe0Block, 1155986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 1156986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 11578e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 1158986dffafSJohn Baldwin fadt->Gpe1Block, 1159986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 1160986dffafSJohn Baldwin fadt->Gpe1Base); 1161986dffafSJohn Baldwin if (fadt->CstControl != 0) 1162986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 116351c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 1164986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 1165e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 1166986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 1167e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 1168986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 1169e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 1170986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 1171e1e9a4bfSMitsuru IWASAKI 1172ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) 1173e1e9a4bfSMitsuru IWASAKI 11748e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 1175986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 1176986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 1177986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 1178986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 1179986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 1180*f6469ce1SAndrew Turner PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC); 1181ec650989SNeel Natu PRINTFLAG_END(); 11828e6a8737SNate Lawson 11838e6a8737SNate Lawson printf("\tFlags="); 1184986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 1185986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 1186986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 1187986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 1188986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 1189986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 1190986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 1191986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 1192986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 1193986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 1194986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 1195986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 1196986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 1197986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 1198986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 1199986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 1200986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 1201986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 1202986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 1203986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 1204*f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, HW_REDUCED); 1205*f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, LOW_POWER_S0); 1206ec650989SNeel Natu PRINTFLAG_END(); 1207e1e9a4bfSMitsuru IWASAKI 1208e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 1209e1e9a4bfSMitsuru IWASAKI 1210986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 12118e6a8737SNate Lawson printf("\tRESET_REG="); 1212986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 1213986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 12148e6a8737SNate Lawson } 1215c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 12167d369c6eSJung-uk Kim printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs); 12177d369c6eSJung-uk Kim printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt); 1218c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 1219986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 1220986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 1221c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 1222986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 1223c08c4e81SNate Lawson } 1224c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 1225986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 1226986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 1227c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 1228986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 1229c08c4e81SNate Lawson } 1230986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 1231773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 1232986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 1233c08c4e81SNate Lawson } 1234773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 1235986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 1236986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 1237773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 1238986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 1239c08c4e81SNate Lawson } 1240986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 1241773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 1242986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 1243c08c4e81SNate Lawson } 1244773b6454SNate Lawson printf("\n"); 1245773b6454SNate Lawson } 12468e6a8737SNate Lawson 12478e6a8737SNate Lawson printf(END_COMMENT); 12488e6a8737SNate Lawson } 12498e6a8737SNate Lawson 12508e6a8737SNate Lawson static void 1251986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 12528e6a8737SNate Lawson { 12538e6a8737SNate Lawson printf(BEGIN_COMMENT); 1254986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 1255986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 1256986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 12578e6a8737SNate Lawson 1258773b6454SNate Lawson printf("\tGlobal_Lock="); 1259986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 1260986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 12618e6a8737SNate Lawson printf("PENDING,"); 1262986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 12638e6a8737SNate Lawson printf("OWNED"); 12648e6a8737SNate Lawson } 1265773b6454SNate Lawson printf("\n"); 12668e6a8737SNate Lawson 1267773b6454SNate Lawson printf("\tFlags="); 1268986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 12698e6a8737SNate Lawson printf("S4BIOS"); 1270773b6454SNate Lawson printf("\n"); 12718e6a8737SNate Lawson 12727d369c6eSJung-uk Kim if (facs->XFirmwareWakingVector != 0) 12737d369c6eSJung-uk Kim printf("\tX_Firm_Wake_Vec=%016jx\n", 12747d369c6eSJung-uk Kim (uintmax_t)facs->XFirmwareWakingVector); 1275986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 12768e6a8737SNate Lawson 1277c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1278e1e9a4bfSMitsuru IWASAKI } 1279e1e9a4bfSMitsuru IWASAKI 1280945137d9SNate Lawson static void 1281986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 1282e1e9a4bfSMitsuru IWASAKI { 1283773b6454SNate Lawson printf(BEGIN_COMMENT); 1284773b6454SNate Lawson acpi_print_sdt(dsdp); 1285773b6454SNate Lawson printf(END_COMMENT); 1286e1e9a4bfSMitsuru IWASAKI } 1287e1e9a4bfSMitsuru IWASAKI 1288e1e9a4bfSMitsuru IWASAKI int 1289e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 1290e1e9a4bfSMitsuru IWASAKI { 1291986dffafSJohn Baldwin uint8_t *bp; 1292986dffafSJohn Baldwin uint8_t sum; 1293e1e9a4bfSMitsuru IWASAKI 1294e1e9a4bfSMitsuru IWASAKI bp = p; 1295e1e9a4bfSMitsuru IWASAKI sum = 0; 1296e1e9a4bfSMitsuru IWASAKI while (length--) 1297e1e9a4bfSMitsuru IWASAKI sum += *bp++; 1298e1e9a4bfSMitsuru IWASAKI 1299e1e9a4bfSMitsuru IWASAKI return (sum); 1300e1e9a4bfSMitsuru IWASAKI } 1301e1e9a4bfSMitsuru IWASAKI 1302986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 1303e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 1304e1e9a4bfSMitsuru IWASAKI { 1305986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 1306e1e9a4bfSMitsuru IWASAKI 1307986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 1308986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 1309e1e9a4bfSMitsuru IWASAKI return (sp); 1310e1e9a4bfSMitsuru IWASAKI } 1311e1e9a4bfSMitsuru IWASAKI 1312945137d9SNate Lawson static void 1313986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 1314e1e9a4bfSMitsuru IWASAKI { 1315c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 1316a74172abSNate Lawson printf(" RSD PTR: OEM="); 1317986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 1318986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 1319986dffafSJohn Baldwin rp->Revision); 1320986dffafSJohn Baldwin if (rp->Revision < 2) { 1321986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 1322986dffafSJohn Baldwin rp->Checksum); 1323a74172abSNate Lawson } else { 13247d369c6eSJung-uk Kim printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n", 13257d369c6eSJung-uk Kim (uintmax_t)rp->XsdtPhysicalAddress, rp->Length, 1326986dffafSJohn Baldwin rp->ExtendedChecksum); 1327a74172abSNate Lawson } 1328c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1329e1e9a4bfSMitsuru IWASAKI } 1330e1e9a4bfSMitsuru IWASAKI 1331945137d9SNate Lawson static void 1332986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 1333e1e9a4bfSMitsuru IWASAKI { 1334986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 1335986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1336986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1337a74172abSNate Lawson vm_offset_t addr; 1338a74172abSNate Lawson int entries, i; 1339e1e9a4bfSMitsuru IWASAKI 1340e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 1341986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1342986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1343986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1344e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1345fe1d0c2dSJung-uk Kim if (addr_size == 4) 1346986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1347fe1d0c2dSJung-uk Kim else 1348986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1349fe1d0c2dSJung-uk Kim if (addr == 0) 1350fe1d0c2dSJung-uk Kim continue; 1351986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1352986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 13535cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 1354986dffafSJohn Baldwin sdp->Signature); 13555cf6d493SNate Lawson continue; 13565cf6d493SNate Lawson } 1357986dffafSJohn Baldwin if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 13582177d4e6SNate Lawson acpi_handle_fadt(sdp); 1359986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 1360986dffafSJohn Baldwin acpi_handle_madt(sdp); 1361986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 136279d7565cSPeter Wemm acpi_handle_hpet(sdp); 1363986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 136455d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 1365986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 1366a47e681bSScott Long acpi_handle_mcfg(sdp); 136733866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 136833866658SJohn Baldwin acpi_handle_slit(sdp); 1369986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 1370a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 1371c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 1372c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 1373ec650989SNeel Natu else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) 1374ec650989SNeel Natu acpi_handle_dmar(sdp); 1375773b6454SNate Lawson else { 1376773b6454SNate Lawson printf(BEGIN_COMMENT); 1377773b6454SNate Lawson acpi_print_sdt(sdp); 1378773b6454SNate Lawson printf(END_COMMENT); 1379773b6454SNate Lawson } 1380e1e9a4bfSMitsuru IWASAKI } 1381e1e9a4bfSMitsuru IWASAKI } 1382c62f1cccSMitsuru IWASAKI 1383986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1384476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 1385945137d9SNate Lawson { 1386986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 1387986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 1388945137d9SNate Lawson 1389945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 1390945137d9SNate Lawson if (!rp) 1391945137d9SNate Lawson errx(1, "Can't find ACPI information"); 1392945137d9SNate Lawson 1393945137d9SNate Lawson if (tflag) 1394945137d9SNate Lawson acpi_print_rsd_ptr(rp); 1395986dffafSJohn Baldwin if (rp->Revision < 2) { 1396986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 1397986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 1398986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1399945137d9SNate Lawson errx(1, "RSDT is corrupted"); 1400a74172abSNate Lawson addr_size = sizeof(uint32_t); 1401a74172abSNate Lawson } else { 1402986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 1403986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 1404986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1405a74172abSNate Lawson errx(1, "XSDT is corrupted"); 1406a74172abSNate Lawson addr_size = sizeof(uint64_t); 1407a74172abSNate Lawson } 1408945137d9SNate Lawson return (rsdp); 1409945137d9SNate Lawson } 1410c62f1cccSMitsuru IWASAKI 141162c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 1412bfa3f012SMarcel Moolenaar static int 1413986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 1414bfa3f012SMarcel Moolenaar { 1415986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 1416986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 1417bfa3f012SMarcel Moolenaar uint8_t sum; 1418bfa3f012SMarcel Moolenaar 141962c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 1420bfa3f012SMarcel Moolenaar sdt = *dsdt; 1421bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 1422986dffafSJohn Baldwin sdt.Checksum = 0; 1423986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 1424986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1425986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 1426f7675a56SNate Lawson while (ssdt != NULL) { 1427986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 1428986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 1429986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 1430986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 1431bfa3f012SMarcel Moolenaar } 1432986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 1433986dffafSJohn Baldwin sdt.Checksum -= sum; 1434bfa3f012SMarcel Moolenaar } 143562c7bde1SNate Lawson 143662c7bde1SNate Lawson /* Write out the DSDT header and body. */ 1437986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 1438986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 143962c7bde1SNate Lawson 1440b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 1441f7675a56SNate Lawson if (rsdt != NULL) { 1442bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 1443bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 1444986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 1445986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1446bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 1447bfa3f012SMarcel Moolenaar } 1448bfa3f012SMarcel Moolenaar } 1449bfa3f012SMarcel Moolenaar return (0); 1450bfa3f012SMarcel Moolenaar } 1451bfa3f012SMarcel Moolenaar 1452c62f1cccSMitsuru IWASAKI void 1453986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1454c62f1cccSMitsuru IWASAKI { 1455945137d9SNate Lawson int fd; 1456945137d9SNate Lawson mode_t mode; 1457945137d9SNate Lawson 1458945137d9SNate Lawson assert(outfile != NULL); 1459945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1460945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 1461945137d9SNate Lawson if (fd == -1) { 1462945137d9SNate Lawson perror("dsdt_save_file"); 1463945137d9SNate Lawson return; 1464945137d9SNate Lawson } 1465bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1466945137d9SNate Lawson close(fd); 1467c62f1cccSMitsuru IWASAKI } 1468c62f1cccSMitsuru IWASAKI 1469945137d9SNate Lawson void 1470986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1471c62f1cccSMitsuru IWASAKI { 14727e2cc014SDon Lewis char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX]; 14737e2cc014SDon Lewis const char *iname = "/acpdump.din"; 14747e2cc014SDon Lewis const char *oname = "/acpdump.dsl"; 147599065116SJung-uk Kim const char *tmpdir; 1476945137d9SNate Lawson FILE *fp; 147799065116SJung-uk Kim size_t len; 14787e2cc014SDon Lewis int fd, status; 14797e2cc014SDon Lewis pid_t pid; 1480945137d9SNate Lawson 148199065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 148299065116SJung-uk Kim if (tmpdir == NULL) 148399065116SJung-uk Kim tmpdir = _PATH_TMP; 14847e2cc014SDon Lewis if (realpath(tmpdir, buf) == NULL) { 1485d6a6e590SJung-uk Kim perror("realpath tmp dir"); 148699065116SJung-uk Kim return; 148799065116SJung-uk Kim } 14887e2cc014SDon Lewis len = sizeof(wrkdir) - strlen(iname); 14897e2cc014SDon Lewis if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) { 14907e2cc014SDon Lewis fprintf(stderr, "$TMPDIR too long\n"); 14917e2cc014SDon Lewis return; 14927e2cc014SDon Lewis } 14937e2cc014SDon Lewis if (mkdtemp(wrkdir) == NULL) { 14947e2cc014SDon Lewis perror("mkdtemp tmp working dir"); 14957e2cc014SDon Lewis return; 14967e2cc014SDon Lewis } 14977e2cc014SDon Lewis assert((size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname) 14987e2cc014SDon Lewis <= sizeof(tmpstr) - 1); 14997e2cc014SDon Lewis fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 1500945137d9SNate Lawson if (fd < 0) { 1501945137d9SNate Lawson perror("iasl tmp file"); 1502945137d9SNate Lawson return; 1503c62f1cccSMitsuru IWASAKI } 1504bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1505945137d9SNate Lawson close(fd); 1506945137d9SNate Lawson 1507945137d9SNate Lawson /* Run iasl -d on the temp file */ 15087e2cc014SDon Lewis if ((pid = fork()) == 0) { 1509945137d9SNate Lawson close(STDOUT_FILENO); 1510945137d9SNate Lawson if (vflag == 0) 1511945137d9SNate Lawson close(STDERR_FILENO); 151299065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 1513945137d9SNate Lawson err(1, "exec"); 1514c62f1cccSMitsuru IWASAKI } 15157e2cc014SDon Lewis if (pid > 0) 15167e2cc014SDon Lewis wait(&status); 15177e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 15187e2cc014SDon Lewis perror("unlink"); 15197e2cc014SDon Lewis goto out; 15207e2cc014SDon Lewis } 15217e2cc014SDon Lewis if (pid < 0) { 15227e2cc014SDon Lewis perror("fork"); 15237e2cc014SDon Lewis goto out; 15247e2cc014SDon Lewis } 15257e2cc014SDon Lewis if (status != 0) { 15267e2cc014SDon Lewis fprintf(stderr, "iast exit status = %d\n", status); 15277e2cc014SDon Lewis } 1528945137d9SNate Lawson 1529945137d9SNate Lawson /* Dump iasl's output to stdout */ 15307e2cc014SDon Lewis assert((size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname) 15317e2cc014SDon Lewis <= sizeof(tmpstr) -1); 153299065116SJung-uk Kim fp = fopen(tmpstr, "r"); 15337e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 15347e2cc014SDon Lewis perror("unlink"); 15357e2cc014SDon Lewis goto out; 15367e2cc014SDon Lewis } 1537945137d9SNate Lawson if (fp == NULL) { 1538945137d9SNate Lawson perror("iasl tmp file (read)"); 15397e2cc014SDon Lewis goto out; 1540945137d9SNate Lawson } 1541945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 1542945137d9SNate Lawson fwrite(buf, 1, len, stdout); 1543945137d9SNate Lawson fclose(fp); 15447e2cc014SDon Lewis 15457e2cc014SDon Lewis out: 15467e2cc014SDon Lewis if (rmdir(wrkdir) < 0) 15477e2cc014SDon Lewis perror("rmdir"); 1548c62f1cccSMitsuru IWASAKI } 1549c62f1cccSMitsuru IWASAKI 1550945137d9SNate Lawson void 1551986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 1552c62f1cccSMitsuru IWASAKI { 1553945137d9SNate Lawson acpi_handle_rsdt(rsdp); 1554c62f1cccSMitsuru IWASAKI } 1555c62f1cccSMitsuru IWASAKI 1556bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 1557986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1558986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 1559c62f1cccSMitsuru IWASAKI { 1560986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1561986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1562986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1563a74172abSNate Lawson vm_offset_t addr; 1564a74172abSNate Lawson int entries, i; 1565945137d9SNate Lawson 1566986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1567986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1568986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1569945137d9SNate Lawson for (i = 0; i < entries; i++) { 1570fe1d0c2dSJung-uk Kim if (addr_size == 4) 1571986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1572fe1d0c2dSJung-uk Kim else 1573986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1574fe1d0c2dSJung-uk Kim if (addr == 0) 1575fe1d0c2dSJung-uk Kim continue; 1576986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1577bfa3f012SMarcel Moolenaar if (last != NULL) { 1578bfa3f012SMarcel Moolenaar if (sdt == last) 1579bfa3f012SMarcel Moolenaar last = NULL; 1580bfa3f012SMarcel Moolenaar continue; 1581bfa3f012SMarcel Moolenaar } 1582986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 1583a74172abSNate Lawson continue; 1584986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1585945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 1586945137d9SNate Lawson return (sdt); 1587c62f1cccSMitsuru IWASAKI } 1588c62f1cccSMitsuru IWASAKI 1589945137d9SNate Lawson return (NULL); 1590c62f1cccSMitsuru IWASAKI } 1591c62f1cccSMitsuru IWASAKI 1592986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1593986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 1594c62f1cccSMitsuru IWASAKI { 1595986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1596c62f1cccSMitsuru IWASAKI 1597986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 1598c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 1599986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 16002e71eb12SNate Lawson else 1601986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 1602986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1603945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1604945137d9SNate Lawson return (sdt); 1605c62f1cccSMitsuru IWASAKI } 1606