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> 43340c0022SEd Maste #include <uuid.h> 44e1e9a4bfSMitsuru IWASAKI 45e1e9a4bfSMitsuru IWASAKI #include "acpidump.h" 46e1e9a4bfSMitsuru IWASAKI 47c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n" 48c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n" 49c62f1cccSMitsuru IWASAKI 50945137d9SNate Lawson static void acpi_print_string(char *s, size_t length); 51986dffafSJohn Baldwin static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas); 52986dffafSJohn Baldwin static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt); 53986dffafSJohn Baldwin static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt); 54945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id); 55986dffafSJohn Baldwin static void acpi_print_cpu_uid(uint32_t uid, char *uid_string); 56986dffafSJohn Baldwin static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags); 57986dffafSJohn Baldwin static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, 58986dffafSJohn Baldwin uint64_t apic_addr); 59986dffafSJohn Baldwin static void acpi_print_mps_flags(uint16_t flags); 60986dffafSJohn Baldwin static void acpi_print_intr(uint32_t intr, uint16_t mps_flags); 61986dffafSJohn Baldwin static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags); 62986dffafSJohn Baldwin static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp); 63986dffafSJohn Baldwin static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp); 64986dffafSJohn Baldwin static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); 65986dffafSJohn Baldwin static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); 66986dffafSJohn Baldwin static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); 6733866658SJohn Baldwin static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); 68*ed26c389SScott Long static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp); 69a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 70a0333ad1SJohn Baldwin uint32_t flags); 71986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); 72986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); 73986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); 74c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); 75340c0022SEd Maste static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit); 76340c0022SEd Maste static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp); 77986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); 78986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); 79986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs); 80986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); 81986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); 82986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); 83986dffafSJohn Baldwin static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); 84986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 85986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)); 86340c0022SEd Maste static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 87340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)); 88c62f1cccSMitsuru IWASAKI 89773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 90a74172abSNate Lawson static int addr_size; 91a74172abSNate Lawson 92c031c93bSTakanori Watanabe /* Strings used in the TCPA table */ 93c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = { 94c031c93bSTakanori Watanabe "PREBOOT Certificate", 95c031c93bSTakanori Watanabe "POST Code", 96c031c93bSTakanori Watanabe "Unused", 97c031c93bSTakanori Watanabe "No Action", 98c031c93bSTakanori Watanabe "Separator", 99c031c93bSTakanori Watanabe "Action", 100c031c93bSTakanori Watanabe "Event Tag", 101c031c93bSTakanori Watanabe "S-CRTM Contents", 102c031c93bSTakanori Watanabe "S-CRTM Version", 103c031c93bSTakanori Watanabe "CPU Microcode", 104c031c93bSTakanori Watanabe "Platform Config Flags", 105c031c93bSTakanori Watanabe "Table of Devices", 106c031c93bSTakanori Watanabe "Compact Hash", 107c031c93bSTakanori Watanabe "IPL", 108c031c93bSTakanori Watanabe "IPL Partition Data", 109c031c93bSTakanori Watanabe "Non-Host Code", 110c031c93bSTakanori Watanabe "Non-Host Config", 111c031c93bSTakanori Watanabe "Non-Host Info" 112c031c93bSTakanori Watanabe }; 113c031c93bSTakanori Watanabe 114c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = { 115c031c93bSTakanori Watanabe "<undefined>", 116c031c93bSTakanori Watanabe "SMBIOS", 117c031c93bSTakanori Watanabe "BIS Certificate", 118c031c93bSTakanori Watanabe "POST BIOS ROM Strings", 119c031c93bSTakanori Watanabe "ESCD", 120c031c93bSTakanori Watanabe "CMOS", 121c031c93bSTakanori Watanabe "NVRAM", 122c031c93bSTakanori Watanabe "Option ROM Execute", 123c031c93bSTakanori Watanabe "Option ROM Configurateion", 124c031c93bSTakanori Watanabe "<undefined>", 125c031c93bSTakanori Watanabe "Option ROM Microcode Update ", 126c031c93bSTakanori Watanabe "S-CRTM Version String", 127c031c93bSTakanori Watanabe "S-CRTM Contents", 128c031c93bSTakanori Watanabe "POST Contents", 129c031c93bSTakanori Watanabe "Table of Devices", 130c031c93bSTakanori Watanabe }; 131c031c93bSTakanori Watanabe 132ec650989SNeel Natu #define PRINTFLAG_END() printflag_end() 133ec650989SNeel Natu 134ec650989SNeel Natu static char pf_sep = '{'; 135ec650989SNeel Natu 136ec650989SNeel Natu static void 137ec650989SNeel Natu printflag_end(void) 138ec650989SNeel Natu { 139ec650989SNeel Natu 140ec650989SNeel Natu if (pf_sep != '{') { 141ec650989SNeel Natu printf("}"); 142ec650989SNeel Natu pf_sep = '{'; 143ec650989SNeel Natu } 144ec650989SNeel Natu printf("\n"); 145ec650989SNeel Natu } 146ec650989SNeel Natu 147ec650989SNeel Natu static void 148ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name) 149ec650989SNeel Natu { 150ec650989SNeel Natu 151ec650989SNeel Natu if (var & mask) { 152ec650989SNeel Natu printf("%c%s", pf_sep, name); 153ec650989SNeel Natu pf_sep = ','; 154ec650989SNeel Natu } 155ec650989SNeel Natu } 156ec650989SNeel Natu 157e1e9a4bfSMitsuru IWASAKI static void 158e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 159e1e9a4bfSMitsuru IWASAKI { 160e1e9a4bfSMitsuru IWASAKI int c; 161e1e9a4bfSMitsuru IWASAKI 162e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 163e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 164e1e9a4bfSMitsuru IWASAKI length--; 165e1e9a4bfSMitsuru IWASAKI 166e1e9a4bfSMitsuru IWASAKI while (length--) { 167e1e9a4bfSMitsuru IWASAKI c = *s++; 168e1e9a4bfSMitsuru IWASAKI putchar(c); 169e1e9a4bfSMitsuru IWASAKI } 170e1e9a4bfSMitsuru IWASAKI } 171e1e9a4bfSMitsuru IWASAKI 172e1e9a4bfSMitsuru IWASAKI static void 173986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1748e6a8737SNate Lawson { 175986dffafSJohn Baldwin switch(gas->SpaceId) { 1768e6a8737SNate Lawson case ACPI_GAS_MEMORY: 1777d369c6eSJung-uk Kim if (gas->BitWidth <= 32) 1787d369c6eSJung-uk Kim printf("0x%08x:%u[%u] (Memory)", 1797d369c6eSJung-uk Kim (u_int)gas->Address, gas->BitOffset, 1807d369c6eSJung-uk Kim gas->BitWidth); 1817d369c6eSJung-uk Kim else 1827d369c6eSJung-uk Kim printf("0x%016jx:%u[%u] (Memory)", 1837d369c6eSJung-uk Kim (uintmax_t)gas->Address, gas->BitOffset, 1847d369c6eSJung-uk Kim gas->BitWidth); 1858e6a8737SNate Lawson break; 1868e6a8737SNate Lawson case ACPI_GAS_IO: 1877d369c6eSJung-uk Kim printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address, 188986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1898e6a8737SNate Lawson break; 1908e6a8737SNate Lawson case ACPI_GAS_PCI: 191986dffafSJohn Baldwin printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), 192986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 193986dffafSJohn Baldwin (uint16_t)gas->Address); 1948e6a8737SNate Lawson break; 1958e6a8737SNate Lawson /* XXX How to handle these below? */ 1968e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 197986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 198986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 1998e6a8737SNate Lawson break; 2008e6a8737SNate Lawson case ACPI_GAS_SMBUS: 201986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 202986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 2038e6a8737SNate Lawson break; 204986dffafSJohn Baldwin case ACPI_GAS_CMOS: 205986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 206986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 2078e6a8737SNate Lawson case ACPI_GAS_FIXED: 2088e6a8737SNate Lawson default: 2097d369c6eSJung-uk Kim printf("0x%016jx (?)", (uintmax_t)gas->Address); 2108e6a8737SNate Lawson break; 2118e6a8737SNate Lawson } 2128e6a8737SNate Lawson } 2138e6a8737SNate Lawson 214c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 215c2962974SNate Lawson static int 216986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) 217e1e9a4bfSMitsuru IWASAKI { 218c2962974SNate Lawson int fadt_revision; 219e1e9a4bfSMitsuru IWASAKI 220c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 221c83f0f99SNate Lawson if (addr_size == 8) { 222c83f0f99SNate Lawson fadt_revision = 2; 2238e6a8737SNate Lawson 224773b6454SNate Lawson /* 225c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 226c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 227c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 228c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 229c83f0f99SNate Lawson * version for all subsequent tables. 230773b6454SNate Lawson */ 231986dffafSJohn Baldwin if (fadt->Facs != 0 && 232986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 233c83f0f99SNate Lawson fadt_revision = 1; 234c2962974SNate Lawson } else 235c83f0f99SNate Lawson fadt_revision = 1; 236c2962974SNate Lawson return (fadt_revision); 237c83f0f99SNate Lawson } 238c2962974SNate Lawson 239c2962974SNate Lawson static void 240986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 241c2962974SNate Lawson { 242986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 243986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 244986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 245c2962974SNate Lawson int fadt_revision; 246c2962974SNate Lawson 247986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2482177d4e6SNate Lawson acpi_print_fadt(sdp); 249c83f0f99SNate Lawson 250c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 251c83f0f99SNate Lawson if (fadt_revision == 1) 252986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); 253773b6454SNate Lawson else 254986dffafSJohn Baldwin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); 255986dffafSJohn Baldwin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) 2568e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2578e6a8737SNate Lawson acpi_print_facs(facs); 2588e6a8737SNate Lawson 259c83f0f99SNate Lawson if (fadt_revision == 1) 260986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 261773b6454SNate Lawson else 262986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 263986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 264945137d9SNate Lawson errx(1, "DSDT is corrupt"); 265945137d9SNate Lawson acpi_print_dsdt(dsdp); 266c62f1cccSMitsuru IWASAKI } 267c62f1cccSMitsuru IWASAKI 268c62f1cccSMitsuru IWASAKI static void 269986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 270986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 271986dffafSJohn Baldwin { 272986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 273986dffafSJohn Baldwin char *end; 274986dffafSJohn Baldwin 275986dffafSJohn Baldwin subtable = first; 276986dffafSJohn Baldwin end = (char *)table + table->Length; 277986dffafSJohn Baldwin while ((char *)subtable < end) { 278986dffafSJohn Baldwin printf("\n"); 279f5d0a8f7SEd Maste if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) { 280f5d0a8f7SEd Maste warnx("invalid subtable length %u", subtable->Length); 281f5d0a8f7SEd Maste return; 282f5d0a8f7SEd Maste } 283986dffafSJohn Baldwin action(subtable); 284986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 285986dffafSJohn Baldwin subtable->Length); 286986dffafSJohn Baldwin } 287986dffafSJohn Baldwin } 288986dffafSJohn Baldwin 289986dffafSJohn Baldwin static void 290340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 291340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)) 292340c0022SEd Maste { 293340c0022SEd Maste ACPI_NFIT_HEADER *subtable; 294340c0022SEd Maste char *end; 295340c0022SEd Maste 296340c0022SEd Maste subtable = first; 297340c0022SEd Maste end = (char *)table + table->Length; 298340c0022SEd Maste while ((char *)subtable < end) { 299340c0022SEd Maste printf("\n"); 300340c0022SEd Maste if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) { 301340c0022SEd Maste warnx("invalid subtable length %u", subtable->Length); 302340c0022SEd Maste return; 303340c0022SEd Maste } 304340c0022SEd Maste action(subtable); 305340c0022SEd Maste subtable = (ACPI_NFIT_HEADER *)((char *)subtable + 306340c0022SEd Maste subtable->Length); 307340c0022SEd Maste } 308340c0022SEd Maste } 309340c0022SEd Maste 310340c0022SEd Maste static void 3110a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 3120a473124SJohn Baldwin { 3130a473124SJohn Baldwin 3140a473124SJohn Baldwin printf("\tACPI CPU="); 3150a473124SJohn Baldwin if (cpu_id == 0xff) 3160a473124SJohn Baldwin printf("ALL\n"); 3170a473124SJohn Baldwin else 3180a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 3190a473124SJohn Baldwin } 3200a473124SJohn Baldwin 3210a473124SJohn Baldwin static void 322986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 3230a473124SJohn Baldwin { 324986dffafSJohn Baldwin 325986dffafSJohn Baldwin printf("\tUID=%d", uid); 326986dffafSJohn Baldwin if (uid_string != NULL) 327986dffafSJohn Baldwin printf(" (%s)", uid_string); 328986dffafSJohn Baldwin printf("\n"); 329986dffafSJohn Baldwin } 330986dffafSJohn Baldwin 331986dffafSJohn Baldwin static void 332986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 333986dffafSJohn Baldwin { 334986dffafSJohn Baldwin 3350a473124SJohn Baldwin printf("\tFlags={"); 336986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 3370a473124SJohn Baldwin printf("ENABLED"); 3380a473124SJohn Baldwin else 3390a473124SJohn Baldwin printf("DISABLED"); 3400a473124SJohn Baldwin printf("}\n"); 341986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3420a473124SJohn Baldwin } 3430a473124SJohn Baldwin 3440a473124SJohn Baldwin static void 345986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 3460a473124SJohn Baldwin { 347986dffafSJohn Baldwin 348986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3490a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 350986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 3510a473124SJohn Baldwin } 3520a473124SJohn Baldwin 3530a473124SJohn Baldwin static void 354986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 3550a473124SJohn Baldwin { 3560a473124SJohn Baldwin 3570a473124SJohn Baldwin printf("\tFlags={Polarity="); 358986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 359986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 3600a473124SJohn Baldwin printf("conforming"); 3610a473124SJohn Baldwin break; 362986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3630a473124SJohn Baldwin printf("active-hi"); 3640a473124SJohn Baldwin break; 365986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3660a473124SJohn Baldwin printf("active-lo"); 3670a473124SJohn Baldwin break; 3680a473124SJohn Baldwin default: 369986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3700a473124SJohn Baldwin break; 3710a473124SJohn Baldwin } 3720a473124SJohn Baldwin printf(", Trigger="); 373986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 374986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 3750a473124SJohn Baldwin printf("conforming"); 3760a473124SJohn Baldwin break; 377986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 3780a473124SJohn Baldwin printf("edge"); 3790a473124SJohn Baldwin break; 380986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 3810a473124SJohn Baldwin printf("level"); 3820a473124SJohn Baldwin break; 3830a473124SJohn Baldwin default: 384986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 3850a473124SJohn Baldwin } 3860a473124SJohn Baldwin printf("}\n"); 3870a473124SJohn Baldwin } 3880a473124SJohn Baldwin 3890a473124SJohn Baldwin static void 3902b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags) 3912b2b1f42SAndrew Turner { 3922b2b1f42SAndrew Turner 3932b2b1f42SAndrew Turner printf("\tFlags={Performance intr="); 3942b2b1f42SAndrew Turner if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE) 3952b2b1f42SAndrew Turner printf("edge"); 3962b2b1f42SAndrew Turner else 3972b2b1f42SAndrew Turner printf("level"); 3982b2b1f42SAndrew Turner printf(", VGIC intr="); 3992b2b1f42SAndrew Turner if (flags & ACPI_MADT_VGIC_IRQ_MODE) 4002b2b1f42SAndrew Turner printf("edge"); 4012b2b1f42SAndrew Turner else 4022b2b1f42SAndrew Turner printf("level"); 4032b2b1f42SAndrew Turner printf("}\n"); 4042b2b1f42SAndrew Turner } 4052b2b1f42SAndrew Turner 4062b2b1f42SAndrew Turner static void 407986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 4080a473124SJohn Baldwin { 4090a473124SJohn Baldwin 410986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 411986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 412986dffafSJohn Baldwin } 413986dffafSJohn Baldwin 414986dffafSJohn Baldwin static void 415986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 416986dffafSJohn Baldwin { 417986dffafSJohn Baldwin 418986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 4190a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 4200a473124SJohn Baldwin } 4210a473124SJohn Baldwin 42227941afaSEd Maste static const char *apic_types[] = { 42327941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC", 42427941afaSEd Maste [ACPI_MADT_TYPE_IO_APIC] = "IO APIC", 42527941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override", 42627941afaSEd Maste [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI", 42727941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI", 42827941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override", 42927941afaSEd Maste [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC", 43027941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC", 43127941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt", 43227941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC", 43327941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI", 43427941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure", 43527941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure", 43627941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame", 43727941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure", 43827941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure" 43927941afaSEd Maste }; 44027941afaSEd Maste 441bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 4420a473124SJohn Baldwin "Corrected Platform Error" }; 4430a473124SJohn Baldwin 4440a473124SJohn Baldwin static void 445986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 4460a473124SJohn Baldwin { 447986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 448986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 449986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 450986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 451986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 452986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 453986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 454986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 455986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 456986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 457986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 4582b2b1f42SAndrew Turner ACPI_MADT_GENERIC_INTERRUPT *gicc; 4592b2b1f42SAndrew Turner ACPI_MADT_GENERIC_DISTRIBUTOR *gicd; 4602b2b1f42SAndrew Turner ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr; 4612b2b1f42SAndrew Turner ACPI_MADT_GENERIC_TRANSLATOR *gict; 4620a473124SJohn Baldwin 463c86932b6SMarcelo Araujo if (mp->Type < nitems(apic_types)) 464986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 465a0333ad1SJohn Baldwin else 466986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 467986dffafSJohn Baldwin switch (mp->Type) { 468986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 469986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 470986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 471986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 4720a473124SJohn Baldwin break; 473986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 474986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 475986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 476986dffafSJohn Baldwin ioapic->Address); 4770a473124SJohn Baldwin break; 478986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 479986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 480986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 481986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 482986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 4830a473124SJohn Baldwin break; 484986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 485986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 486986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 4870a473124SJohn Baldwin break; 488986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 489986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 490986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 491986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 4920a473124SJohn Baldwin break; 493986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 494986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 495945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 496986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 4970a473124SJohn Baldwin break; 498986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 499986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 500986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 501986dffafSJohn Baldwin iosapic->Address); 5020a473124SJohn Baldwin break; 503986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 504986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 505986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 506986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 507986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 508986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 509986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 5100a473124SJohn Baldwin break; 511986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 512986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 513c86932b6SMarcelo Araujo if (isrc->Type < nitems(platform_int_types)) 514986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 515986dffafSJohn Baldwin else 516986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 517986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 518986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 519986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 520986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 521986dffafSJohn Baldwin break; 522986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 523986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 524986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 525986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 526986dffafSJohn Baldwin break; 527986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 528986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 529986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 530986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 5310a473124SJohn Baldwin break; 5322b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 5332b2b1f42SAndrew Turner gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp; 5342b2b1f42SAndrew Turner acpi_print_cpu_uid(gicc->Uid, NULL); 5352b2b1f42SAndrew Turner printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber); 5362b2b1f42SAndrew Turner acpi_print_gicc_flags(gicc->Flags); 5372b2b1f42SAndrew Turner printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion); 5382b2b1f42SAndrew Turner printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt); 5392b2b1f42SAndrew Turner printf("\tParked ADDR=%016jx\n", 5402b2b1f42SAndrew Turner (uintmax_t)gicc->ParkedAddress); 5412b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress); 5422b2b1f42SAndrew Turner printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress); 5432b2b1f42SAndrew Turner printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress); 5442b2b1f42SAndrew Turner printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt); 5452b2b1f42SAndrew Turner printf("\tGICR ADDR=%016jx\n", 5462b2b1f42SAndrew Turner (uintmax_t)gicc->GicrBaseAddress); 5472b2b1f42SAndrew Turner printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr); 5482b2b1f42SAndrew Turner printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass); 5492b2b1f42SAndrew Turner break; 5502b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 5512b2b1f42SAndrew Turner gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp; 5522b2b1f42SAndrew Turner printf("\tGIC ID=%d\n", (u_int)gicd->GicId); 5532b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress); 5542b2b1f42SAndrew Turner printf("\tVector Base=%d\n", gicd->GlobalIrqBase); 5552b2b1f42SAndrew Turner printf("\tGIC VERSION=%d\n", (u_int)gicd->Version); 5562b2b1f42SAndrew Turner break; 5572b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 5582b2b1f42SAndrew Turner gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp; 5592b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress); 5602b2b1f42SAndrew Turner printf("\tLength=%08x\n", gicr->Length); 5612b2b1f42SAndrew Turner break; 5622b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 5632b2b1f42SAndrew Turner gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp; 5642b2b1f42SAndrew Turner printf("\tGIC ITS ID=%d\n", gict->TranslationId); 5652b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress); 5662b2b1f42SAndrew Turner break; 5670a473124SJohn Baldwin } 5680a473124SJohn Baldwin } 5690a473124SJohn Baldwin 5700a473124SJohn Baldwin static void 571986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 5720a473124SJohn Baldwin { 573986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 5740a473124SJohn Baldwin 575773b6454SNate Lawson printf(BEGIN_COMMENT); 576773b6454SNate Lawson acpi_print_sdt(sdp); 577986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 578986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 5790a473124SJohn Baldwin printf("\tFlags={"); 580986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 5810a473124SJohn Baldwin printf("PC-AT"); 5820a473124SJohn Baldwin printf("}\n"); 583986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 5840a473124SJohn Baldwin printf(END_COMMENT); 5850a473124SJohn Baldwin } 5860a473124SJohn Baldwin 5870a473124SJohn Baldwin static void 588986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 58979d7565cSPeter Wemm { 590986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 59179d7565cSPeter Wemm 592773b6454SNate Lawson printf(BEGIN_COMMENT); 593773b6454SNate Lawson acpi_print_sdt(sdp); 594986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 595986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 59687f9f09aSTakanori Watanabe printf("\tADDR="); 597986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 598986dffafSJohn Baldwin printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 599986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 600986dffafSJohn Baldwin 8); 601986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 602986dffafSJohn Baldwin 1 : 0); 60379d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 604986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 60579d7565cSPeter Wemm printf("TRUE}\n"); 60679d7565cSPeter Wemm else 60779d7565cSPeter Wemm printf("FALSE}\n"); 608986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 609986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 6109785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags); 61179d7565cSPeter Wemm printf(END_COMMENT); 61279d7565cSPeter Wemm } 61379d7565cSPeter Wemm 61479d7565cSPeter Wemm static void 615986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 61655d7ff9eSNate Lawson { 617986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 61855d7ff9eSNate Lawson 61955d7ff9eSNate Lawson printf(BEGIN_COMMENT); 62055d7ff9eSNate Lawson acpi_print_sdt(sdp); 621986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 62255d7ff9eSNate Lawson printf("\tEC_CONTROL="); 623986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 62455d7ff9eSNate Lawson printf("\n\tEC_DATA="); 625986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 626986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 627986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 628986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 62955d7ff9eSNate Lawson printf(END_COMMENT); 63055d7ff9eSNate Lawson } 63155d7ff9eSNate Lawson 63255d7ff9eSNate Lawson static void 633986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 634a47e681bSScott Long { 635986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 636986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 637986dffafSJohn Baldwin u_int i, entries; 638a47e681bSScott Long 639a47e681bSScott Long printf(BEGIN_COMMENT); 640a47e681bSScott Long acpi_print_sdt(sdp); 641986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 642986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 643986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 644986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 645986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 646a47e681bSScott Long printf("\n"); 6470c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address); 648986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 649986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 650986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 651a47e681bSScott Long } 652a47e681bSScott Long printf(END_COMMENT); 653a47e681bSScott Long } 654a47e681bSScott Long 655a47e681bSScott Long static void 65633866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 65733866658SJohn Baldwin { 65833866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 65933866658SJohn Baldwin UINT64 i, j; 66033866658SJohn Baldwin 66133866658SJohn Baldwin printf(BEGIN_COMMENT); 66233866658SJohn Baldwin acpi_print_sdt(sdp); 66333866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 6640c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount); 66533866658SJohn Baldwin printf("\n\t "); 66633866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 6670c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i); 66833866658SJohn Baldwin printf("\n\t +"); 66933866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 67033866658SJohn Baldwin printf("----"); 67133866658SJohn Baldwin printf("\n"); 67233866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 6730c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i); 67433866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 67533866658SJohn Baldwin printf(" %3d", 67633866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 67733866658SJohn Baldwin printf("\n"); 67833866658SJohn Baldwin } 67933866658SJohn Baldwin printf(END_COMMENT); 68033866658SJohn Baldwin } 68133866658SJohn Baldwin 68233866658SJohn Baldwin static void 683*ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp) 684*ed26c389SScott Long { 685*ed26c389SScott Long ACPI_TABLE_WDDT *wddt; 686*ed26c389SScott Long 687*ed26c389SScott Long printf(BEGIN_COMMENT); 688*ed26c389SScott Long acpi_print_sdt(sdp); 689*ed26c389SScott Long wddt = (ACPI_TABLE_WDDT *)sdp; 690*ed26c389SScott Long printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n", 691*ed26c389SScott Long wddt->SpecVersion, wddt->TableVersion); 692*ed26c389SScott Long printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId); 693*ed26c389SScott Long acpi_print_gas(&wddt->Address); 694*ed26c389SScott Long printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n", 695*ed26c389SScott Long wddt->MaxCount, wddt->MinCount, wddt->Period); 696*ed26c389SScott Long 697*ed26c389SScott Long #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag) 698*ed26c389SScott Long printf("\tStatus="); 699*ed26c389SScott Long PRINTFLAG(wddt->Status, AVAILABLE); 700*ed26c389SScott Long PRINTFLAG(wddt->Status, ACTIVE); 701*ed26c389SScott Long PRINTFLAG(wddt->Status, TCO_OS_OWNED); 702*ed26c389SScott Long PRINTFLAG(wddt->Status, USER_RESET); 703*ed26c389SScott Long PRINTFLAG(wddt->Status, WDT_RESET); 704*ed26c389SScott Long PRINTFLAG(wddt->Status, POWER_FAIL); 705*ed26c389SScott Long PRINTFLAG(wddt->Status, UNKNOWN_RESET); 706*ed26c389SScott Long PRINTFLAG_END(); 707*ed26c389SScott Long printf("\tCapability="); 708*ed26c389SScott Long PRINTFLAG(wddt->Capability, AUTO_RESET); 709*ed26c389SScott Long PRINTFLAG(wddt->Capability, ALERT_SUPPORT); 710*ed26c389SScott Long PRINTFLAG_END(); 711*ed26c389SScott Long #undef PRINTFLAG 712*ed26c389SScott Long 713*ed26c389SScott Long printf(END_COMMENT); 714*ed26c389SScott Long } 715*ed26c389SScott Long 716*ed26c389SScott Long static void 717a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 718a0333ad1SJohn Baldwin uint32_t flags) 719a0333ad1SJohn Baldwin { 720a0333ad1SJohn Baldwin 721a0333ad1SJohn Baldwin printf("\tFlags={"); 722a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 723a0333ad1SJohn Baldwin printf("ENABLED"); 724a0333ad1SJohn Baldwin else 725a0333ad1SJohn Baldwin printf("DISABLED"); 726a0333ad1SJohn Baldwin printf("}\n"); 727a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 728a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 729a0333ad1SJohn Baldwin } 730a0333ad1SJohn Baldwin 731c031c93bSTakanori Watanabe static char * 732c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 733c031c93bSTakanori Watanabe { 734c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 735c031c93bSTakanori Watanabe char *eventname = NULL; 736c031c93bSTakanori Watanabe 737c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 738c031c93bSTakanori Watanabe 739c031c93bSTakanori Watanabe switch(event->event_type) { 740c031c93bSTakanori Watanabe case PREBOOT: 741c031c93bSTakanori Watanabe case POST_CODE: 742c031c93bSTakanori Watanabe case UNUSED: 743c031c93bSTakanori Watanabe case NO_ACTION: 744c031c93bSTakanori Watanabe case SEPARATOR: 745c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 746c031c93bSTakanori Watanabe case SCRTM_VERSION: 747c031c93bSTakanori Watanabe case CPU_MICROCODE: 748c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 749c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 750c031c93bSTakanori Watanabe case COMPACT_HASH: 751c031c93bSTakanori Watanabe case IPL: 752c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 753c031c93bSTakanori Watanabe case NONHOST_CODE: 754c031c93bSTakanori Watanabe case NONHOST_CONFIG: 755c031c93bSTakanori Watanabe case NONHOST_INFO: 756c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 757c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 758c031c93bSTakanori Watanabe break; 759c031c93bSTakanori Watanabe 760c031c93bSTakanori Watanabe case ACTION: 761c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 762c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 763c031c93bSTakanori Watanabe break; 764c031c93bSTakanori Watanabe 765c031c93bSTakanori Watanabe case EVENT_TAG: 766c031c93bSTakanori Watanabe switch (pc_event->event_id) { 767c031c93bSTakanori Watanabe case SMBIOS: 768c031c93bSTakanori Watanabe case BIS_CERT: 769c031c93bSTakanori Watanabe case CMOS: 770c031c93bSTakanori Watanabe case NVRAM: 771c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 772c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 773c031c93bSTakanori Watanabe case S_CRTM_VERSION: 774c031c93bSTakanori Watanabe case POST_BIOS_ROM: 775c031c93bSTakanori Watanabe case ESCD: 776c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 777c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 778c031c93bSTakanori Watanabe case POST_CONTENTS: 779c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 780c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 781c031c93bSTakanori Watanabe break; 782c031c93bSTakanori Watanabe 783c031c93bSTakanori Watanabe default: 784c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 785c031c93bSTakanori Watanabe pc_event->event_id); 786c031c93bSTakanori Watanabe break; 787c031c93bSTakanori Watanabe } 788c031c93bSTakanori Watanabe break; 789c031c93bSTakanori Watanabe 790c031c93bSTakanori Watanabe default: 791c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 792c031c93bSTakanori Watanabe break; 793c031c93bSTakanori Watanabe } 794c031c93bSTakanori Watanabe 795c031c93bSTakanori Watanabe return eventname; 796c031c93bSTakanori Watanabe } 797c031c93bSTakanori Watanabe 798c031c93bSTakanori Watanabe static void 799c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 800c031c93bSTakanori Watanabe { 801c031c93bSTakanori Watanabe int i; 802c031c93bSTakanori Watanabe char *eventname; 803c031c93bSTakanori Watanabe 804c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 805c031c93bSTakanori Watanabe 806c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 807c031c93bSTakanori Watanabe printf(" 0x"); 808c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 809c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 810c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 811c031c93bSTakanori Watanabe 812c031c93bSTakanori Watanabe free(eventname); 813c031c93bSTakanori Watanabe } 814c031c93bSTakanori Watanabe 815c031c93bSTakanori Watanabe static void 816c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 817c031c93bSTakanori Watanabe { 818c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 819c031c93bSTakanori Watanabe struct TCPAevent *event; 820977fd9daSTakanori Watanabe uintmax_t len, paddr; 821c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 822c031c93bSTakanori Watanabe unsigned char *vend = NULL; 823c031c93bSTakanori Watanabe 824c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 825c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 826c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 827c031c93bSTakanori Watanabe 828c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 829c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 830c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 831c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 832c031c93bSTakanori Watanabe break; 833c031c93bSTakanori Watanabe 834c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 835c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 836c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 837c031c93bSTakanori Watanabe break; 838c031c93bSTakanori Watanabe 839c031c93bSTakanori Watanabe default: 840c031c93bSTakanori Watanabe printf("XXX"); 841c031c93bSTakanori Watanabe printf(END_COMMENT); 842c031c93bSTakanori Watanabe return; 843c031c93bSTakanori Watanabe } 8440e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 845c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 846c031c93bSTakanori Watanabe 847c031c93bSTakanori Watanabe if (len == 0) { 848c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 849c031c93bSTakanori Watanabe printf(END_COMMENT); 850c031c93bSTakanori Watanabe return; 851c031c93bSTakanori Watanabe } 8522ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 8532ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 8542ef23c6dSTakanori Watanabe printf(END_COMMENT); 8552ef23c6dSTakanori Watanabe return; 8562ef23c6dSTakanori Watanabe } 857c031c93bSTakanori Watanabe 858c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 859c031c93bSTakanori Watanabe vend = vaddr + len; 860c031c93bSTakanori Watanabe 861c031c93bSTakanori Watanabe while (vaddr != NULL) { 8622ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 8632ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 864c031c93bSTakanori Watanabe break; 8650e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 866c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 867c031c93bSTakanori Watanabe break; 8682ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 8692ef23c6dSTakanori Watanabe break; 870c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 871c031c93bSTakanori Watanabe break; 872c031c93bSTakanori Watanabe #if 0 873c031c93bSTakanori Watanabe { 874c031c93bSTakanori Watanabe unsigned int i, j, k; 875c031c93bSTakanori Watanabe 876c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 877c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 878c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 879c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 880c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 881c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 882c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 883c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 884c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 885c031c93bSTakanori Watanabe j = i + 1; 886c031c93bSTakanori Watanabe } 887c031c93bSTakanori Watanabe } 888c031c93bSTakanori Watanabe printf("\n"); } 889c031c93bSTakanori Watanabe #endif 890c031c93bSTakanori Watanabe acpi_print_tcpa(event); 891c031c93bSTakanori Watanabe 892c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 893c031c93bSTakanori Watanabe } 894c031c93bSTakanori Watanabe 895c031c93bSTakanori Watanabe printf(END_COMMENT); 896c031c93bSTakanori Watanabe } 897c031c93bSTakanori Watanabe 898ec650989SNeel Natu static const char * 899ec650989SNeel Natu devscope_type2str(int type) 900ec650989SNeel Natu { 901ec650989SNeel Natu static char typebuf[16]; 902ec650989SNeel Natu 903ec650989SNeel Natu switch (type) { 904ec650989SNeel Natu case 1: 905ec650989SNeel Natu return ("PCI Endpoint Device"); 906ec650989SNeel Natu case 2: 907ec650989SNeel Natu return ("PCI Sub-Hierarchy"); 908ec650989SNeel Natu case 3: 909ec650989SNeel Natu return ("IOAPIC"); 910ec650989SNeel Natu case 4: 911ec650989SNeel Natu return ("HPET"); 912ec650989SNeel Natu default: 913ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type); 914ec650989SNeel Natu return (typebuf); 915ec650989SNeel Natu } 916ec650989SNeel Natu } 917ec650989SNeel Natu 918ec650989SNeel Natu static int 919ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining) 920ec650989SNeel Natu { 921ec650989SNeel Natu char sep; 922ec650989SNeel Natu int pathlen; 923ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend; 924ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr; 925ec650989SNeel Natu 926ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) 927ec650989SNeel Natu return (-1); 928ec650989SNeel Natu 929ec650989SNeel Natu if (remaining < devscope->Length) 930ec650989SNeel Natu return (-1); 931ec650989SNeel Natu 932ec650989SNeel Natu printf("\n"); 933ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); 934ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length); 935ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); 936ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus); 937ec650989SNeel Natu 938ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); 939ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); 940ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); 941ec650989SNeel Natu if (path < pathend) { 942ec650989SNeel Natu sep = '{'; 943ec650989SNeel Natu printf("\t\tPath="); 944ec650989SNeel Natu do { 945ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function); 946ec650989SNeel Natu sep=','; 947ec650989SNeel Natu path++; 948ec650989SNeel Natu } while (path < pathend); 949ec650989SNeel Natu printf("}\n"); 950ec650989SNeel Natu } 951ec650989SNeel Natu 952ec650989SNeel Natu return (devscope->Length); 953ec650989SNeel Natu } 954ec650989SNeel Natu 955ec650989SNeel Natu static void 956ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) 957ec650989SNeel Natu { 958ec650989SNeel Natu char *cp; 959ec650989SNeel Natu int remaining, consumed; 960ec650989SNeel Natu 961ec650989SNeel Natu printf("\n"); 962ec650989SNeel Natu printf("\tType=DRHD\n"); 963ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length); 964ec650989SNeel Natu 965ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 966ec650989SNeel Natu 967ec650989SNeel Natu printf("\tFlags="); 968ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL); 969ec650989SNeel Natu PRINTFLAG_END(); 970ec650989SNeel Natu 971ec650989SNeel Natu #undef PRINTFLAG 972ec650989SNeel Natu 973ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment); 9747d369c6eSJung-uk Kim printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address); 975ec650989SNeel Natu 976ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); 977ec650989SNeel Natu if (remaining > 0) 978ec650989SNeel Natu printf("\tDevice Scope:"); 979ec650989SNeel Natu while (remaining > 0) { 980ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining; 981ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 982ec650989SNeel Natu if (consumed <= 0) 983ec650989SNeel Natu break; 984ec650989SNeel Natu else 985ec650989SNeel Natu remaining -= consumed; 986ec650989SNeel Natu } 987ec650989SNeel Natu } 988ec650989SNeel Natu 989ec650989SNeel Natu static void 990ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) 991ec650989SNeel Natu { 992ec650989SNeel Natu char *cp; 993ec650989SNeel Natu int remaining, consumed; 994ec650989SNeel Natu 995ec650989SNeel Natu printf("\n"); 996ec650989SNeel Natu printf("\tType=RMRR\n"); 997ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length); 998ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment); 9997d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress); 10007d369c6eSJung-uk Kim printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress); 1001ec650989SNeel Natu 1002ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); 1003ec650989SNeel Natu if (remaining > 0) 1004ec650989SNeel Natu printf("\tDevice Scope:"); 1005ec650989SNeel Natu while (remaining > 0) { 1006ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining; 1007ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1008ec650989SNeel Natu if (consumed <= 0) 1009ec650989SNeel Natu break; 1010ec650989SNeel Natu else 1011ec650989SNeel Natu remaining -= consumed; 1012ec650989SNeel Natu } 1013ec650989SNeel Natu } 1014ec650989SNeel Natu 1015ec650989SNeel Natu static void 1016ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) 1017ec650989SNeel Natu { 1018ec650989SNeel Natu char *cp; 1019ec650989SNeel Natu int remaining, consumed; 1020ec650989SNeel Natu 1021ec650989SNeel Natu printf("\n"); 1022ec650989SNeel Natu printf("\tType=ATSR\n"); 1023ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length); 1024ec650989SNeel Natu 1025ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1026ec650989SNeel Natu 1027ec650989SNeel Natu printf("\tFlags="); 1028ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS); 1029ec650989SNeel Natu PRINTFLAG_END(); 1030ec650989SNeel Natu 1031ec650989SNeel Natu #undef PRINTFLAG 1032ec650989SNeel Natu 1033ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment); 1034ec650989SNeel Natu 1035ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); 1036ec650989SNeel Natu if (remaining > 0) 1037ec650989SNeel Natu printf("\tDevice Scope:"); 1038ec650989SNeel Natu while (remaining > 0) { 1039ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining; 1040ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1041ec650989SNeel Natu if (consumed <= 0) 1042ec650989SNeel Natu break; 1043ec650989SNeel Natu else 1044ec650989SNeel Natu remaining -= consumed; 1045ec650989SNeel Natu } 1046ec650989SNeel Natu } 1047ec650989SNeel Natu 1048ec650989SNeel Natu static void 1049ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) 1050ec650989SNeel Natu { 1051ec650989SNeel Natu 1052ec650989SNeel Natu printf("\n"); 1053ec650989SNeel Natu printf("\tType=RHSA\n"); 1054ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length); 10557d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress); 1056ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); 1057ec650989SNeel Natu } 1058ec650989SNeel Natu 1059ec650989SNeel Natu static int 1060ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining) 1061ec650989SNeel Natu { 1062ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr; 1063ec650989SNeel Natu 1064ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) 1065ec650989SNeel Natu return (-1); 1066ec650989SNeel Natu 1067ec650989SNeel Natu if (remaining < hdr->Length) 1068ec650989SNeel Natu return (-1); 1069ec650989SNeel Natu 1070ec650989SNeel Natu switch (hdr->Type) { 1071ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1072ec650989SNeel Natu acpi_handle_dmar_drhd(addr); 1073ec650989SNeel Natu break; 1074ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1075ec650989SNeel Natu acpi_handle_dmar_rmrr(addr); 1076ec650989SNeel Natu break; 1077313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS: 1078ec650989SNeel Natu acpi_handle_dmar_atsr(addr); 1079ec650989SNeel Natu break; 1080313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1081ec650989SNeel Natu acpi_handle_dmar_rhsa(addr); 1082ec650989SNeel Natu break; 1083ec650989SNeel Natu default: 1084ec650989SNeel Natu printf("\n"); 1085ec650989SNeel Natu printf("\tType=%d\n", hdr->Type); 1086ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length); 1087ec650989SNeel Natu break; 1088ec650989SNeel Natu } 1089ec650989SNeel Natu return (hdr->Length); 1090ec650989SNeel Natu } 1091ec650989SNeel Natu 1092ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT 1093ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2) 1094ec650989SNeel Natu #endif 1095ec650989SNeel Natu 1096ec650989SNeel Natu static void 1097ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) 1098ec650989SNeel Natu { 1099ec650989SNeel Natu char *cp; 1100ec650989SNeel Natu int remaining, consumed; 1101ec650989SNeel Natu ACPI_TABLE_DMAR *dmar; 1102ec650989SNeel Natu 1103ec650989SNeel Natu printf(BEGIN_COMMENT); 1104ec650989SNeel Natu acpi_print_sdt(sdp); 1105ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp; 1106ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1); 1107ec650989SNeel Natu 1108ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1109ec650989SNeel Natu 1110ec650989SNeel Natu printf("\tFlags="); 1111ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP); 1112ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); 1113ec650989SNeel Natu PRINTFLAG_END(); 1114ec650989SNeel Natu 1115ec650989SNeel Natu #undef PRINTFLAG 1116ec650989SNeel Natu 1117ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); 1118ec650989SNeel Natu while (remaining > 0) { 1119ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining; 1120ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining); 1121ec650989SNeel Natu if (consumed <= 0) 1122ec650989SNeel Natu break; 1123ec650989SNeel Natu else 1124ec650989SNeel Natu remaining -= consumed; 1125ec650989SNeel Natu } 1126ec650989SNeel Natu 1127ec650989SNeel Natu printf(END_COMMENT); 1128ec650989SNeel Natu } 1129ec650989SNeel Natu 1130a0333ad1SJohn Baldwin static void 1131986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 1132a0333ad1SJohn Baldwin { 1133a0333ad1SJohn Baldwin 1134a0333ad1SJohn Baldwin printf("\tFlags={"); 1135986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 1136a0333ad1SJohn Baldwin printf("ENABLED"); 1137a0333ad1SJohn Baldwin else 1138a0333ad1SJohn Baldwin printf("DISABLED"); 1139986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 1140a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 1141986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 1142a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 1143a0333ad1SJohn Baldwin printf("}\n"); 1144986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 1145986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 1146986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 1147a0333ad1SJohn Baldwin } 1148a0333ad1SJohn Baldwin 114927941afaSEd Maste static const char *srat_types[] = { 115027941afaSEd Maste [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU", 115127941afaSEd Maste [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory", 115227941afaSEd Maste [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC", 1153cebb7b19SEd Maste [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC", 1154cebb7b19SEd Maste [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS", 115527941afaSEd Maste }; 1156a0333ad1SJohn Baldwin 1157a0333ad1SJohn Baldwin static void 1158986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 1159a0333ad1SJohn Baldwin { 1160986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 1161986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 11622b2b1f42SAndrew Turner ACPI_SRAT_GICC_AFFINITY *gic; 1163a0333ad1SJohn Baldwin 1164c86932b6SMarcelo Araujo if (srat->Type < nitems(srat_types)) 1165986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 1166a0333ad1SJohn Baldwin else 1167986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 1168986dffafSJohn Baldwin switch (srat->Type) { 1169a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 1170986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 1171986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 1172986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 1173986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 1174986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 1175986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 1176a0333ad1SJohn Baldwin break; 1177a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1178986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 1179a0333ad1SJohn Baldwin break; 1180a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1181986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 1182986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 1183986dffafSJohn Baldwin x2apic->Flags); 1184a0333ad1SJohn Baldwin break; 11852b2b1f42SAndrew Turner case ACPI_SRAT_TYPE_GICC_AFFINITY: 11862b2b1f42SAndrew Turner gic = (ACPI_SRAT_GICC_AFFINITY *)srat; 11872b2b1f42SAndrew Turner acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain, 11882b2b1f42SAndrew Turner gic->Flags); 11892b2b1f42SAndrew Turner break; 1190a0333ad1SJohn Baldwin } 1191a0333ad1SJohn Baldwin } 1192a0333ad1SJohn Baldwin 1193a0333ad1SJohn Baldwin static void 1194986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 1195a0333ad1SJohn Baldwin { 1196986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 1197a0333ad1SJohn Baldwin 1198a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 1199a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 1200986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 1201986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 1202986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 1203a0333ad1SJohn Baldwin printf(END_COMMENT); 1204a0333ad1SJohn Baldwin } 1205a0333ad1SJohn Baldwin 1206340c0022SEd Maste static const char *nfit_types[] = { 1207340c0022SEd Maste [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address", 1208340c0022SEd Maste [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map", 1209340c0022SEd Maste [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave", 1210340c0022SEd Maste [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS", 1211340c0022SEd Maste [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region", 1212340c0022SEd Maste [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region", 1213340c0022SEd Maste [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address" 1214340c0022SEd Maste }; 1215340c0022SEd Maste 1216340c0022SEd Maste 1217340c0022SEd Maste static void 1218340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit) 1219340c0022SEd Maste { 1220340c0022SEd Maste char *uuidstr; 1221340c0022SEd Maste uint32_t status; 1222340c0022SEd Maste 1223340c0022SEd Maste ACPI_NFIT_SYSTEM_ADDRESS *sysaddr; 1224340c0022SEd Maste ACPI_NFIT_MEMORY_MAP *mmap; 1225340c0022SEd Maste ACPI_NFIT_INTERLEAVE *ileave; 1226340c0022SEd Maste ACPI_NFIT_SMBIOS *smbios; 1227340c0022SEd Maste ACPI_NFIT_CONTROL_REGION *ctlreg; 1228340c0022SEd Maste ACPI_NFIT_DATA_REGION *datareg; 1229340c0022SEd Maste ACPI_NFIT_FLUSH_ADDRESS *fladdr; 1230340c0022SEd Maste 1231340c0022SEd Maste if (nfit->Type < nitems(nfit_types)) 1232340c0022SEd Maste printf("\tType=%s\n", nfit_types[nfit->Type]); 1233340c0022SEd Maste else 1234340c0022SEd Maste printf("\tType=%u (unknown)\n", nfit->Type); 1235340c0022SEd Maste switch (nfit->Type) { 1236340c0022SEd Maste case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 1237340c0022SEd Maste sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit; 1238340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex); 1239340c0022SEd Maste printf("\tProximityDomain=%u\n", 1240340c0022SEd Maste (u_int)sysaddr->ProximityDomain); 1241340c0022SEd Maste uuid_to_string((uuid_t *)(sysaddr->RangeGuid), 1242340c0022SEd Maste &uuidstr, &status); 1243340c0022SEd Maste if (status != uuid_s_ok) 1244340c0022SEd Maste errx(1, "uuid_to_string: status=%u", status); 1245340c0022SEd Maste printf("\tRangeGuid=%s\n", uuidstr); 1246340c0022SEd Maste free(uuidstr); 1247340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address); 1248340c0022SEd Maste printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length); 1249340c0022SEd Maste printf("\tMemoryMapping=0x%016jx\n", 1250340c0022SEd Maste (uintmax_t)sysaddr->MemoryMapping); 1251340c0022SEd Maste 1252340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 1253340c0022SEd Maste 1254340c0022SEd Maste printf("\tFlags="); 1255340c0022SEd Maste PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY); 1256340c0022SEd Maste PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID); 1257340c0022SEd Maste PRINTFLAG_END(); 1258340c0022SEd Maste 1259340c0022SEd Maste #undef PRINTFLAG 1260340c0022SEd Maste 1261340c0022SEd Maste break; 1262340c0022SEd Maste case ACPI_NFIT_TYPE_MEMORY_MAP: 1263340c0022SEd Maste mmap = (ACPI_NFIT_MEMORY_MAP *)nfit; 1264340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle); 1265340c0022SEd Maste printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId); 1266340c0022SEd Maste printf("\tRegionId=%u\n", (u_int)mmap->RegionId); 1267340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex); 1268340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex); 1269340c0022SEd Maste printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize); 1270340c0022SEd Maste printf("\tRegionOffset=0x%016jx\n", 1271340c0022SEd Maste (uintmax_t)mmap->RegionOffset); 1272340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address); 1273340c0022SEd Maste printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex); 1274fb1cf2a9SAlexander Motin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays); 1275340c0022SEd Maste 1276340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag) 1277340c0022SEd Maste 1278340c0022SEd Maste printf("\tFlags="); 1279340c0022SEd Maste PRINTFLAG(mmap->Flags, SAVE_FAILED); 1280340c0022SEd Maste PRINTFLAG(mmap->Flags, RESTORE_FAILED); 1281340c0022SEd Maste PRINTFLAG(mmap->Flags, FLUSH_FAILED); 1282340c0022SEd Maste PRINTFLAG(mmap->Flags, NOT_ARMED); 1283340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_OBSERVED); 1284340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_ENABLED); 1285340c0022SEd Maste PRINTFLAG(mmap->Flags, MAP_FAILED); 1286340c0022SEd Maste PRINTFLAG_END(); 1287340c0022SEd Maste 1288340c0022SEd Maste #undef PRINTFLAG 1289340c0022SEd Maste 1290340c0022SEd Maste break; 1291340c0022SEd Maste case ACPI_NFIT_TYPE_INTERLEAVE: 1292340c0022SEd Maste ileave = (ACPI_NFIT_INTERLEAVE *)nfit; 1293340c0022SEd Maste printf("\tInterleaveIndex=%u\n", 1294340c0022SEd Maste (u_int)ileave->InterleaveIndex); 1295340c0022SEd Maste printf("\tLineCount=%u\n", (u_int)ileave->LineCount); 1296340c0022SEd Maste printf("\tLineSize=%u\n", (u_int)ileave->LineSize); 1297340c0022SEd Maste /* XXX ileave->LineOffset[i] output is not supported */ 1298340c0022SEd Maste break; 1299340c0022SEd Maste case ACPI_NFIT_TYPE_SMBIOS: 1300340c0022SEd Maste smbios = (ACPI_NFIT_SMBIOS *)nfit; 1301340c0022SEd Maste /* XXX smbios->Data[x] output is not supported */ 1302340c0022SEd Maste break; 1303340c0022SEd Maste case ACPI_NFIT_TYPE_CONTROL_REGION: 1304340c0022SEd Maste ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit; 1305340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex); 1306340c0022SEd Maste printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId); 1307340c0022SEd Maste printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId); 1308340c0022SEd Maste printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId); 1309340c0022SEd Maste printf("\tSubsystemVendorId=0x%04x\n", 1310340c0022SEd Maste (u_int)ctlreg->SubsystemVendorId); 1311340c0022SEd Maste printf("\tSubsystemDeviceId=0x%04x\n", 1312340c0022SEd Maste (u_int)ctlreg->SubsystemDeviceId); 1313340c0022SEd Maste printf("\tSubsystemRevisionId=%u\n", 1314340c0022SEd Maste (u_int)ctlreg->SubsystemRevisionId); 1315d4c2de2eSAlexander Motin printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields); 1316340c0022SEd Maste printf("\tManufacturingLocation=%u\n", 1317340c0022SEd Maste (u_int)ctlreg->ManufacturingLocation); 1318340c0022SEd Maste printf("\tManufacturingDate=%u\n", 1319340c0022SEd Maste (u_int)ctlreg->ManufacturingDate); 1320340c0022SEd Maste printf("\tSerialNumber=%u\n", 1321340c0022SEd Maste (u_int)ctlreg->SerialNumber); 1322fb1cf2a9SAlexander Motin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code); 1323340c0022SEd Maste printf("\tWindows=%u\n", (u_int)ctlreg->Windows); 1324340c0022SEd Maste printf("\tWindowSize=0x%016jx\n", 1325340c0022SEd Maste (uintmax_t)ctlreg->WindowSize); 1326340c0022SEd Maste printf("\tCommandOffset=0x%016jx\n", 1327340c0022SEd Maste (uintmax_t)ctlreg->CommandOffset); 1328340c0022SEd Maste printf("\tCommandSize=0x%016jx\n", 1329340c0022SEd Maste (uintmax_t)ctlreg->CommandSize); 1330340c0022SEd Maste printf("\tStatusOffset=0x%016jx\n", 1331340c0022SEd Maste (uintmax_t)ctlreg->StatusOffset); 1332340c0022SEd Maste printf("\tStatusSize=0x%016jx\n", 1333340c0022SEd Maste (uintmax_t)ctlreg->StatusSize); 1334340c0022SEd Maste 1335340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 1336340c0022SEd Maste 1337340c0022SEd Maste printf("\tFlags="); 1338d4c2de2eSAlexander Motin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED); 1339340c0022SEd Maste PRINTFLAG_END(); 1340340c0022SEd Maste 1341340c0022SEd Maste #undef PRINTFLAG 1342340c0022SEd Maste 1343340c0022SEd Maste break; 1344340c0022SEd Maste case ACPI_NFIT_TYPE_DATA_REGION: 1345340c0022SEd Maste datareg = (ACPI_NFIT_DATA_REGION *)nfit; 1346340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex); 1347340c0022SEd Maste printf("\tWindows=%u\n", (u_int)datareg->Windows); 1348340c0022SEd Maste printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset); 1349340c0022SEd Maste printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size); 1350340c0022SEd Maste printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity); 1351340c0022SEd Maste printf("\tStartAddress=0x%016jx\n", 1352340c0022SEd Maste (uintmax_t)datareg->StartAddress); 1353340c0022SEd Maste break; 1354340c0022SEd Maste case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 1355340c0022SEd Maste fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit; 1356340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle); 1357340c0022SEd Maste printf("\tHintCount=%u\n", (u_int)fladdr->HintCount); 1358340c0022SEd Maste /* XXX fladdr->HintAddress[i] output is not supported */ 1359340c0022SEd Maste break; 1360340c0022SEd Maste } 1361340c0022SEd Maste } 1362340c0022SEd Maste 1363340c0022SEd Maste static void 1364340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp) 1365340c0022SEd Maste { 1366340c0022SEd Maste ACPI_TABLE_NFIT *nfit; 1367340c0022SEd Maste 1368340c0022SEd Maste printf(BEGIN_COMMENT); 1369340c0022SEd Maste acpi_print_sdt(sdp); 1370340c0022SEd Maste nfit = (ACPI_TABLE_NFIT *)sdp; 1371340c0022SEd Maste acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit); 1372340c0022SEd Maste printf(END_COMMENT); 1373340c0022SEd Maste } 1374340c0022SEd Maste 1375a0333ad1SJohn Baldwin static void 1376986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 1377c62f1cccSMitsuru IWASAKI { 1378773b6454SNate Lawson printf(" "); 1379986dffafSJohn Baldwin acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); 1380c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 1381986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 1382e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 1383986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 1384e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 1385986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 1386986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 1387e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 1388986dffafSJohn Baldwin acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); 1389986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 1390e1e9a4bfSMitsuru IWASAKI } 1391e1e9a4bfSMitsuru IWASAKI 1392945137d9SNate Lawson static void 1393986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 1394e1e9a4bfSMitsuru IWASAKI { 1395986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1396986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1397e1e9a4bfSMitsuru IWASAKI int i, entries; 1398e1e9a4bfSMitsuru IWASAKI 1399986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1400986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1401773b6454SNate Lawson printf(BEGIN_COMMENT); 1402773b6454SNate Lawson acpi_print_sdt(rsdp); 1403986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1404e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 1405e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1406e1e9a4bfSMitsuru IWASAKI if (i > 0) 1407e1e9a4bfSMitsuru IWASAKI printf(", "); 1408fe1d0c2dSJung-uk Kim if (addr_size == 4) 14097d369c6eSJung-uk Kim printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i])); 1410fe1d0c2dSJung-uk Kim else 14117d369c6eSJung-uk Kim printf("0x%016jx", 14127d369c6eSJung-uk Kim (uintmax_t)le64toh(xsdt->TableOffsetEntry[i])); 1413e1e9a4bfSMitsuru IWASAKI } 1414e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 1415c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1416e1e9a4bfSMitsuru IWASAKI } 1417e1e9a4bfSMitsuru IWASAKI 14188e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 14198e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 14208e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 14218e6a8737SNate Lawson }; 14228e6a8737SNate Lawson 1423945137d9SNate Lawson static void 1424986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 1425e1e9a4bfSMitsuru IWASAKI { 1426986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 14278e6a8737SNate Lawson const char *pm; 1428e1e9a4bfSMitsuru IWASAKI 1429986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 1430c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 14312177d4e6SNate Lawson acpi_print_sdt(sdp); 1432986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 1433986dffafSJohn Baldwin fadt->Dsdt); 1434986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 1435986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 14368e6a8737SNate Lawson pm = "Reserved"; 14378e6a8737SNate Lawson else 1438986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 1439986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 1440986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 1441986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 1442986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 1443986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 1444986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 1445986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 1446e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 1447986dffafSJohn Baldwin fadt->Pm1aEventBlock, 1448986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 1449986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 1450e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 1451986dffafSJohn Baldwin fadt->Pm1bEventBlock, 1452986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 1453e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 1454986dffafSJohn Baldwin fadt->Pm1aControlBlock, 1455986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 1456986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 1457e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 1458986dffafSJohn Baldwin fadt->Pm1bControlBlock, 1459986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 1460986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 1461e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 1462986dffafSJohn Baldwin fadt->Pm2ControlBlock, 1463986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 1464c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 1465986dffafSJohn Baldwin fadt->PmTimerBlock, 1466986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 1467986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 14688e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 1469986dffafSJohn Baldwin fadt->Gpe0Block, 1470986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 1471986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 14728e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 1473986dffafSJohn Baldwin fadt->Gpe1Block, 1474986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 1475986dffafSJohn Baldwin fadt->Gpe1Base); 1476986dffafSJohn Baldwin if (fadt->CstControl != 0) 1477986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 147851c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 1479986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 1480e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 1481986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 1482e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 1483986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 1484e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 1485986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 1486e1e9a4bfSMitsuru IWASAKI 1487ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) 1488e1e9a4bfSMitsuru IWASAKI 14898e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 1490986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 1491986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 1492986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 1493986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 1494986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 1495f6469ce1SAndrew Turner PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC); 1496ec650989SNeel Natu PRINTFLAG_END(); 14978e6a8737SNate Lawson 14988e6a8737SNate Lawson printf("\tFlags="); 1499986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 1500986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 1501986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 1502986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 1503986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 1504986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 1505986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 1506986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 1507986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 1508986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 1509986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 1510986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 1511986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 1512986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 1513986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 1514986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 1515986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 1516986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 1517986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 1518986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 1519f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, HW_REDUCED); 1520f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, LOW_POWER_S0); 1521ec650989SNeel Natu PRINTFLAG_END(); 1522e1e9a4bfSMitsuru IWASAKI 1523e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 1524e1e9a4bfSMitsuru IWASAKI 1525986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 15268e6a8737SNate Lawson printf("\tRESET_REG="); 1527986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 1528986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 15298e6a8737SNate Lawson } 1530c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 15317d369c6eSJung-uk Kim printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs); 15327d369c6eSJung-uk Kim printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt); 1533c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 1534986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 1535986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 1536c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 1537986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 1538c08c4e81SNate Lawson } 1539c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 1540986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 1541986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 1542c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 1543986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 1544c08c4e81SNate Lawson } 1545986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 1546773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 1547986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 1548c08c4e81SNate Lawson } 1549773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 1550986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 1551986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 1552773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 1553986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 1554c08c4e81SNate Lawson } 1555986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 1556773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 1557986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 1558c08c4e81SNate Lawson } 1559773b6454SNate Lawson printf("\n"); 1560773b6454SNate Lawson } 15618e6a8737SNate Lawson 15628e6a8737SNate Lawson printf(END_COMMENT); 15638e6a8737SNate Lawson } 15648e6a8737SNate Lawson 15658e6a8737SNate Lawson static void 1566986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 15678e6a8737SNate Lawson { 15688e6a8737SNate Lawson printf(BEGIN_COMMENT); 1569986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 1570986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 1571986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 15728e6a8737SNate Lawson 1573773b6454SNate Lawson printf("\tGlobal_Lock="); 1574986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 1575986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 15768e6a8737SNate Lawson printf("PENDING,"); 1577986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 15788e6a8737SNate Lawson printf("OWNED"); 15798e6a8737SNate Lawson } 1580773b6454SNate Lawson printf("\n"); 15818e6a8737SNate Lawson 1582773b6454SNate Lawson printf("\tFlags="); 1583986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 15848e6a8737SNate Lawson printf("S4BIOS"); 1585773b6454SNate Lawson printf("\n"); 15868e6a8737SNate Lawson 15877d369c6eSJung-uk Kim if (facs->XFirmwareWakingVector != 0) 15887d369c6eSJung-uk Kim printf("\tX_Firm_Wake_Vec=%016jx\n", 15897d369c6eSJung-uk Kim (uintmax_t)facs->XFirmwareWakingVector); 1590986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 15918e6a8737SNate Lawson 1592c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1593e1e9a4bfSMitsuru IWASAKI } 1594e1e9a4bfSMitsuru IWASAKI 1595945137d9SNate Lawson static void 1596986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 1597e1e9a4bfSMitsuru IWASAKI { 1598773b6454SNate Lawson printf(BEGIN_COMMENT); 1599773b6454SNate Lawson acpi_print_sdt(dsdp); 1600773b6454SNate Lawson printf(END_COMMENT); 1601e1e9a4bfSMitsuru IWASAKI } 1602e1e9a4bfSMitsuru IWASAKI 1603e1e9a4bfSMitsuru IWASAKI int 1604e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 1605e1e9a4bfSMitsuru IWASAKI { 1606986dffafSJohn Baldwin uint8_t *bp; 1607986dffafSJohn Baldwin uint8_t sum; 1608e1e9a4bfSMitsuru IWASAKI 1609e1e9a4bfSMitsuru IWASAKI bp = p; 1610e1e9a4bfSMitsuru IWASAKI sum = 0; 1611e1e9a4bfSMitsuru IWASAKI while (length--) 1612e1e9a4bfSMitsuru IWASAKI sum += *bp++; 1613e1e9a4bfSMitsuru IWASAKI 1614e1e9a4bfSMitsuru IWASAKI return (sum); 1615e1e9a4bfSMitsuru IWASAKI } 1616e1e9a4bfSMitsuru IWASAKI 1617986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 1618e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 1619e1e9a4bfSMitsuru IWASAKI { 1620986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 1621e1e9a4bfSMitsuru IWASAKI 1622986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 1623986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 1624e1e9a4bfSMitsuru IWASAKI return (sp); 1625e1e9a4bfSMitsuru IWASAKI } 1626e1e9a4bfSMitsuru IWASAKI 1627945137d9SNate Lawson static void 1628986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 1629e1e9a4bfSMitsuru IWASAKI { 1630c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 1631a74172abSNate Lawson printf(" RSD PTR: OEM="); 1632986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 1633986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 1634986dffafSJohn Baldwin rp->Revision); 1635986dffafSJohn Baldwin if (rp->Revision < 2) { 1636986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 1637986dffafSJohn Baldwin rp->Checksum); 1638a74172abSNate Lawson } else { 16397d369c6eSJung-uk Kim printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n", 16407d369c6eSJung-uk Kim (uintmax_t)rp->XsdtPhysicalAddress, rp->Length, 1641986dffafSJohn Baldwin rp->ExtendedChecksum); 1642a74172abSNate Lawson } 1643c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 1644e1e9a4bfSMitsuru IWASAKI } 1645e1e9a4bfSMitsuru IWASAKI 1646945137d9SNate Lawson static void 1647986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 1648e1e9a4bfSMitsuru IWASAKI { 1649986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 1650986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1651986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1652a74172abSNate Lawson vm_offset_t addr; 1653a74172abSNate Lawson int entries, i; 1654e1e9a4bfSMitsuru IWASAKI 1655e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 1656986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1657986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1658986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1659e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 1660fe1d0c2dSJung-uk Kim if (addr_size == 4) 1661986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1662fe1d0c2dSJung-uk Kim else 1663986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1664fe1d0c2dSJung-uk Kim if (addr == 0) 1665fe1d0c2dSJung-uk Kim continue; 1666986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1667986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 16685cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 1669986dffafSJohn Baldwin sdp->Signature); 16705cf6d493SNate Lawson continue; 16715cf6d493SNate Lawson } 1672986dffafSJohn Baldwin if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 16732177d4e6SNate Lawson acpi_handle_fadt(sdp); 1674986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 1675986dffafSJohn Baldwin acpi_handle_madt(sdp); 1676986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 167779d7565cSPeter Wemm acpi_handle_hpet(sdp); 1678986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 167955d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 1680986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 1681a47e681bSScott Long acpi_handle_mcfg(sdp); 168233866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 168333866658SJohn Baldwin acpi_handle_slit(sdp); 1684986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 1685a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 1686c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 1687c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 1688ec650989SNeel Natu else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) 1689ec650989SNeel Natu acpi_handle_dmar(sdp); 1690340c0022SEd Maste else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4)) 1691340c0022SEd Maste acpi_handle_nfit(sdp); 1692*ed26c389SScott Long else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4)) 1693*ed26c389SScott Long acpi_handle_wddt(sdp); 1694773b6454SNate Lawson else { 1695773b6454SNate Lawson printf(BEGIN_COMMENT); 1696773b6454SNate Lawson acpi_print_sdt(sdp); 1697773b6454SNate Lawson printf(END_COMMENT); 1698773b6454SNate Lawson } 1699e1e9a4bfSMitsuru IWASAKI } 1700e1e9a4bfSMitsuru IWASAKI } 1701c62f1cccSMitsuru IWASAKI 1702986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1703476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 1704945137d9SNate Lawson { 1705986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 1706986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 1707945137d9SNate Lawson 1708945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 1709945137d9SNate Lawson if (!rp) 1710945137d9SNate Lawson errx(1, "Can't find ACPI information"); 1711945137d9SNate Lawson 1712945137d9SNate Lawson if (tflag) 1713945137d9SNate Lawson acpi_print_rsd_ptr(rp); 1714986dffafSJohn Baldwin if (rp->Revision < 2) { 1715986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 1716986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 1717986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1718945137d9SNate Lawson errx(1, "RSDT is corrupted"); 1719a74172abSNate Lawson addr_size = sizeof(uint32_t); 1720a74172abSNate Lawson } else { 1721986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 1722986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 1723986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 1724a74172abSNate Lawson errx(1, "XSDT is corrupted"); 1725a74172abSNate Lawson addr_size = sizeof(uint64_t); 1726a74172abSNate Lawson } 1727945137d9SNate Lawson return (rsdp); 1728945137d9SNate Lawson } 1729c62f1cccSMitsuru IWASAKI 173062c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 1731bfa3f012SMarcel Moolenaar static int 1732986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 1733bfa3f012SMarcel Moolenaar { 1734986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 1735986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 1736bfa3f012SMarcel Moolenaar uint8_t sum; 1737bfa3f012SMarcel Moolenaar 173862c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 1739bfa3f012SMarcel Moolenaar sdt = *dsdt; 1740bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 1741986dffafSJohn Baldwin sdt.Checksum = 0; 1742986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 1743986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1744986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 1745f7675a56SNate Lawson while (ssdt != NULL) { 1746986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 1747986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 1748986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 1749986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 1750bfa3f012SMarcel Moolenaar } 1751986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 1752986dffafSJohn Baldwin sdt.Checksum -= sum; 1753bfa3f012SMarcel Moolenaar } 175462c7bde1SNate Lawson 175562c7bde1SNate Lawson /* Write out the DSDT header and body. */ 1756986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 1757986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 175862c7bde1SNate Lawson 1759b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 1760f7675a56SNate Lawson if (rsdt != NULL) { 1761bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 1762bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 1763986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 1764986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 1765bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 1766bfa3f012SMarcel Moolenaar } 1767bfa3f012SMarcel Moolenaar } 1768bfa3f012SMarcel Moolenaar return (0); 1769bfa3f012SMarcel Moolenaar } 1770bfa3f012SMarcel Moolenaar 1771c62f1cccSMitsuru IWASAKI void 1772986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1773c62f1cccSMitsuru IWASAKI { 1774945137d9SNate Lawson int fd; 1775945137d9SNate Lawson mode_t mode; 1776945137d9SNate Lawson 1777945137d9SNate Lawson assert(outfile != NULL); 1778945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1779945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 1780945137d9SNate Lawson if (fd == -1) { 1781945137d9SNate Lawson perror("dsdt_save_file"); 1782945137d9SNate Lawson return; 1783945137d9SNate Lawson } 1784bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1785945137d9SNate Lawson close(fd); 1786c62f1cccSMitsuru IWASAKI } 1787c62f1cccSMitsuru IWASAKI 1788945137d9SNate Lawson void 1789986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 1790c62f1cccSMitsuru IWASAKI { 17917e2cc014SDon Lewis char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX]; 17927e2cc014SDon Lewis const char *iname = "/acpdump.din"; 17937e2cc014SDon Lewis const char *oname = "/acpdump.dsl"; 179499065116SJung-uk Kim const char *tmpdir; 1795945137d9SNate Lawson FILE *fp; 179699065116SJung-uk Kim size_t len; 17977e2cc014SDon Lewis int fd, status; 17987e2cc014SDon Lewis pid_t pid; 1799945137d9SNate Lawson 180099065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 180199065116SJung-uk Kim if (tmpdir == NULL) 180299065116SJung-uk Kim tmpdir = _PATH_TMP; 18037e2cc014SDon Lewis if (realpath(tmpdir, buf) == NULL) { 1804d6a6e590SJung-uk Kim perror("realpath tmp dir"); 180599065116SJung-uk Kim return; 180699065116SJung-uk Kim } 18077e2cc014SDon Lewis len = sizeof(wrkdir) - strlen(iname); 18087e2cc014SDon Lewis if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) { 18097e2cc014SDon Lewis fprintf(stderr, "$TMPDIR too long\n"); 18107e2cc014SDon Lewis return; 18117e2cc014SDon Lewis } 18127e2cc014SDon Lewis if (mkdtemp(wrkdir) == NULL) { 18137e2cc014SDon Lewis perror("mkdtemp tmp working dir"); 18147e2cc014SDon Lewis return; 18157e2cc014SDon Lewis } 181630bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname); 181730bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 18187e2cc014SDon Lewis fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 1819945137d9SNate Lawson if (fd < 0) { 1820945137d9SNate Lawson perror("iasl tmp file"); 1821945137d9SNate Lawson return; 1822c62f1cccSMitsuru IWASAKI } 1823bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 1824945137d9SNate Lawson close(fd); 1825945137d9SNate Lawson 1826945137d9SNate Lawson /* Run iasl -d on the temp file */ 18277e2cc014SDon Lewis if ((pid = fork()) == 0) { 1828945137d9SNate Lawson close(STDOUT_FILENO); 1829945137d9SNate Lawson if (vflag == 0) 1830945137d9SNate Lawson close(STDERR_FILENO); 183199065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 1832945137d9SNate Lawson err(1, "exec"); 1833c62f1cccSMitsuru IWASAKI } 18347e2cc014SDon Lewis if (pid > 0) 18357e2cc014SDon Lewis wait(&status); 18367e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 18377e2cc014SDon Lewis perror("unlink"); 18387e2cc014SDon Lewis goto out; 18397e2cc014SDon Lewis } 18407e2cc014SDon Lewis if (pid < 0) { 18417e2cc014SDon Lewis perror("fork"); 18427e2cc014SDon Lewis goto out; 18437e2cc014SDon Lewis } 18447e2cc014SDon Lewis if (status != 0) { 18457e2cc014SDon Lewis fprintf(stderr, "iast exit status = %d\n", status); 18467e2cc014SDon Lewis } 1847945137d9SNate Lawson 1848945137d9SNate Lawson /* Dump iasl's output to stdout */ 184930bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname); 185030bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 185199065116SJung-uk Kim fp = fopen(tmpstr, "r"); 18527e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 18537e2cc014SDon Lewis perror("unlink"); 18547e2cc014SDon Lewis goto out; 18557e2cc014SDon Lewis } 1856945137d9SNate Lawson if (fp == NULL) { 1857945137d9SNate Lawson perror("iasl tmp file (read)"); 18587e2cc014SDon Lewis goto out; 1859945137d9SNate Lawson } 1860945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 1861945137d9SNate Lawson fwrite(buf, 1, len, stdout); 1862945137d9SNate Lawson fclose(fp); 18637e2cc014SDon Lewis 18647e2cc014SDon Lewis out: 18657e2cc014SDon Lewis if (rmdir(wrkdir) < 0) 18667e2cc014SDon Lewis perror("rmdir"); 1867c62f1cccSMitsuru IWASAKI } 1868c62f1cccSMitsuru IWASAKI 1869945137d9SNate Lawson void 1870986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 1871c62f1cccSMitsuru IWASAKI { 1872945137d9SNate Lawson acpi_handle_rsdt(rsdp); 1873c62f1cccSMitsuru IWASAKI } 1874c62f1cccSMitsuru IWASAKI 1875bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 1876986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1877986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 1878c62f1cccSMitsuru IWASAKI { 1879986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1880986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 1881986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 1882a74172abSNate Lawson vm_offset_t addr; 1883a74172abSNate Lawson int entries, i; 1884945137d9SNate Lawson 1885986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 1886986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 1887986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 1888945137d9SNate Lawson for (i = 0; i < entries; i++) { 1889fe1d0c2dSJung-uk Kim if (addr_size == 4) 1890986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 1891fe1d0c2dSJung-uk Kim else 1892986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 1893fe1d0c2dSJung-uk Kim if (addr == 0) 1894fe1d0c2dSJung-uk Kim continue; 1895986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 1896bfa3f012SMarcel Moolenaar if (last != NULL) { 1897bfa3f012SMarcel Moolenaar if (sdt == last) 1898bfa3f012SMarcel Moolenaar last = NULL; 1899bfa3f012SMarcel Moolenaar continue; 1900bfa3f012SMarcel Moolenaar } 1901986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 1902a74172abSNate Lawson continue; 1903986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1904945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 1905945137d9SNate Lawson return (sdt); 1906c62f1cccSMitsuru IWASAKI } 1907c62f1cccSMitsuru IWASAKI 1908945137d9SNate Lawson return (NULL); 1909c62f1cccSMitsuru IWASAKI } 1910c62f1cccSMitsuru IWASAKI 1911986dffafSJohn Baldwin ACPI_TABLE_HEADER * 1912986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 1913c62f1cccSMitsuru IWASAKI { 1914986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 1915c62f1cccSMitsuru IWASAKI 1916986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 1917c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 1918986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 19192e71eb12SNate Lawson else 1920986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 1921986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 1922945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1923945137d9SNate Lawson return (sdt); 1924c62f1cccSMitsuru IWASAKI } 1925