1e1e9a4bfSMitsuru IWASAKI /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4e1e9a4bfSMitsuru IWASAKI * Copyright (c) 1998 Doug Rabson 5e1e9a4bfSMitsuru IWASAKI * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 6ebc22d04SAlexander Motin * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org> 7*f1519a82SKonstantin Belousov * Copyright (c) 2024 The FreeBSD Foundation 8e1e9a4bfSMitsuru IWASAKI * All rights reserved. 9e1e9a4bfSMitsuru IWASAKI * 10*f1519a82SKonstantin Belousov * Portions of this software were developed by Konstantin Belousov 11*f1519a82SKonstantin Belousov * under sponsorship from the FreeBSD Foundation. 12*f1519a82SKonstantin Belousov * 13e1e9a4bfSMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without 14e1e9a4bfSMitsuru IWASAKI * modification, are permitted provided that the following conditions 15e1e9a4bfSMitsuru IWASAKI * are met: 16e1e9a4bfSMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright 17e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer. 18e1e9a4bfSMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright 19e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the 20e1e9a4bfSMitsuru IWASAKI * documentation and/or other materials provided with the distribution. 21e1e9a4bfSMitsuru IWASAKI * 22e1e9a4bfSMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23e1e9a4bfSMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24e1e9a4bfSMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25e1e9a4bfSMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26e1e9a4bfSMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27e1e9a4bfSMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28e1e9a4bfSMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29e1e9a4bfSMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30e1e9a4bfSMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31e1e9a4bfSMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32e1e9a4bfSMitsuru IWASAKI * SUCH DAMAGE. 33e1e9a4bfSMitsuru IWASAKI */ 34e1e9a4bfSMitsuru IWASAKI 35e1e9a4bfSMitsuru IWASAKI #include <sys/param.h> 36a74172abSNate Lawson #include <sys/endian.h> 37e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h> 38945137d9SNate Lawson #include <sys/wait.h> 39e1e9a4bfSMitsuru IWASAKI #include <assert.h> 40e1e9a4bfSMitsuru IWASAKI #include <err.h> 41e1e9a4bfSMitsuru IWASAKI #include <fcntl.h> 4299065116SJung-uk Kim #include <paths.h> 436d789b61SKonstantin Belousov #include <stdbool.h> 44e1e9a4bfSMitsuru IWASAKI #include <stdio.h> 45a0333ad1SJohn Baldwin #include <stdint.h> 4699065116SJung-uk Kim #include <stdlib.h> 47945137d9SNate Lawson #include <string.h> 48e1e9a4bfSMitsuru IWASAKI #include <unistd.h> 49340c0022SEd Maste #include <uuid.h> 50e1e9a4bfSMitsuru IWASAKI 51e1e9a4bfSMitsuru IWASAKI #include "acpidump.h" 52e1e9a4bfSMitsuru IWASAKI 53c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n" 54c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n" 55c62f1cccSMitsuru IWASAKI 56945137d9SNate Lawson static void acpi_print_string(char *s, size_t length); 57986dffafSJohn Baldwin static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas); 58986dffafSJohn Baldwin static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt); 59986dffafSJohn Baldwin static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt); 60945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id); 61986dffafSJohn Baldwin static void acpi_print_cpu_uid(uint32_t uid, char *uid_string); 62986dffafSJohn Baldwin static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags); 63986dffafSJohn Baldwin static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, 64986dffafSJohn Baldwin uint64_t apic_addr); 65986dffafSJohn Baldwin static void acpi_print_mps_flags(uint16_t flags); 66986dffafSJohn Baldwin static void acpi_print_intr(uint32_t intr, uint16_t mps_flags); 67986dffafSJohn Baldwin static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags); 68986dffafSJohn Baldwin static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp); 69986dffafSJohn Baldwin static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp); 70986dffafSJohn Baldwin static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); 71986dffafSJohn Baldwin static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); 72986dffafSJohn Baldwin static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); 7333866658SJohn Baldwin static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); 74ed26c389SScott Long static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp); 755857fba5SBen Widawsky static void acpi_handle_lpit(ACPI_TABLE_HEADER *sdp); 76a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 77a0333ad1SJohn Baldwin uint32_t flags); 78986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); 79986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); 80986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); 81c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); 82340c0022SEd Maste static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit); 83340c0022SEd Maste static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp); 84986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); 85986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); 86986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs); 87986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); 88986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); 89986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); 90986dffafSJohn Baldwin static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); 91986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 92986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)); 93340c0022SEd Maste static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 94340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)); 95c62f1cccSMitsuru IWASAKI 96773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 97a74172abSNate Lawson static int addr_size; 98a74172abSNate Lawson 99c031c93bSTakanori Watanabe /* Strings used in the TCPA table */ 100c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = { 101c031c93bSTakanori Watanabe "PREBOOT Certificate", 102c031c93bSTakanori Watanabe "POST Code", 103c031c93bSTakanori Watanabe "Unused", 104c031c93bSTakanori Watanabe "No Action", 105c031c93bSTakanori Watanabe "Separator", 106c031c93bSTakanori Watanabe "Action", 107c031c93bSTakanori Watanabe "Event Tag", 108c031c93bSTakanori Watanabe "S-CRTM Contents", 109c031c93bSTakanori Watanabe "S-CRTM Version", 110c031c93bSTakanori Watanabe "CPU Microcode", 111c031c93bSTakanori Watanabe "Platform Config Flags", 112c031c93bSTakanori Watanabe "Table of Devices", 113c031c93bSTakanori Watanabe "Compact Hash", 114c031c93bSTakanori Watanabe "IPL", 115c031c93bSTakanori Watanabe "IPL Partition Data", 116c031c93bSTakanori Watanabe "Non-Host Code", 117c031c93bSTakanori Watanabe "Non-Host Config", 118c031c93bSTakanori Watanabe "Non-Host Info" 119c031c93bSTakanori Watanabe }; 120c031c93bSTakanori Watanabe 121c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = { 122c031c93bSTakanori Watanabe "<undefined>", 123c031c93bSTakanori Watanabe "SMBIOS", 124c031c93bSTakanori Watanabe "BIS Certificate", 125c031c93bSTakanori Watanabe "POST BIOS ROM Strings", 126c031c93bSTakanori Watanabe "ESCD", 127c031c93bSTakanori Watanabe "CMOS", 128c031c93bSTakanori Watanabe "NVRAM", 129c031c93bSTakanori Watanabe "Option ROM Execute", 130c031c93bSTakanori Watanabe "Option ROM Configurateion", 131c031c93bSTakanori Watanabe "<undefined>", 132c031c93bSTakanori Watanabe "Option ROM Microcode Update ", 133c031c93bSTakanori Watanabe "S-CRTM Version String", 134c031c93bSTakanori Watanabe "S-CRTM Contents", 135c031c93bSTakanori Watanabe "POST Contents", 136c031c93bSTakanori Watanabe "Table of Devices", 137c031c93bSTakanori Watanabe }; 138c031c93bSTakanori Watanabe 139ec650989SNeel Natu #define PRINTFLAG_END() printflag_end() 140ec650989SNeel Natu 141ec650989SNeel Natu static char pf_sep = '{'; 142ec650989SNeel Natu 143ec650989SNeel Natu static void 144ec650989SNeel Natu printflag_end(void) 145ec650989SNeel Natu { 146ec650989SNeel Natu 147ec650989SNeel Natu if (pf_sep != '{') { 148ec650989SNeel Natu printf("}"); 149ec650989SNeel Natu pf_sep = '{'; 150ec650989SNeel Natu } 151ec650989SNeel Natu printf("\n"); 152ec650989SNeel Natu } 153ec650989SNeel Natu 154ec650989SNeel Natu static void 155ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name) 156ec650989SNeel Natu { 157ec650989SNeel Natu 158ec650989SNeel Natu if (var & mask) { 159ec650989SNeel Natu printf("%c%s", pf_sep, name); 160ec650989SNeel Natu pf_sep = ','; 161ec650989SNeel Natu } 162ec650989SNeel Natu } 163ec650989SNeel Natu 164e1e9a4bfSMitsuru IWASAKI static void 165969a4b8bSKonstantin Belousov printfield(uint64_t var, int lbit, int hbit, const char *name) 166969a4b8bSKonstantin Belousov { 167969a4b8bSKonstantin Belousov uint64_t mask; 168969a4b8bSKonstantin Belousov int len; 169969a4b8bSKonstantin Belousov 170969a4b8bSKonstantin Belousov len = hbit - lbit + 1; 171969a4b8bSKonstantin Belousov mask = ((1 << (len + 1)) - 1) << lbit; 172969a4b8bSKonstantin Belousov printf("%c%s=%#jx", pf_sep, name, (uintmax_t)((var & mask) >> lbit)); 173969a4b8bSKonstantin Belousov pf_sep = ','; 174969a4b8bSKonstantin Belousov } 175969a4b8bSKonstantin Belousov 176969a4b8bSKonstantin Belousov static void 177e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 178e1e9a4bfSMitsuru IWASAKI { 179e1e9a4bfSMitsuru IWASAKI int c; 180e1e9a4bfSMitsuru IWASAKI 181e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 182e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 183e1e9a4bfSMitsuru IWASAKI length--; 184e1e9a4bfSMitsuru IWASAKI 185e1e9a4bfSMitsuru IWASAKI while (length--) { 186e1e9a4bfSMitsuru IWASAKI c = *s++; 187e1e9a4bfSMitsuru IWASAKI putchar(c); 188e1e9a4bfSMitsuru IWASAKI } 189e1e9a4bfSMitsuru IWASAKI } 190e1e9a4bfSMitsuru IWASAKI 191e1e9a4bfSMitsuru IWASAKI static void 192986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) 1938e6a8737SNate Lawson { 194986dffafSJohn Baldwin switch(gas->SpaceId) { 1958e6a8737SNate Lawson case ACPI_GAS_MEMORY: 196ebc22d04SAlexander Motin printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address, 197ebc22d04SAlexander Motin gas->BitOffset, gas->BitWidth); 1988e6a8737SNate Lawson break; 1998e6a8737SNate Lawson case ACPI_GAS_IO: 200ebc22d04SAlexander Motin printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address, 201986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 2028e6a8737SNate Lawson break; 2038e6a8737SNate Lawson case ACPI_GAS_PCI: 204ebc22d04SAlexander Motin printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32), 205986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff), 206ebc22d04SAlexander Motin (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth); 2078e6a8737SNate Lawson break; 2088e6a8737SNate Lawson /* XXX How to handle these below? */ 2098e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 210986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, 211986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 2128e6a8737SNate Lawson break; 2138e6a8737SNate Lawson case ACPI_GAS_SMBUS: 214986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, 215986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth); 2168e6a8737SNate Lawson break; 217986dffafSJohn Baldwin case ACPI_GAS_CMOS: 218986dffafSJohn Baldwin case ACPI_GAS_PCIBAR: 219986dffafSJohn Baldwin case ACPI_GAS_DATATABLE: 2208e6a8737SNate Lawson case ACPI_GAS_FIXED: 2218e6a8737SNate Lawson default: 2227d369c6eSJung-uk Kim printf("0x%016jx (?)", (uintmax_t)gas->Address); 2238e6a8737SNate Lawson break; 2248e6a8737SNate Lawson } 2258e6a8737SNate Lawson } 2268e6a8737SNate Lawson 227c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 228c2962974SNate Lawson static int 2294262ad56SKonstantin Belousov acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt __unused) 230e1e9a4bfSMitsuru IWASAKI { 231c2962974SNate Lawson int fadt_revision; 232e1e9a4bfSMitsuru IWASAKI 233c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 234c83f0f99SNate Lawson if (addr_size == 8) { 235c83f0f99SNate Lawson fadt_revision = 2; 2368e6a8737SNate Lawson 23701593a0fSAndrew Turner #if defined(__i386__) 238773b6454SNate Lawson /* 239c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 240c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 241c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 242c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 243c83f0f99SNate Lawson * version for all subsequent tables. 24401593a0fSAndrew Turner * 24501593a0fSAndrew Turner * The only known ACPI systems this affects are early 24601593a0fSAndrew Turner * implementations on 32-bit x86. Because of this limit the 24701593a0fSAndrew Turner * workaround to i386. 248773b6454SNate Lawson */ 249986dffafSJohn Baldwin if (fadt->Facs != 0 && 250986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs) 251c83f0f99SNate Lawson fadt_revision = 1; 25201593a0fSAndrew Turner #endif 253c2962974SNate Lawson } else 254c83f0f99SNate Lawson fadt_revision = 1; 255c2962974SNate Lawson return (fadt_revision); 256c83f0f99SNate Lawson } 257c2962974SNate Lawson 258c2962974SNate Lawson static void 259986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) 260c2962974SNate Lawson { 261986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp; 262986dffafSJohn Baldwin ACPI_TABLE_FACS *facs; 263986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 264bc711181SAndrew Turner vm_offset_t addr; 265c2962974SNate Lawson int fadt_revision; 266c2962974SNate Lawson 267986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2682177d4e6SNate Lawson acpi_print_fadt(sdp); 269c83f0f99SNate Lawson 270c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 271c83f0f99SNate Lawson if (fadt_revision == 1) 272bc711181SAndrew Turner addr = fadt->Facs; 273773b6454SNate Lawson else 274bc711181SAndrew Turner addr = fadt->XFacs; 275bc711181SAndrew Turner if (addr != 0) { 276bc711181SAndrew Turner facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr); 277bc711181SAndrew Turner 278bc711181SAndrew Turner if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || 279bc711181SAndrew Turner facs->Length < 64) 2808e6a8737SNate Lawson errx(1, "FACS is corrupt"); 2818e6a8737SNate Lawson acpi_print_facs(facs); 282bc711181SAndrew Turner } 2838e6a8737SNate Lawson 284c83f0f99SNate Lawson if (fadt_revision == 1) 285986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 286773b6454SNate Lawson else 287986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 288986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length)) 289945137d9SNate Lawson errx(1, "DSDT is corrupt"); 290945137d9SNate Lawson acpi_print_dsdt(dsdp); 291c62f1cccSMitsuru IWASAKI } 292c62f1cccSMitsuru IWASAKI 293c62f1cccSMitsuru IWASAKI static void 294986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, 295986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *)) 296986dffafSJohn Baldwin { 297986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable; 298986dffafSJohn Baldwin char *end; 299986dffafSJohn Baldwin 300986dffafSJohn Baldwin subtable = first; 301986dffafSJohn Baldwin end = (char *)table + table->Length; 302986dffafSJohn Baldwin while ((char *)subtable < end) { 303986dffafSJohn Baldwin printf("\n"); 304f5d0a8f7SEd Maste if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) { 305f5d0a8f7SEd Maste warnx("invalid subtable length %u", subtable->Length); 306f5d0a8f7SEd Maste return; 307f5d0a8f7SEd Maste } 308986dffafSJohn Baldwin action(subtable); 309986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + 310986dffafSJohn Baldwin subtable->Length); 311986dffafSJohn Baldwin } 312986dffafSJohn Baldwin } 313986dffafSJohn Baldwin 314986dffafSJohn Baldwin static void 315340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first, 316340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *)) 317340c0022SEd Maste { 318340c0022SEd Maste ACPI_NFIT_HEADER *subtable; 319340c0022SEd Maste char *end; 320340c0022SEd Maste 321340c0022SEd Maste subtable = first; 322340c0022SEd Maste end = (char *)table + table->Length; 323340c0022SEd Maste while ((char *)subtable < end) { 324340c0022SEd Maste printf("\n"); 325340c0022SEd Maste if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) { 326340c0022SEd Maste warnx("invalid subtable length %u", subtable->Length); 327340c0022SEd Maste return; 328340c0022SEd Maste } 329340c0022SEd Maste action(subtable); 330340c0022SEd Maste subtable = (ACPI_NFIT_HEADER *)((char *)subtable + 331340c0022SEd Maste subtable->Length); 332340c0022SEd Maste } 333340c0022SEd Maste } 334340c0022SEd Maste 335340c0022SEd Maste static void 3360a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 3370a473124SJohn Baldwin { 3380a473124SJohn Baldwin 3390a473124SJohn Baldwin printf("\tACPI CPU="); 3400a473124SJohn Baldwin if (cpu_id == 0xff) 3410a473124SJohn Baldwin printf("ALL\n"); 3420a473124SJohn Baldwin else 3430a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 3440a473124SJohn Baldwin } 3450a473124SJohn Baldwin 3460a473124SJohn Baldwin static void 347986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string) 3480a473124SJohn Baldwin { 349986dffafSJohn Baldwin 350986dffafSJohn Baldwin printf("\tUID=%d", uid); 351986dffafSJohn Baldwin if (uid_string != NULL) 352986dffafSJohn Baldwin printf(" (%s)", uid_string); 353986dffafSJohn Baldwin printf("\n"); 354986dffafSJohn Baldwin } 355986dffafSJohn Baldwin 356986dffafSJohn Baldwin static void 357986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags) 358986dffafSJohn Baldwin { 359986dffafSJohn Baldwin 3600a473124SJohn Baldwin printf("\tFlags={"); 361986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED) 3620a473124SJohn Baldwin printf("ENABLED"); 3630a473124SJohn Baldwin else 3640a473124SJohn Baldwin printf("DISABLED"); 3650a473124SJohn Baldwin printf("}\n"); 366986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3670a473124SJohn Baldwin } 3680a473124SJohn Baldwin 3690a473124SJohn Baldwin static void 370986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) 3710a473124SJohn Baldwin { 372986dffafSJohn Baldwin 373986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 3740a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 375986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); 3760a473124SJohn Baldwin } 3770a473124SJohn Baldwin 3780a473124SJohn Baldwin static void 379986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags) 3800a473124SJohn Baldwin { 3810a473124SJohn Baldwin 3820a473124SJohn Baldwin printf("\tFlags={Polarity="); 383986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) { 384986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS: 3850a473124SJohn Baldwin printf("conforming"); 3860a473124SJohn Baldwin break; 387986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH: 3880a473124SJohn Baldwin printf("active-hi"); 3890a473124SJohn Baldwin break; 390986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW: 3910a473124SJohn Baldwin printf("active-lo"); 3920a473124SJohn Baldwin break; 3930a473124SJohn Baldwin default: 394986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); 3950a473124SJohn Baldwin break; 3960a473124SJohn Baldwin } 3970a473124SJohn Baldwin printf(", Trigger="); 398986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) { 399986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS: 4000a473124SJohn Baldwin printf("conforming"); 4010a473124SJohn Baldwin break; 402986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE: 4030a473124SJohn Baldwin printf("edge"); 4040a473124SJohn Baldwin break; 405986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL: 4060a473124SJohn Baldwin printf("level"); 4070a473124SJohn Baldwin break; 4080a473124SJohn Baldwin default: 409986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); 4100a473124SJohn Baldwin } 4110a473124SJohn Baldwin printf("}\n"); 4120a473124SJohn Baldwin } 4130a473124SJohn Baldwin 4140a473124SJohn Baldwin static void 4152b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags) 4162b2b1f42SAndrew Turner { 4172b2b1f42SAndrew Turner 4182b2b1f42SAndrew Turner printf("\tFlags={Performance intr="); 4192b2b1f42SAndrew Turner if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE) 4202b2b1f42SAndrew Turner printf("edge"); 4212b2b1f42SAndrew Turner else 4222b2b1f42SAndrew Turner printf("level"); 4232b2b1f42SAndrew Turner printf(", VGIC intr="); 4242b2b1f42SAndrew Turner if (flags & ACPI_MADT_VGIC_IRQ_MODE) 4252b2b1f42SAndrew Turner printf("edge"); 4262b2b1f42SAndrew Turner else 4272b2b1f42SAndrew Turner printf("level"); 4282b2b1f42SAndrew Turner printf("}\n"); 4292b2b1f42SAndrew Turner } 4302b2b1f42SAndrew Turner 4312b2b1f42SAndrew Turner static void 432986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags) 4330a473124SJohn Baldwin { 4340a473124SJohn Baldwin 435986dffafSJohn Baldwin printf("\tINTR=%d\n", intr); 436986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags); 437986dffafSJohn Baldwin } 438986dffafSJohn Baldwin 439986dffafSJohn Baldwin static void 440986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags) 441986dffafSJohn Baldwin { 442986dffafSJohn Baldwin 443986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint); 4440a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 4450a473124SJohn Baldwin } 4460a473124SJohn Baldwin 44727941afaSEd Maste static const char *apic_types[] = { 44827941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC", 44927941afaSEd Maste [ACPI_MADT_TYPE_IO_APIC] = "IO APIC", 45027941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override", 45127941afaSEd Maste [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI", 45227941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI", 45327941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override", 45427941afaSEd Maste [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC", 45527941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC", 45627941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt", 45727941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC", 45827941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI", 45927941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure", 46027941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure", 46127941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame", 46227941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure", 46327941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure" 46427941afaSEd Maste }; 46527941afaSEd Maste 466bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", 4670a473124SJohn Baldwin "Corrected Platform Error" }; 4680a473124SJohn Baldwin 4690a473124SJohn Baldwin static void 470986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) 4710a473124SJohn Baldwin { 472986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic; 473986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic; 474986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over; 475986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi; 476986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; 477986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; 478986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic; 479986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic; 480986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc; 481986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic; 482986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; 4832b2b1f42SAndrew Turner ACPI_MADT_GENERIC_INTERRUPT *gicc; 4842b2b1f42SAndrew Turner ACPI_MADT_GENERIC_DISTRIBUTOR *gicd; 4852b2b1f42SAndrew Turner ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr; 4862b2b1f42SAndrew Turner ACPI_MADT_GENERIC_TRANSLATOR *gict; 4870a473124SJohn Baldwin 488c86932b6SMarcelo Araujo if (mp->Type < nitems(apic_types)) 489986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]); 490a0333ad1SJohn Baldwin else 491986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type); 492986dffafSJohn Baldwin switch (mp->Type) { 493986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC: 494986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp; 495986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId); 496986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags); 4970a473124SJohn Baldwin break; 498986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC: 499986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp; 500986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, 501986dffafSJohn Baldwin ioapic->Address); 5020a473124SJohn Baldwin break; 503986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 504986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; 505986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus); 506986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq); 507986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags); 5080a473124SJohn Baldwin break; 509986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE: 510986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp; 511986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); 5120a473124SJohn Baldwin break; 513986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 514986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; 515986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId); 516986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); 5170a473124SJohn Baldwin break; 518986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 519986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; 520945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 521986dffafSJohn Baldwin (uintmax_t)lapic_over->Address); 5220a473124SJohn Baldwin break; 523986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC: 524986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp; 525986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, 526986dffafSJohn Baldwin iosapic->Address); 5270a473124SJohn Baldwin break; 528986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC: 529986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; 530986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId); 531986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); 532986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); 533986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) 534986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); 5350a473124SJohn Baldwin break; 536986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 537986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; 538c86932b6SMarcelo Araujo if (isrc->Type < nitems(platform_int_types)) 539986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]); 540986dffafSJohn Baldwin else 541986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type); 542986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id); 543986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); 544986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); 545986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); 546986dffafSJohn Baldwin break; 547986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC: 548986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; 549986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL); 550986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); 551986dffafSJohn Baldwin break; 552986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 553986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; 554986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); 555986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); 5560a473124SJohn Baldwin break; 5572b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 5582b2b1f42SAndrew Turner gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp; 5592b2b1f42SAndrew Turner acpi_print_cpu_uid(gicc->Uid, NULL); 5602b2b1f42SAndrew Turner printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber); 5612b2b1f42SAndrew Turner acpi_print_gicc_flags(gicc->Flags); 5622b2b1f42SAndrew Turner printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion); 5632b2b1f42SAndrew Turner printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt); 5642b2b1f42SAndrew Turner printf("\tParked ADDR=%016jx\n", 5652b2b1f42SAndrew Turner (uintmax_t)gicc->ParkedAddress); 5662b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress); 5672b2b1f42SAndrew Turner printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress); 5682b2b1f42SAndrew Turner printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress); 5692b2b1f42SAndrew Turner printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt); 5702b2b1f42SAndrew Turner printf("\tGICR ADDR=%016jx\n", 5712b2b1f42SAndrew Turner (uintmax_t)gicc->GicrBaseAddress); 5722b2b1f42SAndrew Turner printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr); 5730b4302aaSGordon Bergling printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass); 574c363da4aSAndrew Turner printf("\tSPE INTR=%d\n", gicc->SpeInterrupt); 5752b2b1f42SAndrew Turner break; 5762b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 5772b2b1f42SAndrew Turner gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp; 5782b2b1f42SAndrew Turner printf("\tGIC ID=%d\n", (u_int)gicd->GicId); 5792b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress); 5802b2b1f42SAndrew Turner printf("\tVector Base=%d\n", gicd->GlobalIrqBase); 5812b2b1f42SAndrew Turner printf("\tGIC VERSION=%d\n", (u_int)gicd->Version); 5822b2b1f42SAndrew Turner break; 5832b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 5842b2b1f42SAndrew Turner gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp; 5852b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress); 5862b2b1f42SAndrew Turner printf("\tLength=%08x\n", gicr->Length); 5872b2b1f42SAndrew Turner break; 5882b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 5892b2b1f42SAndrew Turner gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp; 5902b2b1f42SAndrew Turner printf("\tGIC ITS ID=%d\n", gict->TranslationId); 5912b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress); 5922b2b1f42SAndrew Turner break; 5930a473124SJohn Baldwin } 5940a473124SJohn Baldwin } 5950a473124SJohn Baldwin 5960a473124SJohn Baldwin static void 597986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp) 5980a473124SJohn Baldwin { 599986dffafSJohn Baldwin ACPI_TABLE_MADT *madt; 6000a473124SJohn Baldwin 601773b6454SNate Lawson printf(BEGIN_COMMENT); 602773b6454SNate Lawson acpi_print_sdt(sdp); 603986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp; 604986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); 6050a473124SJohn Baldwin printf("\tFlags={"); 606986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT) 6070a473124SJohn Baldwin printf("PC-AT"); 6080a473124SJohn Baldwin printf("}\n"); 609986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); 6100a473124SJohn Baldwin printf(END_COMMENT); 6110a473124SJohn Baldwin } 6120a473124SJohn Baldwin 6130a473124SJohn Baldwin static void 614ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp) 615ebc22d04SAlexander Motin { 616ebc22d04SAlexander Motin ACPI_TABLE_BERT *bert; 617ebc22d04SAlexander Motin 618ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 619ebc22d04SAlexander Motin acpi_print_sdt(sdp); 620ebc22d04SAlexander Motin bert = (ACPI_TABLE_BERT *)sdp; 621ebc22d04SAlexander Motin printf("\tRegionLength=%d\n", bert->RegionLength); 622ebc22d04SAlexander Motin printf("\tAddress=0x%016jx\n", bert->Address); 623ebc22d04SAlexander Motin printf(END_COMMENT); 624ebc22d04SAlexander Motin } 625ebc22d04SAlexander Motin 626ebc22d04SAlexander Motin static void 627ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w) 628ebc22d04SAlexander Motin { 629ebc22d04SAlexander Motin 630ebc22d04SAlexander Motin printf("\n\tAction=%d\n", w->Action); 631ebc22d04SAlexander Motin printf("\tInstruction=%d\n", w->Instruction); 632ebc22d04SAlexander Motin printf("\tFlags=%02x\n", w->Flags); 633ebc22d04SAlexander Motin printf("\tRegisterRegion="); 634ebc22d04SAlexander Motin acpi_print_gas(&w->RegisterRegion); 635ebc22d04SAlexander Motin printf("\n\tValue=0x%016jx\n", w->Value); 636ebc22d04SAlexander Motin printf("\tMask=0x%016jx\n", w->Mask); 637ebc22d04SAlexander Motin } 638ebc22d04SAlexander Motin 639ebc22d04SAlexander Motin static void 640ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp) 641ebc22d04SAlexander Motin { 642ebc22d04SAlexander Motin ACPI_TABLE_EINJ *einj; 643ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w; 644ebc22d04SAlexander Motin u_int i; 645ebc22d04SAlexander Motin 646ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 647ebc22d04SAlexander Motin acpi_print_sdt(sdp); 648ebc22d04SAlexander Motin einj = (ACPI_TABLE_EINJ *)sdp; 649ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", einj->HeaderLength); 650ebc22d04SAlexander Motin printf("\tFlags=0x%02x\n", einj->Flags); 651ebc22d04SAlexander Motin printf("\tEntries=%d\n", einj->Entries); 652ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(einj + 1); 653ebc22d04SAlexander Motin for (i = 0; i < MIN(einj->Entries, (sdp->Length - 654ebc22d04SAlexander Motin sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++) 655ebc22d04SAlexander Motin acpi_print_whea(w + i); 656ebc22d04SAlexander Motin printf(END_COMMENT); 657ebc22d04SAlexander Motin } 658ebc22d04SAlexander Motin 659ebc22d04SAlexander Motin static void 660ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp) 661ebc22d04SAlexander Motin { 662ebc22d04SAlexander Motin ACPI_TABLE_ERST *erst; 663ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w; 664ebc22d04SAlexander Motin u_int i; 665ebc22d04SAlexander Motin 666ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 667ebc22d04SAlexander Motin acpi_print_sdt(sdp); 668ebc22d04SAlexander Motin erst = (ACPI_TABLE_ERST *)sdp; 669ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", erst->HeaderLength); 670ebc22d04SAlexander Motin printf("\tEntries=%d\n", erst->Entries); 671ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(erst + 1); 672ebc22d04SAlexander Motin for (i = 0; i < MIN(erst->Entries, (sdp->Length - 673ebc22d04SAlexander Motin sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++) 674ebc22d04SAlexander Motin acpi_print_whea(w + i); 675ebc22d04SAlexander Motin printf(END_COMMENT); 676ebc22d04SAlexander Motin } 677ebc22d04SAlexander Motin 678ebc22d04SAlexander Motin static void 679ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b) 680ebc22d04SAlexander Motin { 681ebc22d04SAlexander Motin 682ebc22d04SAlexander Motin printf("\tBank:\n"); 683ebc22d04SAlexander Motin printf("\t\tBankNumber=%d\n", b->BankNumber); 684ebc22d04SAlexander Motin printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit); 685ebc22d04SAlexander Motin printf("\t\tStatusFormat=%d\n", b->StatusFormat); 686ebc22d04SAlexander Motin printf("\t\tControlRegister=%x\n", b->ControlRegister); 687ebc22d04SAlexander Motin printf("\t\tControlData=%jx\n", b->ControlData); 688ebc22d04SAlexander Motin printf("\t\tStatusRegister=%x\n", b->StatusRegister); 689ebc22d04SAlexander Motin printf("\t\tAddressRegister=%x\n", b->AddressRegister); 690ebc22d04SAlexander Motin printf("\t\tMiscRegister=%x\n", b->MiscRegister); 691ebc22d04SAlexander Motin } 692ebc22d04SAlexander Motin 693ebc22d04SAlexander Motin static void 694ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n) 695ebc22d04SAlexander Motin { 696ebc22d04SAlexander Motin 697ebc22d04SAlexander Motin printf("\t\tType=%d\n", n->Type); 698ebc22d04SAlexander Motin printf("\t\tLength=%d\n", n->Length); 699ebc22d04SAlexander Motin printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable); 700ebc22d04SAlexander Motin printf("\t\tPollInterval=%d\n", n->PollInterval); 701ebc22d04SAlexander Motin printf("\t\tVector=%d\n", n->Vector); 702ebc22d04SAlexander Motin printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue); 703ebc22d04SAlexander Motin printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow); 704ebc22d04SAlexander Motin printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue); 705ebc22d04SAlexander Motin printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow); 706ebc22d04SAlexander Motin } 707ebc22d04SAlexander Motin 708ebc22d04SAlexander Motin static void 709ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a) 710ebc22d04SAlexander Motin { 711ebc22d04SAlexander Motin 712ebc22d04SAlexander Motin printf("\tFlags=%02x\n", a->Flags); 713ebc22d04SAlexander Motin printf("\tEnabled=%d\n", a->Enabled); 714ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate); 715ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord); 716ebc22d04SAlexander Motin printf("\tBus=%d\n", a->Bus); 717ebc22d04SAlexander Motin printf("\tDevice=%d\n", a->Device); 718ebc22d04SAlexander Motin printf("\tFunction=%d\n", a->Function); 719ebc22d04SAlexander Motin printf("\tDeviceControl=%d\n", a->DeviceControl); 720ebc22d04SAlexander Motin printf("\tUncorrectableMask=%d\n", a->UncorrectableMask); 721ebc22d04SAlexander Motin printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity); 722ebc22d04SAlexander Motin printf("\tCorrectableMask=%d\n", a->CorrectableMask); 723ebc22d04SAlexander Motin printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities); 724ebc22d04SAlexander Motin } 725ebc22d04SAlexander Motin 726ebc22d04SAlexander Motin static int 727ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining) 728ebc22d04SAlexander Motin { 729ebc22d04SAlexander Motin ACPI_HEST_HEADER *hdr = addr; 730ebc22d04SAlexander Motin int i; 731ebc22d04SAlexander Motin 732ebc22d04SAlexander Motin if (remaining < (int)sizeof(ACPI_HEST_HEADER)) 733ebc22d04SAlexander Motin return (-1); 734ebc22d04SAlexander Motin 735ebc22d04SAlexander Motin printf("\n\tType=%d\n", hdr->Type); 736ebc22d04SAlexander Motin printf("\tSourceId=%d\n", hdr->SourceId); 737ebc22d04SAlexander Motin switch (hdr->Type) { 738ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CHECK: { 739ebc22d04SAlexander Motin ACPI_HEST_IA_MACHINE_CHECK *s = addr; 740ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 741ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 742ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 743ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 744ebc22d04SAlexander Motin printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData); 745ebc22d04SAlexander Motin printf("\tGlobalControlData=%jd\n", s->GlobalControlData); 746ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 747ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 748ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 749ebc22d04SAlexander Motin (s + 1) + i); 750ebc22d04SAlexander Motin } 751ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 752ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 753ebc22d04SAlexander Motin } 754ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: { 755ebc22d04SAlexander Motin ACPI_HEST_IA_CORRECTED *s = addr; 756ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 757ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 758ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 759ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 760ebc22d04SAlexander Motin printf("\tNotify:\n"); 761ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 762ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 763ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 764ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 765ebc22d04SAlexander Motin (s + 1) + i); 766ebc22d04SAlexander Motin } 767ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 768ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 769ebc22d04SAlexander Motin } 770ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_NMI: { 771ebc22d04SAlexander Motin ACPI_HEST_IA_NMI *s = addr; 772ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 773ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 774ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 775ebc22d04SAlexander Motin return (sizeof(*s)); 776ebc22d04SAlexander Motin } 777ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ROOT_PORT: { 778ebc22d04SAlexander Motin ACPI_HEST_AER_ROOT *s = addr; 779ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 780ebc22d04SAlexander Motin printf("\tRootErrorCommand=%d\n", s->RootErrorCommand); 781ebc22d04SAlexander Motin return (sizeof(*s)); 782ebc22d04SAlexander Motin } 783ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ENDPOINT: { 784ebc22d04SAlexander Motin ACPI_HEST_AER *s = addr; 785ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 786ebc22d04SAlexander Motin return (sizeof(*s)); 787ebc22d04SAlexander Motin } 788ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_BRIDGE: { 789ebc22d04SAlexander Motin ACPI_HEST_AER_BRIDGE *s = addr; 790ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer); 791ebc22d04SAlexander Motin printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2); 792ebc22d04SAlexander Motin printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2); 793ebc22d04SAlexander Motin printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2); 794ebc22d04SAlexander Motin return (sizeof(*s)); 795ebc22d04SAlexander Motin } 796ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR: { 797ebc22d04SAlexander Motin ACPI_HEST_GENERIC *s = addr; 798ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId); 799ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 800ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 801ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 802ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 803ebc22d04SAlexander Motin printf("\tErrorStatusAddress="); 804ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress); 805ebc22d04SAlexander Motin printf("\n"); 806ebc22d04SAlexander Motin printf("\tNotify:\n"); 807ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 808ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength); 809ebc22d04SAlexander Motin return (sizeof(*s)); 810ebc22d04SAlexander Motin } 811ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR_V2: { 812ebc22d04SAlexander Motin ACPI_HEST_GENERIC_V2 *s = addr; 813ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId); 814ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 815ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 816ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 817ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength); 818ebc22d04SAlexander Motin printf("\tErrorStatusAddress="); 819ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress); 820ebc22d04SAlexander Motin printf("\n"); 821ebc22d04SAlexander Motin printf("\tNotify:\n"); 822ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 823ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength); 824ebc22d04SAlexander Motin printf("\tReadAckRegister="); 825ebc22d04SAlexander Motin acpi_print_gas(&s->ReadAckRegister); 826ebc22d04SAlexander Motin printf("\n"); 827ebc22d04SAlexander Motin printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve); 828ebc22d04SAlexander Motin printf("\tReadAckWrite=%jd\n", s->ReadAckWrite); 829ebc22d04SAlexander Motin return (sizeof(*s)); 830ebc22d04SAlexander Motin } 831ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: { 832ebc22d04SAlexander Motin ACPI_HEST_IA_DEFERRED_CHECK *s = addr; 833ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags); 834ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled); 835ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate); 836ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord); 837ebc22d04SAlexander Motin printf("\tNotify:\n"); 838ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify); 839ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks); 840ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) { 841ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *) 842ebc22d04SAlexander Motin (s + 1) + i); 843ebc22d04SAlexander Motin } 844ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks * 845ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK)); 846ebc22d04SAlexander Motin } 847ebc22d04SAlexander Motin default: 848ebc22d04SAlexander Motin return (-1); 849ebc22d04SAlexander Motin } 850ebc22d04SAlexander Motin } 851ebc22d04SAlexander Motin 852ebc22d04SAlexander Motin static void 853ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp) 854ebc22d04SAlexander Motin { 855ebc22d04SAlexander Motin char *cp; 856ebc22d04SAlexander Motin int remaining, consumed; 857ebc22d04SAlexander Motin ACPI_TABLE_HEST *hest; 858ebc22d04SAlexander Motin 859ebc22d04SAlexander Motin printf(BEGIN_COMMENT); 860ebc22d04SAlexander Motin acpi_print_sdt(sdp); 861ebc22d04SAlexander Motin hest = (ACPI_TABLE_HEST *)sdp; 862ebc22d04SAlexander Motin printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount); 863ebc22d04SAlexander Motin 864ebc22d04SAlexander Motin remaining = sdp->Length - sizeof(ACPI_TABLE_HEST); 865ebc22d04SAlexander Motin while (remaining > 0) { 866ebc22d04SAlexander Motin cp = (char *)sdp + sdp->Length - remaining; 867ebc22d04SAlexander Motin consumed = acpi_handle_hest_structure(cp, remaining); 868ebc22d04SAlexander Motin if (consumed <= 0) 869ebc22d04SAlexander Motin break; 870ebc22d04SAlexander Motin else 871ebc22d04SAlexander Motin remaining -= consumed; 872ebc22d04SAlexander Motin } 873ebc22d04SAlexander Motin printf(END_COMMENT); 874ebc22d04SAlexander Motin } 875ebc22d04SAlexander Motin 876ebc22d04SAlexander Motin static void 877986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) 87879d7565cSPeter Wemm { 879986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet; 88079d7565cSPeter Wemm 881773b6454SNate Lawson printf(BEGIN_COMMENT); 882773b6454SNate Lawson acpi_print_sdt(sdp); 883986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp; 884986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence); 88587f9f09aSTakanori Watanabe printf("\tADDR="); 886986dffafSJohn Baldwin acpi_print_gas(&hpet->Address); 887ebc22d04SAlexander Motin printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); 888986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> 889986dffafSJohn Baldwin 8); 890986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? 891986dffafSJohn Baldwin 1 : 0); 89279d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 893986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) 89479d7565cSPeter Wemm printf("TRUE}\n"); 89579d7565cSPeter Wemm else 89679d7565cSPeter Wemm printf("FALSE}\n"); 897986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); 898986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick); 8999785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags); 90079d7565cSPeter Wemm printf(END_COMMENT); 90179d7565cSPeter Wemm } 90279d7565cSPeter Wemm 90379d7565cSPeter Wemm static void 904986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) 90555d7ff9eSNate Lawson { 906986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt; 90755d7ff9eSNate Lawson 90855d7ff9eSNate Lawson printf(BEGIN_COMMENT); 90955d7ff9eSNate Lawson acpi_print_sdt(sdp); 910986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp; 91155d7ff9eSNate Lawson printf("\tEC_CONTROL="); 912986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control); 91355d7ff9eSNate Lawson printf("\n\tEC_DATA="); 914986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data); 915986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid); 916986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe); 917986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id); 91855d7ff9eSNate Lawson printf(END_COMMENT); 91955d7ff9eSNate Lawson } 92055d7ff9eSNate Lawson 92155d7ff9eSNate Lawson static void 922986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) 923a47e681bSScott Long { 924986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg; 925986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc; 926986dffafSJohn Baldwin u_int i, entries; 927a47e681bSScott Long 928a47e681bSScott Long printf(BEGIN_COMMENT); 929a47e681bSScott Long acpi_print_sdt(sdp); 930986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp; 931986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / 932986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION); 933986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); 934986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) { 935a47e681bSScott Long printf("\n"); 9360c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address); 937986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment); 938986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber); 939986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber); 940a47e681bSScott Long } 941a47e681bSScott Long printf(END_COMMENT); 942a47e681bSScott Long } 943a47e681bSScott Long 944a47e681bSScott Long static void 94533866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp) 94633866658SJohn Baldwin { 94733866658SJohn Baldwin ACPI_TABLE_SLIT *slit; 94833866658SJohn Baldwin UINT64 i, j; 94933866658SJohn Baldwin 95033866658SJohn Baldwin printf(BEGIN_COMMENT); 95133866658SJohn Baldwin acpi_print_sdt(sdp); 95233866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp; 9530c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount); 95433866658SJohn Baldwin printf("\n\t "); 95533866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 9560c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i); 95733866658SJohn Baldwin printf("\n\t +"); 95833866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) 95933866658SJohn Baldwin printf("----"); 96033866658SJohn Baldwin printf("\n"); 96133866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) { 9620c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i); 96333866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++) 96433866658SJohn Baldwin printf(" %3d", 96533866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]); 96633866658SJohn Baldwin printf("\n"); 96733866658SJohn Baldwin } 96833866658SJohn Baldwin printf(END_COMMENT); 96933866658SJohn Baldwin } 97033866658SJohn Baldwin 97133866658SJohn Baldwin static void 972ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp) 973ed26c389SScott Long { 974ed26c389SScott Long ACPI_TABLE_WDDT *wddt; 975ed26c389SScott Long 976ed26c389SScott Long printf(BEGIN_COMMENT); 977ed26c389SScott Long acpi_print_sdt(sdp); 978ed26c389SScott Long wddt = (ACPI_TABLE_WDDT *)sdp; 979ed26c389SScott Long printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n", 980ed26c389SScott Long wddt->SpecVersion, wddt->TableVersion); 981ed26c389SScott Long printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId); 982ed26c389SScott Long acpi_print_gas(&wddt->Address); 983ed26c389SScott Long printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n", 984ed26c389SScott Long wddt->MaxCount, wddt->MinCount, wddt->Period); 985ed26c389SScott Long 986ed26c389SScott Long #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag) 987ed26c389SScott Long printf("\tStatus="); 988ed26c389SScott Long PRINTFLAG(wddt->Status, AVAILABLE); 989ed26c389SScott Long PRINTFLAG(wddt->Status, ACTIVE); 990ed26c389SScott Long PRINTFLAG(wddt->Status, TCO_OS_OWNED); 991ed26c389SScott Long PRINTFLAG(wddt->Status, USER_RESET); 992ed26c389SScott Long PRINTFLAG(wddt->Status, WDT_RESET); 993ed26c389SScott Long PRINTFLAG(wddt->Status, POWER_FAIL); 994ed26c389SScott Long PRINTFLAG(wddt->Status, UNKNOWN_RESET); 995ed26c389SScott Long PRINTFLAG_END(); 996ed26c389SScott Long printf("\tCapability="); 997ed26c389SScott Long PRINTFLAG(wddt->Capability, AUTO_RESET); 998ed26c389SScott Long PRINTFLAG(wddt->Capability, ALERT_SUPPORT); 999ed26c389SScott Long PRINTFLAG_END(); 1000ed26c389SScott Long #undef PRINTFLAG 1001ed26c389SScott Long 1002ed26c389SScott Long printf(END_COMMENT); 1003ed26c389SScott Long } 1004ed26c389SScott Long 1005ed26c389SScott Long static void 10065857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl) 10075857fba5SBen Widawsky { 10085857fba5SBen Widawsky printf("\tEntryTrigger="); 10095857fba5SBen Widawsky acpi_print_gas(&nl->EntryTrigger); 1010ebc22d04SAlexander Motin printf("\n\tResidency=%u\n", nl->Residency); 10115857fba5SBen Widawsky printf("\tLatency=%u\n", nl->Latency); 10125857fba5SBen Widawsky if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER) 10135857fba5SBen Widawsky printf("\tResidencyCounter=Not Present"); 10145857fba5SBen Widawsky else { 10155857fba5SBen Widawsky printf("\tResidencyCounter="); 10165857fba5SBen Widawsky acpi_print_gas(&nl->ResidencyCounter); 1017ebc22d04SAlexander Motin printf("\n"); 10185857fba5SBen Widawsky } 10195857fba5SBen Widawsky if (nl->CounterFrequency) 10205857fba5SBen Widawsky printf("\tCounterFrequency=%ju\n", nl->CounterFrequency); 10215857fba5SBen Widawsky else 10225857fba5SBen Widawsky printf("\tCounterFrequency=TSC\n"); 10235857fba5SBen Widawsky } 10245857fba5SBen Widawsky 10255857fba5SBen Widawsky static void 10265857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit) 10275857fba5SBen Widawsky { 10285857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE) 10295857fba5SBen Widawsky printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n"); 10305857fba5SBen Widawsky else 10315857fba5SBen Widawsky warnx("unknown LPIT type %u", lpit->Type); 10325857fba5SBen Widawsky 10335857fba5SBen Widawsky printf("\tLength=%u\n", lpit->Length); 10345857fba5SBen Widawsky printf("\tUniqueId=0x%04x\n", lpit->UniqueId); 10355857fba5SBen Widawsky #define PRINTFLAG(var, flag) printflag((var), ACPI_LPIT_## flag, #flag) 10365857fba5SBen Widawsky printf("\tFlags="); 10375857fba5SBen Widawsky PRINTFLAG(lpit->Flags, STATE_DISABLED); 10385857fba5SBen Widawsky PRINTFLAG_END(); 10395857fba5SBen Widawsky #undef PRINTFLAG 10405857fba5SBen Widawsky 10415857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE) 10425857fba5SBen Widawsky return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit); 10435857fba5SBen Widawsky } 10445857fba5SBen Widawsky 10455857fba5SBen Widawsky static void 10465857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first, 10475857fba5SBen Widawsky void (*action)(ACPI_LPIT_HEADER *)) 10485857fba5SBen Widawsky { 10495857fba5SBen Widawsky ACPI_LPIT_HEADER *subtable; 10505857fba5SBen Widawsky char *end; 10515857fba5SBen Widawsky 10525857fba5SBen Widawsky subtable = first; 10535857fba5SBen Widawsky end = (char *)table + table->Length; 10545857fba5SBen Widawsky while ((char *)subtable < end) { 10555857fba5SBen Widawsky printf("\n"); 10565857fba5SBen Widawsky if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) { 10575857fba5SBen Widawsky warnx("invalid subtable length %u", subtable->Length); 10585857fba5SBen Widawsky return; 10595857fba5SBen Widawsky } 10605857fba5SBen Widawsky action(subtable); 10615857fba5SBen Widawsky subtable = (ACPI_LPIT_HEADER *)((char *)subtable + 10625857fba5SBen Widawsky subtable->Length); 10635857fba5SBen Widawsky } 10645857fba5SBen Widawsky } 10655857fba5SBen Widawsky 10665857fba5SBen Widawsky static void 10675857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp) 10685857fba5SBen Widawsky { 10695857fba5SBen Widawsky ACPI_TABLE_LPIT *lpit; 10705857fba5SBen Widawsky 10715857fba5SBen Widawsky printf(BEGIN_COMMENT); 10725857fba5SBen Widawsky acpi_print_sdt(sdp); 10735857fba5SBen Widawsky lpit = (ACPI_TABLE_LPIT *)sdp; 10745857fba5SBen Widawsky acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit); 10755857fba5SBen Widawsky 10765857fba5SBen Widawsky printf(END_COMMENT); 10775857fba5SBen Widawsky } 10785857fba5SBen Widawsky 10795857fba5SBen Widawsky static void 1080a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 1081a0333ad1SJohn Baldwin uint32_t flags) 1082a0333ad1SJohn Baldwin { 1083a0333ad1SJohn Baldwin 1084a0333ad1SJohn Baldwin printf("\tFlags={"); 1085a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 1086a0333ad1SJohn Baldwin printf("ENABLED"); 1087a0333ad1SJohn Baldwin else 1088a0333ad1SJohn Baldwin printf("DISABLED"); 1089a0333ad1SJohn Baldwin printf("}\n"); 1090a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 1091a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 1092a0333ad1SJohn Baldwin } 1093a0333ad1SJohn Baldwin 1094c031c93bSTakanori Watanabe static char * 1095c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event) 1096c031c93bSTakanori Watanabe { 1097c031c93bSTakanori Watanabe struct TCPApc_event *pc_event; 1098c031c93bSTakanori Watanabe char *eventname = NULL; 1099c031c93bSTakanori Watanabe 1100c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1); 1101c031c93bSTakanori Watanabe 1102c031c93bSTakanori Watanabe switch(event->event_type) { 1103c031c93bSTakanori Watanabe case PREBOOT: 1104c031c93bSTakanori Watanabe case POST_CODE: 1105c031c93bSTakanori Watanabe case UNUSED: 1106c031c93bSTakanori Watanabe case NO_ACTION: 1107c031c93bSTakanori Watanabe case SEPARATOR: 1108c031c93bSTakanori Watanabe case SCRTM_CONTENTS: 1109c031c93bSTakanori Watanabe case SCRTM_VERSION: 1110c031c93bSTakanori Watanabe case CPU_MICROCODE: 1111c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS: 1112c031c93bSTakanori Watanabe case TABLE_OF_DEVICES: 1113c031c93bSTakanori Watanabe case COMPACT_HASH: 1114c031c93bSTakanori Watanabe case IPL: 1115c031c93bSTakanori Watanabe case IPL_PARTITION_DATA: 1116c031c93bSTakanori Watanabe case NONHOST_CODE: 1117c031c93bSTakanori Watanabe case NONHOST_CONFIG: 1118c031c93bSTakanori Watanabe case NONHOST_INFO: 1119c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 1120c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]); 1121c031c93bSTakanori Watanabe break; 1122c031c93bSTakanori Watanabe 1123c031c93bSTakanori Watanabe case ACTION: 1124c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char)); 1125c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size); 1126c031c93bSTakanori Watanabe break; 1127c031c93bSTakanori Watanabe 1128c031c93bSTakanori Watanabe case EVENT_TAG: 1129c031c93bSTakanori Watanabe switch (pc_event->event_id) { 1130c031c93bSTakanori Watanabe case SMBIOS: 1131c031c93bSTakanori Watanabe case BIS_CERT: 1132c031c93bSTakanori Watanabe case CMOS: 1133c031c93bSTakanori Watanabe case NVRAM: 1134c031c93bSTakanori Watanabe case OPTION_ROM_EXEC: 1135c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG: 1136c031c93bSTakanori Watanabe case S_CRTM_VERSION: 1137c031c93bSTakanori Watanabe case POST_BIOS_ROM: 1138c031c93bSTakanori Watanabe case ESCD: 1139c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE: 1140c031c93bSTakanori Watanabe case S_CRTM_CONTENTS: 1141c031c93bSTakanori Watanabe case POST_CONTENTS: 1142c031c93bSTakanori Watanabe asprintf(&eventname, "%s", 1143c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]); 1144c031c93bSTakanori Watanabe break; 1145c031c93bSTakanori Watanabe 1146c031c93bSTakanori Watanabe default: 1147c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>", 1148c031c93bSTakanori Watanabe pc_event->event_id); 1149c031c93bSTakanori Watanabe break; 1150c031c93bSTakanori Watanabe } 1151c031c93bSTakanori Watanabe break; 1152c031c93bSTakanori Watanabe 1153c031c93bSTakanori Watanabe default: 1154c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type); 1155c031c93bSTakanori Watanabe break; 1156c031c93bSTakanori Watanabe } 1157c031c93bSTakanori Watanabe 1158c031c93bSTakanori Watanabe return eventname; 1159c031c93bSTakanori Watanabe } 1160c031c93bSTakanori Watanabe 1161c031c93bSTakanori Watanabe static void 1162c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event) 1163c031c93bSTakanori Watanabe { 1164c031c93bSTakanori Watanabe int i; 1165c031c93bSTakanori Watanabe char *eventname; 1166c031c93bSTakanori Watanabe 1167c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event); 1168c031c93bSTakanori Watanabe 1169c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index); 1170c031c93bSTakanori Watanabe printf(" 0x"); 1171c031c93bSTakanori Watanabe for (i = 0; i < 20; i++) 1172c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]); 1173c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>"); 1174c031c93bSTakanori Watanabe 1175c031c93bSTakanori Watanabe free(eventname); 1176c031c93bSTakanori Watanabe } 1177c031c93bSTakanori Watanabe 1178c031c93bSTakanori Watanabe static void 1179c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) 1180c031c93bSTakanori Watanabe { 1181c031c93bSTakanori Watanabe struct TCPAbody *tcpa; 1182c031c93bSTakanori Watanabe struct TCPAevent *event; 1183977fd9daSTakanori Watanabe uintmax_t len, paddr; 1184c031c93bSTakanori Watanabe unsigned char *vaddr = NULL; 1185c031c93bSTakanori Watanabe unsigned char *vend = NULL; 1186c031c93bSTakanori Watanabe 1187c031c93bSTakanori Watanabe printf(BEGIN_COMMENT); 1188c031c93bSTakanori Watanabe acpi_print_sdt(sdp); 1189c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp; 1190c031c93bSTakanori Watanabe 1191c031c93bSTakanori Watanabe switch (tcpa->platform_class) { 1192c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT: 1193c031c93bSTakanori Watanabe len = tcpa->client.log_max_len; 1194c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr; 1195c031c93bSTakanori Watanabe break; 1196c031c93bSTakanori Watanabe 1197c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER: 1198c031c93bSTakanori Watanabe len = tcpa->server.log_max_len; 1199c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr; 1200c031c93bSTakanori Watanabe break; 1201c031c93bSTakanori Watanabe 1202c031c93bSTakanori Watanabe default: 1203c031c93bSTakanori Watanabe printf("XXX"); 1204c031c93bSTakanori Watanabe printf(END_COMMENT); 1205c031c93bSTakanori Watanabe return; 1206c031c93bSTakanori Watanabe } 12070e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n", 1208c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len); 1209c031c93bSTakanori Watanabe 1210c031c93bSTakanori Watanabe if (len == 0) { 1211c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n"); 1212c031c93bSTakanori Watanabe printf(END_COMMENT); 1213c031c93bSTakanori Watanabe return; 1214c031c93bSTakanori Watanabe } 12152ef23c6dSTakanori Watanabe if(sdp->Revision == 1){ 12162ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n"); 12172ef23c6dSTakanori Watanabe printf(END_COMMENT); 12182ef23c6dSTakanori Watanabe return; 12192ef23c6dSTakanori Watanabe } 1220c031c93bSTakanori Watanabe 1221c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len); 1222c031c93bSTakanori Watanabe vend = vaddr + len; 1223c031c93bSTakanori Watanabe 1224c031c93bSTakanori Watanabe while (vaddr != NULL) { 12252ef23c6dSTakanori Watanabe if ((vaddr + sizeof(struct TCPAevent) >= vend)|| 12262ef23c6dSTakanori Watanabe (vaddr + sizeof(struct TCPAevent) < vaddr)) 1227c031c93bSTakanori Watanabe break; 12280e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr; 1229c031c93bSTakanori Watanabe if (vaddr + event->event_size >= vend) 1230c031c93bSTakanori Watanabe break; 12312ef23c6dSTakanori Watanabe if (vaddr + event->event_size < vaddr) 12322ef23c6dSTakanori Watanabe break; 1233c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0) 1234c031c93bSTakanori Watanabe break; 1235c031c93bSTakanori Watanabe #if 0 1236c031c93bSTakanori Watanabe { 1237c031c93bSTakanori Watanabe unsigned int i, j, k; 1238c031c93bSTakanori Watanabe 1239c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr); 1240c031c93bSTakanori Watanabe for (j = 0, i = 0; i < 1241c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) { 1242c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]); 1243c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) { 1244c031c93bSTakanori Watanabe for (k = 0; k < 8; k++) 1245c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ? 1246c031c93bSTakanori Watanabe vaddr[j+k] : '.'); 1247c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]); 1248c031c93bSTakanori Watanabe j = i + 1; 1249c031c93bSTakanori Watanabe } 1250c031c93bSTakanori Watanabe } 1251c031c93bSTakanori Watanabe printf("\n"); } 1252c031c93bSTakanori Watanabe #endif 1253c031c93bSTakanori Watanabe acpi_print_tcpa(event); 1254c031c93bSTakanori Watanabe 1255c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size; 1256c031c93bSTakanori Watanabe } 1257c031c93bSTakanori Watanabe 1258c031c93bSTakanori Watanabe printf(END_COMMENT); 1259c031c93bSTakanori Watanabe } 1260877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp) 1261877fc2e3STakanori Watanabe { 1262877fc2e3STakanori Watanabe ACPI_TABLE_TPM2 *tpm2; 1263877fc2e3STakanori Watanabe 1264877fc2e3STakanori Watanabe printf (BEGIN_COMMENT); 1265877fc2e3STakanori Watanabe acpi_print_sdt(sdp); 1266877fc2e3STakanori Watanabe tpm2 = (ACPI_TABLE_TPM2 *) sdp; 12677aef7138SCy Schubert printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress); 1268877fc2e3STakanori Watanabe printf ("\t\tStartMethod=%x\n", tpm2->StartMethod); 1269877fc2e3STakanori Watanabe printf (END_COMMENT); 1270877fc2e3STakanori Watanabe } 1271c031c93bSTakanori Watanabe 1272ec650989SNeel Natu static const char * 1273ec650989SNeel Natu devscope_type2str(int type) 1274ec650989SNeel Natu { 1275ec650989SNeel Natu static char typebuf[16]; 1276ec650989SNeel Natu 1277ec650989SNeel Natu switch (type) { 1278ec650989SNeel Natu case 1: 1279ec650989SNeel Natu return ("PCI Endpoint Device"); 1280ec650989SNeel Natu case 2: 1281ec650989SNeel Natu return ("PCI Sub-Hierarchy"); 1282ec650989SNeel Natu case 3: 1283ec650989SNeel Natu return ("IOAPIC"); 1284ec650989SNeel Natu case 4: 1285ec650989SNeel Natu return ("HPET"); 1286ec650989SNeel Natu default: 1287ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type); 1288ec650989SNeel Natu return (typebuf); 1289ec650989SNeel Natu } 1290ec650989SNeel Natu } 1291ec650989SNeel Natu 1292ec650989SNeel Natu static int 1293ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining) 1294ec650989SNeel Natu { 1295ec650989SNeel Natu char sep; 1296ec650989SNeel Natu int pathlen; 1297ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend; 1298ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr; 1299ec650989SNeel Natu 1300ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) 1301ec650989SNeel Natu return (-1); 1302ec650989SNeel Natu 1303ec650989SNeel Natu if (remaining < devscope->Length) 1304ec650989SNeel Natu return (-1); 1305ec650989SNeel Natu 1306ec650989SNeel Natu printf("\n"); 1307ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); 1308ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length); 1309ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); 1310ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus); 1311ec650989SNeel Natu 1312ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); 1313ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); 1314ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); 1315ec650989SNeel Natu if (path < pathend) { 1316ec650989SNeel Natu sep = '{'; 1317ec650989SNeel Natu printf("\t\tPath="); 1318ec650989SNeel Natu do { 1319ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function); 1320ec650989SNeel Natu sep=','; 1321ec650989SNeel Natu path++; 1322ec650989SNeel Natu } while (path < pathend); 1323ec650989SNeel Natu printf("}\n"); 1324ec650989SNeel Natu } 1325ec650989SNeel Natu 1326ec650989SNeel Natu return (devscope->Length); 1327ec650989SNeel Natu } 1328ec650989SNeel Natu 1329ec650989SNeel Natu static void 1330ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) 1331ec650989SNeel Natu { 1332ec650989SNeel Natu char *cp; 1333ec650989SNeel Natu int remaining, consumed; 1334ec650989SNeel Natu 1335ec650989SNeel Natu printf("\n"); 1336ec650989SNeel Natu printf("\tType=DRHD\n"); 1337ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length); 1338ec650989SNeel Natu 1339ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1340ec650989SNeel Natu 1341ec650989SNeel Natu printf("\tFlags="); 1342ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL); 1343ec650989SNeel Natu PRINTFLAG_END(); 1344ec650989SNeel Natu 1345ec650989SNeel Natu #undef PRINTFLAG 1346ec650989SNeel Natu 1347ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment); 13487d369c6eSJung-uk Kim printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address); 1349ec650989SNeel Natu 1350ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); 1351ec650989SNeel Natu if (remaining > 0) 1352ec650989SNeel Natu printf("\tDevice Scope:"); 1353ec650989SNeel Natu while (remaining > 0) { 1354ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining; 1355ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1356ec650989SNeel Natu if (consumed <= 0) 1357ec650989SNeel Natu break; 1358ec650989SNeel Natu else 1359ec650989SNeel Natu remaining -= consumed; 1360ec650989SNeel Natu } 1361ec650989SNeel Natu } 1362ec650989SNeel Natu 1363ec650989SNeel Natu static void 1364ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) 1365ec650989SNeel Natu { 1366ec650989SNeel Natu char *cp; 1367ec650989SNeel Natu int remaining, consumed; 1368ec650989SNeel Natu 1369ec650989SNeel Natu printf("\n"); 1370ec650989SNeel Natu printf("\tType=RMRR\n"); 1371ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length); 1372ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment); 13737d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress); 13747d369c6eSJung-uk Kim printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress); 1375ec650989SNeel Natu 1376ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); 1377ec650989SNeel Natu if (remaining > 0) 1378ec650989SNeel Natu printf("\tDevice Scope:"); 1379ec650989SNeel Natu while (remaining > 0) { 1380ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining; 1381ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1382ec650989SNeel Natu if (consumed <= 0) 1383ec650989SNeel Natu break; 1384ec650989SNeel Natu else 1385ec650989SNeel Natu remaining -= consumed; 1386ec650989SNeel Natu } 1387ec650989SNeel Natu } 1388ec650989SNeel Natu 1389ec650989SNeel Natu static void 1390ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) 1391ec650989SNeel Natu { 1392ec650989SNeel Natu char *cp; 1393ec650989SNeel Natu int remaining, consumed; 1394ec650989SNeel Natu 1395ec650989SNeel Natu printf("\n"); 1396ec650989SNeel Natu printf("\tType=ATSR\n"); 1397ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length); 1398ec650989SNeel Natu 1399ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1400ec650989SNeel Natu 1401ec650989SNeel Natu printf("\tFlags="); 1402ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS); 1403ec650989SNeel Natu PRINTFLAG_END(); 1404ec650989SNeel Natu 1405ec650989SNeel Natu #undef PRINTFLAG 1406ec650989SNeel Natu 1407ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment); 1408ec650989SNeel Natu 1409ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); 1410ec650989SNeel Natu if (remaining > 0) 1411ec650989SNeel Natu printf("\tDevice Scope:"); 1412ec650989SNeel Natu while (remaining > 0) { 1413ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining; 1414ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining); 1415ec650989SNeel Natu if (consumed <= 0) 1416ec650989SNeel Natu break; 1417ec650989SNeel Natu else 1418ec650989SNeel Natu remaining -= consumed; 1419ec650989SNeel Natu } 1420ec650989SNeel Natu } 1421ec650989SNeel Natu 1422ec650989SNeel Natu static void 1423ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) 1424ec650989SNeel Natu { 1425ec650989SNeel Natu 1426ec650989SNeel Natu printf("\n"); 1427ec650989SNeel Natu printf("\tType=RHSA\n"); 1428ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length); 14297d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress); 1430ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); 1431ec650989SNeel Natu } 1432ec650989SNeel Natu 1433ec650989SNeel Natu static int 1434ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining) 1435ec650989SNeel Natu { 1436ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr; 1437ec650989SNeel Natu 1438ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) 1439ec650989SNeel Natu return (-1); 1440ec650989SNeel Natu 1441ec650989SNeel Natu if (remaining < hdr->Length) 1442ec650989SNeel Natu return (-1); 1443ec650989SNeel Natu 1444ec650989SNeel Natu switch (hdr->Type) { 1445ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT: 1446ec650989SNeel Natu acpi_handle_dmar_drhd(addr); 1447ec650989SNeel Natu break; 1448ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY: 1449ec650989SNeel Natu acpi_handle_dmar_rmrr(addr); 1450ec650989SNeel Natu break; 1451313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS: 1452ec650989SNeel Natu acpi_handle_dmar_atsr(addr); 1453ec650989SNeel Natu break; 1454313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: 1455ec650989SNeel Natu acpi_handle_dmar_rhsa(addr); 1456ec650989SNeel Natu break; 1457ec650989SNeel Natu default: 1458ec650989SNeel Natu printf("\n"); 1459ec650989SNeel Natu printf("\tType=%d\n", hdr->Type); 1460ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length); 1461ec650989SNeel Natu break; 1462ec650989SNeel Natu } 1463ec650989SNeel Natu return (hdr->Length); 1464ec650989SNeel Natu } 1465ec650989SNeel Natu 1466ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT 1467ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2) 1468ec650989SNeel Natu #endif 1469ec650989SNeel Natu 1470ec650989SNeel Natu static void 1471ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) 1472ec650989SNeel Natu { 1473ec650989SNeel Natu char *cp; 1474ec650989SNeel Natu int remaining, consumed; 1475ec650989SNeel Natu ACPI_TABLE_DMAR *dmar; 1476ec650989SNeel Natu 1477ec650989SNeel Natu printf(BEGIN_COMMENT); 1478ec650989SNeel Natu acpi_print_sdt(sdp); 1479ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp; 1480ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1); 1481ec650989SNeel Natu 1482ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) 1483ec650989SNeel Natu 1484ec650989SNeel Natu printf("\tFlags="); 1485ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP); 1486ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); 1487ec650989SNeel Natu PRINTFLAG_END(); 1488ec650989SNeel Natu 1489ec650989SNeel Natu #undef PRINTFLAG 1490ec650989SNeel Natu 1491ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); 1492ec650989SNeel Natu while (remaining > 0) { 1493ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining; 1494ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining); 1495ec650989SNeel Natu if (consumed <= 0) 1496ec650989SNeel Natu break; 1497ec650989SNeel Natu else 1498ec650989SNeel Natu remaining -= consumed; 1499ec650989SNeel Natu } 1500ec650989SNeel Natu 1501ec650989SNeel Natu printf(END_COMMENT); 1502ec650989SNeel Natu } 1503ec650989SNeel Natu 1504a0333ad1SJohn Baldwin static void 15056d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER *addr) 15066d789b61SKonstantin Belousov { 15076d789b61SKonstantin Belousov printf("\n\tIVHD Type=%#x IOMMUId=%x\n\tFlags=", 15086d789b61SKonstantin Belousov addr->Type, addr->DeviceId); 15096d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Flags, flag, #name) 15106d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_TT_ENABLE, HtTunEn); 15116d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ISOC, PassPW); 15126d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_RES_PASS_PW, ResPassPW); 15136d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ISOC, Isoc); 15146d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_TT_ENABLE, IotlbSup); 15156d789b61SKonstantin Belousov PRINTFLAG((1 << 5), Coherent); 15166d789b61SKonstantin Belousov PRINTFLAG((1 << 6), PreFSup); 15176d789b61SKonstantin Belousov PRINTFLAG((1 << 7), PPRSup); 15186d789b61SKonstantin Belousov #undef PRINTFLAG 15196d789b61SKonstantin Belousov PRINTFLAG_END(); 15206d789b61SKonstantin Belousov } 15216d789b61SKonstantin Belousov 15226d789b61SKonstantin Belousov static void 15236d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(UINT8 dte) 15246d789b61SKonstantin Belousov { 15256d789b61SKonstantin Belousov if (dte == 0) { 15266d789b61SKonstantin Belousov printf("\n"); 15276d789b61SKonstantin Belousov return; 15286d789b61SKonstantin Belousov } 15296d789b61SKonstantin Belousov printf(" DTE="); 15306d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(dte, flag, #name) 15316d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_INIT_PASS, INITPass); 15326d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_EINT_PASS, EIntPass); 15336d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_NMI_PASS, NMIPass); 15346d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_SYSTEM_MGMT, SysMgtPass); 15356d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_LINT0_PASS, Lint0Pass); 15366d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_LINT1_PASS, Lint1Pass); 15376d789b61SKonstantin Belousov #undef PRINTFLAG 15386d789b61SKonstantin Belousov PRINTFLAG_END(); 15396d789b61SKonstantin Belousov } 15406d789b61SKonstantin Belousov 15416d789b61SKonstantin Belousov static void 15426d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(UINT32 edte) 15436d789b61SKonstantin Belousov { 15446d789b61SKonstantin Belousov if (edte == 0) 15456d789b61SKonstantin Belousov return; 15466d789b61SKonstantin Belousov printf("\t\t ExtDTE="); 15476d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(edte, flag, #name) 15486d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ATS_DISABLED, AtsDisabled); 15496d789b61SKonstantin Belousov #undef PRINTFLAG 15506d789b61SKonstantin Belousov PRINTFLAG_END(); 15516d789b61SKonstantin Belousov } 15526d789b61SKonstantin Belousov 15536d789b61SKonstantin Belousov static const char * 15546d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(UINT8 v) 15556d789b61SKonstantin Belousov { 15566d789b61SKonstantin Belousov switch (v) { 15576d789b61SKonstantin Belousov case ACPI_IVHD_IOAPIC: 15586d789b61SKonstantin Belousov return ("IOAPIC"); 15596d789b61SKonstantin Belousov case ACPI_IVHD_HPET: 15606d789b61SKonstantin Belousov return ("HPET"); 15616d789b61SKonstantin Belousov default: 15626d789b61SKonstantin Belousov return ("UNKNOWN"); 15636d789b61SKonstantin Belousov } 15646d789b61SKonstantin Belousov } 15656d789b61SKonstantin Belousov 15666d789b61SKonstantin Belousov static void 15676d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER *d, char *de) 15686d789b61SKonstantin Belousov { 15696d789b61SKonstantin Belousov char *db; 15706d789b61SKonstantin Belousov ACPI_IVRS_DEVICE4 *d4; 15716d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8A *d8a; 15726d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8B *d8b; 15736d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8C *d8c; 15746d789b61SKonstantin Belousov ACPI_IVRS_DEVICE_HID *dh; 15756d789b61SKonstantin Belousov size_t len; 15766d789b61SKonstantin Belousov UINT32 x32; 15776d789b61SKonstantin Belousov 15786d789b61SKonstantin Belousov for (; (char *)d < de; d = (ACPI_IVRS_DE_HEADER *)(db + len)) { 15796d789b61SKonstantin Belousov db = (char *)d; 15806d789b61SKonstantin Belousov if (d->Type == ACPI_IVRS_TYPE_PAD4) { 15816d789b61SKonstantin Belousov len = sizeof(*d4); 15826d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALL) { 15836d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db; 15846d789b61SKonstantin Belousov len = sizeof(*d4); 15856d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=ALL", d4->Header.Type); 15866d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); 15876d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_SELECT) { 15886d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db; 15896d789b61SKonstantin Belousov len = sizeof(*d4); 15906d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x", d4->Header.Type, 15916d789b61SKonstantin Belousov d4->Header.Id); 15926d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); 15936d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_START) { 15946d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db; 15956d789b61SKonstantin Belousov len = 2 * sizeof(*d4); 15966d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x", 15976d789b61SKonstantin Belousov d4->Header.Type, 15986d789b61SKonstantin Belousov d4->Header.Id, (d4 + 1)->Header.Id); 15996d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting); 16006d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_END) { 16016d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db; 16026d789b61SKonstantin Belousov len = 2 * sizeof(*d4); 16036d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x BIOS BUG\n", 16046d789b61SKonstantin Belousov d4->Header.Type, d4->Header.Id); 16056d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_PAD8) { 16066d789b61SKonstantin Belousov len = sizeof(*d8a); 16076d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_SELECT) { 16086d789b61SKonstantin Belousov d8a = (ACPI_IVRS_DEVICE8A *)db; 16096d789b61SKonstantin Belousov len = sizeof(*d8a); 16106d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x AliasId=%#06x", 16116d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d8a->UsedId); 16126d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting); 16136d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_START) { 16146d789b61SKonstantin Belousov d8a = (ACPI_IVRS_DEVICE8A *)db; 16156d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a)); 16166d789b61SKonstantin Belousov len = sizeof(*d8a) + sizeof(*d4); 16176d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x AliasId=%#06x", 16186d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d4->Header.Id, 16196d789b61SKonstantin Belousov d8a->UsedId); 16206d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting); 16216d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_EXT_SELECT) { 16226d789b61SKonstantin Belousov d8b = (ACPI_IVRS_DEVICE8B *)db; 16236d789b61SKonstantin Belousov len = sizeof(*d8b); 16246d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x", 16256d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id); 16266d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting); 16276d789b61SKonstantin Belousov printf("\t\t"); 16286d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData); 16296d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_EXT_START) { 16306d789b61SKonstantin Belousov d8b = (ACPI_IVRS_DEVICE8B *)db; 16316d789b61SKonstantin Belousov len = sizeof(*d8b); 16326d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a)); 16336d789b61SKonstantin Belousov len = sizeof(*d8a) + sizeof(*d4); 16346d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x", 16356d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d4->Header.Id); 16366d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting); 16376d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData); 16386d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_SPECIAL) { 16396d789b61SKonstantin Belousov d8c = (ACPI_IVRS_DEVICE8C *)db; 16406d789b61SKonstantin Belousov len = sizeof(*d8c); 16416d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x Handle=%#x " 16426d789b61SKonstantin Belousov "Variety=%d(%s)", 16436d789b61SKonstantin Belousov d8c->Header.Type, d8c->UsedId, d8c->Handle, 16446d789b61SKonstantin Belousov d8c->Variety, 16456d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(d8c->Variety)); 16466d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8c->Header.DataSetting); 16476d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_HID) { 16486d789b61SKonstantin Belousov dh = (ACPI_IVRS_DEVICE_HID *)db; 16496d789b61SKonstantin Belousov len = sizeof(*dh) + dh->UidLength; 16506d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x HID=", 16516d789b61SKonstantin Belousov dh->Header.Type, dh->Header.Id); 16526d789b61SKonstantin Belousov acpi_print_string((char *)&dh->AcpiHid, 16536d789b61SKonstantin Belousov sizeof(dh->AcpiHid)); 16546d789b61SKonstantin Belousov printf(" CID="); 16556d789b61SKonstantin Belousov acpi_print_string((char *)&dh->AcpiCid, 16566d789b61SKonstantin Belousov sizeof(dh->AcpiCid)); 16576d789b61SKonstantin Belousov printf(" UID="); 16586d789b61SKonstantin Belousov switch (dh->UidType) { 16596d789b61SKonstantin Belousov case ACPI_IVRS_UID_NOT_PRESENT: 16606d789b61SKonstantin Belousov default: 16616d789b61SKonstantin Belousov printf("none"); 16626d789b61SKonstantin Belousov break; 16636d789b61SKonstantin Belousov case ACPI_IVRS_UID_IS_INTEGER: 16646d789b61SKonstantin Belousov memcpy(&x32, dh + 1, sizeof(x32)); 16656d789b61SKonstantin Belousov printf("%#x", x32); 16666d789b61SKonstantin Belousov break; 16676d789b61SKonstantin Belousov case ACPI_IVRS_UID_IS_STRING: 16686d789b61SKonstantin Belousov acpi_print_string((char *)(dh + 1), 16696d789b61SKonstantin Belousov dh->UidLength); 16706d789b61SKonstantin Belousov break; 16716d789b61SKonstantin Belousov } 16726d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(dh->Header.DataSetting); 16736d789b61SKonstantin Belousov } else { 16746d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Unknown\n", d->Type); 16756d789b61SKonstantin Belousov if (d->Type <= 63) 16766d789b61SKonstantin Belousov len = sizeof(*d4); 16776d789b61SKonstantin Belousov else if (d->Type <= 127) 16786d789b61SKonstantin Belousov len = sizeof(*d8a); 16796d789b61SKonstantin Belousov else { 16806d789b61SKonstantin Belousov printf("Abort, cannot advance iterator.\n"); 16816d789b61SKonstantin Belousov return; 16826d789b61SKonstantin Belousov } 16836d789b61SKonstantin Belousov } 16846d789b61SKonstantin Belousov } 16856d789b61SKonstantin Belousov } 16866d789b61SKonstantin Belousov 16876d789b61SKonstantin Belousov static void 16886d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 *addr, bool efrsup) 16896d789b61SKonstantin Belousov { 16906d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(&addr->Header); 16916d789b61SKonstantin Belousov printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n", 16926d789b61SKonstantin Belousov addr->CapabilityOffset, (uintmax_t)addr->BaseAddress, 16936d789b61SKonstantin Belousov addr->PciSegmentGroup, (addr->Info & ACPI_IVHD_UNIT_ID_MASK) >> 8, 16946d789b61SKonstantin Belousov addr->Info & ACPI_IVHD_MSI_NUMBER_MASK); 16956d789b61SKonstantin Belousov if (efrsup) { 16966d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->FeatureReporting, flag, #name) 16976d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \ 16986d789b61SKonstantin Belousov printfield(addr->FeatureReporting, lbit, hbit, #name) 16996d789b61SKonstantin Belousov PRINTFIELD(30, 31, HATS); 17006d789b61SKonstantin Belousov PRINTFIELD(28, 29, GATS); 17016d789b61SKonstantin Belousov PRINTFIELD(23, 27, MsiNumPPR); 17026d789b61SKonstantin Belousov PRINTFIELD(17, 22, PNBanks); 17036d789b61SKonstantin Belousov PRINTFIELD(13, 16, PNCounters); 17046d789b61SKonstantin Belousov PRINTFIELD(8, 12, PASmax); 17056d789b61SKonstantin Belousov PRINTFLAG(1 << 7, HESup); 17066d789b61SKonstantin Belousov PRINTFLAG(1 << 6, GASup); 17076d789b61SKonstantin Belousov PRINTFLAG(1 << 5, UASup); 17086d789b61SKonstantin Belousov PRINTFIELD(3, 2, GLXSup); 17096d789b61SKonstantin Belousov PRINTFLAG(1 << 1, NXSup); 17106d789b61SKonstantin Belousov PRINTFLAG(1 << 0, XTSup); 17116d789b61SKonstantin Belousov #undef PRINTFLAG 17126d789b61SKonstantin Belousov #undef PRINTFIELD 17136d789b61SKonstantin Belousov PRINTFLAG_END(); 17146d789b61SKonstantin Belousov } 17156d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), 17166d789b61SKonstantin Belousov (char *)addr + addr->Header.Length); 17176d789b61SKonstantin Belousov } 17186d789b61SKonstantin Belousov 17196d789b61SKonstantin Belousov static void 17206d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 *addr) 17216d789b61SKonstantin Belousov { 17226d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(&addr->Header); 17236d789b61SKonstantin Belousov printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n", 17246d789b61SKonstantin Belousov addr->CapabilityOffset, (uintmax_t)addr->BaseAddress, 17256d789b61SKonstantin Belousov addr->PciSegmentGroup, (addr->Info >> 8) & 0x1f, 17266d789b61SKonstantin Belousov addr->Info & 0x5); 17276d789b61SKonstantin Belousov printf("\tAttr="); 17286d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \ 17296d789b61SKonstantin Belousov printfield(addr->Attributes, lbit, hbit, #name) 17306d789b61SKonstantin Belousov PRINTFIELD(23, 27, MsiNumPPR); 17316d789b61SKonstantin Belousov PRINTFIELD(17, 22, PNBanks); 17326d789b61SKonstantin Belousov PRINTFIELD(13, 16, PNCounters); 17336d789b61SKonstantin Belousov #undef PRINTFIELD 17346d789b61SKonstantin Belousov PRINTFLAG_END(); 17356d789b61SKonstantin Belousov } 17366d789b61SKonstantin Belousov 17376d789b61SKonstantin Belousov static void 17386d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 *addr) 17396d789b61SKonstantin Belousov { 17406d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(addr); 17416d789b61SKonstantin Belousov printf("\tEFRreg=%#018jx\n", (uintmax_t)addr->EfrRegisterImage); 17426d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), 17436d789b61SKonstantin Belousov (char *)addr + addr->Header.Length); 17446d789b61SKonstantin Belousov } 17456d789b61SKonstantin Belousov 17466d789b61SKonstantin Belousov static void 17476d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 *addr) 17486d789b61SKonstantin Belousov { 17496d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(addr); 17506d789b61SKonstantin Belousov printf("\tEFRreg=%#018jx EFR2reg=%#018jx\n", 17516d789b61SKonstantin Belousov (uintmax_t)addr->EfrRegisterImage, (uintmax_t)addr->Reserved); 17526d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1), 17536d789b61SKonstantin Belousov (char *)addr + addr->Header.Length); 17546d789b61SKonstantin Belousov } 17556d789b61SKonstantin Belousov 17566d789b61SKonstantin Belousov static const char * 17576d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY *addr) 17586d789b61SKonstantin Belousov { 17596d789b61SKonstantin Belousov switch (addr->Header.Type) { 17606d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY1: 17616d789b61SKonstantin Belousov return ("ALL"); 17626d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2: 17636d789b61SKonstantin Belousov return ("specified"); 17646d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3: 17656d789b61SKonstantin Belousov return ("range"); 17666d789b61SKonstantin Belousov default: 17676d789b61SKonstantin Belousov return ("unknown"); 17686d789b61SKonstantin Belousov } 17696d789b61SKonstantin Belousov } 17706d789b61SKonstantin Belousov 17716d789b61SKonstantin Belousov static void 17726d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY *addr) 17736d789b61SKonstantin Belousov { 17746d789b61SKonstantin Belousov printf("\tMem Type=%#x(%s) ", 17756d789b61SKonstantin Belousov addr->Header.Type, acpi_handle_ivrs_ivmd_type(addr)); 17766d789b61SKonstantin Belousov switch (addr->Header.Type) { 17776d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2: 17786d789b61SKonstantin Belousov printf("Id=%#06x PCISeg=%#x ", addr->Header.DeviceId, 17796d789b61SKonstantin Belousov *(UINT16 *)&addr->Reserved); 17806d789b61SKonstantin Belousov break; 17816d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3: 17826d789b61SKonstantin Belousov printf("Id=%#06x-%#06x PCISeg=%#x", addr->Header.DeviceId, 17836d789b61SKonstantin Belousov addr->AuxData, *(UINT16 *)&addr->Reserved); 17846d789b61SKonstantin Belousov break; 17856d789b61SKonstantin Belousov } 17866d789b61SKonstantin Belousov printf("Start=%#18jx Length=%#jx Flags=", 17876d789b61SKonstantin Belousov (uintmax_t)addr->StartAddress, (uintmax_t)addr->MemoryLength); 17886d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Header.Flags, flag, #name) 17896d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_EXCLUSION_RANGE, ExclusionRange); 17906d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_WRITE, IW); 17916d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_READ, IR); 17926d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_UNITY, Unity); 17936d789b61SKonstantin Belousov #undef PRINTFLAG 17946d789b61SKonstantin Belousov PRINTFLAG_END(); 17956d789b61SKonstantin Belousov } 17966d789b61SKonstantin Belousov 17976d789b61SKonstantin Belousov static int 17986d789b61SKonstantin Belousov acpi_handle_ivrs_blocks(void *addr, int remaining, bool efrsup) 17996d789b61SKonstantin Belousov { 18006d789b61SKonstantin Belousov ACPI_IVRS_HEADER *hdr = addr; 18016d789b61SKonstantin Belousov 18026d789b61SKonstantin Belousov if (remaining < (int)sizeof(ACPI_IVRS_HEADER)) 18036d789b61SKonstantin Belousov return (-1); 18046d789b61SKonstantin Belousov 18056d789b61SKonstantin Belousov if (remaining < hdr->Length) 18066d789b61SKonstantin Belousov return (-1); 18076d789b61SKonstantin Belousov 18086d789b61SKonstantin Belousov switch (hdr->Type) { 18096d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE1: 18106d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(addr, efrsup); 18116d789b61SKonstantin Belousov break; 18126d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE2: 18136d789b61SKonstantin Belousov if (!efrsup) 18146d789b61SKonstantin Belousov printf("\t!! Found IVHD block 0x11 but !EFRsup\n"); 18156d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(addr); 18166d789b61SKonstantin Belousov break; 18176d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE3: 18186d789b61SKonstantin Belousov if (!efrsup) 18196d789b61SKonstantin Belousov printf("\t!! Found IVHD block 0x40 but !EFRsup\n"); 18206d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(addr); 18216d789b61SKonstantin Belousov break; 18226d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY1: 18236d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2: 18246d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3: 18256d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(addr); 18266d789b61SKonstantin Belousov break; 18276d789b61SKonstantin Belousov default: 18286d789b61SKonstantin Belousov printf("\n"); 18296d789b61SKonstantin Belousov printf("\tType=%d\n", hdr->Type); 18306d789b61SKonstantin Belousov printf("\tLength=%d\n", hdr->Length); 18316d789b61SKonstantin Belousov break; 18326d789b61SKonstantin Belousov } 18336d789b61SKonstantin Belousov return (hdr->Length); 18346d789b61SKonstantin Belousov } 18356d789b61SKonstantin Belousov 18366d789b61SKonstantin Belousov #define ACPI_IVRS_DMAREMAP 0x00000002 18376d789b61SKonstantin Belousov #define ACPI_IVRS_EFRSUP 0x00000001 18386d789b61SKonstantin Belousov #define ACPI_IVRS_GVA_SIZE 0x000000e0 18396d789b61SKonstantin Belousov 18406d789b61SKonstantin Belousov static void 18416d789b61SKonstantin Belousov acpi_handle_ivrs(ACPI_TABLE_HEADER *sdp) 18426d789b61SKonstantin Belousov { 18436d789b61SKonstantin Belousov ACPI_TABLE_IVRS *ivrs; 18446d789b61SKonstantin Belousov char *cp; 18456d789b61SKonstantin Belousov int remaining, consumed; 18466d789b61SKonstantin Belousov bool efrsup; 18476d789b61SKonstantin Belousov 18486d789b61SKonstantin Belousov printf(BEGIN_COMMENT); 18496d789b61SKonstantin Belousov acpi_print_sdt(sdp); 18506d789b61SKonstantin Belousov ivrs = (ACPI_TABLE_IVRS *)sdp; 18516d789b61SKonstantin Belousov efrsup = (ivrs->Info & ACPI_IVRS_EFRSUP) != 0; 18526d789b61SKonstantin Belousov printf("\tVAsize=%d PAsize=%d GVAsize=%d\n", 18536d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_VIRTUAL_SIZE) >> 15, 18546d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_PHYSICAL_SIZE) >> 8, 18556d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_GVA_SIZE) >> 5); 18566d789b61SKonstantin Belousov printf("\tATS_resp_res=%d DMA_preboot_remap=%d EFRsup=%d\n", 18576d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_ATS_RESERVED) != 0, 18586d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_DMAREMAP) != 0, efrsup); 18596d789b61SKonstantin Belousov 18606d789b61SKonstantin Belousov remaining = sdp->Length - sizeof(ACPI_TABLE_IVRS); 18616d789b61SKonstantin Belousov while (remaining > 0) { 18626d789b61SKonstantin Belousov cp = (char *)sdp + sdp->Length - remaining; 18636d789b61SKonstantin Belousov consumed = acpi_handle_ivrs_blocks(cp, remaining, efrsup); 18646d789b61SKonstantin Belousov if (consumed <= 0) 18656d789b61SKonstantin Belousov break; 18666d789b61SKonstantin Belousov else 18676d789b61SKonstantin Belousov remaining -= consumed; 18686d789b61SKonstantin Belousov } 18696d789b61SKonstantin Belousov 18706d789b61SKonstantin Belousov printf(END_COMMENT); 18716d789b61SKonstantin Belousov } 18726d789b61SKonstantin Belousov 18736d789b61SKonstantin Belousov static void 1874986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) 1875a0333ad1SJohn Baldwin { 1876a0333ad1SJohn Baldwin 1877a0333ad1SJohn Baldwin printf("\tFlags={"); 1878986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED) 1879a0333ad1SJohn Baldwin printf("ENABLED"); 1880a0333ad1SJohn Baldwin else 1881a0333ad1SJohn Baldwin printf("DISABLED"); 1882986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 1883a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 1884986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) 1885a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 1886a0333ad1SJohn Baldwin printf("}\n"); 1887986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); 1888986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); 1889986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain); 1890a0333ad1SJohn Baldwin } 1891a0333ad1SJohn Baldwin 189227941afaSEd Maste static const char *srat_types[] = { 189327941afaSEd Maste [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU", 189427941afaSEd Maste [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory", 189527941afaSEd Maste [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC", 1896cebb7b19SEd Maste [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC", 1897cebb7b19SEd Maste [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS", 189827941afaSEd Maste }; 1899a0333ad1SJohn Baldwin 1900a0333ad1SJohn Baldwin static void 1901986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) 1902a0333ad1SJohn Baldwin { 1903986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu; 1904986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; 19052b2b1f42SAndrew Turner ACPI_SRAT_GICC_AFFINITY *gic; 1906a0333ad1SJohn Baldwin 1907c86932b6SMarcelo Araujo if (srat->Type < nitems(srat_types)) 1908986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]); 1909a0333ad1SJohn Baldwin else 1910986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type); 1911986dffafSJohn Baldwin switch (srat->Type) { 1912a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 1913986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; 1914986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId, 1915986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 | 1916986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 | 1917986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 | 1918986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags); 1919a0333ad1SJohn Baldwin break; 1920a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1921986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); 1922a0333ad1SJohn Baldwin break; 1923a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1924986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; 1925986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, 1926986dffafSJohn Baldwin x2apic->Flags); 1927a0333ad1SJohn Baldwin break; 19282b2b1f42SAndrew Turner case ACPI_SRAT_TYPE_GICC_AFFINITY: 19292b2b1f42SAndrew Turner gic = (ACPI_SRAT_GICC_AFFINITY *)srat; 19302b2b1f42SAndrew Turner acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain, 19312b2b1f42SAndrew Turner gic->Flags); 19322b2b1f42SAndrew Turner break; 1933a0333ad1SJohn Baldwin } 1934a0333ad1SJohn Baldwin } 1935a0333ad1SJohn Baldwin 1936a0333ad1SJohn Baldwin static void 1937986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp) 1938a0333ad1SJohn Baldwin { 1939986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat; 1940a0333ad1SJohn Baldwin 1941a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 1942a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 1943986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp; 1944986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision); 1945986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); 1946a0333ad1SJohn Baldwin printf(END_COMMENT); 1947a0333ad1SJohn Baldwin } 1948a0333ad1SJohn Baldwin 1949340c0022SEd Maste static const char *nfit_types[] = { 1950340c0022SEd Maste [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address", 1951340c0022SEd Maste [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map", 1952340c0022SEd Maste [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave", 1953340c0022SEd Maste [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS", 1954340c0022SEd Maste [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region", 1955340c0022SEd Maste [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region", 19561b109c69SAlexander Motin [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address", 19571b109c69SAlexander Motin [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities" 1958340c0022SEd Maste }; 1959340c0022SEd Maste 1960340c0022SEd Maste 1961340c0022SEd Maste static void 1962340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit) 1963340c0022SEd Maste { 1964340c0022SEd Maste char *uuidstr; 19653b7935f3SAlexander Motin uint32_t m, status; 1966340c0022SEd Maste 1967340c0022SEd Maste ACPI_NFIT_SYSTEM_ADDRESS *sysaddr; 1968340c0022SEd Maste ACPI_NFIT_MEMORY_MAP *mmap; 1969340c0022SEd Maste ACPI_NFIT_INTERLEAVE *ileave; 1970340c0022SEd Maste ACPI_NFIT_CONTROL_REGION *ctlreg; 1971340c0022SEd Maste ACPI_NFIT_DATA_REGION *datareg; 1972340c0022SEd Maste ACPI_NFIT_FLUSH_ADDRESS *fladdr; 19731b109c69SAlexander Motin ACPI_NFIT_CAPABILITIES *caps; 1974340c0022SEd Maste 1975340c0022SEd Maste if (nfit->Type < nitems(nfit_types)) 1976340c0022SEd Maste printf("\tType=%s\n", nfit_types[nfit->Type]); 1977340c0022SEd Maste else 1978340c0022SEd Maste printf("\tType=%u (unknown)\n", nfit->Type); 1979340c0022SEd Maste switch (nfit->Type) { 1980340c0022SEd Maste case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 1981340c0022SEd Maste sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit; 1982340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex); 1983340c0022SEd Maste printf("\tProximityDomain=%u\n", 1984340c0022SEd Maste (u_int)sysaddr->ProximityDomain); 1985de937ecbSKonstantin Belousov uuid_to_string((uuid_t *)(uintptr_t)(sysaddr->RangeGuid), 1986340c0022SEd Maste &uuidstr, &status); 1987340c0022SEd Maste if (status != uuid_s_ok) 1988340c0022SEd Maste errx(1, "uuid_to_string: status=%u", status); 1989340c0022SEd Maste printf("\tRangeGuid=%s\n", uuidstr); 1990340c0022SEd Maste free(uuidstr); 1991340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address); 1992340c0022SEd Maste printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length); 1993340c0022SEd Maste printf("\tMemoryMapping=0x%016jx\n", 1994340c0022SEd Maste (uintmax_t)sysaddr->MemoryMapping); 1995340c0022SEd Maste 1996340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 1997340c0022SEd Maste 1998340c0022SEd Maste printf("\tFlags="); 1999340c0022SEd Maste PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY); 2000340c0022SEd Maste PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID); 2001340c0022SEd Maste PRINTFLAG_END(); 2002340c0022SEd Maste 2003340c0022SEd Maste #undef PRINTFLAG 2004340c0022SEd Maste 2005340c0022SEd Maste break; 2006340c0022SEd Maste case ACPI_NFIT_TYPE_MEMORY_MAP: 2007340c0022SEd Maste mmap = (ACPI_NFIT_MEMORY_MAP *)nfit; 200892d0d6bbSAlexander Motin printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle); 200992d0d6bbSAlexander Motin printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId); 2010340c0022SEd Maste printf("\tRegionId=%u\n", (u_int)mmap->RegionId); 2011340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex); 2012340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex); 2013340c0022SEd Maste printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize); 2014340c0022SEd Maste printf("\tRegionOffset=0x%016jx\n", 2015340c0022SEd Maste (uintmax_t)mmap->RegionOffset); 2016340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address); 2017340c0022SEd Maste printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex); 2018fb1cf2a9SAlexander Motin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays); 2019340c0022SEd Maste 2020340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag) 2021340c0022SEd Maste 2022340c0022SEd Maste printf("\tFlags="); 2023340c0022SEd Maste PRINTFLAG(mmap->Flags, SAVE_FAILED); 2024340c0022SEd Maste PRINTFLAG(mmap->Flags, RESTORE_FAILED); 2025340c0022SEd Maste PRINTFLAG(mmap->Flags, FLUSH_FAILED); 2026340c0022SEd Maste PRINTFLAG(mmap->Flags, NOT_ARMED); 2027340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_OBSERVED); 2028340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_ENABLED); 2029340c0022SEd Maste PRINTFLAG(mmap->Flags, MAP_FAILED); 2030340c0022SEd Maste PRINTFLAG_END(); 2031340c0022SEd Maste 2032340c0022SEd Maste #undef PRINTFLAG 2033340c0022SEd Maste 2034340c0022SEd Maste break; 2035340c0022SEd Maste case ACPI_NFIT_TYPE_INTERLEAVE: 2036340c0022SEd Maste ileave = (ACPI_NFIT_INTERLEAVE *)nfit; 2037340c0022SEd Maste printf("\tInterleaveIndex=%u\n", 2038340c0022SEd Maste (u_int)ileave->InterleaveIndex); 2039340c0022SEd Maste printf("\tLineCount=%u\n", (u_int)ileave->LineCount); 2040340c0022SEd Maste printf("\tLineSize=%u\n", (u_int)ileave->LineSize); 20413b7935f3SAlexander Motin for (m = 0; m < ileave->LineCount; m++) { 20423b7935f3SAlexander Motin printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1, 20433b7935f3SAlexander Motin (u_int)ileave->LineOffset[m]); 20443b7935f3SAlexander Motin } 2045340c0022SEd Maste break; 2046340c0022SEd Maste case ACPI_NFIT_TYPE_SMBIOS: 2047340c0022SEd Maste /* XXX smbios->Data[x] output is not supported */ 2048340c0022SEd Maste break; 2049340c0022SEd Maste case ACPI_NFIT_TYPE_CONTROL_REGION: 2050340c0022SEd Maste ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit; 2051340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex); 2052340c0022SEd Maste printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId); 2053340c0022SEd Maste printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId); 205435e39fd9SAlexander Motin printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId); 2055340c0022SEd Maste printf("\tSubsystemVendorId=0x%04x\n", 2056340c0022SEd Maste (u_int)ctlreg->SubsystemVendorId); 2057340c0022SEd Maste printf("\tSubsystemDeviceId=0x%04x\n", 2058340c0022SEd Maste (u_int)ctlreg->SubsystemDeviceId); 205935e39fd9SAlexander Motin printf("\tSubsystemRevisionId=0x%02x\n", 2060340c0022SEd Maste (u_int)ctlreg->SubsystemRevisionId); 2061d4c2de2eSAlexander Motin printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields); 206235e39fd9SAlexander Motin printf("\tManufacturingLocation=0x%02x\n", 2063340c0022SEd Maste (u_int)ctlreg->ManufacturingLocation); 206435e39fd9SAlexander Motin printf("\tManufacturingDate=%04x\n", 206535e39fd9SAlexander Motin (u_int)be16toh(ctlreg->ManufacturingDate)); 206635e39fd9SAlexander Motin printf("\tSerialNumber=%08X\n", 206735e39fd9SAlexander Motin (u_int)be32toh(ctlreg->SerialNumber)); 2068fb1cf2a9SAlexander Motin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code); 2069340c0022SEd Maste printf("\tWindows=%u\n", (u_int)ctlreg->Windows); 2070340c0022SEd Maste printf("\tWindowSize=0x%016jx\n", 2071340c0022SEd Maste (uintmax_t)ctlreg->WindowSize); 2072340c0022SEd Maste printf("\tCommandOffset=0x%016jx\n", 2073340c0022SEd Maste (uintmax_t)ctlreg->CommandOffset); 2074340c0022SEd Maste printf("\tCommandSize=0x%016jx\n", 2075340c0022SEd Maste (uintmax_t)ctlreg->CommandSize); 2076340c0022SEd Maste printf("\tStatusOffset=0x%016jx\n", 2077340c0022SEd Maste (uintmax_t)ctlreg->StatusOffset); 2078340c0022SEd Maste printf("\tStatusSize=0x%016jx\n", 2079340c0022SEd Maste (uintmax_t)ctlreg->StatusSize); 2080340c0022SEd Maste 2081340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag) 2082340c0022SEd Maste 2083340c0022SEd Maste printf("\tFlags="); 2084d4c2de2eSAlexander Motin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED); 2085340c0022SEd Maste PRINTFLAG_END(); 2086340c0022SEd Maste 2087340c0022SEd Maste #undef PRINTFLAG 2088340c0022SEd Maste 2089340c0022SEd Maste break; 2090340c0022SEd Maste case ACPI_NFIT_TYPE_DATA_REGION: 2091340c0022SEd Maste datareg = (ACPI_NFIT_DATA_REGION *)nfit; 2092340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex); 2093340c0022SEd Maste printf("\tWindows=%u\n", (u_int)datareg->Windows); 2094340c0022SEd Maste printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset); 2095340c0022SEd Maste printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size); 2096340c0022SEd Maste printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity); 2097340c0022SEd Maste printf("\tStartAddress=0x%016jx\n", 2098340c0022SEd Maste (uintmax_t)datareg->StartAddress); 2099340c0022SEd Maste break; 2100340c0022SEd Maste case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 2101340c0022SEd Maste fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit; 2102340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle); 2103340c0022SEd Maste printf("\tHintCount=%u\n", (u_int)fladdr->HintCount); 21043b7935f3SAlexander Motin for (m = 0; m < fladdr->HintCount; m++) { 21053b7935f3SAlexander Motin printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1, 21063b7935f3SAlexander Motin (uintmax_t)fladdr->HintAddress[m]); 21073b7935f3SAlexander Motin } 2108340c0022SEd Maste break; 21091b109c69SAlexander Motin case ACPI_NFIT_TYPE_CAPABILITIES: 21101b109c69SAlexander Motin caps = (ACPI_NFIT_CAPABILITIES *)nfit; 21111b109c69SAlexander Motin printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability); 21121b109c69SAlexander Motin 21131b109c69SAlexander Motin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag) 21141b109c69SAlexander Motin 21151b109c69SAlexander Motin printf("\tCapabilities="); 21161b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, CACHE_FLUSH); 21171b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, MEM_FLUSH); 21181b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, MEM_MIRRORING); 21191b109c69SAlexander Motin PRINTFLAG_END(); 21201b109c69SAlexander Motin 21211b109c69SAlexander Motin #undef PRINTFLAG 21221b109c69SAlexander Motin break; 2123340c0022SEd Maste } 2124340c0022SEd Maste } 2125340c0022SEd Maste 2126340c0022SEd Maste static void 2127340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp) 2128340c0022SEd Maste { 2129340c0022SEd Maste ACPI_TABLE_NFIT *nfit; 2130340c0022SEd Maste 2131340c0022SEd Maste printf(BEGIN_COMMENT); 2132340c0022SEd Maste acpi_print_sdt(sdp); 2133340c0022SEd Maste nfit = (ACPI_TABLE_NFIT *)sdp; 2134340c0022SEd Maste acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit); 2135340c0022SEd Maste printf(END_COMMENT); 2136340c0022SEd Maste } 2137340c0022SEd Maste 2138a0333ad1SJohn Baldwin static void 2139986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp) 2140c62f1cccSMitsuru IWASAKI { 2141773b6454SNate Lawson printf(" "); 2142278f0de6SJung-uk Kim acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE); 2143c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 2144986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum); 2145e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 2146986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); 2147e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 2148986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 2149986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision); 2150e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 2151278f0de6SJung-uk Kim acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE); 2152986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); 2153e1e9a4bfSMitsuru IWASAKI } 2154e1e9a4bfSMitsuru IWASAKI 2155945137d9SNate Lawson static void 2156986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) 2157e1e9a4bfSMitsuru IWASAKI { 2158986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 2159986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 2160e1e9a4bfSMitsuru IWASAKI int i, entries; 2161e1e9a4bfSMitsuru IWASAKI 2162986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 2163986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 2164773b6454SNate Lawson printf(BEGIN_COMMENT); 2165773b6454SNate Lawson acpi_print_sdt(rsdp); 2166986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 2167e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 2168e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 2169e1e9a4bfSMitsuru IWASAKI if (i > 0) 2170e1e9a4bfSMitsuru IWASAKI printf(", "); 2171fe1d0c2dSJung-uk Kim if (addr_size == 4) 21727d369c6eSJung-uk Kim printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i])); 2173fe1d0c2dSJung-uk Kim else 21747d369c6eSJung-uk Kim printf("0x%016jx", 21757d369c6eSJung-uk Kim (uintmax_t)le64toh(xsdt->TableOffsetEntry[i])); 2176e1e9a4bfSMitsuru IWASAKI } 2177e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 2178c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 2179e1e9a4bfSMitsuru IWASAKI } 2180e1e9a4bfSMitsuru IWASAKI 21818e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 21828e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 21838e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 21848e6a8737SNate Lawson }; 21858e6a8737SNate Lawson 2186945137d9SNate Lawson static void 2187986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp) 2188e1e9a4bfSMitsuru IWASAKI { 2189986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt; 21908e6a8737SNate Lawson const char *pm; 2191e1e9a4bfSMitsuru IWASAKI 2192986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp; 2193c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 21942177d4e6SNate Lawson acpi_print_sdt(sdp); 2195986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, 2196986dffafSJohn Baldwin fadt->Dsdt); 2197986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); 2198986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 21998e6a8737SNate Lawson pm = "Reserved"; 22008e6a8737SNate Lawson else 2201986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile]; 2202986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); 2203986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt); 2204986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); 2205986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); 2206986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); 2207986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); 2208986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); 2209e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 2210986dffafSJohn Baldwin fadt->Pm1aEventBlock, 2211986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); 2212986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0) 2213e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 2214986dffafSJohn Baldwin fadt->Pm1bEventBlock, 2215986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); 2216e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 2217986dffafSJohn Baldwin fadt->Pm1aControlBlock, 2218986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); 2219986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0) 2220e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 2221986dffafSJohn Baldwin fadt->Pm1bControlBlock, 2222986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); 2223986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0) 2224e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 2225986dffafSJohn Baldwin fadt->Pm2ControlBlock, 2226986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); 2227c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 2228986dffafSJohn Baldwin fadt->PmTimerBlock, 2229986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1); 2230986dffafSJohn Baldwin if (fadt->Gpe0Block != 0) 22318e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 2232986dffafSJohn Baldwin fadt->Gpe0Block, 2233986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); 2234986dffafSJohn Baldwin if (fadt->Gpe1Block != 0) 22358e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 2236986dffafSJohn Baldwin fadt->Gpe1Block, 2237986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, 2238986dffafSJohn Baldwin fadt->Gpe1Base); 2239986dffafSJohn Baldwin if (fadt->CstControl != 0) 2240986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl); 224151c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 2242986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency); 2243e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 2244986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride); 2245e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 2246986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth); 2247e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 2248986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); 2249e1e9a4bfSMitsuru IWASAKI 2250ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) 2251e1e9a4bfSMitsuru IWASAKI 22528e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 2253986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); 2254986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042); 2255986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA); 2256986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI); 2257986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM); 2258f6469ce1SAndrew Turner PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC); 2259ec650989SNeel Natu PRINTFLAG_END(); 22608e6a8737SNate Lawson 22618e6a8737SNate Lawson printf("\tFlags="); 2262986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD); 2263986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH); 2264986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED); 2265986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); 2266986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON); 2267986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON); 2268986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC); 2269986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE); 2270986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER); 2271986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); 2272986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER); 2273986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE); 2274986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS); 2275986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE); 2276986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); 2277986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); 2278986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID); 2279986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); 2280986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER); 2281986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL); 2282f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, HW_REDUCED); 2283f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, LOW_POWER_S0); 2284ec650989SNeel Natu PRINTFLAG_END(); 2285e1e9a4bfSMitsuru IWASAKI 2286e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 2287e1e9a4bfSMitsuru IWASAKI 2288986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { 22898e6a8737SNate Lawson printf("\tRESET_REG="); 2290986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister); 2291986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue); 22928e6a8737SNate Lawson } 2293c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 22947d369c6eSJung-uk Kim printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs); 22957d369c6eSJung-uk Kim printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt); 2296c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 2297986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock); 2298986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) { 2299c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 2300986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock); 2301c08c4e81SNate Lawson } 2302c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 2303986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock); 2304986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) { 2305c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 2306986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock); 2307c08c4e81SNate Lawson } 2308986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) { 2309773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 2310986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock); 2311c08c4e81SNate Lawson } 2312773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 2313986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock); 2314986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) { 2315773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 2316986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block); 2317c08c4e81SNate Lawson } 2318986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) { 2319773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 2320986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block); 2321c08c4e81SNate Lawson } 2322773b6454SNate Lawson printf("\n"); 2323773b6454SNate Lawson } 23248e6a8737SNate Lawson 23258e6a8737SNate Lawson printf(END_COMMENT); 23268e6a8737SNate Lawson } 23278e6a8737SNate Lawson 23288e6a8737SNate Lawson static void 2329986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs) 23308e6a8737SNate Lawson { 23318e6a8737SNate Lawson printf(BEGIN_COMMENT); 2332986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length); 2333986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature); 2334986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); 23358e6a8737SNate Lawson 2336773b6454SNate Lawson printf("\tGlobal_Lock="); 2337986dffafSJohn Baldwin if (facs->GlobalLock != 0) { 2338986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING) 23398e6a8737SNate Lawson printf("PENDING,"); 2340986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED) 23418e6a8737SNate Lawson printf("OWNED"); 23428e6a8737SNate Lawson } 2343773b6454SNate Lawson printf("\n"); 23448e6a8737SNate Lawson 2345773b6454SNate Lawson printf("\tFlags="); 2346986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) 23478e6a8737SNate Lawson printf("S4BIOS"); 2348773b6454SNate Lawson printf("\n"); 23498e6a8737SNate Lawson 23507d369c6eSJung-uk Kim if (facs->XFirmwareWakingVector != 0) 23517d369c6eSJung-uk Kim printf("\tX_Firm_Wake_Vec=%016jx\n", 23527d369c6eSJung-uk Kim (uintmax_t)facs->XFirmwareWakingVector); 2353986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version); 23548e6a8737SNate Lawson 2355c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 2356e1e9a4bfSMitsuru IWASAKI } 2357e1e9a4bfSMitsuru IWASAKI 2358945137d9SNate Lawson static void 2359986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) 2360e1e9a4bfSMitsuru IWASAKI { 2361773b6454SNate Lawson printf(BEGIN_COMMENT); 2362773b6454SNate Lawson acpi_print_sdt(dsdp); 2363773b6454SNate Lawson printf(END_COMMENT); 2364e1e9a4bfSMitsuru IWASAKI } 2365e1e9a4bfSMitsuru IWASAKI 2366e1e9a4bfSMitsuru IWASAKI int 2367e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 2368e1e9a4bfSMitsuru IWASAKI { 2369986dffafSJohn Baldwin uint8_t *bp; 2370986dffafSJohn Baldwin uint8_t sum; 2371e1e9a4bfSMitsuru IWASAKI 2372e1e9a4bfSMitsuru IWASAKI bp = p; 2373e1e9a4bfSMitsuru IWASAKI sum = 0; 2374e1e9a4bfSMitsuru IWASAKI while (length--) 2375e1e9a4bfSMitsuru IWASAKI sum += *bp++; 2376e1e9a4bfSMitsuru IWASAKI 2377e1e9a4bfSMitsuru IWASAKI return (sum); 2378e1e9a4bfSMitsuru IWASAKI } 2379e1e9a4bfSMitsuru IWASAKI 2380986dffafSJohn Baldwin static ACPI_TABLE_HEADER * 2381e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 2382e1e9a4bfSMitsuru IWASAKI { 2383986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp; 2384e1e9a4bfSMitsuru IWASAKI 2385986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); 2386986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length); 2387e1e9a4bfSMitsuru IWASAKI return (sp); 2388e1e9a4bfSMitsuru IWASAKI } 2389e1e9a4bfSMitsuru IWASAKI 2390945137d9SNate Lawson static void 2391986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) 2392e1e9a4bfSMitsuru IWASAKI { 2393c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 2394a74172abSNate Lawson printf(" RSD PTR: OEM="); 2395986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); 2396986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", 2397986dffafSJohn Baldwin rp->Revision); 2398986dffafSJohn Baldwin if (rp->Revision < 2) { 2399986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, 2400986dffafSJohn Baldwin rp->Checksum); 2401a74172abSNate Lawson } else { 24027d369c6eSJung-uk Kim printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n", 24037d369c6eSJung-uk Kim (uintmax_t)rp->XsdtPhysicalAddress, rp->Length, 2404986dffafSJohn Baldwin rp->ExtendedChecksum); 2405a74172abSNate Lawson } 2406c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 2407e1e9a4bfSMitsuru IWASAKI } 2408e1e9a4bfSMitsuru IWASAKI 2409945137d9SNate Lawson static void 2410986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) 2411e1e9a4bfSMitsuru IWASAKI { 2412986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp; 2413986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 2414986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 2415a74172abSNate Lawson vm_offset_t addr; 2416a74172abSNate Lawson int entries, i; 2417e1e9a4bfSMitsuru IWASAKI 2418e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 2419986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 2420986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 2421986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 2422e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 2423fe1d0c2dSJung-uk Kim if (addr_size == 4) 2424986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 2425fe1d0c2dSJung-uk Kim else 2426986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 2427fe1d0c2dSJung-uk Kim if (addr == 0) 2428fe1d0c2dSJung-uk Kim continue; 2429986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 2430986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) { 24315cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 2432986dffafSJohn Baldwin sdp->Signature); 24335cf6d493SNate Lawson continue; 24345cf6d493SNate Lawson } 2435ebc22d04SAlexander Motin if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4)) 2436ebc22d04SAlexander Motin acpi_handle_bert(sdp); 2437ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4)) 2438ebc22d04SAlexander Motin acpi_handle_einj(sdp); 2439ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4)) 2440ebc22d04SAlexander Motin acpi_handle_erst(sdp); 2441ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) 24422177d4e6SNate Lawson acpi_handle_fadt(sdp); 2443986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) 2444986dffafSJohn Baldwin acpi_handle_madt(sdp); 2445ebc22d04SAlexander Motin else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4)) 2446ebc22d04SAlexander Motin acpi_handle_hest(sdp); 2447986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) 244879d7565cSPeter Wemm acpi_handle_hpet(sdp); 2449986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) 245055d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 2451986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) 2452a47e681bSScott Long acpi_handle_mcfg(sdp); 245333866658SJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) 245433866658SJohn Baldwin acpi_handle_slit(sdp); 2455986dffafSJohn Baldwin else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) 2456a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 2457c031c93bSTakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) 2458c031c93bSTakanori Watanabe acpi_handle_tcpa(sdp); 2459ec650989SNeel Natu else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) 2460ec650989SNeel Natu acpi_handle_dmar(sdp); 24616d789b61SKonstantin Belousov else if (!memcmp(sdp->Signature, ACPI_SIG_IVRS, 4)) 24626d789b61SKonstantin Belousov acpi_handle_ivrs(sdp); 2463340c0022SEd Maste else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4)) 2464340c0022SEd Maste acpi_handle_nfit(sdp); 2465ed26c389SScott Long else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4)) 2466ed26c389SScott Long acpi_handle_wddt(sdp); 24675857fba5SBen Widawsky else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4)) 24685857fba5SBen Widawsky acpi_handle_lpit(sdp); 2469877fc2e3STakanori Watanabe else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4)) 2470877fc2e3STakanori Watanabe acpi_handle_tpm2(sdp); 2471773b6454SNate Lawson else { 2472773b6454SNate Lawson printf(BEGIN_COMMENT); 2473773b6454SNate Lawson acpi_print_sdt(sdp); 2474773b6454SNate Lawson printf(END_COMMENT); 2475773b6454SNate Lawson } 2476e1e9a4bfSMitsuru IWASAKI } 2477e1e9a4bfSMitsuru IWASAKI } 2478c62f1cccSMitsuru IWASAKI 2479986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2480476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 2481945137d9SNate Lawson { 2482986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp; 2483986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp; 2484945137d9SNate Lawson 2485945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 2486945137d9SNate Lawson if (!rp) 2487945137d9SNate Lawson errx(1, "Can't find ACPI information"); 2488945137d9SNate Lawson 2489945137d9SNate Lawson if (tflag) 2490945137d9SNate Lawson acpi_print_rsd_ptr(rp); 2491986dffafSJohn Baldwin if (rp->Revision < 2) { 2492986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); 2493986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || 2494986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 2495945137d9SNate Lawson errx(1, "RSDT is corrupted"); 2496a74172abSNate Lawson addr_size = sizeof(uint32_t); 2497a74172abSNate Lawson } else { 2498986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); 2499986dffafSJohn Baldwin if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || 2500986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0) 2501a74172abSNate Lawson errx(1, "XSDT is corrupted"); 2502a74172abSNate Lawson addr_size = sizeof(uint64_t); 2503a74172abSNate Lawson } 2504945137d9SNate Lawson return (rsdp); 2505945137d9SNate Lawson } 2506c62f1cccSMitsuru IWASAKI 250762c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 2508bfa3f012SMarcel Moolenaar static int 2509986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) 2510bfa3f012SMarcel Moolenaar { 2511986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt; 2512986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt; 2513bfa3f012SMarcel Moolenaar uint8_t sum; 2514bfa3f012SMarcel Moolenaar 251562c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 2516bfa3f012SMarcel Moolenaar sdt = *dsdt; 2517bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 2518986dffafSJohn Baldwin sdt.Checksum = 0; 2519986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length - 2520986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 2521986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); 2522f7675a56SNate Lawson while (ssdt != NULL) { 2523986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); 2524986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1, 2525986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER)); 2526986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); 2527bfa3f012SMarcel Moolenaar } 2528986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); 2529986dffafSJohn Baldwin sdt.Checksum -= sum; 2530bfa3f012SMarcel Moolenaar } 253162c7bde1SNate Lawson 253262c7bde1SNate Lawson /* Write out the DSDT header and body. */ 2533986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); 2534986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); 253562c7bde1SNate Lawson 2536b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 2537f7675a56SNate Lawson if (rsdt != NULL) { 2538bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 2539bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 2540986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length - 2541986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER)); 2542bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 2543bfa3f012SMarcel Moolenaar } 2544bfa3f012SMarcel Moolenaar } 2545bfa3f012SMarcel Moolenaar return (0); 2546bfa3f012SMarcel Moolenaar } 2547bfa3f012SMarcel Moolenaar 2548c62f1cccSMitsuru IWASAKI void 2549986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 2550c62f1cccSMitsuru IWASAKI { 2551945137d9SNate Lawson int fd; 2552945137d9SNate Lawson mode_t mode; 2553945137d9SNate Lawson 2554945137d9SNate Lawson assert(outfile != NULL); 2555945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 2556945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 2557945137d9SNate Lawson if (fd == -1) { 2558945137d9SNate Lawson perror("dsdt_save_file"); 2559945137d9SNate Lawson return; 2560945137d9SNate Lawson } 2561bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 2562945137d9SNate Lawson close(fd); 2563c62f1cccSMitsuru IWASAKI } 2564c62f1cccSMitsuru IWASAKI 2565945137d9SNate Lawson void 2566986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) 2567c62f1cccSMitsuru IWASAKI { 25687e2cc014SDon Lewis char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX]; 25697e2cc014SDon Lewis const char *iname = "/acpdump.din"; 25707e2cc014SDon Lewis const char *oname = "/acpdump.dsl"; 257199065116SJung-uk Kim const char *tmpdir; 2572945137d9SNate Lawson FILE *fp; 257399065116SJung-uk Kim size_t len; 25747e2cc014SDon Lewis int fd, status; 25757e2cc014SDon Lewis pid_t pid; 2576945137d9SNate Lawson 257799065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 257899065116SJung-uk Kim if (tmpdir == NULL) 257999065116SJung-uk Kim tmpdir = _PATH_TMP; 25807e2cc014SDon Lewis if (realpath(tmpdir, buf) == NULL) { 2581d6a6e590SJung-uk Kim perror("realpath tmp dir"); 258299065116SJung-uk Kim return; 258399065116SJung-uk Kim } 25847e2cc014SDon Lewis len = sizeof(wrkdir) - strlen(iname); 25857e2cc014SDon Lewis if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) { 25867e2cc014SDon Lewis fprintf(stderr, "$TMPDIR too long\n"); 25877e2cc014SDon Lewis return; 25887e2cc014SDon Lewis } 25897e2cc014SDon Lewis if (mkdtemp(wrkdir) == NULL) { 25907e2cc014SDon Lewis perror("mkdtemp tmp working dir"); 25917e2cc014SDon Lewis return; 25927e2cc014SDon Lewis } 259330bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname); 259430bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 25957e2cc014SDon Lewis fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 2596945137d9SNate Lawson if (fd < 0) { 2597945137d9SNate Lawson perror("iasl tmp file"); 2598945137d9SNate Lawson return; 2599c62f1cccSMitsuru IWASAKI } 2600bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 2601945137d9SNate Lawson close(fd); 2602945137d9SNate Lawson 2603945137d9SNate Lawson /* Run iasl -d on the temp file */ 26047e2cc014SDon Lewis if ((pid = fork()) == 0) { 2605945137d9SNate Lawson close(STDOUT_FILENO); 2606945137d9SNate Lawson if (vflag == 0) 2607945137d9SNate Lawson close(STDERR_FILENO); 260899065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 2609945137d9SNate Lawson err(1, "exec"); 2610c62f1cccSMitsuru IWASAKI } 26117e2cc014SDon Lewis if (pid > 0) 26127e2cc014SDon Lewis wait(&status); 26137e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 26147e2cc014SDon Lewis perror("unlink"); 26157e2cc014SDon Lewis goto out; 26167e2cc014SDon Lewis } 26177e2cc014SDon Lewis if (pid < 0) { 26187e2cc014SDon Lewis perror("fork"); 26197e2cc014SDon Lewis goto out; 26207e2cc014SDon Lewis } 26217e2cc014SDon Lewis if (status != 0) { 2622861f5b95SSHENG-YI HONG fprintf(stderr, "iasl exit status = %d\n", status); 26237e2cc014SDon Lewis } 2624945137d9SNate Lawson 2625945137d9SNate Lawson /* Dump iasl's output to stdout */ 262630bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname); 262730bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1); 262899065116SJung-uk Kim fp = fopen(tmpstr, "r"); 26297e2cc014SDon Lewis if (unlink(tmpstr) < 0) { 26307e2cc014SDon Lewis perror("unlink"); 26317e2cc014SDon Lewis goto out; 26327e2cc014SDon Lewis } 2633945137d9SNate Lawson if (fp == NULL) { 2634945137d9SNate Lawson perror("iasl tmp file (read)"); 26357e2cc014SDon Lewis goto out; 2636945137d9SNate Lawson } 2637945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 2638945137d9SNate Lawson fwrite(buf, 1, len, stdout); 2639945137d9SNate Lawson fclose(fp); 26407e2cc014SDon Lewis 26417e2cc014SDon Lewis out: 26427e2cc014SDon Lewis if (rmdir(wrkdir) < 0) 26437e2cc014SDon Lewis perror("rmdir"); 2644c62f1cccSMitsuru IWASAKI } 2645c62f1cccSMitsuru IWASAKI 2646945137d9SNate Lawson void 2647986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp) 2648c62f1cccSMitsuru IWASAKI { 2649945137d9SNate Lawson acpi_handle_rsdt(rsdp); 2650c62f1cccSMitsuru IWASAKI } 2651c62f1cccSMitsuru IWASAKI 2652bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 2653986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2654986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) 2655c62f1cccSMitsuru IWASAKI { 2656986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 2657986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 2658986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 2659a74172abSNate Lawson vm_offset_t addr; 2660a74172abSNate Lawson int entries, i; 2661945137d9SNate Lawson 2662986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp; 2663986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp; 2664986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; 2665945137d9SNate Lawson for (i = 0; i < entries; i++) { 2666fe1d0c2dSJung-uk Kim if (addr_size == 4) 2667986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]); 2668fe1d0c2dSJung-uk Kim else 2669986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]); 2670fe1d0c2dSJung-uk Kim if (addr == 0) 2671fe1d0c2dSJung-uk Kim continue; 2672986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); 2673bfa3f012SMarcel Moolenaar if (last != NULL) { 2674bfa3f012SMarcel Moolenaar if (sdt == last) 2675bfa3f012SMarcel Moolenaar last = NULL; 2676bfa3f012SMarcel Moolenaar continue; 2677bfa3f012SMarcel Moolenaar } 2678986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig))) 2679a74172abSNate Lawson continue; 2680986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 2681945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 2682945137d9SNate Lawson return (sdt); 2683c62f1cccSMitsuru IWASAKI } 2684c62f1cccSMitsuru IWASAKI 2685945137d9SNate Lawson return (NULL); 2686c62f1cccSMitsuru IWASAKI } 2687c62f1cccSMitsuru IWASAKI 2688986dffafSJohn Baldwin ACPI_TABLE_HEADER * 2689986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt) 2690c62f1cccSMitsuru IWASAKI { 2691986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt; 2692c62f1cccSMitsuru IWASAKI 2693986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ 2694c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 2695986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); 26962e71eb12SNate Lawson else 2697986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); 2698986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length)) 2699945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 2700945137d9SNate Lawson return (sdt); 2701c62f1cccSMitsuru IWASAKI } 2702