1e1e9a4bfSMitsuru IWASAKI /*- 2e1e9a4bfSMitsuru IWASAKI * Copyright (c) 1998 Doug Rabson 3e1e9a4bfSMitsuru IWASAKI * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 4e1e9a4bfSMitsuru IWASAKI * All rights reserved. 5e1e9a4bfSMitsuru IWASAKI * 6e1e9a4bfSMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without 7e1e9a4bfSMitsuru IWASAKI * modification, are permitted provided that the following conditions 8e1e9a4bfSMitsuru IWASAKI * are met: 9e1e9a4bfSMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright 10e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer. 11e1e9a4bfSMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright 12e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the 13e1e9a4bfSMitsuru IWASAKI * documentation and/or other materials provided with the distribution. 14e1e9a4bfSMitsuru IWASAKI * 15e1e9a4bfSMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e1e9a4bfSMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e1e9a4bfSMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e1e9a4bfSMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e1e9a4bfSMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e1e9a4bfSMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e1e9a4bfSMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e1e9a4bfSMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e1e9a4bfSMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e1e9a4bfSMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e1e9a4bfSMitsuru IWASAKI * SUCH DAMAGE. 26e1e9a4bfSMitsuru IWASAKI * 27e1e9a4bfSMitsuru IWASAKI * $FreeBSD$ 28e1e9a4bfSMitsuru IWASAKI */ 29e1e9a4bfSMitsuru IWASAKI 30e1e9a4bfSMitsuru IWASAKI #include <sys/param.h> 31a74172abSNate Lawson #include <sys/endian.h> 32e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h> 33945137d9SNate Lawson #include <sys/wait.h> 34e1e9a4bfSMitsuru IWASAKI #include <assert.h> 35e1e9a4bfSMitsuru IWASAKI #include <err.h> 36e1e9a4bfSMitsuru IWASAKI #include <fcntl.h> 3799065116SJung-uk Kim #include <paths.h> 38e1e9a4bfSMitsuru IWASAKI #include <stdio.h> 39a0333ad1SJohn Baldwin #include <stdint.h> 4099065116SJung-uk Kim #include <stdlib.h> 41945137d9SNate Lawson #include <string.h> 42e1e9a4bfSMitsuru IWASAKI #include <unistd.h> 43e1e9a4bfSMitsuru IWASAKI 44e1e9a4bfSMitsuru IWASAKI #include "acpidump.h" 45e1e9a4bfSMitsuru IWASAKI 46c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n" 47c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n" 48c62f1cccSMitsuru IWASAKI 49945137d9SNate Lawson static void acpi_print_string(char *s, size_t length); 508e6a8737SNate Lawson static void acpi_print_gas(struct ACPIgas *gas); 51c2962974SNate Lawson static int acpi_get_fadt_revision(struct FADTbody *fadt); 522177d4e6SNate Lawson static void acpi_handle_fadt(struct ACPIsdt *fadt); 53945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id); 54945137d9SNate Lawson static void acpi_print_local_apic(u_char cpu_id, u_char apic_id, 55945137d9SNate Lawson u_int32_t flags); 56945137d9SNate Lawson static void acpi_print_io_apic(u_char apic_id, u_int32_t int_base, 57945137d9SNate Lawson u_int64_t apic_addr); 58945137d9SNate Lawson static void acpi_print_mps_flags(u_int16_t flags); 59945137d9SNate Lawson static void acpi_print_intr(u_int32_t intr, u_int16_t mps_flags); 60945137d9SNate Lawson static void acpi_print_apic(struct MADT_APIC *mp); 61945137d9SNate Lawson static void acpi_handle_apic(struct ACPIsdt *sdp); 62945137d9SNate Lawson static void acpi_handle_hpet(struct ACPIsdt *sdp); 63a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 64a0333ad1SJohn Baldwin uint32_t flags); 65a0333ad1SJohn Baldwin static void acpi_print_srat_memory(struct SRAT_memory *mp); 66a0333ad1SJohn Baldwin static void acpi_print_srat(struct SRATentry *srat); 67a0333ad1SJohn Baldwin static void acpi_handle_srat(struct ACPIsdt *sdp); 68773b6454SNate Lawson static void acpi_print_sdt(struct ACPIsdt *sdp); 692177d4e6SNate Lawson static void acpi_print_fadt(struct ACPIsdt *sdp); 708e6a8737SNate Lawson static void acpi_print_facs(struct FACSbody *facs); 71945137d9SNate Lawson static void acpi_print_dsdt(struct ACPIsdt *dsdp); 72a74172abSNate Lawson static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa); 73945137d9SNate Lawson static void acpi_print_rsd_ptr(struct ACPIrsdp *rp); 74945137d9SNate Lawson static void acpi_handle_rsdt(struct ACPIsdt *rsdp); 75c62f1cccSMitsuru IWASAKI 76773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ 77a74172abSNate Lawson static int addr_size; 78a74172abSNate Lawson 79e1e9a4bfSMitsuru IWASAKI static void 80e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length) 81e1e9a4bfSMitsuru IWASAKI { 82e1e9a4bfSMitsuru IWASAKI int c; 83e1e9a4bfSMitsuru IWASAKI 84e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */ 85e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 86e1e9a4bfSMitsuru IWASAKI length--; 87e1e9a4bfSMitsuru IWASAKI 88e1e9a4bfSMitsuru IWASAKI while (length--) { 89e1e9a4bfSMitsuru IWASAKI c = *s++; 90e1e9a4bfSMitsuru IWASAKI putchar(c); 91e1e9a4bfSMitsuru IWASAKI } 92e1e9a4bfSMitsuru IWASAKI } 93e1e9a4bfSMitsuru IWASAKI 94e1e9a4bfSMitsuru IWASAKI static void 958e6a8737SNate Lawson acpi_print_gas(struct ACPIgas *gas) 968e6a8737SNate Lawson { 978e6a8737SNate Lawson switch(gas->address_space_id) { 988e6a8737SNate Lawson case ACPI_GAS_MEMORY: 99773b6454SNate Lawson printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->address, 1008e6a8737SNate Lawson gas->bit_offset, gas->bit_width); 1018e6a8737SNate Lawson break; 1028e6a8737SNate Lawson case ACPI_GAS_IO: 103e47f1780SNate Lawson printf("0x%02lx:%u[%u] (IO)", (u_long)gas->address, 1048e6a8737SNate Lawson gas->bit_offset, gas->bit_width); 1058e6a8737SNate Lawson break; 1068e6a8737SNate Lawson case ACPI_GAS_PCI: 107e47f1780SNate Lawson printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->address >> 32), 1088e6a8737SNate Lawson (uint16_t)((gas->address >> 16) & 0xffff), 1098e6a8737SNate Lawson (uint16_t)gas->address); 1108e6a8737SNate Lawson break; 1118e6a8737SNate Lawson /* XXX How to handle these below? */ 1128e6a8737SNate Lawson case ACPI_GAS_EMBEDDED: 113e47f1780SNate Lawson printf("0x%x:%u[%u] (EC)", (uint16_t)gas->address, 1148e6a8737SNate Lawson gas->bit_offset, gas->bit_width); 1158e6a8737SNate Lawson break; 1168e6a8737SNate Lawson case ACPI_GAS_SMBUS: 117e47f1780SNate Lawson printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->address, 1188e6a8737SNate Lawson gas->bit_offset, gas->bit_width); 1198e6a8737SNate Lawson break; 1208e6a8737SNate Lawson case ACPI_GAS_FIXED: 1218e6a8737SNate Lawson default: 122773b6454SNate Lawson printf("0x%08lx (?)", (u_long)gas->address); 1238e6a8737SNate Lawson break; 1248e6a8737SNate Lawson } 1258e6a8737SNate Lawson } 1268e6a8737SNate Lawson 127c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ 128c2962974SNate Lawson static int 129c2962974SNate Lawson acpi_get_fadt_revision(struct FADTbody *fadt) 130e1e9a4bfSMitsuru IWASAKI { 131c2962974SNate Lawson int fadt_revision; 132e1e9a4bfSMitsuru IWASAKI 133c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */ 134c83f0f99SNate Lawson if (addr_size == 8) { 135c83f0f99SNate Lawson fadt_revision = 2; 1368e6a8737SNate Lawson 137773b6454SNate Lawson /* 138c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims 139c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If 140c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the 141c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit 142c83f0f99SNate Lawson * version for all subsequent tables. 143773b6454SNate Lawson */ 144c83f0f99SNate Lawson if (fadt->facs_ptr != 0 && 145c83f0f99SNate Lawson (fadt->x_facs_ptr & 0xffffffff) != fadt->facs_ptr) 146c83f0f99SNate Lawson fadt_revision = 1; 147c2962974SNate Lawson } else 148c83f0f99SNate Lawson fadt_revision = 1; 149c2962974SNate Lawson return (fadt_revision); 150c83f0f99SNate Lawson } 151c2962974SNate Lawson 152c2962974SNate Lawson static void 1532177d4e6SNate Lawson acpi_handle_fadt(struct ACPIsdt *sdp) 154c2962974SNate Lawson { 155c2962974SNate Lawson struct ACPIsdt *dsdp; 156c2962974SNate Lawson struct FACSbody *facs; 1572177d4e6SNate Lawson struct FADTbody *fadt; 158c2962974SNate Lawson int fadt_revision; 159c2962974SNate Lawson 1602177d4e6SNate Lawson fadt = (struct FADTbody *)sdp->body; 1612177d4e6SNate Lawson acpi_print_fadt(sdp); 162c83f0f99SNate Lawson 163c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt); 164c83f0f99SNate Lawson if (fadt_revision == 1) 1658e6a8737SNate Lawson facs = (struct FACSbody *)acpi_map_sdt(fadt->facs_ptr); 166773b6454SNate Lawson else 167773b6454SNate Lawson facs = (struct FACSbody *)acpi_map_sdt(fadt->x_facs_ptr); 1688e6a8737SNate Lawson if (memcmp(facs->signature, "FACS", 4) != 0 || facs->len < 64) 1698e6a8737SNate Lawson errx(1, "FACS is corrupt"); 1708e6a8737SNate Lawson acpi_print_facs(facs); 1718e6a8737SNate Lawson 172c83f0f99SNate Lawson if (fadt_revision == 1) 1738e6a8737SNate Lawson dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr); 174773b6454SNate Lawson else 175773b6454SNate Lawson dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr); 176e1e9a4bfSMitsuru IWASAKI if (acpi_checksum(dsdp, dsdp->len)) 177945137d9SNate Lawson errx(1, "DSDT is corrupt"); 178945137d9SNate Lawson acpi_print_dsdt(dsdp); 179c62f1cccSMitsuru IWASAKI } 180c62f1cccSMitsuru IWASAKI 181c62f1cccSMitsuru IWASAKI static void 1820a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id) 1830a473124SJohn Baldwin { 1840a473124SJohn Baldwin 1850a473124SJohn Baldwin printf("\tACPI CPU="); 1860a473124SJohn Baldwin if (cpu_id == 0xff) 1870a473124SJohn Baldwin printf("ALL\n"); 1880a473124SJohn Baldwin else 1890a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id); 1900a473124SJohn Baldwin } 1910a473124SJohn Baldwin 1920a473124SJohn Baldwin static void 1930a473124SJohn Baldwin acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags) 1940a473124SJohn Baldwin { 1950a473124SJohn Baldwin acpi_print_cpu(cpu_id); 1960a473124SJohn Baldwin printf("\tFlags={"); 1970a473124SJohn Baldwin if (flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED) 1980a473124SJohn Baldwin printf("ENABLED"); 1990a473124SJohn Baldwin else 2000a473124SJohn Baldwin printf("DISABLED"); 2010a473124SJohn Baldwin printf("}\n"); 2020a473124SJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)apic_id); 2030a473124SJohn Baldwin } 2040a473124SJohn Baldwin 2050a473124SJohn Baldwin static void 2060a473124SJohn Baldwin acpi_print_io_apic(u_char apic_id, u_int32_t int_base, u_int64_t apic_addr) 2070a473124SJohn Baldwin { 2080a473124SJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)apic_id); 2090a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base); 210945137d9SNate Lawson printf("\tADDR=0x%016jx\n", apic_addr); 2110a473124SJohn Baldwin } 2120a473124SJohn Baldwin 2130a473124SJohn Baldwin static void 2140a473124SJohn Baldwin acpi_print_mps_flags(u_int16_t flags) 2150a473124SJohn Baldwin { 2160a473124SJohn Baldwin 2170a473124SJohn Baldwin printf("\tFlags={Polarity="); 2180a473124SJohn Baldwin switch (flags & MPS_INT_FLAG_POLARITY_MASK) { 2190a473124SJohn Baldwin case MPS_INT_FLAG_POLARITY_CONFORM: 2200a473124SJohn Baldwin printf("conforming"); 2210a473124SJohn Baldwin break; 2220a473124SJohn Baldwin case MPS_INT_FLAG_POLARITY_HIGH: 2230a473124SJohn Baldwin printf("active-hi"); 2240a473124SJohn Baldwin break; 2250a473124SJohn Baldwin case MPS_INT_FLAG_POLARITY_LOW: 2260a473124SJohn Baldwin printf("active-lo"); 2270a473124SJohn Baldwin break; 2280a473124SJohn Baldwin default: 2290a473124SJohn Baldwin printf("0x%x", flags & MPS_INT_FLAG_POLARITY_MASK); 2300a473124SJohn Baldwin break; 2310a473124SJohn Baldwin } 2320a473124SJohn Baldwin printf(", Trigger="); 2330a473124SJohn Baldwin switch (flags & MPS_INT_FLAG_TRIGGER_MASK) { 2340a473124SJohn Baldwin case MPS_INT_FLAG_TRIGGER_CONFORM: 2350a473124SJohn Baldwin printf("conforming"); 2360a473124SJohn Baldwin break; 2370a473124SJohn Baldwin case MPS_INT_FLAG_TRIGGER_EDGE: 2380a473124SJohn Baldwin printf("edge"); 2390a473124SJohn Baldwin break; 2400a473124SJohn Baldwin case MPS_INT_FLAG_TRIGGER_LEVEL: 2410a473124SJohn Baldwin printf("level"); 2420a473124SJohn Baldwin break; 2430a473124SJohn Baldwin default: 2440a473124SJohn Baldwin printf("0x%x", (flags & MPS_INT_FLAG_TRIGGER_MASK) >> 2); 2450a473124SJohn Baldwin } 2460a473124SJohn Baldwin printf("}\n"); 2470a473124SJohn Baldwin } 2480a473124SJohn Baldwin 2490a473124SJohn Baldwin static void 2500a473124SJohn Baldwin acpi_print_intr(u_int32_t intr, u_int16_t mps_flags) 2510a473124SJohn Baldwin { 2520a473124SJohn Baldwin 2530a473124SJohn Baldwin printf("\tINTR=%d\n", (u_int)intr); 2540a473124SJohn Baldwin acpi_print_mps_flags(mps_flags); 2550a473124SJohn Baldwin } 2560a473124SJohn Baldwin 2570a473124SJohn Baldwin const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI", 2580a473124SJohn Baldwin "Local NMI", "Local APIC Override", "IO SAPIC", 2590a473124SJohn Baldwin "Local SAPIC", "Platform Interrupt" }; 2600a473124SJohn Baldwin const char *platform_int_types[] = { "PMI", "INIT", 2610a473124SJohn Baldwin "Corrected Platform Error" }; 2620a473124SJohn Baldwin 2630a473124SJohn Baldwin static void 2640a473124SJohn Baldwin acpi_print_apic(struct MADT_APIC *mp) 2650a473124SJohn Baldwin { 2660a473124SJohn Baldwin 267a0333ad1SJohn Baldwin if (mp->type < sizeof(apic_types) / sizeof(apic_types[0])) 2680a473124SJohn Baldwin printf("\tType=%s\n", apic_types[mp->type]); 269a0333ad1SJohn Baldwin else 270a0333ad1SJohn Baldwin printf("\tType=%d (unknown)\n", mp->type); 2710a473124SJohn Baldwin switch (mp->type) { 2720a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_LOCAL_APIC: 2730a473124SJohn Baldwin acpi_print_local_apic(mp->body.local_apic.cpu_id, 2740a473124SJohn Baldwin mp->body.local_apic.apic_id, mp->body.local_apic.flags); 2750a473124SJohn Baldwin break; 2760a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_IO_APIC: 2770a473124SJohn Baldwin acpi_print_io_apic(mp->body.io_apic.apic_id, 2780a473124SJohn Baldwin mp->body.io_apic.int_base, 2790a473124SJohn Baldwin mp->body.io_apic.apic_addr); 2800a473124SJohn Baldwin break; 2810a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_INT_OVERRIDE: 2820a473124SJohn Baldwin printf("\tBUS=%d\n", (u_int)mp->body.int_override.bus); 2830a473124SJohn Baldwin printf("\tIRQ=%d\n", (u_int)mp->body.int_override.source); 2840a473124SJohn Baldwin acpi_print_intr(mp->body.int_override.intr, 2850a473124SJohn Baldwin mp->body.int_override.mps_flags); 2860a473124SJohn Baldwin break; 2870a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_NMI: 2880a473124SJohn Baldwin acpi_print_intr(mp->body.nmi.intr, mp->body.nmi.mps_flags); 2890a473124SJohn Baldwin break; 2900a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_LOCAL_NMI: 2910a473124SJohn Baldwin acpi_print_cpu(mp->body.local_nmi.cpu_id); 2920a473124SJohn Baldwin printf("\tLINT Pin=%d\n", mp->body.local_nmi.lintpin); 2930a473124SJohn Baldwin acpi_print_mps_flags(mp->body.local_nmi.mps_flags); 2940a473124SJohn Baldwin break; 2950a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE: 296945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n", 297945137d9SNate Lawson mp->body.local_apic_override.apic_addr); 2980a473124SJohn Baldwin break; 2990a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_IO_SAPIC: 3000a473124SJohn Baldwin acpi_print_io_apic(mp->body.io_sapic.apic_id, 3010a473124SJohn Baldwin mp->body.io_sapic.int_base, 3020a473124SJohn Baldwin mp->body.io_sapic.apic_addr); 3030a473124SJohn Baldwin break; 3040a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC: 3050a473124SJohn Baldwin acpi_print_local_apic(mp->body.local_sapic.cpu_id, 3060a473124SJohn Baldwin mp->body.local_sapic.apic_id, mp->body.local_sapic.flags); 3070a473124SJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)mp->body.local_sapic.apic_eid); 3080a473124SJohn Baldwin break; 3090a473124SJohn Baldwin case ACPI_MADT_APIC_TYPE_INT_SRC: 3100a473124SJohn Baldwin printf("\tType=%s\n", 3110a473124SJohn Baldwin platform_int_types[mp->body.int_src.type]); 3120a473124SJohn Baldwin printf("\tCPU ID=%d\n", (u_int)mp->body.int_src.cpu_id); 3130a473124SJohn Baldwin printf("\tCPU EID=%d\n", (u_int)mp->body.int_src.cpu_id); 3140a473124SJohn Baldwin printf("\tSAPIC Vector=%d\n", 3150a473124SJohn Baldwin (u_int)mp->body.int_src.sapic_vector); 3160a473124SJohn Baldwin acpi_print_intr(mp->body.int_src.intr, 3170a473124SJohn Baldwin mp->body.int_src.mps_flags); 3180a473124SJohn Baldwin break; 3190a473124SJohn Baldwin } 3200a473124SJohn Baldwin } 3210a473124SJohn Baldwin 3220a473124SJohn Baldwin static void 3230a473124SJohn Baldwin acpi_handle_apic(struct ACPIsdt *sdp) 3240a473124SJohn Baldwin { 3250a473124SJohn Baldwin struct MADTbody *madtp; 3260a473124SJohn Baldwin struct MADT_APIC *madt_apicp; 3270a473124SJohn Baldwin 328773b6454SNate Lawson printf(BEGIN_COMMENT); 329773b6454SNate Lawson acpi_print_sdt(sdp); 3300a473124SJohn Baldwin madtp = (struct MADTbody *) sdp->body; 3310a473124SJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr); 3320a473124SJohn Baldwin printf("\tFlags={"); 3330a473124SJohn Baldwin if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT) 3340a473124SJohn Baldwin printf("PC-AT"); 3350a473124SJohn Baldwin printf("}\n"); 3360a473124SJohn Baldwin madt_apicp = (struct MADT_APIC *)madtp->body; 3370a473124SJohn Baldwin while (((uintptr_t)madt_apicp) - ((uintptr_t)sdp) < sdp->len) { 3380a473124SJohn Baldwin printf("\n"); 3390a473124SJohn Baldwin acpi_print_apic(madt_apicp); 3400a473124SJohn Baldwin madt_apicp = (struct MADT_APIC *) ((char *)madt_apicp + 3410a473124SJohn Baldwin madt_apicp->len); 3420a473124SJohn Baldwin } 3430a473124SJohn Baldwin printf(END_COMMENT); 3440a473124SJohn Baldwin } 3450a473124SJohn Baldwin 3460a473124SJohn Baldwin static void 34779d7565cSPeter Wemm acpi_handle_hpet(struct ACPIsdt *sdp) 34879d7565cSPeter Wemm { 34979d7565cSPeter Wemm struct HPETbody *hpetp; 35079d7565cSPeter Wemm 351773b6454SNate Lawson printf(BEGIN_COMMENT); 352773b6454SNate Lawson acpi_print_sdt(sdp); 35379d7565cSPeter Wemm hpetp = (struct HPETbody *) sdp->body; 35479d7565cSPeter Wemm printf("\tHPET Number=%d\n", hpetp->hpet_number); 35587f9f09aSTakanori Watanabe printf("\tADDR="); 35687f9f09aSTakanori Watanabe acpi_print_gas(&hpetp->genaddr); 35779d7565cSPeter Wemm printf("\tHW Rev=0x%x\n", hpetp->block_hwrev); 35879d7565cSPeter Wemm printf("\tComparitors=%d\n", hpetp->block_comparitors); 35979d7565cSPeter Wemm printf("\tCounter Size=%d\n", hpetp->block_counter_size); 36079d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={"); 36179d7565cSPeter Wemm if (hpetp->block_legacy_capable) 36279d7565cSPeter Wemm printf("TRUE}\n"); 36379d7565cSPeter Wemm else 36479d7565cSPeter Wemm printf("FALSE}\n"); 36579d7565cSPeter Wemm printf("\tPCI Vendor ID=0x%04x\n", hpetp->block_pcivendor); 36655da3c73SPeter Wemm printf("\tMinimal Tick=%d\n", hpetp->clock_tick); 36779d7565cSPeter Wemm printf(END_COMMENT); 36879d7565cSPeter Wemm } 36979d7565cSPeter Wemm 37079d7565cSPeter Wemm static void 37155d7ff9eSNate Lawson acpi_handle_ecdt(struct ACPIsdt *sdp) 37255d7ff9eSNate Lawson { 37355d7ff9eSNate Lawson struct ECDTbody *ecdt; 37455d7ff9eSNate Lawson 37555d7ff9eSNate Lawson printf(BEGIN_COMMENT); 37655d7ff9eSNate Lawson acpi_print_sdt(sdp); 37755d7ff9eSNate Lawson ecdt = (struct ECDTbody *) sdp->body; 37855d7ff9eSNate Lawson printf("\tEC_CONTROL="); 37955d7ff9eSNate Lawson acpi_print_gas(&ecdt->ec_control); 38055d7ff9eSNate Lawson printf("\n\tEC_DATA="); 38155d7ff9eSNate Lawson acpi_print_gas(&ecdt->ec_data); 38255d7ff9eSNate Lawson printf("\n\tUID=%#x, ", ecdt->uid); 38355d7ff9eSNate Lawson printf("GPE_BIT=%#x\n", ecdt->gpe_bit); 38455d7ff9eSNate Lawson printf("\tEC_ID=%s\n", ecdt->ec_id); 38555d7ff9eSNate Lawson printf(END_COMMENT); 38655d7ff9eSNate Lawson } 38755d7ff9eSNate Lawson 38855d7ff9eSNate Lawson static void 389a47e681bSScott Long acpi_handle_mcfg(struct ACPIsdt *sdp) 390a47e681bSScott Long { 391a47e681bSScott Long struct MCFGbody *mcfg; 392a47e681bSScott Long u_int i, e; 393a47e681bSScott Long 394a47e681bSScott Long printf(BEGIN_COMMENT); 395a47e681bSScott Long acpi_print_sdt(sdp); 396a47e681bSScott Long mcfg = (struct MCFGbody *) sdp->body; 397a47e681bSScott Long 398a47e681bSScott Long e = (sdp->len - ((caddr_t)&mcfg->s[0] - (caddr_t)sdp)) / 399a47e681bSScott Long sizeof(*mcfg->s); 400a47e681bSScott Long for (i = 0; i < e; i++, mcfg++) { 401a47e681bSScott Long printf("\n"); 402a47e681bSScott Long printf("\tBase Address=0x%016jx\n", mcfg->s[i].baseaddr); 403a47e681bSScott Long printf("\tSegment Group=0x%04x\n", mcfg->s[i].seg_grp); 404a47e681bSScott Long printf("\tStart Bus=%d\n", mcfg->s[i].start); 405a47e681bSScott Long printf("\tEnd Bus=%d\n", mcfg->s[i].end); 406a47e681bSScott Long } 407a47e681bSScott Long printf(END_COMMENT); 408a47e681bSScott Long } 409a47e681bSScott Long 410a47e681bSScott Long static void 411a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, 412a0333ad1SJohn Baldwin uint32_t flags) 413a0333ad1SJohn Baldwin { 414a0333ad1SJohn Baldwin 415a0333ad1SJohn Baldwin printf("\tFlags={"); 416a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED) 417a0333ad1SJohn Baldwin printf("ENABLED"); 418a0333ad1SJohn Baldwin else 419a0333ad1SJohn Baldwin printf("DISABLED"); 420a0333ad1SJohn Baldwin printf("}\n"); 421a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id); 422a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain); 423a0333ad1SJohn Baldwin } 424a0333ad1SJohn Baldwin 425a0333ad1SJohn Baldwin static void 426a0333ad1SJohn Baldwin acpi_print_srat_memory(struct SRAT_memory *mp) 427a0333ad1SJohn Baldwin { 428a0333ad1SJohn Baldwin 429a0333ad1SJohn Baldwin printf("\tFlags={"); 430a0333ad1SJohn Baldwin if (mp->flags & ACPI_SRAT_MEM_ENABLED) 431a0333ad1SJohn Baldwin printf("ENABLED"); 432a0333ad1SJohn Baldwin else 433a0333ad1SJohn Baldwin printf("DISABLED"); 434a0333ad1SJohn Baldwin if (mp->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) 435a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE"); 436a0333ad1SJohn Baldwin if (mp->flags & ACPI_SRAT_MEM_NON_VOLATILE) 437a0333ad1SJohn Baldwin printf(",NON_VOLATILE"); 438a0333ad1SJohn Baldwin printf("}\n"); 439a0333ad1SJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->base_address); 440a0333ad1SJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->length); 441a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", mp->proximity_domain); 442a0333ad1SJohn Baldwin } 443a0333ad1SJohn Baldwin 444a0333ad1SJohn Baldwin const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; 445a0333ad1SJohn Baldwin 446a0333ad1SJohn Baldwin static void 447a0333ad1SJohn Baldwin acpi_print_srat(struct SRATentry *srat) 448a0333ad1SJohn Baldwin { 449a0333ad1SJohn Baldwin 450a0333ad1SJohn Baldwin if (srat->type < sizeof(srat_types) / sizeof(srat_types[0])) 451a0333ad1SJohn Baldwin printf("\tType=%s\n", srat_types[srat->type]); 452a0333ad1SJohn Baldwin else 453a0333ad1SJohn Baldwin printf("\tType=%d (unknown)\n", srat->type); 454a0333ad1SJohn Baldwin switch (srat->type) { 455a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY: 456a0333ad1SJohn Baldwin acpi_print_srat_cpu(srat->body.cpu.apic_id, 457a0333ad1SJohn Baldwin srat->body.cpu.proximity_domain_hi[2] << 24 | 458a0333ad1SJohn Baldwin srat->body.cpu.proximity_domain_hi[1] << 16 | 459a0333ad1SJohn Baldwin srat->body.cpu.proximity_domain_hi[0] << 0 | 460a0333ad1SJohn Baldwin srat->body.cpu.proximity_domain_lo, srat->body.cpu.flags); 461a0333ad1SJohn Baldwin break; 462a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 463a0333ad1SJohn Baldwin acpi_print_srat_memory(&srat->body.mem); 464a0333ad1SJohn Baldwin break; 465a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 466a0333ad1SJohn Baldwin acpi_print_srat_cpu(srat->body.x2apic.apic_id, 467a0333ad1SJohn Baldwin srat->body.x2apic.proximity_domain, 468a0333ad1SJohn Baldwin srat->body.x2apic.flags); 469a0333ad1SJohn Baldwin break; 470a0333ad1SJohn Baldwin } 471a0333ad1SJohn Baldwin } 472a0333ad1SJohn Baldwin 473a0333ad1SJohn Baldwin static void 474a0333ad1SJohn Baldwin acpi_handle_srat(struct ACPIsdt *sdp) 475a0333ad1SJohn Baldwin { 476a0333ad1SJohn Baldwin struct SRATbody *sratp; 477a0333ad1SJohn Baldwin struct SRATentry *entry; 478a0333ad1SJohn Baldwin 479a0333ad1SJohn Baldwin printf(BEGIN_COMMENT); 480a0333ad1SJohn Baldwin acpi_print_sdt(sdp); 481a0333ad1SJohn Baldwin sratp = (struct SRATbody *)sdp->body; 482a0333ad1SJohn Baldwin printf("\tTable Revision=%d\n", sratp->table_revision); 483a0333ad1SJohn Baldwin entry = sratp->body; 484a0333ad1SJohn Baldwin while (((uintptr_t)entry) - ((uintptr_t)sdp) < sdp->len) { 485a0333ad1SJohn Baldwin printf("\n"); 486a0333ad1SJohn Baldwin acpi_print_srat(entry); 487a0333ad1SJohn Baldwin entry = (struct SRATentry *)((char *)entry + entry->len); 488a0333ad1SJohn Baldwin } 489a0333ad1SJohn Baldwin printf(END_COMMENT); 490a0333ad1SJohn Baldwin } 491a0333ad1SJohn Baldwin 492a0333ad1SJohn Baldwin static void 493773b6454SNate Lawson acpi_print_sdt(struct ACPIsdt *sdp) 494c62f1cccSMitsuru IWASAKI { 495773b6454SNate Lawson printf(" "); 496e1e9a4bfSMitsuru IWASAKI acpi_print_string(sdp->signature, 4); 497c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n", 498e1e9a4bfSMitsuru IWASAKI sdp->len, sdp->rev, sdp->check); 499e1e9a4bfSMitsuru IWASAKI printf("\tOEMID="); 500e1e9a4bfSMitsuru IWASAKI acpi_print_string(sdp->oemid, 6); 501e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID="); 502e1e9a4bfSMitsuru IWASAKI acpi_print_string(sdp->oemtblid, 8); 503e1e9a4bfSMitsuru IWASAKI printf(", OEM Revision=0x%x,\n", sdp->oemrev); 504e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID="); 505e1e9a4bfSMitsuru IWASAKI acpi_print_string(sdp->creator, 4); 506e1e9a4bfSMitsuru IWASAKI printf(", Creator Revision=0x%x\n", sdp->crerev); 507e1e9a4bfSMitsuru IWASAKI } 508e1e9a4bfSMitsuru IWASAKI 509945137d9SNate Lawson static void 510e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(struct ACPIsdt *rsdp) 511e1e9a4bfSMitsuru IWASAKI { 512e1e9a4bfSMitsuru IWASAKI int i, entries; 513a74172abSNate Lawson u_long addr; 514e1e9a4bfSMitsuru IWASAKI 515773b6454SNate Lawson printf(BEGIN_COMMENT); 516773b6454SNate Lawson acpi_print_sdt(rsdp); 517a74172abSNate Lawson entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size; 518e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ "); 519e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 520e1e9a4bfSMitsuru IWASAKI if (i > 0) 521e1e9a4bfSMitsuru IWASAKI printf(", "); 522a74172abSNate Lawson switch (addr_size) { 523a74172abSNate Lawson case 4: 524a74172abSNate Lawson addr = le32dec((char*)rsdp->body + i * addr_size); 525a74172abSNate Lawson break; 526a74172abSNate Lawson case 8: 527a74172abSNate Lawson addr = le64dec((char*)rsdp->body + i * addr_size); 528a74172abSNate Lawson break; 529a74172abSNate Lawson default: 530a74172abSNate Lawson addr = 0; 531a74172abSNate Lawson } 532a74172abSNate Lawson assert(addr != 0); 533a74172abSNate Lawson printf("0x%08lx", addr); 534e1e9a4bfSMitsuru IWASAKI } 535e1e9a4bfSMitsuru IWASAKI printf(" }\n"); 536c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 537e1e9a4bfSMitsuru IWASAKI } 538e1e9a4bfSMitsuru IWASAKI 5398e6a8737SNate Lawson static const char *acpi_pm_profiles[] = { 5408e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation", 5418e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC" 5428e6a8737SNate Lawson }; 5438e6a8737SNate Lawson 544945137d9SNate Lawson static void 5452177d4e6SNate Lawson acpi_print_fadt(struct ACPIsdt *sdp) 546e1e9a4bfSMitsuru IWASAKI { 5472177d4e6SNate Lawson struct FADTbody *fadt; 5488e6a8737SNate Lawson const char *pm; 549e1e9a4bfSMitsuru IWASAKI char sep; 550e1e9a4bfSMitsuru IWASAKI 5512177d4e6SNate Lawson fadt = (struct FADTbody *)sdp->body; 552c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 5532177d4e6SNate Lawson acpi_print_sdt(sdp); 5542177d4e6SNate Lawson printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->facs_ptr, 5558e6a8737SNate Lawson fadt->dsdt_ptr); 5568e6a8737SNate Lawson printf("\tINT_MODEL=%s\n", fadt->int_model ? "APIC" : "PIC"); 5578e6a8737SNate Lawson if (fadt->pm_profile >= sizeof(acpi_pm_profiles) / sizeof(char *)) 5588e6a8737SNate Lawson pm = "Reserved"; 5598e6a8737SNate Lawson else 5608e6a8737SNate Lawson pm = acpi_pm_profiles[fadt->pm_profile]; 5618e6a8737SNate Lawson printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->pm_profile); 5628e6a8737SNate Lawson printf("\tSCI_INT=%d\n", fadt->sci_int); 5638e6a8737SNate Lawson printf("\tSMI_CMD=0x%x, ", fadt->smi_cmd); 5648e6a8737SNate Lawson printf("ACPI_ENABLE=0x%x, ", fadt->acpi_enable); 5658e6a8737SNate Lawson printf("ACPI_DISABLE=0x%x, ", fadt->acpi_disable); 5668e6a8737SNate Lawson printf("S4BIOS_REQ=0x%x\n", fadt->s4biosreq); 5678e6a8737SNate Lawson printf("\tPSTATE_CNT=0x%x\n", fadt->pstate_cnt); 568e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 5698e6a8737SNate Lawson fadt->pm1a_evt_blk, 5708e6a8737SNate Lawson fadt->pm1a_evt_blk + fadt->pm1_evt_len - 1); 5718e6a8737SNate Lawson if (fadt->pm1b_evt_blk != 0) 572e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 5738e6a8737SNate Lawson fadt->pm1b_evt_blk, 5748e6a8737SNate Lawson fadt->pm1b_evt_blk + fadt->pm1_evt_len - 1); 575e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 5768e6a8737SNate Lawson fadt->pm1a_cnt_blk, 5778e6a8737SNate Lawson fadt->pm1a_cnt_blk + fadt->pm1_cnt_len - 1); 5788e6a8737SNate Lawson if (fadt->pm1b_cnt_blk != 0) 579e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 5808e6a8737SNate Lawson fadt->pm1b_cnt_blk, 5818e6a8737SNate Lawson fadt->pm1b_cnt_blk + fadt->pm1_cnt_len - 1); 5828e6a8737SNate Lawson if (fadt->pm2_cnt_blk != 0) 583e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 5848e6a8737SNate Lawson fadt->pm2_cnt_blk, 5858e6a8737SNate Lawson fadt->pm2_cnt_blk + fadt->pm2_cnt_len - 1); 586c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n", 5878e6a8737SNate Lawson fadt->pm_tmr_blk, 5888e6a8737SNate Lawson fadt->pm_tmr_blk + fadt->pm_tmr_len - 1); 5898e6a8737SNate Lawson if (fadt->gpe0_blk != 0) 5908e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n", 5918e6a8737SNate Lawson fadt->gpe0_blk, 5928e6a8737SNate Lawson fadt->gpe0_blk + fadt->gpe0_len - 1); 5938e6a8737SNate Lawson if (fadt->gpe1_blk != 0) 5948e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 5958e6a8737SNate Lawson fadt->gpe1_blk, 5968e6a8737SNate Lawson fadt->gpe1_blk + fadt->gpe1_len - 1, 5978e6a8737SNate Lawson fadt->gpe1_base); 5988e6a8737SNate Lawson if (fadt->cst_cnt != 0) 5998e6a8737SNate Lawson printf("\tCST_CNT=0x%x\n", fadt->cst_cnt); 60051c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", 6018e6a8737SNate Lawson fadt->p_lvl2_lat, fadt->p_lvl3_lat); 602e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 6038e6a8737SNate Lawson fadt->flush_size, fadt->flush_stride); 604e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 6058e6a8737SNate Lawson fadt->duty_off, fadt->duty_width); 606e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 6078e6a8737SNate Lawson fadt->day_alrm, fadt->mon_alrm, fadt->century); 608e1e9a4bfSMitsuru IWASAKI 6098e6a8737SNate Lawson #define PRINTFLAG(var, flag) do { \ 6108e6a8737SNate Lawson if ((var) & FADT_FLAG_## flag) { \ 6118e6a8737SNate Lawson printf("%c%s", sep, #flag); sep = ','; \ 612e1e9a4bfSMitsuru IWASAKI } \ 613e1e9a4bfSMitsuru IWASAKI } while (0) 614e1e9a4bfSMitsuru IWASAKI 6158e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH="); 6168e6a8737SNate Lawson sep = '{'; 6178e6a8737SNate Lawson PRINTFLAG(fadt->iapc_boot_arch, LEGACY_DEV); 6188e6a8737SNate Lawson PRINTFLAG(fadt->iapc_boot_arch, 8042); 61969a9febdSNate Lawson if (fadt->iapc_boot_arch != 0) 6204e36f5a1SNate Lawson printf("}"); 6214e36f5a1SNate Lawson printf("\n"); 6228e6a8737SNate Lawson 6238e6a8737SNate Lawson printf("\tFlags="); 6248e6a8737SNate Lawson sep = '{'; 6258e6a8737SNate Lawson PRINTFLAG(fadt->flags, WBINVD); 6268e6a8737SNate Lawson PRINTFLAG(fadt->flags, WBINVD_FLUSH); 6278e6a8737SNate Lawson PRINTFLAG(fadt->flags, PROC_C1); 6288e6a8737SNate Lawson PRINTFLAG(fadt->flags, P_LVL2_UP); 6298e6a8737SNate Lawson PRINTFLAG(fadt->flags, PWR_BUTTON); 6308e6a8737SNate Lawson PRINTFLAG(fadt->flags, SLP_BUTTON); 6318e6a8737SNate Lawson PRINTFLAG(fadt->flags, FIX_RTC); 6328e6a8737SNate Lawson PRINTFLAG(fadt->flags, RTC_S4); 6338e6a8737SNate Lawson PRINTFLAG(fadt->flags, TMR_VAL_EXT); 6348e6a8737SNate Lawson PRINTFLAG(fadt->flags, DCK_CAP); 6358e6a8737SNate Lawson PRINTFLAG(fadt->flags, RESET_REG); 6368e6a8737SNate Lawson PRINTFLAG(fadt->flags, SEALED_CASE); 6378e6a8737SNate Lawson PRINTFLAG(fadt->flags, HEADLESS); 6388e6a8737SNate Lawson PRINTFLAG(fadt->flags, CPU_SW_SLP); 63969a9febdSNate Lawson if (fadt->flags != 0) 6408e6a8737SNate Lawson printf("}\n"); 641e1e9a4bfSMitsuru IWASAKI 642e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG 643e1e9a4bfSMitsuru IWASAKI 6448e6a8737SNate Lawson if (fadt->flags & FADT_FLAG_RESET_REG) { 6458e6a8737SNate Lawson printf("\tRESET_REG="); 6468e6a8737SNate Lawson acpi_print_gas(&fadt->reset_reg); 6478e6a8737SNate Lawson printf(", RESET_VALUE=%#x\n", fadt->reset_value); 6488e6a8737SNate Lawson } 649c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) { 650773b6454SNate Lawson printf("\tX_FACS=0x%08lx, ", (u_long)fadt->x_facs_ptr); 651773b6454SNate Lawson printf("X_DSDT=0x%08lx\n", (u_long)fadt->x_dsdt_ptr); 652c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK="); 653773b6454SNate Lawson acpi_print_gas(&fadt->x_pm1a_evt_blk); 654c08c4e81SNate Lawson if (fadt->x_pm1b_evt_blk.address != 0) { 655c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK="); 656773b6454SNate Lawson acpi_print_gas(&fadt->x_pm1b_evt_blk); 657c08c4e81SNate Lawson } 658c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK="); 659773b6454SNate Lawson acpi_print_gas(&fadt->x_pm1a_cnt_blk); 660c08c4e81SNate Lawson if (fadt->x_pm1b_cnt_blk.address != 0) { 661c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK="); 662773b6454SNate Lawson acpi_print_gas(&fadt->x_pm1b_cnt_blk); 663c08c4e81SNate Lawson } 664c08c4e81SNate Lawson if (fadt->x_pm1b_cnt_blk.address != 0) { 665773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK="); 666773b6454SNate Lawson acpi_print_gas(&fadt->x_pm2_cnt_blk); 667c08c4e81SNate Lawson } 668773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK="); 669773b6454SNate Lawson acpi_print_gas(&fadt->x_pm_tmr_blk); 670c08c4e81SNate Lawson if (fadt->x_gpe0_blk.address != 0) { 671773b6454SNate Lawson printf("\n\tX_GPE0_BLK="); 672773b6454SNate Lawson acpi_print_gas(&fadt->x_gpe0_blk); 673c08c4e81SNate Lawson } 674c08c4e81SNate Lawson if (fadt->x_gpe1_blk.address != 0) { 675773b6454SNate Lawson printf("\n\tX_GPE1_BLK="); 676773b6454SNate Lawson acpi_print_gas(&fadt->x_gpe1_blk); 677c08c4e81SNate Lawson } 678773b6454SNate Lawson printf("\n"); 679773b6454SNate Lawson } 6808e6a8737SNate Lawson 6818e6a8737SNate Lawson printf(END_COMMENT); 6828e6a8737SNate Lawson } 6838e6a8737SNate Lawson 6848e6a8737SNate Lawson static void 6858e6a8737SNate Lawson acpi_print_facs(struct FACSbody *facs) 6868e6a8737SNate Lawson { 6878e6a8737SNate Lawson printf(BEGIN_COMMENT); 6888e6a8737SNate Lawson printf(" FACS:\tLength=%u, ", facs->len); 6898e6a8737SNate Lawson printf("HwSig=0x%08x, ", facs->hw_sig); 6908e6a8737SNate Lawson printf("Firm_Wake_Vec=0x%08x\n", facs->firm_wake_vec); 6918e6a8737SNate Lawson 692773b6454SNate Lawson printf("\tGlobal_Lock="); 6938e6a8737SNate Lawson if (facs->global_lock != 0) { 6948e6a8737SNate Lawson if (facs->global_lock & FACS_FLAG_LOCK_PENDING) 6958e6a8737SNate Lawson printf("PENDING,"); 6968e6a8737SNate Lawson if (facs->global_lock & FACS_FLAG_LOCK_OWNED) 6978e6a8737SNate Lawson printf("OWNED"); 6988e6a8737SNate Lawson } 699773b6454SNate Lawson printf("\n"); 7008e6a8737SNate Lawson 701773b6454SNate Lawson printf("\tFlags="); 7028e6a8737SNate Lawson if (facs->flags & FACS_FLAG_S4BIOS_F) 7038e6a8737SNate Lawson printf("S4BIOS"); 704773b6454SNate Lawson printf("\n"); 7058e6a8737SNate Lawson 7068e6a8737SNate Lawson if (facs->x_firm_wake_vec != 0) { 7078e6a8737SNate Lawson printf("\tX_Firm_Wake_Vec=%08lx\n", 7088e6a8737SNate Lawson (u_long)facs->x_firm_wake_vec); 7098e6a8737SNate Lawson } 710773b6454SNate Lawson printf("\tVersion=%u\n", facs->version); 7118e6a8737SNate Lawson 712c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 713e1e9a4bfSMitsuru IWASAKI } 714e1e9a4bfSMitsuru IWASAKI 715945137d9SNate Lawson static void 716e1e9a4bfSMitsuru IWASAKI acpi_print_dsdt(struct ACPIsdt *dsdp) 717e1e9a4bfSMitsuru IWASAKI { 718773b6454SNate Lawson printf(BEGIN_COMMENT); 719773b6454SNate Lawson acpi_print_sdt(dsdp); 720773b6454SNate Lawson printf(END_COMMENT); 721e1e9a4bfSMitsuru IWASAKI } 722e1e9a4bfSMitsuru IWASAKI 723e1e9a4bfSMitsuru IWASAKI int 724e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length) 725e1e9a4bfSMitsuru IWASAKI { 726e1e9a4bfSMitsuru IWASAKI u_int8_t *bp; 727e1e9a4bfSMitsuru IWASAKI u_int8_t sum; 728e1e9a4bfSMitsuru IWASAKI 729e1e9a4bfSMitsuru IWASAKI bp = p; 730e1e9a4bfSMitsuru IWASAKI sum = 0; 731e1e9a4bfSMitsuru IWASAKI while (length--) 732e1e9a4bfSMitsuru IWASAKI sum += *bp++; 733e1e9a4bfSMitsuru IWASAKI 734e1e9a4bfSMitsuru IWASAKI return (sum); 735e1e9a4bfSMitsuru IWASAKI } 736e1e9a4bfSMitsuru IWASAKI 737945137d9SNate Lawson static struct ACPIsdt * 738e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa) 739e1e9a4bfSMitsuru IWASAKI { 740e1e9a4bfSMitsuru IWASAKI struct ACPIsdt *sp; 741e1e9a4bfSMitsuru IWASAKI 742e1e9a4bfSMitsuru IWASAKI sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); 743e1e9a4bfSMitsuru IWASAKI sp = acpi_map_physical(pa, sp->len); 744e1e9a4bfSMitsuru IWASAKI return (sp); 745e1e9a4bfSMitsuru IWASAKI } 746e1e9a4bfSMitsuru IWASAKI 747945137d9SNate Lawson static void 748e1e9a4bfSMitsuru IWASAKI acpi_print_rsd_ptr(struct ACPIrsdp *rp) 749e1e9a4bfSMitsuru IWASAKI { 750c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT); 751a74172abSNate Lawson printf(" RSD PTR: OEM="); 752e1e9a4bfSMitsuru IWASAKI acpi_print_string(rp->oem, 6); 753773b6454SNate Lawson printf(", ACPI_Rev=%s (%d)\n", rp->revision < 2 ? "1.0x" : "2.0x", 754a74172abSNate Lawson rp->revision); 755a74172abSNate Lawson if (rp->revision < 2) { 756a74172abSNate Lawson printf("\tRSDT=0x%08x, cksum=%u\n", rp->rsdt_addr, rp->sum); 757a74172abSNate Lawson } else { 758a74172abSNate Lawson printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", 759a74172abSNate Lawson (u_long)rp->xsdt_addr, rp->length, rp->xsum); 760a74172abSNate Lawson } 761c62f1cccSMitsuru IWASAKI printf(END_COMMENT); 762e1e9a4bfSMitsuru IWASAKI } 763e1e9a4bfSMitsuru IWASAKI 764945137d9SNate Lawson static void 765e1e9a4bfSMitsuru IWASAKI acpi_handle_rsdt(struct ACPIsdt *rsdp) 766e1e9a4bfSMitsuru IWASAKI { 767e1e9a4bfSMitsuru IWASAKI struct ACPIsdt *sdp; 768a74172abSNate Lawson vm_offset_t addr; 769a74172abSNate Lawson int entries, i; 770e1e9a4bfSMitsuru IWASAKI 771e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp); 772a74172abSNate Lawson entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size; 773e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) { 774a74172abSNate Lawson switch (addr_size) { 775a74172abSNate Lawson case 4: 776a74172abSNate Lawson addr = le32dec((char*)rsdp->body + i * addr_size); 777a74172abSNate Lawson break; 778a74172abSNate Lawson case 8: 779a74172abSNate Lawson addr = le64dec((char*)rsdp->body + i * addr_size); 780a74172abSNate Lawson break; 781a74172abSNate Lawson default: 782a74172abSNate Lawson assert((addr = 0)); 783a74172abSNate Lawson } 784a74172abSNate Lawson 785a74172abSNate Lawson sdp = (struct ACPIsdt *)acpi_map_sdt(addr); 7865cf6d493SNate Lawson if (acpi_checksum(sdp, sdp->len)) { 7875cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i, 7885cf6d493SNate Lawson sdp->signature); 7895cf6d493SNate Lawson continue; 7905cf6d493SNate Lawson } 791945137d9SNate Lawson if (!memcmp(sdp->signature, "FACP", 4)) 7922177d4e6SNate Lawson acpi_handle_fadt(sdp); 793945137d9SNate Lawson else if (!memcmp(sdp->signature, "APIC", 4)) 7940a473124SJohn Baldwin acpi_handle_apic(sdp); 795945137d9SNate Lawson else if (!memcmp(sdp->signature, "HPET", 4)) 79679d7565cSPeter Wemm acpi_handle_hpet(sdp); 79755d7ff9eSNate Lawson else if (!memcmp(sdp->signature, "ECDT", 4)) 79855d7ff9eSNate Lawson acpi_handle_ecdt(sdp); 799a47e681bSScott Long else if (!memcmp(sdp->signature, "MCFG", 4)) 800a47e681bSScott Long acpi_handle_mcfg(sdp); 801a0333ad1SJohn Baldwin else if (!memcmp(sdp->signature, "SRAT", 4)) 802a0333ad1SJohn Baldwin acpi_handle_srat(sdp); 803773b6454SNate Lawson else { 804773b6454SNate Lawson printf(BEGIN_COMMENT); 805773b6454SNate Lawson acpi_print_sdt(sdp); 806773b6454SNate Lawson printf(END_COMMENT); 807773b6454SNate Lawson } 808e1e9a4bfSMitsuru IWASAKI } 809e1e9a4bfSMitsuru IWASAKI } 810c62f1cccSMitsuru IWASAKI 811945137d9SNate Lawson struct ACPIsdt * 812476daaecSDag-Erling Smørgrav sdt_load_devmem(void) 813945137d9SNate Lawson { 814945137d9SNate Lawson struct ACPIrsdp *rp; 815945137d9SNate Lawson struct ACPIsdt *rsdp; 816945137d9SNate Lawson 817945137d9SNate Lawson rp = acpi_find_rsd_ptr(); 818945137d9SNate Lawson if (!rp) 819945137d9SNate Lawson errx(1, "Can't find ACPI information"); 820945137d9SNate Lawson 821945137d9SNate Lawson if (tflag) 822945137d9SNate Lawson acpi_print_rsd_ptr(rp); 823a74172abSNate Lawson if (rp->revision < 2) { 824945137d9SNate Lawson rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr); 825945137d9SNate Lawson if (memcmp(rsdp->signature, "RSDT", 4) != 0 || 826945137d9SNate Lawson acpi_checksum(rsdp, rsdp->len) != 0) 827945137d9SNate Lawson errx(1, "RSDT is corrupted"); 828a74172abSNate Lawson addr_size = sizeof(uint32_t); 829a74172abSNate Lawson } else { 830a74172abSNate Lawson rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr); 831a74172abSNate Lawson if (memcmp(rsdp->signature, "XSDT", 4) != 0 || 832a74172abSNate Lawson acpi_checksum(rsdp, rsdp->len) != 0) 833a74172abSNate Lawson errx(1, "XSDT is corrupted"); 834a74172abSNate Lawson addr_size = sizeof(uint64_t); 835a74172abSNate Lawson } 836945137d9SNate Lawson return (rsdp); 837945137d9SNate Lawson } 838c62f1cccSMitsuru IWASAKI 83962c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */ 840bfa3f012SMarcel Moolenaar static int 841bfa3f012SMarcel Moolenaar write_dsdt(int fd, struct ACPIsdt *rsdt, struct ACPIsdt *dsdt) 842bfa3f012SMarcel Moolenaar { 843bfa3f012SMarcel Moolenaar struct ACPIsdt sdt; 844bfa3f012SMarcel Moolenaar struct ACPIsdt *ssdt; 845bfa3f012SMarcel Moolenaar uint8_t sum; 846bfa3f012SMarcel Moolenaar 84762c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */ 848bfa3f012SMarcel Moolenaar sdt = *dsdt; 849bfa3f012SMarcel Moolenaar if (rsdt != NULL) { 850bfa3f012SMarcel Moolenaar sdt.check = 0; 851bfa3f012SMarcel Moolenaar sum = acpi_checksum(dsdt->body, dsdt->len - SIZEOF_SDT_HDR); 852bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 853f7675a56SNate Lawson while (ssdt != NULL) { 854bfa3f012SMarcel Moolenaar sdt.len += ssdt->len - SIZEOF_SDT_HDR; 855bfa3f012SMarcel Moolenaar sum += acpi_checksum(ssdt->body, 856bfa3f012SMarcel Moolenaar ssdt->len - SIZEOF_SDT_HDR); 857bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 858bfa3f012SMarcel Moolenaar } 859bfa3f012SMarcel Moolenaar sum += acpi_checksum(&sdt, SIZEOF_SDT_HDR); 860bfa3f012SMarcel Moolenaar sdt.check -= sum; 861bfa3f012SMarcel Moolenaar } 86262c7bde1SNate Lawson 86362c7bde1SNate Lawson /* Write out the DSDT header and body. */ 864bfa3f012SMarcel Moolenaar write(fd, &sdt, SIZEOF_SDT_HDR); 865bfa3f012SMarcel Moolenaar write(fd, dsdt->body, dsdt->len - SIZEOF_SDT_HDR); 86662c7bde1SNate Lawson 867b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */ 868f7675a56SNate Lawson if (rsdt != NULL) { 869bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); 870bfa3f012SMarcel Moolenaar while (ssdt != NULL) { 871bfa3f012SMarcel Moolenaar write(fd, ssdt->body, ssdt->len - SIZEOF_SDT_HDR); 872bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); 873bfa3f012SMarcel Moolenaar } 874bfa3f012SMarcel Moolenaar } 875bfa3f012SMarcel Moolenaar return (0); 876bfa3f012SMarcel Moolenaar } 877bfa3f012SMarcel Moolenaar 878c62f1cccSMitsuru IWASAKI void 879bfa3f012SMarcel Moolenaar dsdt_save_file(char *outfile, struct ACPIsdt *rsdt, struct ACPIsdt *dsdp) 880c62f1cccSMitsuru IWASAKI { 881945137d9SNate Lawson int fd; 882945137d9SNate Lawson mode_t mode; 883945137d9SNate Lawson 884945137d9SNate Lawson assert(outfile != NULL); 885945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 886945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); 887945137d9SNate Lawson if (fd == -1) { 888945137d9SNate Lawson perror("dsdt_save_file"); 889945137d9SNate Lawson return; 890945137d9SNate Lawson } 891bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 892945137d9SNate Lawson close(fd); 893c62f1cccSMitsuru IWASAKI } 894c62f1cccSMitsuru IWASAKI 895945137d9SNate Lawson void 896bfa3f012SMarcel Moolenaar aml_disassemble(struct ACPIsdt *rsdt, struct ACPIsdt *dsdp) 897c62f1cccSMitsuru IWASAKI { 89899065116SJung-uk Kim char buf[PATH_MAX], tmpstr[PATH_MAX]; 89999065116SJung-uk Kim const char *tmpdir; 90099065116SJung-uk Kim char *tmpext; 901945137d9SNate Lawson FILE *fp; 90299065116SJung-uk Kim size_t len; 90399065116SJung-uk Kim int fd; 904945137d9SNate Lawson 90599065116SJung-uk Kim tmpdir = getenv("TMPDIR"); 90699065116SJung-uk Kim if (tmpdir == NULL) 90799065116SJung-uk Kim tmpdir = _PATH_TMP; 90899065116SJung-uk Kim strncpy(tmpstr, tmpdir, sizeof(tmpstr)); 90999065116SJung-uk Kim strncat(tmpstr, "/acpidump.", sizeof(tmpstr) - strlen(tmpdir)); 91099065116SJung-uk Kim if (realpath(tmpstr, buf) == NULL) { 91199065116SJung-uk Kim perror("realpath tmp file"); 91299065116SJung-uk Kim return; 91399065116SJung-uk Kim } 91499065116SJung-uk Kim strncpy(tmpstr, buf, sizeof(tmpstr)); 91599065116SJung-uk Kim len = strlen(buf); 91699065116SJung-uk Kim tmpext = tmpstr + len; 91799065116SJung-uk Kim strncpy(tmpext, "XXXXXX", sizeof(tmpstr) - len); 918945137d9SNate Lawson fd = mkstemp(tmpstr); 919945137d9SNate Lawson if (fd < 0) { 920945137d9SNate Lawson perror("iasl tmp file"); 921945137d9SNate Lawson return; 922c62f1cccSMitsuru IWASAKI } 923bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp); 924945137d9SNate Lawson close(fd); 925945137d9SNate Lawson 926945137d9SNate Lawson /* Run iasl -d on the temp file */ 927945137d9SNate Lawson if (fork() == 0) { 928945137d9SNate Lawson close(STDOUT_FILENO); 929945137d9SNate Lawson if (vflag == 0) 930945137d9SNate Lawson close(STDERR_FILENO); 93199065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL); 932945137d9SNate Lawson err(1, "exec"); 933c62f1cccSMitsuru IWASAKI } 934c62f1cccSMitsuru IWASAKI 935945137d9SNate Lawson wait(NULL); 936945137d9SNate Lawson unlink(tmpstr); 937945137d9SNate Lawson 938945137d9SNate Lawson /* Dump iasl's output to stdout */ 93999065116SJung-uk Kim strncpy(tmpext, "dsl", sizeof(tmpstr) - len); 94099065116SJung-uk Kim fp = fopen(tmpstr, "r"); 94199065116SJung-uk Kim unlink(tmpstr); 942945137d9SNate Lawson if (fp == NULL) { 943945137d9SNate Lawson perror("iasl tmp file (read)"); 944945137d9SNate Lawson return; 945945137d9SNate Lawson } 946945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) 947945137d9SNate Lawson fwrite(buf, 1, len, stdout); 948945137d9SNate Lawson fclose(fp); 949c62f1cccSMitsuru IWASAKI } 950c62f1cccSMitsuru IWASAKI 951945137d9SNate Lawson void 952945137d9SNate Lawson sdt_print_all(struct ACPIsdt *rsdp) 953c62f1cccSMitsuru IWASAKI { 954945137d9SNate Lawson acpi_handle_rsdt(rsdp); 955c62f1cccSMitsuru IWASAKI } 956c62f1cccSMitsuru IWASAKI 957bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */ 958945137d9SNate Lawson struct ACPIsdt * 959bfa3f012SMarcel Moolenaar sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig, struct ACPIsdt *last) 960c62f1cccSMitsuru IWASAKI { 961945137d9SNate Lawson struct ACPIsdt *sdt; 962a74172abSNate Lawson vm_offset_t addr; 963a74172abSNate Lawson int entries, i; 964945137d9SNate Lawson 965a74172abSNate Lawson entries = (rsdt->len - SIZEOF_SDT_HDR) / addr_size; 966945137d9SNate Lawson for (i = 0; i < entries; i++) { 967a74172abSNate Lawson switch (addr_size) { 968a74172abSNate Lawson case 4: 969a74172abSNate Lawson addr = le32dec((char*)rsdt->body + i * addr_size); 970a74172abSNate Lawson break; 971a74172abSNate Lawson case 8: 972a74172abSNate Lawson addr = le64dec((char*)rsdt->body + i * addr_size); 973a74172abSNate Lawson break; 974a74172abSNate Lawson default: 975a74172abSNate Lawson assert((addr = 0)); 976a74172abSNate Lawson } 977a74172abSNate Lawson sdt = (struct ACPIsdt *)acpi_map_sdt(addr); 978bfa3f012SMarcel Moolenaar if (last != NULL) { 979bfa3f012SMarcel Moolenaar if (sdt == last) 980bfa3f012SMarcel Moolenaar last = NULL; 981bfa3f012SMarcel Moolenaar continue; 982bfa3f012SMarcel Moolenaar } 983a74172abSNate Lawson if (memcmp(sdt->signature, sig, strlen(sig))) 984a74172abSNate Lawson continue; 985945137d9SNate Lawson if (acpi_checksum(sdt, sdt->len)) 986945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i); 987945137d9SNate Lawson return (sdt); 988c62f1cccSMitsuru IWASAKI } 989c62f1cccSMitsuru IWASAKI 990945137d9SNate Lawson return (NULL); 991c62f1cccSMitsuru IWASAKI } 992c62f1cccSMitsuru IWASAKI 993945137d9SNate Lawson struct ACPIsdt * 9948e6a8737SNate Lawson dsdt_from_fadt(struct FADTbody *fadt) 995c62f1cccSMitsuru IWASAKI { 996945137d9SNate Lawson struct ACPIsdt *sdt; 997c62f1cccSMitsuru IWASAKI 998c83f0f99SNate Lawson /* Use the DSDT address if it is version 1, otherwise use X_DSDT. */ 999c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1) 10008e6a8737SNate Lawson sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr); 10012e71eb12SNate Lawson else 10022e71eb12SNate Lawson sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr); 1003945137d9SNate Lawson if (acpi_checksum(sdt, sdt->len)) 1004945137d9SNate Lawson errx(1, "DSDT is corrupt\n"); 1005945137d9SNate Lawson return (sdt); 1006c62f1cccSMitsuru IWASAKI } 1007