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: 171986dffafSJohn Baldwin printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address, 172986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1738e6a8737SNate Lawson break; 1748e6a8737SNate Lawson case ACPI_GAS_IO: 175986dffafSJohn Baldwin printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address, 176986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1778e6a8737SNate Lawson break; 1788e6a8737SNate Lawson case ACPI_GAS_PCI: 179986dffafSJohn Baldwin printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), 180986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 181986dffafSJohn Baldwin (uint16_t)gas->Address); 1828e6a8737SNate Lawson break; 1838e6a8737SNate Lawson /* XXX How to handle these below? */ 1848e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 185986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 186986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1878e6a8737SNate Lawson break; 1888e6a8737SNate Lawson case ACPI_GAS_SMBUS: 189986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 190986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1918e6a8737SNate Lawson break; 192986dffafSJohn Baldwin case ACPI_GAS_CMOS: 193986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 194986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 1958e6a8737SNate Lawson case ACPI_GAS_FIXED: 1968e6a8737SNate Lawson default: 197986dffafSJohn Baldwin printf("0x%08lx (?)", (u_long)gas->Address); 1988e6a8737SNate Lawson break; 1998e6a8737SNate Lawson } 2008e6a8737SNate Lawson } 2018e6a8737SNate Lawson 202c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 203c2962974SNate Lawson static int 204986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 205e1e9a4bfSMitsuru IWASAKI { 206c2962974SNate Lawson int fadt_revision; 207e1e9a4bfSMitsuru IWASAKI 208c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 209c83f0f99SNate Lawson if (addr_size == 8) { 210c83f0f99SNate Lawson fadt_revision = 2; 2118e6a8737SNate Lawson 212773b6454SNate Lawson /* 213c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 214c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 215c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 216c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 217c83f0f99SNate Lawson * version for all subsequent tables. 218773b6454SNate Lawson */ 219986dffafSJohn Baldwin if (fadt->Facs != 0 && 220986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 221c83f0f99SNate Lawson fadt_revision = 1; 222c2962974SNate Lawson } else 223c83f0f99SNate Lawson fadt_revision = 1; 224c2962974SNate Lawson return (fadt_revision); 225c83f0f99SNate Lawson } 226c2962974SNate Lawson 227c2962974SNate Lawson static void 228986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 229c2962974SNate Lawson { 230986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 231986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 232986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 233c2962974SNate Lawson int fadt_revision; 234c2962974SNate Lawson 235986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2362177d4e6SNate Lawson acpi_print_fadt(sdp); 237c83f0f99SNate Lawson 238c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 239c83f0f99SNate Lawson if (fadt_revision == 1) 240986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); 241773b6454SNate Lawson else 242986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); 243986dffafSJohn Baldwin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) 2448e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2458e6a8737SNate Lawson acpi_print_facs(facs); 2468e6a8737SNate Lawson 247c83f0f99SNate Lawson if (fadt_revision == 1) 248986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 249773b6454SNate Lawson else 250986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 251986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 252945137d9SNate Lawson errx(1, "DSDT is corrupt"); 253945137d9SNate Lawson acpi_print_dsdt(dsdp); 254c62f1cccSMitsuru IWASAKI } 255c62f1cccSMitsuru IWASAKI 256c62f1cccSMitsuru IWASAKI static void 257986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 258986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 259986dffafSJohn Baldwin { 260986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 261986dffafSJohn Baldwin char *end; 262986dffafSJohn Baldwin 263986dffafSJohn Baldwin subtable = first; 264986dffafSJohn Baldwin end = (char *)table + table->Length; 265986dffafSJohn Baldwin while ((char *)subtable < end) { 266986dffafSJohn Baldwin printf("\n"); 267986dffafSJohn Baldwin action(subtable); 268986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 269986dffafSJohn Baldwin subtable->Length); 270986dffafSJohn Baldwin } 271986dffafSJohn Baldwin } 272986dffafSJohn Baldwin 273986dffafSJohn Baldwin static void 2740a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 2750a473124SJohn Baldwin { 2760a473124SJohn Baldwin 2770a473124SJohn Baldwin printf("\tACPI CPU="); 2780a473124SJohn Baldwin if (cpu_id == 0xff) 2790a473124SJohn Baldwin printf("ALL\n"); 2800a473124SJohn Baldwin else 2810a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 2820a473124SJohn Baldwin } 2830a473124SJohn Baldwin 2840a473124SJohn Baldwin static void 285986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 2860a473124SJohn Baldwin { 287986dffafSJohn Baldwin 288986dffafSJohn Baldwin printf("\tUID=%d", uid); 289986dffafSJohn Baldwin if (uid_string != NULL) 290986dffafSJohn Baldwin printf(" (%s)", uid_string); 291986dffafSJohn Baldwin printf("\n"); 292986dffafSJohn Baldwin } 293986dffafSJohn Baldwin 294986dffafSJohn Baldwin static void 295986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 296986dffafSJohn Baldwin { 297986dffafSJohn Baldwin 2980a473124SJohn Baldwin printf("\tFlags={"); 299986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 3000a473124SJohn Baldwin printf("ENABLED"); 3010a473124SJohn Baldwin else 3020a473124SJohn Baldwin printf("DISABLED"); 3030a473124SJohn Baldwin printf("}\n"); 304986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3050a473124SJohn Baldwin } 3060a473124SJohn Baldwin 3070a473124SJohn Baldwin static void 308986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 3090a473124SJohn Baldwin { 310986dffafSJohn Baldwin 311986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3120a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 313986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 3140a473124SJohn Baldwin } 3150a473124SJohn Baldwin 3160a473124SJohn Baldwin static void 317986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 3180a473124SJohn Baldwin { 3190a473124SJohn Baldwin 3200a473124SJohn Baldwin printf("\tFlags={Polarity="); 321986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 322986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 3230a473124SJohn Baldwin printf("conforming"); 3240a473124SJohn Baldwin break; 325986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3260a473124SJohn Baldwin printf("active-hi"); 3270a473124SJohn Baldwin break; 328986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3290a473124SJohn Baldwin printf("active-lo"); 3300a473124SJohn Baldwin break; 3310a473124SJohn Baldwin default: 332986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3330a473124SJohn Baldwin break; 3340a473124SJohn Baldwin } 3350a473124SJohn Baldwin printf(", Trigger="); 336986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 337986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3380a473124SJohn Baldwin printf("conforming"); 3390a473124SJohn Baldwin break; 340986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3410a473124SJohn Baldwin printf("edge"); 3420a473124SJohn Baldwin break; 343986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3440a473124SJohn Baldwin printf("level"); 3450a473124SJohn Baldwin break; 3460a473124SJohn Baldwin default: 347986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3480a473124SJohn Baldwin } 3490a473124SJohn Baldwin printf("}\n"); 3500a473124SJohn Baldwin } 3510a473124SJohn Baldwin 3520a473124SJohn Baldwin static void 353986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 3540a473124SJohn Baldwin { 3550a473124SJohn Baldwin 356986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 357986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 358986dffafSJohn Baldwin } 359986dffafSJohn Baldwin 360986dffafSJohn Baldwin static void 361986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 362986dffafSJohn Baldwin { 363986dffafSJohn Baldwin 364986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 3650a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 3660a473124SJohn Baldwin } 3670a473124SJohn Baldwin 368bf70beceSEd Schouten static const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", 369bf70beceSEd Schouten "NMI", "Local APIC NMI", 370bf70beceSEd Schouten "Local APIC Override", "IO SAPIC", 371bf70beceSEd Schouten "Local SAPIC", "Platform Interrupt", 372986dffafSJohn Baldwin "Local X2APIC", "Local X2APIC NMI" }; 373bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 3740a473124SJohn Baldwin "Corrected Platform Error" }; 3750a473124SJohn Baldwin 3760a473124SJohn Baldwin static void 377986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 3780a473124SJohn Baldwin { 379986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 380986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 381986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 382986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 383986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 384986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 385986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 386986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 387986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 388986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 389986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 3900a473124SJohn Baldwin 391986dffafSJohn Baldwin if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0])) 392986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 393a0333ad1SJohn Baldwin else 394986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 395986dffafSJohn Baldwin switch (mp->Type) { 396986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 397986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 398986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 399986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 4000a473124SJohn Baldwin break; 401986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 402986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 403986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 404986dffafSJohn Baldwin ioapic->Address); 4050a473124SJohn Baldwin break; 406986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 407986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 408986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 409986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 410986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 4110a473124SJohn Baldwin break; 412986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 413986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 414986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 4150a473124SJohn Baldwin break; 416986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 417986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 418986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 419986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 4200a473124SJohn Baldwin break; 421986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 422986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 423945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 424986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 4250a473124SJohn Baldwin break; 426986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 427986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 428986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 429986dffafSJohn Baldwin iosapic->Address); 4300a473124SJohn Baldwin break; 431986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 432986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 433986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 434986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 435986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 436986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 437986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 4380a473124SJohn Baldwin break; 439986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 440986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 441986dffafSJohn Baldwin if (isrc->Type < sizeof(platform_int_types) / 442986dffafSJohn Baldwin sizeof(platform_int_types[0])) 443986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 444986dffafSJohn Baldwin else 445986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 446986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 447986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 448986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 449986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 450986dffafSJohn Baldwin break; 451986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 452986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 453986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 454986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 455986dffafSJohn Baldwin break; 456986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 457986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 458986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 459986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 4600a473124SJohn Baldwin break; 4610a473124SJohn Baldwin } 4620a473124SJohn Baldwin } 4630a473124SJohn Baldwin 4640a473124SJohn Baldwin static void 465986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 4660a473124SJohn Baldwin { 467986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 4680a473124SJohn Baldwin 469773b6454SNate Lawson printf(BEGIN_COMMENT); 470773b6454SNate Lawson acpi_print_sdt(sdp); 471986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 472986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 4730a473124SJohn Baldwin printf("\tFlags={"); 474986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 4750a473124SJohn Baldwin printf("PC-AT"); 4760a473124SJohn Baldwin printf("}\n"); 477986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 4780a473124SJohn Baldwin printf(END_COMMENT); 4790a473124SJohn Baldwin } 4800a473124SJohn Baldwin 4810a473124SJohn Baldwin static void 482986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 48379d7565cSPeter Wemm { 484986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 48579d7565cSPeter Wemm 486773b6454SNate Lawson printf(BEGIN_COMMENT); 487773b6454SNate Lawson acpi_print_sdt(sdp); 488986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 489986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 49087f9f09aSTakanori Watanabe printf("\tADDR="); 491986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 492986dffafSJohn Baldwin printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 493986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 494986dffafSJohn Baldwin 8); 495986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 496986dffafSJohn Baldwin 1 : 0); 49779d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 498986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 49979d7565cSPeter Wemm printf("TRUE}\n"); 50079d7565cSPeter Wemm else 50179d7565cSPeter Wemm printf("FALSE}\n"); 502986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 503986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 5049785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags); 50579d7565cSPeter Wemm printf(END_COMMENT); 50679d7565cSPeter Wemm } 50779d7565cSPeter Wemm 50879d7565cSPeter Wemm static void 509986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 51055d7ff9eSNate Lawson { 511986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 51255d7ff9eSNate Lawson 51355d7ff9eSNate Lawson printf(BEGIN_COMMENT); 51455d7ff9eSNate Lawson acpi_print_sdt(sdp); 515986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 51655d7ff9eSNate Lawson printf("\tEC_CONTROL="); 517986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 51855d7ff9eSNate Lawson printf("\n\tEC_DATA="); 519986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 520986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 521986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 522986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 52355d7ff9eSNate Lawson printf(END_COMMENT); 52455d7ff9eSNate Lawson } 52555d7ff9eSNate Lawson 52655d7ff9eSNate Lawson static void 527986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 528a47e681bSScott Long { 529986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 530986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 531986dffafSJohn Baldwin u_int i, entries; 532a47e681bSScott Long 533a47e681bSScott Long printf(BEGIN_COMMENT); 534a47e681bSScott Long acpi_print_sdt(sdp); 535986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 536986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 537986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 538986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 539986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 540a47e681bSScott Long printf("\n"); 5410c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address); 542986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 543986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 544986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 545a47e681bSScott Long } 546a47e681bSScott Long printf(END_COMMENT); 547a47e681bSScott Long } 548a47e681bSScott Long 549a47e681bSScott Long static void 55033866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 55133866658SJohn Baldwin { 55233866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 55333866658SJohn Baldwin UINT64 i, j; 55433866658SJohn Baldwin 55533866658SJohn Baldwin printf(BEGIN_COMMENT); 55633866658SJohn Baldwin acpi_print_sdt(sdp); 55733866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 5580c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount); 55933866658SJohn Baldwin printf("\n\t "); 56033866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 5610c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i); 56233866658SJohn Baldwin printf("\n\t +"); 56333866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 56433866658SJohn Baldwin printf("----"); 56533866658SJohn Baldwin printf("\n"); 56633866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 5670c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i); 56833866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 56933866658SJohn Baldwin printf(" %3d", 57033866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 57133866658SJohn Baldwin printf("\n"); 57233866658SJohn Baldwin } 57333866658SJohn Baldwin printf(END_COMMENT); 57433866658SJohn Baldwin } 57533866658SJohn Baldwin 57633866658SJohn Baldwin static void 577a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 578a0333ad1SJohn Baldwin uint32_t flags) 579a0333ad1SJohn Baldwin { 580a0333ad1SJohn Baldwin 581a0333ad1SJohn Baldwin printf("\tFlags={"); 582a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 583a0333ad1SJohn Baldwin printf("ENABLED"); 584a0333ad1SJohn Baldwin else 585a0333ad1SJohn Baldwin printf("DISABLED"); 586a0333ad1SJohn Baldwin printf("}\n"); 587a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 588a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 589a0333ad1SJohn Baldwin } 590a0333ad1SJohn Baldwin 591c031c93bSTakanori Watanabe static char * 592c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 593c031c93bSTakanori Watanabe { 594c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 595c031c93bSTakanori Watanabe char *eventname = NULL; 596c031c93bSTakanori Watanabe 597c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 598c031c93bSTakanori Watanabe 599c031c93bSTakanori Watanabe switch(event->event_type) { 600c031c93bSTakanori Watanabe case PREBOOT: 601c031c93bSTakanori Watanabe case POST_CODE: 602c031c93bSTakanori Watanabe case UNUSED: 603c031c93bSTakanori Watanabe case NO_ACTION: 604c031c93bSTakanori Watanabe case SEPARATOR: 605c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 606c031c93bSTakanori Watanabe case SCRTM_VERSION: 607c031c93bSTakanori Watanabe case CPU_MICROCODE: 608c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 609c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 610c031c93bSTakanori Watanabe case COMPACT_HASH: 611c031c93bSTakanori Watanabe case IPL: 612c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 613c031c93bSTakanori Watanabe case NONHOST_CODE: 614c031c93bSTakanori Watanabe case NONHOST_CONFIG: 615c031c93bSTakanori Watanabe case NONHOST_INFO: 616c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 617c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 618c031c93bSTakanori Watanabe break; 619c031c93bSTakanori Watanabe 620c031c93bSTakanori Watanabe case ACTION: 621c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 622c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 623c031c93bSTakanori Watanabe break; 624c031c93bSTakanori Watanabe 625c031c93bSTakanori Watanabe case EVENT_TAG: 626c031c93bSTakanori Watanabe switch (pc_event->event_id) { 627c031c93bSTakanori Watanabe case SMBIOS: 628c031c93bSTakanori Watanabe case BIS_CERT: 629c031c93bSTakanori Watanabe case CMOS: 630c031c93bSTakanori Watanabe case NVRAM: 631c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 632c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 633c031c93bSTakanori Watanabe case S_CRTM_VERSION: 634c031c93bSTakanori Watanabe case POST_BIOS_ROM: 635c031c93bSTakanori Watanabe case ESCD: 636c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 637c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 638c031c93bSTakanori Watanabe case POST_CONTENTS: 639c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 640c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 641c031c93bSTakanori Watanabe break; 642c031c93bSTakanori Watanabe 643c031c93bSTakanori Watanabe default: 644c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 645c031c93bSTakanori Watanabe pc_event->event_id); 646c031c93bSTakanori Watanabe break; 647c031c93bSTakanori Watanabe } 648c031c93bSTakanori Watanabe break; 649c031c93bSTakanori Watanabe 650c031c93bSTakanori Watanabe default: 651c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 652c031c93bSTakanori Watanabe break; 653c031c93bSTakanori Watanabe } 654c031c93bSTakanori Watanabe 655c031c93bSTakanori Watanabe return eventname; 656c031c93bSTakanori Watanabe } 657c031c93bSTakanori Watanabe 658c031c93bSTakanori Watanabe static void 659c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 660c031c93bSTakanori Watanabe { 661c031c93bSTakanori Watanabe int i; 662c031c93bSTakanori Watanabe char *eventname; 663c031c93bSTakanori Watanabe 664c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 665c031c93bSTakanori Watanabe 666c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 667c031c93bSTakanori Watanabe printf(" 0x"); 668c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 669c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 670c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 671c031c93bSTakanori Watanabe 672c031c93bSTakanori Watanabe free(eventname); 673c031c93bSTakanori Watanabe } 674c031c93bSTakanori Watanabe 675c031c93bSTakanori Watanabe static void 676c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 677c031c93bSTakanori Watanabe { 678c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 679c031c93bSTakanori Watanabe struct TCPAevent *event; 680977fd9daSTakanori Watanabe uintmax_t len, paddr; 681c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 682c031c93bSTakanori Watanabe unsigned char *vend = NULL; 683c031c93bSTakanori Watanabe 684c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 685c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 686c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 687c031c93bSTakanori Watanabe 688c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 689c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 690c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 691c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 692c031c93bSTakanori Watanabe break; 693c031c93bSTakanori Watanabe 694c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 695c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 696c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 697c031c93bSTakanori Watanabe break; 698c031c93bSTakanori Watanabe 699c031c93bSTakanori Watanabe default: 700c031c93bSTakanori Watanabe printf("XXX"); 701c031c93bSTakanori Watanabe printf(END_COMMENT); 702c031c93bSTakanori Watanabe return; 703c031c93bSTakanori Watanabe } 7040e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 705c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 706c031c93bSTakanori Watanabe 707c031c93bSTakanori Watanabe if (len == 0) { 708c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 709c031c93bSTakanori Watanabe printf(END_COMMENT); 710c031c93bSTakanori Watanabe return; 711c031c93bSTakanori Watanabe } 7122ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 7132ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 7142ef23c6dSTakanori Watanabe printf(END_COMMENT); 7152ef23c6dSTakanori Watanabe return; 7162ef23c6dSTakanori Watanabe } 717c031c93bSTakanori Watanabe 718c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 719c031c93bSTakanori Watanabe vend = vaddr + len; 720c031c93bSTakanori Watanabe 721c031c93bSTakanori Watanabe while (vaddr != NULL) { 7222ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 7232ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 724c031c93bSTakanori Watanabe break; 7250e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 726c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 727c031c93bSTakanori Watanabe break; 7282ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 7292ef23c6dSTakanori Watanabe break; 730c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 731c031c93bSTakanori Watanabe break; 732c031c93bSTakanori Watanabe #if 0 733c031c93bSTakanori Watanabe { 734c031c93bSTakanori Watanabe unsigned int i, j, k; 735c031c93bSTakanori Watanabe 736c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 737c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 738c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 739c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 740c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 741c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 742c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 743c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 744c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 745c031c93bSTakanori Watanabe j = i + 1; 746c031c93bSTakanori Watanabe } 747c031c93bSTakanori Watanabe } 748c031c93bSTakanori Watanabe printf("\n"); } 749c031c93bSTakanori Watanabe #endif 750c031c93bSTakanori Watanabe acpi_print_tcpa(event); 751c031c93bSTakanori Watanabe 752c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 753c031c93bSTakanori Watanabe } 754c031c93bSTakanori Watanabe 755c031c93bSTakanori Watanabe printf(END_COMMENT); 756c031c93bSTakanori Watanabe } 757c031c93bSTakanori Watanabe 758ec650989SNeel Natu static const char * 759ec650989SNeel Natu devscope_type2str(int type) 760ec650989SNeel Natu { 761ec650989SNeel Natu static char typebuf[16]; 762ec650989SNeel Natu 763ec650989SNeel Natu switch (type) { 764ec650989SNeel Natu case 1: 765ec650989SNeel Natu return ("PCI Endpoint Device"); 766ec650989SNeel Natu case 2: 767ec650989SNeel Natu return ("PCI Sub-Hierarchy"); 768ec650989SNeel Natu case 3: 769ec650989SNeel Natu return ("IOAPIC"); 770ec650989SNeel Natu case 4: 771ec650989SNeel Natu return ("HPET"); 772ec650989SNeel Natu default: 773ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type); 774ec650989SNeel Natu return (typebuf); 775ec650989SNeel Natu } 776ec650989SNeel Natu } 777ec650989SNeel Natu 778ec650989SNeel Natu static int 779ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining) 780ec650989SNeel Natu { 781ec650989SNeel Natu char sep; 782ec650989SNeel Natu int pathlen; 783ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend; 784ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr; 785ec650989SNeel Natu 786ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) 787ec650989SNeel Natu return (-1); 788ec650989SNeel Natu 789ec650989SNeel Natu if (remaining < devscope->Length) 790ec650989SNeel Natu return (-1); 791ec650989SNeel Natu 792ec650989SNeel Natu printf("\n"); 793ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); 794ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length); 795ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); 796ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus); 797ec650989SNeel Natu 798ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); 799ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); 800ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); 801ec650989SNeel Natu if (path < pathend) { 802ec650989SNeel Natu sep = '{'; 803ec650989SNeel Natu printf("\t\tPath="); 804ec650989SNeel Natu do { 805ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function); 806ec650989SNeel Natu sep=','; 807ec650989SNeel Natu path++; 808ec650989SNeel Natu } while (path < pathend); 809ec650989SNeel Natu printf("}\n"); 810ec650989SNeel Natu } 811ec650989SNeel Natu 812ec650989SNeel Natu return (devscope->Length); 813ec650989SNeel Natu } 814ec650989SNeel Natu 815ec650989SNeel Natu static void 816ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) 817ec650989SNeel Natu { 818ec650989SNeel Natu char *cp; 819ec650989SNeel Natu int remaining, consumed; 820ec650989SNeel Natu 821ec650989SNeel Natu printf("\n"); 822ec650989SNeel Natu printf("\tType=DRHD\n"); 823ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length); 824ec650989SNeel Natu 825ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 826ec650989SNeel Natu 827ec650989SNeel Natu printf("\tFlags="); 828ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL); 829ec650989SNeel Natu PRINTFLAG_END(); 830ec650989SNeel Natu 831ec650989SNeel Natu #undef PRINTFLAG 832ec650989SNeel Natu 833ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment); 8340c10b85aSJung-uk Kim printf("\tAddress=0x%0jx\n", (uintmax_t)drhd->Address); 835ec650989SNeel Natu 836ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); 837ec650989SNeel Natu if (remaining > 0) 838ec650989SNeel Natu printf("\tDevice Scope:"); 839ec650989SNeel Natu while (remaining > 0) { 840ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining; 841ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 842ec650989SNeel Natu if (consumed <= 0) 843ec650989SNeel Natu break; 844ec650989SNeel Natu else 845ec650989SNeel Natu remaining -= consumed; 846ec650989SNeel Natu } 847ec650989SNeel Natu } 848ec650989SNeel Natu 849ec650989SNeel Natu static void 850ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) 851ec650989SNeel Natu { 852ec650989SNeel Natu char *cp; 853ec650989SNeel Natu int remaining, consumed; 854ec650989SNeel Natu 855ec650989SNeel Natu printf("\n"); 856ec650989SNeel Natu printf("\tType=RMRR\n"); 857ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length); 858ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment); 8590c10b85aSJung-uk Kim printf("\tBaseAddress=0x%0jx\n", (uintmax_t)rmrr->BaseAddress); 8600c10b85aSJung-uk Kim printf("\tLimitAddress=0x%0jx\n", (uintmax_t)rmrr->EndAddress); 861ec650989SNeel Natu 862ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); 863ec650989SNeel Natu if (remaining > 0) 864ec650989SNeel Natu printf("\tDevice Scope:"); 865ec650989SNeel Natu while (remaining > 0) { 866ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining; 867ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 868ec650989SNeel Natu if (consumed <= 0) 869ec650989SNeel Natu break; 870ec650989SNeel Natu else 871ec650989SNeel Natu remaining -= consumed; 872ec650989SNeel Natu } 873ec650989SNeel Natu } 874ec650989SNeel Natu 875ec650989SNeel Natu static void 876ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) 877ec650989SNeel Natu { 878ec650989SNeel Natu char *cp; 879ec650989SNeel Natu int remaining, consumed; 880ec650989SNeel Natu 881ec650989SNeel Natu printf("\n"); 882ec650989SNeel Natu printf("\tType=ATSR\n"); 883ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length); 884ec650989SNeel Natu 885ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 886ec650989SNeel Natu 887ec650989SNeel Natu printf("\tFlags="); 888ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS); 889ec650989SNeel Natu PRINTFLAG_END(); 890ec650989SNeel Natu 891ec650989SNeel Natu #undef PRINTFLAG 892ec650989SNeel Natu 893ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment); 894ec650989SNeel Natu 895ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); 896ec650989SNeel Natu if (remaining > 0) 897ec650989SNeel Natu printf("\tDevice Scope:"); 898ec650989SNeel Natu while (remaining > 0) { 899ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining; 900ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 901ec650989SNeel Natu if (consumed <= 0) 902ec650989SNeel Natu break; 903ec650989SNeel Natu else 904ec650989SNeel Natu remaining -= consumed; 905ec650989SNeel Natu } 906ec650989SNeel Natu } 907ec650989SNeel Natu 908ec650989SNeel Natu static void 909ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) 910ec650989SNeel Natu { 911ec650989SNeel Natu 912ec650989SNeel Natu printf("\n"); 913ec650989SNeel Natu printf("\tType=RHSA\n"); 914ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length); 9150c10b85aSJung-uk Kim printf("\tBaseAddress=0x%0jx\n", (uintmax_t)rhsa->BaseAddress); 916ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); 917ec650989SNeel Natu } 918ec650989SNeel Natu 919ec650989SNeel Natu static int 920ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining) 921ec650989SNeel Natu { 922ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr; 923ec650989SNeel Natu 924ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) 925ec650989SNeel Natu return (-1); 926ec650989SNeel Natu 927ec650989SNeel Natu if (remaining < hdr->Length) 928ec650989SNeel Natu return (-1); 929ec650989SNeel Natu 930ec650989SNeel Natu switch (hdr->Type) { 931ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT: 932ec650989SNeel Natu acpi_handle_dmar_drhd(addr); 933ec650989SNeel Natu break; 934ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY: 935ec650989SNeel Natu acpi_handle_dmar_rmrr(addr); 936ec650989SNeel Natu break; 937*313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS: 938ec650989SNeel Natu acpi_handle_dmar_atsr(addr); 939ec650989SNeel Natu break; 940*313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 941ec650989SNeel Natu acpi_handle_dmar_rhsa(addr); 942ec650989SNeel Natu break; 943ec650989SNeel Natu default: 944ec650989SNeel Natu printf("\n"); 945ec650989SNeel Natu printf("\tType=%d\n", hdr->Type); 946ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length); 947ec650989SNeel Natu break; 948ec650989SNeel Natu } 949ec650989SNeel Natu return (hdr->Length); 950ec650989SNeel Natu } 951ec650989SNeel Natu 952ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT 953ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2) 954ec650989SNeel Natu #endif 955ec650989SNeel Natu 956ec650989SNeel Natu static void 957ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) 958ec650989SNeel Natu { 959ec650989SNeel Natu char *cp; 960ec650989SNeel Natu int remaining, consumed; 961ec650989SNeel Natu ACPI_TABLE_DMAR *dmar; 962ec650989SNeel Natu 963ec650989SNeel Natu printf(BEGIN_COMMENT); 964ec650989SNeel Natu acpi_print_sdt(sdp); 965ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp; 966ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1); 967ec650989SNeel Natu 968ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 969ec650989SNeel Natu 970ec650989SNeel Natu printf("\tFlags="); 971ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP); 972ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); 973ec650989SNeel Natu PRINTFLAG_END(); 974ec650989SNeel Natu 975ec650989SNeel Natu #undef PRINTFLAG 976ec650989SNeel Natu 977ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); 978ec650989SNeel Natu while (remaining > 0) { 979ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining; 980ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining); 981ec650989SNeel Natu if (consumed <= 0) 982ec650989SNeel Natu break; 983ec650989SNeel Natu else 984ec650989SNeel Natu remaining -= consumed; 985ec650989SNeel Natu } 986ec650989SNeel Natu 987ec650989SNeel Natu printf(END_COMMENT); 988ec650989SNeel Natu } 989ec650989SNeel Natu 990a0333ad1SJohn Baldwin static void 991986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 992a0333ad1SJohn Baldwin { 993a0333ad1SJohn Baldwin 994a0333ad1SJohn Baldwin printf("\tFlags={"); 995986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 996a0333ad1SJohn Baldwin printf("ENABLED"); 997a0333ad1SJohn Baldwin else 998a0333ad1SJohn Baldwin printf("DISABLED"); 999986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 1000a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 1001986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 1002a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 1003a0333ad1SJohn Baldwin printf("}\n"); 1004986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 1005986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 1006986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 1007a0333ad1SJohn Baldwin } 1008a0333ad1SJohn Baldwin 1009bf70beceSEd Schouten static const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; 1010a0333ad1SJohn Baldwin 1011a0333ad1SJohn Baldwin static void 1012986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 1013a0333ad1SJohn Baldwin { 1014986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 1015986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 1016a0333ad1SJohn Baldwin 1017986dffafSJohn Baldwin if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0])) 1018986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 1019a0333ad1SJohn Baldwin else 1020986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 1021986dffafSJohn Baldwin switch (srat->Type) { 1022a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 1023986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 1024986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 1025986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 1026986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 1027986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 1028986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 1029a0333ad1SJohn Baldwin break; 1030a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1031986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 1032a0333ad1SJohn Baldwin break; 1033a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1034986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 1035986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 1036986dffafSJohn Baldwin x2apic->Flags); 1037a0333ad1SJohn Baldwin break; 1038a0333ad1SJohn Baldwin } 1039a0333ad1SJohn Baldwin } 1040a0333ad1SJohn Baldwin 1041a0333ad1SJohn Baldwin static void 1042986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 1043a0333ad1SJohn Baldwin { 1044986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 1045a0333ad1SJohn Baldwin 1046a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 1047a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 1048986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 1049986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 1050986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 1051a0333ad1SJohn Baldwin printf(END_COMMENT); 1052a0333ad1SJohn Baldwin } 1053a0333ad1SJohn Baldwin 1054a0333ad1SJohn Baldwin static void 1055986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 1056c62f1cccSMitsuru IWASAKI { 1057773b6454SNate Lawson printf(" "); 1058986dffafSJohn Baldwin acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); 1059c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 1060986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 1061e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 1062986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 1063e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 1064986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 1065986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 1066e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 1067986dffafSJohn Baldwin acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); 1068986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 1069e1e9a4bfSMitsuru IWASAKI } 1070e1e9a4bfSMitsuru IWASAKI 1071945137d9SNate Lawson static void 1072986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 1073e1e9a4bfSMitsuru IWASAKI { 1074986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1075986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1076e1e9a4bfSMitsuru IWASAKI int i, entries; 1077a74172abSNate Lawson u_long addr; 1078e1e9a4bfSMitsuru IWASAKI 1079986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1080986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1081773b6454SNate Lawson printf(BEGIN_COMMENT); 1082773b6454SNate Lawson acpi_print_sdt(rsdp); 1083986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1084e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 1085e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1086e1e9a4bfSMitsuru IWASAKI if (i > 0) 1087e1e9a4bfSMitsuru IWASAKI printf(", "); 1088a74172abSNate Lawson switch (addr_size) { 1089a74172abSNate Lawson case 4: 1090986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1091a74172abSNate Lawson break; 1092a74172abSNate Lawson case 8: 1093986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1094a74172abSNate Lawson break; 1095a74172abSNate Lawson default: 1096a74172abSNate Lawson addr = 0; 1097a74172abSNate Lawson } 1098a74172abSNate Lawson assert(addr != 0); 1099a74172abSNate Lawson printf("0x%08lx", addr); 1100e1e9a4bfSMitsuru IWASAKI } 1101e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 1102c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1103e1e9a4bfSMitsuru IWASAKI } 1104e1e9a4bfSMitsuru IWASAKI 11058e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 11068e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 11078e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 11088e6a8737SNate Lawson }; 11098e6a8737SNate Lawson 1110945137d9SNate Lawson static void 1111986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 1112e1e9a4bfSMitsuru IWASAKI { 1113986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 11148e6a8737SNate Lawson const char *pm; 1115e1e9a4bfSMitsuru IWASAKI 1116986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 1117c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 11182177d4e6SNate Lawson acpi_print_sdt(sdp); 1119986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 1120986dffafSJohn Baldwin fadt->Dsdt); 1121986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 1122986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 11238e6a8737SNate Lawson pm = "Reserved"; 11248e6a8737SNate Lawson else 1125986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 1126986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 1127986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 1128986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 1129986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 1130986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 1131986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 1132986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 1133e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 1134986dffafSJohn Baldwin fadt->Pm1aEventBlock, 1135986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 1136986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 1137e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 1138986dffafSJohn Baldwin fadt->Pm1bEventBlock, 1139986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 1140e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 1141986dffafSJohn Baldwin fadt->Pm1aControlBlock, 1142986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 1143986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 1144e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 1145986dffafSJohn Baldwin fadt->Pm1bControlBlock, 1146986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 1147986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 1148e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 1149986dffafSJohn Baldwin fadt->Pm2ControlBlock, 1150986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 1151c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 1152986dffafSJohn Baldwin fadt->PmTimerBlock, 1153986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 1154986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 11558e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 1156986dffafSJohn Baldwin fadt->Gpe0Block, 1157986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 1158986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 11598e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 1160986dffafSJohn Baldwin fadt->Gpe1Block, 1161986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 1162986dffafSJohn Baldwin fadt->Gpe1Base); 1163986dffafSJohn Baldwin if (fadt->CstControl != 0) 1164986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 116551c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 1166986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 1167e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 1168986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 1169e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 1170986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 1171e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 1172986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 1173e1e9a4bfSMitsuru IWASAKI 1174ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) 1175e1e9a4bfSMitsuru IWASAKI 11768e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 1177986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 1178986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 1179986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 1180986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 1181986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 1182ec650989SNeel Natu PRINTFLAG_END(); 11838e6a8737SNate Lawson 11848e6a8737SNate Lawson printf("\tFlags="); 1185986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 1186986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 1187986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 1188986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 1189986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 1190986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 1191986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 1192986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 1193986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 1194986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 1195986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 1196986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 1197986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 1198986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 1199986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 1200986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 1201986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 1202986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 1203986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 1204986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 1205ec650989SNeel Natu PRINTFLAG_END(); 1206e1e9a4bfSMitsuru IWASAKI 1207e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 1208e1e9a4bfSMitsuru IWASAKI 1209986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 12108e6a8737SNate Lawson printf("\tRESET_REG="); 1211986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 1212986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 12138e6a8737SNate Lawson } 1214c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 1215986dffafSJohn Baldwin printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs); 1216986dffafSJohn Baldwin printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt); 1217c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 1218986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 1219986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 1220c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 1221986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 1222c08c4e81SNate Lawson } 1223c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 1224986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 1225986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 1226c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 1227986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 1228c08c4e81SNate Lawson } 1229986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 1230773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 1231986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 1232c08c4e81SNate Lawson } 1233773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 1234986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 1235986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 1236773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 1237986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 1238c08c4e81SNate Lawson } 1239986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 1240773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 1241986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 1242c08c4e81SNate Lawson } 1243773b6454SNate Lawson printf("\n"); 1244773b6454SNate Lawson } 12458e6a8737SNate Lawson 12468e6a8737SNate Lawson printf(END_COMMENT); 12478e6a8737SNate Lawson } 12488e6a8737SNate Lawson 12498e6a8737SNate Lawson static void 1250986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 12518e6a8737SNate Lawson { 12528e6a8737SNate Lawson printf(BEGIN_COMMENT); 1253986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 1254986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 1255986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 12568e6a8737SNate Lawson 1257773b6454SNate Lawson printf("\tGlobal_Lock="); 1258986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 1259986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 12608e6a8737SNate Lawson printf("PENDING,"); 1261986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 12628e6a8737SNate Lawson printf("OWNED"); 12638e6a8737SNate Lawson } 1264773b6454SNate Lawson printf("\n"); 12658e6a8737SNate Lawson 1266773b6454SNate Lawson printf("\tFlags="); 1267986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 12688e6a8737SNate Lawson printf("S4BIOS"); 1269773b6454SNate Lawson printf("\n"); 12708e6a8737SNate Lawson 1271986dffafSJohn Baldwin if (facs->XFirmwareWakingVector != 0) { 12728e6a8737SNate Lawson printf("\tX_Firm_Wake_Vec=%08lx\n", 1273986dffafSJohn Baldwin (u_long)facs->XFirmwareWakingVector); 12748e6a8737SNate Lawson } 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 { 1324a74172abSNate Lawson printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", 1325986dffafSJohn Baldwin (u_long)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++) { 1345a74172abSNate Lawson switch (addr_size) { 1346a74172abSNate Lawson case 4: 1347986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1348a74172abSNate Lawson break; 1349a74172abSNate Lawson case 8: 1350986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1351a74172abSNate Lawson break; 1352a74172abSNate Lawson default: 1353a74172abSNate Lawson assert((addr = 0)); 1354a74172abSNate Lawson } 1355a74172abSNate Lawson 1356986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1357986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 13585cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 1359986dffafSJohn Baldwin sdp->Signature); 13605cf6d493SNate Lawson continue; 13615cf6d493SNate Lawson } 1362986dffafSJohn Baldwin if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 13632177d4e6SNate Lawson acpi_handle_fadt(sdp); 1364986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 1365986dffafSJohn Baldwin acpi_handle_madt(sdp); 1366986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 136779d7565cSPeter Wemm acpi_handle_hpet(sdp); 1368986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 136955d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 1370986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 1371a47e681bSScott Long acpi_handle_mcfg(sdp); 137233866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 137333866658SJohn Baldwin acpi_handle_slit(sdp); 1374986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 1375a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 1376c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 1377c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 1378ec650989SNeel Natu else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) 1379ec650989SNeel Natu acpi_handle_dmar(sdp); 1380773b6454SNate Lawson else { 1381773b6454SNate Lawson printf(BEGIN_COMMENT); 1382773b6454SNate Lawson acpi_print_sdt(sdp); 1383773b6454SNate Lawson printf(END_COMMENT); 1384773b6454SNate Lawson } 1385e1e9a4bfSMitsuru IWASAKI } 1386e1e9a4bfSMitsuru IWASAKI } 1387c62f1cccSMitsuru IWASAKI 1388986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1389476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 1390945137d9SNate Lawson { 1391986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 1392986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 1393945137d9SNate Lawson 1394945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 1395945137d9SNate Lawson if (!rp) 1396945137d9SNate Lawson errx(1, "Can't find ACPI information"); 1397945137d9SNate Lawson 1398945137d9SNate Lawson if (tflag) 1399945137d9SNate Lawson acpi_print_rsd_ptr(rp); 1400986dffafSJohn Baldwin if (rp->Revision < 2) { 1401986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 1402986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 1403986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1404945137d9SNate Lawson errx(1, "RSDT is corrupted"); 1405a74172abSNate Lawson addr_size = sizeof(uint32_t); 1406a74172abSNate Lawson } else { 1407986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 1408986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 1409986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1410a74172abSNate Lawson errx(1, "XSDT is corrupted"); 1411a74172abSNate Lawson addr_size = sizeof(uint64_t); 1412a74172abSNate Lawson } 1413945137d9SNate Lawson return (rsdp); 1414945137d9SNate Lawson } 1415c62f1cccSMitsuru IWASAKI 141662c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 1417bfa3f012SMarcel Moolenaar static int 1418986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 1419bfa3f012SMarcel Moolenaar { 1420986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 1421986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 1422bfa3f012SMarcel Moolenaar uint8_t sum; 1423bfa3f012SMarcel Moolenaar 142462c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 1425bfa3f012SMarcel Moolenaar sdt = *dsdt; 1426bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 1427986dffafSJohn Baldwin sdt.Checksum = 0; 1428986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 1429986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1430986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 1431f7675a56SNate Lawson while (ssdt != NULL) { 1432986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 1433986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 1434986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 1435986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 1436bfa3f012SMarcel Moolenaar } 1437986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 1438986dffafSJohn Baldwin sdt.Checksum -= sum; 1439bfa3f012SMarcel Moolenaar } 144062c7bde1SNate Lawson 144162c7bde1SNate Lawson /* Write out the DSDT header and body. */ 1442986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 1443986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 144462c7bde1SNate Lawson 1445b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 1446f7675a56SNate Lawson if (rsdt != NULL) { 1447bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 1448bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 1449986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 1450986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1451bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 1452bfa3f012SMarcel Moolenaar } 1453bfa3f012SMarcel Moolenaar } 1454bfa3f012SMarcel Moolenaar return (0); 1455bfa3f012SMarcel Moolenaar } 1456bfa3f012SMarcel Moolenaar 1457c62f1cccSMitsuru IWASAKI void 1458986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1459c62f1cccSMitsuru IWASAKI { 1460945137d9SNate Lawson int fd; 1461945137d9SNate Lawson mode_t mode; 1462945137d9SNate Lawson 1463945137d9SNate Lawson assert(outfile != NULL); 1464945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1465945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 1466945137d9SNate Lawson if (fd == -1) { 1467945137d9SNate Lawson perror("dsdt_save_file"); 1468945137d9SNate Lawson return; 1469945137d9SNate Lawson } 1470bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1471945137d9SNate Lawson close(fd); 1472c62f1cccSMitsuru IWASAKI } 1473c62f1cccSMitsuru IWASAKI 1474945137d9SNate Lawson void 1475986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1476c62f1cccSMitsuru IWASAKI { 147799065116SJung-uk Kim char buf[PATH_MAX], tmpstr[PATH_MAX]; 147899065116SJung-uk Kim const char *tmpdir; 147999065116SJung-uk Kim char *tmpext; 1480945137d9SNate Lawson FILE *fp; 148199065116SJung-uk Kim size_t len; 148299065116SJung-uk Kim int fd; 1483945137d9SNate Lawson 148499065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 148599065116SJung-uk Kim if (tmpdir == NULL) 148699065116SJung-uk Kim tmpdir = _PATH_TMP; 148799065116SJung-uk Kim strncpy(tmpstr, tmpdir, sizeof(tmpstr)); 148899065116SJung-uk Kim if (realpath(tmpstr, buf) == NULL) { 1489d6a6e590SJung-uk Kim perror("realpath tmp dir"); 149099065116SJung-uk Kim return; 149199065116SJung-uk Kim } 149299065116SJung-uk Kim strncpy(tmpstr, buf, sizeof(tmpstr)); 1493d6a6e590SJung-uk Kim strncat(tmpstr, "/acpidump.", sizeof(tmpstr) - strlen(buf)); 1494d6a6e590SJung-uk Kim len = strlen(tmpstr); 149599065116SJung-uk Kim tmpext = tmpstr + len; 149699065116SJung-uk Kim strncpy(tmpext, "XXXXXX", sizeof(tmpstr) - len); 1497945137d9SNate Lawson fd = mkstemp(tmpstr); 1498945137d9SNate Lawson if (fd < 0) { 1499945137d9SNate Lawson perror("iasl tmp file"); 1500945137d9SNate Lawson return; 1501c62f1cccSMitsuru IWASAKI } 1502bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1503945137d9SNate Lawson close(fd); 1504945137d9SNate Lawson 1505945137d9SNate Lawson /* Run iasl -d on the temp file */ 1506945137d9SNate Lawson if (fork() == 0) { 1507945137d9SNate Lawson close(STDOUT_FILENO); 1508945137d9SNate Lawson if (vflag == 0) 1509945137d9SNate Lawson close(STDERR_FILENO); 151099065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 1511945137d9SNate Lawson err(1, "exec"); 1512c62f1cccSMitsuru IWASAKI } 1513c62f1cccSMitsuru IWASAKI 1514945137d9SNate Lawson wait(NULL); 1515945137d9SNate Lawson unlink(tmpstr); 1516945137d9SNate Lawson 1517945137d9SNate Lawson /* Dump iasl's output to stdout */ 151899065116SJung-uk Kim strncpy(tmpext, "dsl", sizeof(tmpstr) - len); 151999065116SJung-uk Kim fp = fopen(tmpstr, "r"); 152099065116SJung-uk Kim unlink(tmpstr); 1521945137d9SNate Lawson if (fp == NULL) { 1522945137d9SNate Lawson perror("iasl tmp file (read)"); 1523945137d9SNate Lawson return; 1524945137d9SNate Lawson } 1525945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 1526945137d9SNate Lawson fwrite(buf, 1, len, stdout); 1527945137d9SNate Lawson fclose(fp); 1528c62f1cccSMitsuru IWASAKI } 1529c62f1cccSMitsuru IWASAKI 1530945137d9SNate Lawson void 1531986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 1532c62f1cccSMitsuru IWASAKI { 1533945137d9SNate Lawson acpi_handle_rsdt(rsdp); 1534c62f1cccSMitsuru IWASAKI } 1535c62f1cccSMitsuru IWASAKI 1536bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 1537986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1538986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 1539c62f1cccSMitsuru IWASAKI { 1540986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1541986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1542986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1543a74172abSNate Lawson vm_offset_t addr; 1544a74172abSNate Lawson int entries, i; 1545945137d9SNate Lawson 1546986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1547986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1548986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1549945137d9SNate Lawson for (i = 0; i < entries; i++) { 1550a74172abSNate Lawson switch (addr_size) { 1551a74172abSNate Lawson case 4: 1552986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1553a74172abSNate Lawson break; 1554a74172abSNate Lawson case 8: 1555986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1556a74172abSNate Lawson break; 1557a74172abSNate Lawson default: 1558a74172abSNate Lawson assert((addr = 0)); 1559a74172abSNate Lawson } 1560986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1561bfa3f012SMarcel Moolenaar if (last != NULL) { 1562bfa3f012SMarcel Moolenaar if (sdt == last) 1563bfa3f012SMarcel Moolenaar last = NULL; 1564bfa3f012SMarcel Moolenaar continue; 1565bfa3f012SMarcel Moolenaar } 1566986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 1567a74172abSNate Lawson continue; 1568986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1569945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 1570945137d9SNate Lawson return (sdt); 1571c62f1cccSMitsuru IWASAKI } 1572c62f1cccSMitsuru IWASAKI 1573945137d9SNate Lawson return (NULL); 1574c62f1cccSMitsuru IWASAKI } 1575c62f1cccSMitsuru IWASAKI 1576986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1577986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 1578c62f1cccSMitsuru IWASAKI { 1579986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1580c62f1cccSMitsuru IWASAKI 1581986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 1582c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 1583986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 15842e71eb12SNate Lawson else 1585986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 1586986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1587945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1588945137d9SNate Lawson return (sdt); 1589c62f1cccSMitsuru IWASAKI } 1590