# HG changeset patch # User cegger@powermacg5.local # Date 1260277658 -3600 Import acpidump from FreeBSD Changes made in the port: - adapt path to iasl from /usr/sbin/iasl to /usr/bin/iasl - fix realpath() usage to accomplish NetBSD's behaviour - use EXIT_FAILURE/EXIT_SUCCESS everywhere - fix crash on corrupt DSDT file and print proper error message - implemented new ACPI table parsers for BOOT, DBGP, SBST, SLIT, SPCR, TCPA, WDAT and WDRT diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/Makefile --- a/usr.sbin/acpitools/acpidump/Makefile +++ b/usr.sbin/acpitools/acpidump/Makefile @@ -1,15 +1,12 @@ -# Id: Makefile,v 1.2 2000/07/14 18:16:29 iwasaki Exp -# $FreeBSD: src/usr.sbin/acpi/acpidump/Makefile,v 1.6 2001/10/22 17:25:25 iwasaki Exp $ +# $NetBSD: $ +# $FreeBSD: src/usr.sbin/acpi/acpidump/Makefile,v 1.7 2003/08/28 03:33:07 njl Exp $ .if (${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64") +CPPFLAGS+=-I${.CURDIR}/../../../sys +CPPFLAGS+=-I${.CURDIR}/.. PROG= acpidump -SRCS= acpi.c acpi_user.c asl_dump.c aml_dump.c acpidump.c -SRCS+= aml_parse.c aml_name.c aml_amlmem.c aml_memman.c aml_store.c \ - aml_obj.c aml_evalobj.c aml_common.c - -CPPFLAGS+=-I${.CURDIR}/../amldb +MAN= acpidump.8 +SRCS= acpi.c acpi_user.c acpidump.c .endif -MAN= acpidump.8 .include -.PATH: ${.CURDIR}/../aml diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/acpi.c --- a/usr.sbin/acpitools/acpidump/acpi.c +++ b/usr.sbin/acpitools/acpidump/acpi.c @@ -1,9 +1,8 @@ -/* $NetBSD: acpi.c,v 1.4 2008/02/13 18:59:18 drochner Exp $ */ +/* $NetBSD: $ */ /*- * Copyright (c) 1998 Doug Rabson * Copyright (c) 2000 Mitsuru IWASAKI - * Copyright (c) 2008 Joerg Sonnenberger * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,71 +26,77 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.4 2001/10/22 17:25:25 iwasaki Exp $ + * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.37 2009/08/25 20:35:57 jhb Exp $ */ + #include __RCSID("$NetBSD: acpi.c,v 1.4 2008/02/13 18:59:18 drochner Exp $"); #include +#include #include - +#include #include #include #include +#include #include +#include +#include +#include #include -#include +#include -#include #include "acpidump.h" -#include "aml/aml_env.h" -#include "aml/aml_common.h" -#include "aml/aml_parse.h" -#include "aml/aml_region.h" - #define BEGIN_COMMENT "/*\n" #define END_COMMENT " */\n" -struct ACPIsdt dsdt_header = { - .signature = "DSDT", - .rev = 1, - .oemid = "OEMID", - .oemtblid = "OEMTBLID", - .oemrev = 0x12345678, - .creator = "CRTR", - .crerev = 0x12345678, -}; +static void acpi_print_string(char *s, size_t length); +static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas); +static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt); +static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt); +static void acpi_print_cpu(u_char cpu_id); +static void acpi_print_cpu_uid(uint32_t uid, char *uid_string); +static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags); +static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, + uint64_t apic_addr); +static void acpi_print_mps_flags(uint16_t flags); +static void acpi_print_intr(uint32_t intr, uint16_t mps_flags); +static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags); +static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp); +static void acpi_handle_boot(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_sbst(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp); +static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, + uint32_t flags, uint32_t clockdomain); +static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); +static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat); +static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_wdat(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp); +static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp); +static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp); +static void acpi_print_facs(ACPI_TABLE_FACS *facs); +static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp); +static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa); +static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp); +static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp); +static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, + void (*action)(ACPI_SUBTABLE_HEADER *)); + +/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */ +static int addr_size; static void -acpi_trim_string(char *s, size_t length) -{ - - /* Trim trailing spaces and NULLs */ - while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) - s[length-- - 1] = '\0'; -} - -static void -acpi_print_dsdt_definition(void) -{ - char oemid[6 + 1]; - char oemtblid[8 + 1]; - - acpi_trim_string((char *)dsdt_header.oemid, sizeof(oemid) - 1); - acpi_trim_string((char *)dsdt_header.oemtblid, sizeof(oemtblid) - 1); - (void)strlcpy(oemid, (const char *)dsdt_header.oemid, sizeof(oemid)); - (void)strlcpy(oemtblid, (const char *)dsdt_header.oemtblid, - sizeof(oemtblid)); - - printf("DefinitionBlock (\"%s\", \"%s\", 0x%x, \"%s\", \"%s\", 0x%x)", - "acpi_dst.aml", "DSDT", dsdt_header.rev, oemid, oemtblid, - dsdt_header.oemrev); -} - -static void -acpi_print_string(const char *s, size_t length) +acpi_print_string(char *s, size_t length) { int c; @@ -106,214 +111,1152 @@ acpi_print_string(const char *s, size_t } static void -acpi_handle_dsdt(struct ACPIsdt *dsdp) +acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) { - u_int8_t *dp; - u_int8_t *end; + switch(gas->SpaceId) { + case ACPI_GAS_MEMORY: + printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address, + gas->BitOffset, gas->BitWidth); + break; + case ACPI_GAS_IO: + printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address, + gas->BitOffset, gas->BitWidth); + break; + case ACPI_GAS_PCI: + printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), + (uint16_t)((gas->Address >> 16) & 0xffff), + (uint16_t)gas->Address); + break; + /* XXX How to handle these below? */ + case ACPI_GAS_EMBEDDED: + printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address, + gas->BitOffset, gas->BitWidth); + break; + case ACPI_GAS_SMBUS: + printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address, + gas->BitOffset, gas->BitWidth); + break; + case ACPI_GAS_CMOS: + case ACPI_GAS_PCIBAR: + case ACPI_GAS_DATATABLE: + case ACPI_GAS_FIXED: + default: + printf("0x%08lx (?)", (u_long)gas->Address); + break; + } +} - acpi_print_dsdt(dsdp); - dp = (u_int8_t *)dsdp->body; - end = (u_int8_t *)dsdp + dsdp->len; +/* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */ +static int +acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt) +{ + int fadt_revision; - acpi_dump_dsdt(dp, end); + /* Set the FADT revision separately from the RSDP version. */ + if (addr_size == 8) { + fadt_revision = 2; + + /* + * A few systems (e.g., IBM T23) have an RSDP that claims + * revision 2 but the 64 bit addresses are invalid. If + * revision 2 and the 32 bit address is non-zero but the + * 32 and 64 bit versions don't match, prefer the 32 bit + * version for all subsequent tables. + */ + if (fadt->Facs != 0 && + (fadt->XFacs & 0xffffffff) != fadt->Facs) + fadt_revision = 1; + } else + fadt_revision = 1; + return (fadt_revision); } static void -acpi_handle_facp(struct FACPbody *facp) +acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) { - struct ACPIsdt *dsdp; + ACPI_TABLE_HEADER *dsdp; + ACPI_TABLE_FACS *facs; + ACPI_TABLE_FADT *fadt; + int fadt_revision; - acpi_print_facp(facp); - dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr); - if (acpi_checksum(dsdp, dsdp->len)) - errx(1, "DSDT is corrupt"); - acpi_handle_dsdt(dsdp); - aml_dump(dsdp); + fadt = (ACPI_TABLE_FADT *)sdp; + acpi_print_fadt(sdp); + + fadt_revision = acpi_get_fadt_revision(fadt); + if (fadt_revision == 1) + facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs); + else + facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs); + if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64) + errx(EXIT_FAILURE, "FACS is corrupt"); + acpi_print_facs(facs); + + if (fadt_revision == 1) + dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); + else + dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); + if (acpi_checksum(dsdp, dsdp->Length)) + errx(EXIT_FAILURE, "DSDT is corrupt"); + acpi_print_dsdt(dsdp); } static void -init_namespace(void) +acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, + void (*action)(ACPI_SUBTABLE_HEADER *)) { - struct aml_environ env; - struct aml_name *newname; + ACPI_SUBTABLE_HEADER *subtable; + char *end; - aml_new_name_group((void *)AML_NAME_GROUP_OS_DEFINED); - env.curname = aml_get_rootname(); - newname = aml_create_name(&env, (const unsigned char *)"\\_OS_"); - newname->property = aml_alloc_object(aml_t_string, NULL); - newname->property->str.needfree = 0; - newname->property->str.string = __UNCONST("Microsoft Windows NT"); - - newname = aml_create_name(&env, (const unsigned char *)"\\_OSI"); - newname->property = aml_alloc_object(aml_t_method, NULL); - newname->property->meth.argnum = 1; -} - -/* - * Public interfaces - */ - -void -acpi_dump_dsdt(u_int8_t *dp, u_int8_t *end) -{ - extern struct aml_environ asl_env; - - acpi_print_dsdt_definition(); - - /* 1st stage: parse only w/o printing */ - init_namespace(); - aml_new_name_group(dp); - bzero(&asl_env, sizeof(asl_env)); - - asl_env.dp = dp; - asl_env.end = end; - asl_env.curname = aml_get_rootname(); - - aml_local_stack_push(aml_local_stack_create()); - aml_parse_objectlist(&asl_env, 0); - aml_local_stack_delete(aml_local_stack_pop()); - - assert(asl_env.dp == asl_env.end); - asl_env.dp = dp; - - /* 2nd stage: dump whole object list */ - printf("\n{\n"); - asl_dump_objectlist(&dp, end, 0); - printf("\n}\n"); - assert(dp == end); -} -void -acpi_print_sdt(struct ACPIsdt *sdp) -{ - - printf(BEGIN_COMMENT); - acpi_print_string((const char *)sdp->signature, 4); - printf(": Length=%d, Revision=%d, Checksum=%d,\n", - sdp->len, sdp->rev, sdp->check); - printf("\tOEMID="); - acpi_print_string((const char *)sdp->oemid, 6); - printf(", OEM Table ID="); - acpi_print_string((const char *)sdp->oemtblid, 8); - printf(", OEM Revision=0x%x,\n", sdp->oemrev); - printf("\tCreator ID="); - acpi_print_string((const char *)sdp->creator, 4); - printf(", Creator Revision=0x%x\n", sdp->crerev); - printf(END_COMMENT); - if (!memcmp(sdp->signature, "DSDT", 4)) { - memcpy(&dsdt_header, sdp, sizeof(dsdt_header)); + subtable = first; + end = (char *)table + table->Length; + while ((char *)subtable < end) { + printf("\n"); + action(subtable); + subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + + subtable->Length); } } -void -acpi_print_rsdt(struct ACPIsdt *rsdp) +static void +acpi_print_cpu(u_char cpu_id) { + + printf("\tACPI CPU="); + if (cpu_id == 0xff) + printf("ALL\n"); + else + printf("%d\n", (u_int)cpu_id); +} + +static void +acpi_print_cpu_uid(uint32_t uid, char *uid_string) +{ + + printf("\tUID=%d", uid); + if (uid_string != NULL) + printf(" (%s)", uid_string); + printf("\n"); +} + +static void +acpi_print_local_apic(uint32_t apic_id, uint32_t flags) +{ + + printf("\tFlags={"); + if (flags & ACPI_MADT_ENABLED) + printf("ENABLED"); + else + printf("DISABLED"); + printf("}\n"); + printf("\tAPIC ID=%d\n", apic_id); +} + +static void +acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr) +{ + + printf("\tAPIC ID=%d\n", apic_id); + printf("\tINT BASE=%d\n", int_base); + printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr); +} + +static void +acpi_print_mps_flags(uint16_t flags) +{ + + printf("\tFlags={Polarity="); + switch (flags & ACPI_MADT_POLARITY_MASK) { + case ACPI_MADT_POLARITY_CONFORMS: + printf("conforming"); + break; + case ACPI_MADT_POLARITY_ACTIVE_HIGH: + printf("active-hi"); + break; + case ACPI_MADT_POLARITY_ACTIVE_LOW: + printf("active-lo"); + break; + default: + printf("0x%x", flags & ACPI_MADT_POLARITY_MASK); + break; + } + printf(", Trigger="); + switch (flags & ACPI_MADT_TRIGGER_MASK) { + case ACPI_MADT_TRIGGER_CONFORMS: + printf("conforming"); + break; + case ACPI_MADT_TRIGGER_EDGE: + printf("edge"); + break; + case ACPI_MADT_TRIGGER_LEVEL: + printf("level"); + break; + default: + printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2); + } + printf("}\n"); +} + +static void +acpi_print_intr(uint32_t intr, uint16_t mps_flags) +{ + + printf("\tINTR=%d\n", intr); + acpi_print_mps_flags(mps_flags); +} + +static void +acpi_print_local_nmi(u_int lint, uint16_t mps_flags) +{ + + printf("\tLINT Pin=%d\n", lint); + acpi_print_mps_flags(mps_flags); +} + +const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI", + "Local APIC NMI", "Local APIC Override", + "IO SAPIC", "Local SAPIC", "Platform Interrupt", + "Local X2APIC", "Local X2APIC NMI" }; +const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT", + "Corrected Platform Error" }; + +static void +acpi_print_madt(ACPI_SUBTABLE_HEADER *mp) +{ + ACPI_MADT_LOCAL_APIC *lapic; + ACPI_MADT_IO_APIC *ioapic; + ACPI_MADT_INTERRUPT_OVERRIDE *over; + ACPI_MADT_NMI_SOURCE *nmi; + ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi; + ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over; + ACPI_MADT_IO_SAPIC *iosapic; + ACPI_MADT_LOCAL_SAPIC *lsapic; + ACPI_MADT_INTERRUPT_SOURCE *isrc; + ACPI_MADT_LOCAL_X2APIC *x2apic; + ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi; + + if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0])) + printf("\tType=%s\n", apic_types[mp->Type]); + else + printf("\tType=%d (unknown)\n", mp->Type); + switch (mp->Type) { + case ACPI_MADT_TYPE_LOCAL_APIC: + lapic = (ACPI_MADT_LOCAL_APIC *)mp; + acpi_print_cpu(lapic->ProcessorId); + acpi_print_local_apic(lapic->Id, lapic->LapicFlags); + break; + case ACPI_MADT_TYPE_IO_APIC: + ioapic = (ACPI_MADT_IO_APIC *)mp; + acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase, + ioapic->Address); + break; + case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: + over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp; + printf("\tBUS=%d\n", (u_int)over->Bus); + printf("\tIRQ=%d\n", (u_int)over->SourceIrq); + acpi_print_intr(over->GlobalIrq, over->IntiFlags); + break; + case ACPI_MADT_TYPE_NMI_SOURCE: + nmi = (ACPI_MADT_NMI_SOURCE *)mp; + acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags); + break; + case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp; + acpi_print_cpu(lapic_nmi->ProcessorId); + acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags); + break; + case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp; + printf("\tLocal APIC ADDR=0x%016jx\n", + (uintmax_t)lapic_over->Address); + break; + case ACPI_MADT_TYPE_IO_SAPIC: + iosapic = (ACPI_MADT_IO_SAPIC *)mp; + acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase, + iosapic->Address); + break; + case ACPI_MADT_TYPE_LOCAL_SAPIC: + lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp; + acpi_print_cpu(lsapic->ProcessorId); + acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags); + printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid); + if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid)) + acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString); + break; + case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp; + if (isrc->Type < sizeof(platform_int_types) / + sizeof(platform_int_types[0])) + printf("\tType=%s\n", platform_int_types[isrc->Type]); + else + printf("\tType=%d (unknown)\n", isrc->Type); + printf("\tAPIC ID=%d\n", (u_int)isrc->Id); + printf("\tAPIC EID=%d\n", (u_int)isrc->Eid); + printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector); + acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags); + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC: + x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp; + acpi_print_cpu_uid(x2apic->Uid, NULL); + acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags); + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: + x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp; + acpi_print_cpu_uid(x2apic_nmi->Uid, NULL); + acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags); + break; + } +} + +static void +acpi_handle_boot(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_BOOT *boot; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + boot = (ACPI_TABLE_BOOT *)sdp; + printf("\tCMOS Index=0x%02x\n", boot->CmosIndex); + printf(END_COMMENT); +} + +static void +acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_DBGP *dbgp; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + dbgp = (ACPI_TABLE_DBGP *)sdp; + printf("\tType={"); + switch (dbgp->Type) { + case 0: + printf("full 16550"); + break; + case 1: + printf("subset of 16550"); + break; + } + printf("}\n"); + printf("DebugPort="); + acpi_print_gas(&dbgp->DebugPort); + printf(END_COMMENT); +} + +static void +acpi_handle_madt(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_MADT *madt; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + madt = (ACPI_TABLE_MADT *)sdp; + printf("\tLocal APIC ADDR=0x%08x\n", madt->Address); + printf("\tFlags={"); + if (madt->Flags & ACPI_MADT_PCAT_COMPAT) + printf("PC-AT"); + printf("}\n"); + acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt); + printf(END_COMMENT); +} + +static void +acpi_handle_hpet(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_HPET *hpet; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + hpet = (ACPI_TABLE_HPET *)sdp; + printf("\tHPET Number=%d\n", hpet->Sequence); + printf("\tADDR="); + acpi_print_gas(&hpet->Address); + printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID); + printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >> + 8); + printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ? + 1 : 0); + printf("\tLegacy IRQ routing capable={"); + if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE) + printf("TRUE}\n"); + else + printf("FALSE}\n"); + printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16); + printf("\tMinimal Tick=%d\n", hpet->MinimumTick); + printf(END_COMMENT); +} + +static void +acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_ECDT *ecdt; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + ecdt = (ACPI_TABLE_ECDT *)sdp; + printf("\tEC_CONTROL="); + acpi_print_gas(&ecdt->Control); + printf("\n\tEC_DATA="); + acpi_print_gas(&ecdt->Data); + printf("\n\tUID=%#x, ", ecdt->Uid); + printf("GPE_BIT=%#x\n", ecdt->Gpe); + printf("\tEC_ID=%s\n", ecdt->Id); + printf(END_COMMENT); +} + +static void +acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_MCFG *mcfg; + ACPI_MCFG_ALLOCATION *alloc; + u_int i, entries; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + mcfg = (ACPI_TABLE_MCFG *)sdp; + entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) / + sizeof(ACPI_MCFG_ALLOCATION); + alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1); + for (i = 0; i < entries; i++, alloc++) { + printf("\n"); + printf("\tBase Address=0x%016jx\n", alloc->Address); + printf("\tSegment Group=0x%04x\n", alloc->PciSegment); + printf("\tStart Bus=%d\n", alloc->StartBusNumber); + printf("\tEnd Bus=%d\n", alloc->EndBusNumber); + } + printf(END_COMMENT); +} + +static void +acpi_handle_sbst(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_SBST *sbst; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + sbst = (ACPI_TABLE_SBST *)sdp; + + printf("\tWarning Level=%d mWh\n", sbst->WarningLevel); + printf("\tLow Level=%d mWh\n", sbst->LowLevel); + printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel); + + printf(END_COMMENT); +} + +static void +acpi_handle_slit(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_SLIT *slit; + u_int idx; + uint64_t cnt; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + slit = (ACPI_TABLE_SLIT *)sdp; + + cnt = slit->LocalityCount * slit->LocalityCount; + printf("\tLocalityCount=%"PRIu64"\n", slit->LocalityCount); + printf("\tEntry=\n\t"); + for (idx = 0; idx < cnt; idx++) { + printf("%u ", slit->Entry[idx]); + if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) { + printf("\n"); + if (idx < cnt - 1) + printf("\t"); + } + } + + printf(END_COMMENT); +} + +static void +acpi_handle_spcr(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_SPCR *spcr; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + spcr = (ACPI_TABLE_SPCR *)sdp; + + printf("\tSerial Port="); + acpi_print_gas(&spcr->SerialPort); + printf("\n\tInterrupt Type={"); + if (spcr->InterruptType & 0x1) { + printf("\n\t\tdual-8259 IRQ="); + switch (spcr->PcInterrupt) { + case 2 ... 7: + case 9 ... 12: + case 14 ... 15: + printf("%d", spcr->PcInterrupt); + break; + default: + printf("%d (invalid entry)", spcr->PcInterrupt); + break; + } + } + if (spcr->InterruptType & 0x2) { + printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt); + } + if (spcr->InterruptType & 0x4) { + printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt); + } + printf("\n\t}\n"); + + printf("\tBaud Rate="); + switch (spcr->BaudRate) { + case 3: + printf("9600"); + break; + case 4: + printf("19200"); + break; + case 6: + printf("57600"); + break; + case 7: + printf("115200"); + break; + default: + printf("unknown speed index %d", spcr->BaudRate); + break; + } + printf("\n\tParity={"); + switch (spcr->Parity) { + case 0: + printf("OFF"); + break; + default: + printf("ON"); + break; + } + printf("}\n"); + + printf("\tStop Bits={"); + switch (spcr->StopBits) { + case 1: + printf("ON"); + break; + default: + printf("OFF"); + break; + } + printf("}\n"); + + printf("\tFlow Control={"); + if (spcr->FlowControl & 0x1) + printf("DCD, "); + if (spcr->FlowControl & 0x2) + printf("RTS/CTS hardware, "); + if (spcr->FlowControl & 0x4) + printf("XON/XOFF software"); + printf("}\n"); + + printf("\tTerminal="); + switch (spcr->TerminalType) { + case 0: + printf("VT100"); + break; + case 1: + printf("VT100+"); + break; + case 2: + printf("VT-UTF8"); + break; + case 3: + printf("ANSI"); + break; + default: + printf("unknown type %d", spcr->TerminalType); + break; + } + printf("\n"); + + printf("\tPCI DeviceId=0x%x", spcr->PciDeviceId); + if (spcr->PciDeviceId == 0xffff) + printf(" (No PCI device)"); + printf("\n"); + + printf("\tPCI VendorId=0x%x", spcr->PciVendorId); + if (spcr->PciVendorId == 0xffff) + printf(" (No PCI device)"); + printf("\n"); + + printf("\tPCI Bus=%d", spcr->PciBus); + if (spcr->PciBus == 0x0) + printf(" (No PCI device)"); + printf("\n"); + printf("\tPCI Device=%d", spcr->PciDevice); + if (spcr->PciDevice == 0x0) + printf(" (No PCI device)"); + printf("\n"); + printf("\tPCI Function=%d", spcr->PciFunction); + if (spcr->PciFunction == 0x0) + printf(" (No PCI device)"); + printf("\n"); + + printf("\tPCI Flags={"); + if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE) + printf("DONOT_DISABLE"); + printf("}\n"); + + printf("\tPCI Segment Group=%d", spcr->PciSegment); + if (spcr->PciSegment == 0xff) + printf(" (No PCI device)"); + printf("\n"); + + printf(END_COMMENT); +} + +static void +acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, + uint32_t flags, uint32_t clockdomain) +{ + + printf("\tFlags={"); + if (flags & ACPI_SRAT_CPU_ENABLED) + printf("ENABLED"); + else + printf("DISABLED"); + printf("}\n"); + printf("\tAPIC ID=%d\n", apic_id); + printf("\tProximity Domain=%d\n", proximity_domain); + printf("\tClock Domain=%d\n", clockdomain); +} + +static void +acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) +{ + + printf("\tFlags={"); + if (mp->Flags & ACPI_SRAT_MEM_ENABLED) + printf("ENABLED"); + else + printf("DISABLED"); + if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) + printf(",HOT_PLUGGABLE"); + if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE) + printf(",NON_VOLATILE"); + printf("}\n"); + printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress); + printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length); + printf("\tProximity Domain=%d\n", mp->ProximityDomain); +} + +const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; + +static void +acpi_print_srat(ACPI_SUBTABLE_HEADER *srat) +{ + ACPI_SRAT_CPU_AFFINITY *cpu; + ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; + + if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0])) + printf("\tType=%s\n", srat_types[srat->Type]); + else + printf("\tType=%d (unknown)\n", srat->Type); + switch (srat->Type) { + case ACPI_SRAT_TYPE_CPU_AFFINITY: + cpu = (ACPI_SRAT_CPU_AFFINITY *)srat; + acpi_print_srat_cpu(cpu->ApicId, + cpu->ProximityDomainHi[2] << 24 | + cpu->ProximityDomainHi[1] << 16 | + cpu->ProximityDomainHi[0] << 0 | + cpu->ProximityDomainLo, + cpu->Flags, cpu->ClockDomain); + break; + case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat); + break; + case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: + x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat; + acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain, + x2apic->Flags, x2apic->ClockDomain); + break; + } +} + +static void +acpi_handle_srat(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_SRAT *srat; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + srat = (ACPI_TABLE_SRAT *)sdp; + printf("\tTable Revision=%d\n", srat->TableRevision); + acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat); + printf(END_COMMENT); +} + +static void +acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_TCPA *tcpa; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + tcpa = (ACPI_TABLE_TCPA *)sdp; + + printf("\tMaximum Length of Event Log Area=%d\n", tcpa->MaxLogLength); + printf("\tPhysical Address of Log Area=0x%08"PRIx64"\n", + tcpa->LogAddress); + + printf(END_COMMENT); +} + +static void +acpi_print_wdat_action(uint8_t action) +{ + printf("\tACTION={"); + switch (action) { + case ACPI_WDAT_RESET: + printf("RESET"); + break; + case ACPI_WDAT_GET_CURRENT_COUNTDOWN: + printf("GET_CURRENT_COUNTDOWN"); + break; + case ACPI_WDAT_GET_COUNTDOWN: + printf("GET_COUNTDOWN"); + break; + case ACPI_WDAT_SET_COUNTDOWN: + printf("SET_COUNTDOWN"); + break; + case ACPI_WDAT_GET_RUNNING_STATE: + printf("GET_RUNNING_STATE"); + break; + case ACPI_WDAT_SET_RUNNING_STATE: + printf("SET_RUNNING_STATE"); + break; + case ACPI_WDAT_GET_STOPPED_STATE: + printf("GET_STOPPED_STATE"); + break; + case ACPI_WDAT_SET_STOPPED_STATE: + printf("SET_STOPPED_STATE"); + break; + case ACPI_WDAT_GET_REBOOT: + printf("GET_REBOOT"); + break; + case ACPI_WDAT_SET_REBOOT: + printf("SET_REBOOT"); + break; + case ACPI_WDAT_GET_SHUTDOWN: + printf("GET_SHUTDOWN"); + break; + case ACPI_WDAT_SET_SHUTDOWN: + printf("SET_SHUTDOWN"); + break; + case ACPI_WDAT_GET_STATUS: + printf("GET_STATUS"); + break; + case ACPI_WDAT_SET_STATUS: + printf("SET_STATUS"); + break; + case ACPI_WDAT_ACTION_RESERVED: + printf("ACTION_RESERVED"); + break; + default: + printf("%d", action); + break; + } + printf("}\n"); +} + +static void +acpi_print_wdat_instruction(uint8_t instruction, uint32_t mask) +{ + uint32_t ins, bitmap; + + ins = instruction & ~ACPI_WDAT_PRESERVE_REGISTER; + bitmap = instruction & mask; + + printf("\tINSTRUCTION={"); + switch (ins) { + case ACPI_WDAT_READ_VALUE: + printf("READ_VALUE"); + break; + case ACPI_WDAT_READ_COUNTDOWN: + printf("READ_COUNTDOWN"); + break; + case ACPI_WDAT_WRITE_VALUE: + printf("WRITE_VALUE"); + break; + case ACPI_WDAT_WRITE_COUNTDOWN: + printf("WRITE_COUNTDOWN"); + break; + case ACPI_WDAT_INSTRUCTION_RESERVED: + printf("INSTRUCTION_RESERVED"); + break; + default: + printf("%d", ins); + break; + } + if (bitmap & ACPI_WDAT_PRESERVE_REGISTER) + printf(", PRESERVE_REGISTER"); + printf("}\n"); + printf("\tMASK={"); + if (mask & ACPI_WDAT_PRESERVE_REGISTER) + printf("PRESERVE_REGISTER"); + else + printf("NONE"); + printf("}\n"); +} + +static void +acpi_handle_wdat(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_WDAT *wdat; + ACPI_WDAT_ENTRY *wdat_entry; + char *wdat_pos; + u_int i; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + wdat = (ACPI_TABLE_WDAT *)sdp; + + printf("\tHeader Length=%d\n", wdat->HeaderLength); + printf("\tPCI Segment Group=%d", wdat->PciSegment); + if (wdat->PciSegment == 0xff) + printf(" (No PCI segment support)"); + printf("\n\tPCI Bus=%d", wdat->PciBus); + if (wdat->PciBus == 0xff) + printf(" (No PCI device)"); + printf("\n\tPCI Device=%d", wdat->PciDevice); + if (wdat->PciDevice == 0xff) + printf(" (No PCI device)"); + printf("\n\tPCI Function=%d", wdat->PciFunction); + if (wdat->PciFunction == 0xff) + printf(" (No PCI device)"); + printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod); + printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount); + printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount); + + printf("\tFlags={"); + if (wdat->Flags & ACPI_WDAT_ENABLED) + printf("ENABLED"); + if (wdat->Flags & ACPI_WDAT_STOPPED) + printf(", STOPPED"); + printf("}\n"); + + wdat_pos = ((char *)wdat + sizeof(ACPI_TABLE_HEADER) + wdat->HeaderLength); + + for (i = 0; i < wdat->Entries; i++) { + wdat_entry = (ACPI_WDAT_ENTRY *)wdat_pos; + printf("\n"); + acpi_print_wdat_action(wdat_entry->Action); + acpi_print_wdat_instruction(wdat_entry->Instruction, + wdat_entry->Mask); + printf("\tRegisterRegion="); + acpi_print_gas(&wdat_entry->RegisterRegion); + printf("\n"); + wdat_pos += sizeof(ACPI_WDAT_ENTRY); + } + printf(END_COMMENT); +} + +static void +acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_WDRT *wdrt; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + wdrt = (ACPI_TABLE_WDRT *)sdp; + + printf("\tControl Register="); + acpi_print_gas(&wdrt->ControlRegister); + printf("\tCount Register="); + acpi_print_gas(&wdrt->CountRegister); + printf("\tPCI DeviceId=0x%x", wdrt->PciDeviceId); + if (wdrt->PciDeviceId == 0xffff) + printf(" (No PCI device)"); + printf("\n\tPCI VendorId=0x%x", wdrt->PciVendorId); + if (wdrt->PciVendorId == 0xffff) + printf(" (No PCI device)"); + printf("\n\tPCI Bus=%d\n", wdrt->PciBus); + if (wdrt->PciDevice == 0x0) + printf(" (No PCI device)"); + printf("\n\tPCI Device=%d\n", wdrt->PciDevice); + if (wdrt->PciDevice == 0x0) + printf(" (No PCI device)"); + printf("\n\tPCI Function=%d\n", wdrt->PciFunction); + if (wdrt->PciFunction == 0x0) + printf(" (No PCI device)"); + printf("\n\tPCI Segment Group=%d\n", wdrt->PciSegment); + + /* Value must be >= 511 and < 65535 */ + printf("\tMaxCount=%d", wdrt->MaxCount); + if (wdrt->MaxCount < 511) + printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)"); + printf("\n"); + + printf("\tUnit={"); + switch (wdrt->Units) { + case 0: + printf("1 seconds/count"); + break; + case 1: + printf("100 milliseconds/count"); + break; + case 2: + printf("10 milliseconds/count"); + break; + default: + printf("%d", wdrt->Units); + break; + } + printf("}\n"); + + printf(END_COMMENT); +} + +static void +acpi_print_sdt(ACPI_TABLE_HEADER *sdp) +{ + printf(" "); + acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); + printf(": Length=%d, Revision=%d, Checksum=%d,\n", + sdp->Length, sdp->Revision, sdp->Checksum); + printf("\tOEMID="); + acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE); + printf(", OEM Table ID="); + acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE); + printf(", OEM Revision=0x%x,\n", sdp->OemRevision); + printf("\tCreator ID="); + acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE); + printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); +} + +static void +acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) +{ + ACPI_TABLE_RSDT *rsdt; + ACPI_TABLE_XSDT *xsdt; int i, entries; + u_long addr; + rsdt = (ACPI_TABLE_RSDT *)rsdp; + xsdt = (ACPI_TABLE_XSDT *)rsdp; + printf(BEGIN_COMMENT); acpi_print_sdt(rsdp); - entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); - printf(BEGIN_COMMENT); + entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; printf("\tEntries={ "); for (i = 0; i < entries; i++) { if (i > 0) printf(", "); - printf("0x%08x", rsdp->body[i]); + switch (addr_size) { + case 4: + addr = le32toh(rsdt->TableOffsetEntry[i]); + break; + case 8: + addr = le64toh(xsdt->TableOffsetEntry[i]); + break; + default: + addr = 0; + } + assert(addr != 0); + printf("0x%08lx", addr); } printf(" }\n"); printf(END_COMMENT); } -void -acpi_print_facp(struct FACPbody *facp) +static const char *acpi_pm_profiles[] = { + "Unspecified", "Desktop", "Mobile", "Workstation", + "Enterprise Server", "SOHO Server", "Appliance PC" +}; + +static void +acpi_print_fadt(ACPI_TABLE_HEADER *sdp) { - char sep; + ACPI_TABLE_FADT *fadt; + const char *pm; + char sep; + fadt = (ACPI_TABLE_FADT *)sdp; printf(BEGIN_COMMENT); - printf("\tDSDT=0x%x\n", facp->dsdt_ptr); - printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); - printf("\tSCI_INT=%d\n", facp->sci_int); - printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); - printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); - printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); - printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); - if (facp->pm1a_evt_blk) - printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", - facp->pm1a_evt_blk, - facp->pm1a_evt_blk + facp->pm1_evt_len - 1); - if (facp->pm1b_evt_blk) + acpi_print_sdt(sdp); + printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs, + fadt->Dsdt); + printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC"); + if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *)) + pm = "Reserved"; + else + pm = acpi_pm_profiles[fadt->PreferredProfile]; + printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile); + printf("\tSCI_INT=%d\n", fadt->SciInterrupt); + printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand); + printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable); + printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable); + printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest); + printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl); + printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", + fadt->Pm1aEventBlock, + fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1); + if (fadt->Pm1bEventBlock != 0) printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", - facp->pm1b_evt_blk, - facp->pm1b_evt_blk + facp->pm1_evt_len - 1); - if (facp->pm1a_cnt_blk) - printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", - facp->pm1a_cnt_blk, - facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); - if (facp->pm1b_cnt_blk) + fadt->Pm1bEventBlock, + fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1); + printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", + fadt->Pm1aControlBlock, + fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1); + if (fadt->Pm1bControlBlock != 0) printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", - facp->pm1b_cnt_blk, - facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); - if (facp->pm2_cnt_blk) + fadt->Pm1bControlBlock, + fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1); + if (fadt->Pm2ControlBlock != 0) printf("\tPM2_CNT_BLK=0x%x-0x%x\n", - facp->pm2_cnt_blk, - facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); - if (facp->pm_tmr_blk) - printf("\tPM2_TMR_BLK=0x%x-0x%x\n", - facp->pm_tmr_blk, - facp->pm_tmr_blk + facp->pm_tmr_len - 1); - if (facp->gpe0_blk) - printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", - facp->gpe0_blk, - facp->gpe0_blk + facp->gpe0_len - 1); - if (facp->gpe1_blk) - printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", - facp->gpe1_blk, - facp->gpe1_blk + facp->gpe1_len - 1, - facp->gpe1_base); - printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", - facp->p_lvl2_lat, facp->p_lvl3_lat); + fadt->Pm2ControlBlock, + fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1); + printf("\tPM_TMR_BLK=0x%x-0x%x\n", + fadt->PmTimerBlock, + fadt->PmTimerBlock + fadt->PmTimerLength - 1); + if (fadt->Gpe0Block != 0) + printf("\tGPE0_BLK=0x%x-0x%x\n", + fadt->Gpe0Block, + fadt->Gpe0Block + fadt->Gpe0BlockLength - 1); + if (fadt->Gpe1Block != 0) + printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", + fadt->Gpe1Block, + fadt->Gpe1Block + fadt->Gpe1BlockLength - 1, + fadt->Gpe1Base); + if (fadt->CstControl != 0) + printf("\tCST_CNT=0x%x\n", fadt->CstControl); + printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n", + fadt->C2Latency, fadt->C3Latency); printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", - facp->flush_size, facp->flush_stride); + fadt->FlushSize, fadt->FlushStride); printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", - facp->duty_off, facp->duty_width); + fadt->DutyOffset, fadt->DutyWidth); printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", - facp->day_alrm, facp->mon_alrm, facp->century); + fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); + +#define PRINTFLAG(var, flag) do { \ + if ((var) & ACPI_FADT_## flag) { \ + printf("%c%s", sep, #flag); sep = ','; \ + } \ +} while (0) + + printf("\tIAPC_BOOT_ARCH="); + sep = '{'; + PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); + PRINTFLAG(fadt->BootFlags, 8042); + PRINTFLAG(fadt->BootFlags, NO_VGA); + PRINTFLAG(fadt->BootFlags, NO_MSI); + PRINTFLAG(fadt->BootFlags, NO_ASPM); + if (fadt->BootFlags != 0) + printf("}"); + printf("\n"); + printf("\tFlags="); sep = '{'; - -#define PRINTFLAG(xx) do { \ - if (facp->flags & ACPI_FACP_FLAG_## xx) { \ - printf("%c%s", sep, #xx); sep = ','; \ - } \ -} while (0) - - PRINTFLAG(WBINVD); - PRINTFLAG(WBINVD_FLUSH); - PRINTFLAG(PROC_C1); - PRINTFLAG(P_LVL2_UP); - PRINTFLAG(PWR_BUTTON); - PRINTFLAG(SLP_BUTTON); - PRINTFLAG(FIX_RTC); - PRINTFLAG(RTC_S4); - PRINTFLAG(TMR_VAL_EXT); - PRINTFLAG(DCK_CAP); + PRINTFLAG(fadt->Flags, WBINVD); + PRINTFLAG(fadt->Flags, WBINVD_FLUSH); + PRINTFLAG(fadt->Flags, C1_SUPPORTED); + PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED); + PRINTFLAG(fadt->Flags, POWER_BUTTON); + PRINTFLAG(fadt->Flags, SLEEP_BUTTON); + PRINTFLAG(fadt->Flags, FIXED_RTC); + PRINTFLAG(fadt->Flags, S4_RTC_WAKE); + PRINTFLAG(fadt->Flags, 32BIT_TIMER); + PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED); + PRINTFLAG(fadt->Flags, RESET_REGISTER); + PRINTFLAG(fadt->Flags, SEALED_CASE); + PRINTFLAG(fadt->Flags, HEADLESS); + PRINTFLAG(fadt->Flags, SLEEP_TYPE); + PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE); + PRINTFLAG(fadt->Flags, PLATFORM_CLOCK); + PRINTFLAG(fadt->Flags, S4_RTC_VALID); + PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); + PRINTFLAG(fadt->Flags, APIC_CLUSTER); + PRINTFLAG(fadt->Flags, APIC_PHYSICAL); + if (fadt->Flags != 0) + printf("}\n"); #undef PRINTFLAG - printf("}\n"); + if (fadt->Flags & ACPI_FADT_RESET_REGISTER) { + printf("\tRESET_REG="); + acpi_print_gas(&fadt->ResetRegister); + printf(", RESET_VALUE=%#x\n", fadt->ResetValue); + } + if (acpi_get_fadt_revision(fadt) > 1) { + printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs); + printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt); + printf("\tX_PM1a_EVT_BLK="); + acpi_print_gas(&fadt->XPm1aEventBlock); + if (fadt->XPm1bEventBlock.Address != 0) { + printf("\n\tX_PM1b_EVT_BLK="); + acpi_print_gas(&fadt->XPm1bEventBlock); + } + printf("\n\tX_PM1a_CNT_BLK="); + acpi_print_gas(&fadt->XPm1aControlBlock); + if (fadt->XPm1bControlBlock.Address != 0) { + printf("\n\tX_PM1b_CNT_BLK="); + acpi_print_gas(&fadt->XPm1bControlBlock); + } + if (fadt->XPm2ControlBlock.Address != 0) { + printf("\n\tX_PM2_CNT_BLK="); + acpi_print_gas(&fadt->XPm2ControlBlock); + } + printf("\n\tX_PM_TMR_BLK="); + acpi_print_gas(&fadt->XPmTimerBlock); + if (fadt->XGpe0Block.Address != 0) { + printf("\n\tX_GPE0_BLK="); + acpi_print_gas(&fadt->XGpe0Block); + } + if (fadt->XGpe1Block.Address != 0) { + printf("\n\tX_GPE1_BLK="); + acpi_print_gas(&fadt->XGpe1Block); + } + printf("\n"); + } + printf(END_COMMENT); } -void -acpi_print_dsdt(struct ACPIsdt *dsdp) +static void +acpi_print_facs(ACPI_TABLE_FACS *facs) { + printf(BEGIN_COMMENT); + printf(" FACS:\tLength=%u, ", facs->Length); + printf("HwSig=0x%08x, ", facs->HardwareSignature); + printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector); + printf("\tGlobal_Lock="); + if (facs->GlobalLock != 0) { + if (facs->GlobalLock & ACPI_GLOCK_PENDING) + printf("PENDING,"); + if (facs->GlobalLock & ACPI_GLOCK_OWNED) + printf("OWNED"); + } + printf("\n"); + + printf("\tFlags="); + if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT) + printf("S4BIOS"); + printf("\n"); + + if (facs->XFirmwareWakingVector != 0) { + printf("\tX_Firm_Wake_Vec=%08lx\n", + (u_long)facs->XFirmwareWakingVector); + } + printf("\tVersion=%u\n", facs->Version); + + printf(END_COMMENT); +} + +static void +acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp) +{ + printf(BEGIN_COMMENT); acpi_print_sdt(dsdp); + printf(END_COMMENT); } int acpi_checksum(void *p, size_t length) { - u_int8_t *bp; - u_int8_t sum; + uint8_t *bp; + uint8_t sum; bp = p; sum = 0; @@ -323,128 +1266,306 @@ acpi_checksum(void *p, size_t length) return (sum); } -struct ACPIsdt * +static ACPI_TABLE_HEADER * acpi_map_sdt(vm_offset_t pa) { - struct ACPIsdt *sp; + ACPI_TABLE_HEADER *sp; - sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); - sp = acpi_map_physical(pa, sp->len); + sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER)); + sp = acpi_map_physical(pa, sp->Length); return (sp); } -void -acpi_print_rsd_ptr(struct ACPIrsdp *rp) +static void +acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) { - printf(BEGIN_COMMENT); - printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); - acpi_print_string((const char *)rp->oem, 6); - printf(", RsdtAddress=0x%08x\n", rp->addr); + printf(" RSD PTR: OEM="); + acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); + printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x", + rp->Revision); + if (rp->Revision < 2) { + printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, + rp->Checksum); + } else { + printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", + (u_long)rp->XsdtPhysicalAddress, rp->Length, + rp->ExtendedChecksum); + } printf(END_COMMENT); } -void -acpi_handle_rsdt(struct ACPIsdt *rsdp) +static void +acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) { - int i; - int entries; - struct ACPIsdt *sdp; + ACPI_TABLE_HEADER *sdp; + ACPI_TABLE_RSDT *rsdt; + ACPI_TABLE_XSDT *xsdt; + vm_offset_t addr; + int entries, i; - entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); acpi_print_rsdt(rsdp); + rsdt = (ACPI_TABLE_RSDT *)rsdp; + xsdt = (ACPI_TABLE_XSDT *)rsdp; + entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; for (i = 0; i < entries; i++) { - sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]); - if (acpi_checksum(sdp, sdp->len)) { - warnx("RSDT entry %d: bad checksum", i); + switch (addr_size) { + case 4: + addr = le32toh(rsdt->TableOffsetEntry[i]); + break; + case 8: + addr = le64toh(xsdt->TableOffsetEntry[i]); + break; + default: + assert((addr = 0)); + } + + sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); + if (acpi_checksum(sdp, sdp->Length)) { + warnx("RSDT entry %d (sig %.4s) is corrupt", i, + sdp->Signature); continue; } - if (!memcmp(sdp->signature, "FACP", 4)) { - acpi_handle_facp((struct FACPbody *) sdp->body); - } else { + if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) + acpi_handle_fadt(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4)) + acpi_handle_boot(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4)) + acpi_handle_dbgp(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4)) + acpi_handle_madt(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4)) + acpi_handle_hpet(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4)) + acpi_handle_ecdt(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4)) + acpi_handle_mcfg(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4)) + acpi_handle_sbst(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4)) + acpi_handle_slit(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4)) + acpi_handle_spcr(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4)) + acpi_handle_srat(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) + acpi_handle_tcpa(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4)) + acpi_handle_wdat(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4)) + acpi_handle_wdrt(sdp); + else { + printf(BEGIN_COMMENT); acpi_print_sdt(sdp); + printf(END_COMMENT); } } } -/* - * Dummy functions - */ +ACPI_TABLE_HEADER * +sdt_load_devmem(void) +{ + ACPI_TABLE_RSDP *rp; + ACPI_TABLE_HEADER *rsdp; -void -aml_dbgr(struct aml_environ *env1, struct aml_environ *env2) -{ - /* do nothing */ + rp = acpi_find_rsd_ptr(); + if (!rp) + errx(EXIT_FAILURE, "Can't find ACPI information"); + + if (tflag) + acpi_print_rsd_ptr(rp); + if (rp->Revision < 2) { + rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); + if (memcmp(rsdp->Signature, "RSDT", 4) != 0 || + acpi_checksum(rsdp, rsdp->Length) != 0) + errx(EXIT_FAILURE, "RSDT is corrupted"); + addr_size = sizeof(uint32_t); + } else { + rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress); + if (memcmp(rsdp->Signature, "XSDT", 4) != 0 || + acpi_checksum(rsdp, rsdp->Length) != 0) + errx(EXIT_FAILURE, "XSDT is corrupted"); + addr_size = sizeof(uint64_t); + } + return (rsdp); } -int -aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset, - u_int32_t *valuep) +/* Write the DSDT to a file, concatenating any SSDTs (if present). */ +static int +write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt) { + ACPI_TABLE_HEADER sdt; + ACPI_TABLE_HEADER *ssdt; + uint8_t sum; + + /* Create a new checksum to account for the DSDT and any SSDTs. */ + sdt = *dsdt; + if (rsdt != NULL) { + sdt.Checksum = 0; + sum = acpi_checksum(dsdt + 1, dsdt->Length - + sizeof(ACPI_TABLE_HEADER)); + ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL); + while (ssdt != NULL) { + sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER); + sum += acpi_checksum(ssdt + 1, + ssdt->Length - sizeof(ACPI_TABLE_HEADER)); + ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt); + } + sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER)); + sdt.Checksum -= sum; + } + + /* Write out the DSDT header and body. */ + write(fd, &sdt, sizeof(ACPI_TABLE_HEADER)); + write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER)); + + /* Write out any SSDTs (if present.) */ + if (rsdt != NULL) { + ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL); + while (ssdt != NULL) { + write(fd, ssdt + 1, ssdt->Length - + sizeof(ACPI_TABLE_HEADER)); + ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt); + } + } return (0); } -int -aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset, - u_int32_t value) +void +dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) { - return (0); + int fd; + mode_t mode; + + assert(outfile != NULL); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode); + if (fd == -1) { + perror("dsdt_save_file"); + return; + } + write_dsdt(fd, rsdt, dsdp); + close(fd); } -u_int32_t -aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value) +void +aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp) { - return (0); + char buf[PATH_MAX], tmpstr[PATH_MAX]; + const char *tmpdir; + char *tmpext; + FILE *fp; + size_t len; + int fd; + + if (rsdt == NULL) + errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt"); + if (dsdp == NULL) + errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp"); + + tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL) + tmpdir = _PATH_TMP; + strlcpy(tmpstr, tmpdir, sizeof(tmpstr)); + if (realpath(tmpstr, buf) == NULL) { + perror("realpath tmp file"); + return; + } + strlcpy(tmpstr, buf, sizeof(tmpstr)); + strlcat(tmpstr, "/acpidump.", sizeof(tmpstr)); + len = strlen(tmpstr); + tmpext = tmpstr + len; + strlcpy(tmpext, "XXXXXX", sizeof(tmpstr) - len); + fd = mkstemp(tmpstr); + if (fd < 0) { + perror("iasl tmp file"); + return; + } + write_dsdt(fd, rsdt, dsdp); + close(fd); + + /* Run iasl -d on the temp file */ + if (fork() == 0) { + close(STDOUT_FILENO); + if (vflag == 0) + close(STDERR_FILENO); + execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL); + err(EXIT_FAILURE, "exec"); + } + + wait(NULL); + unlink(tmpstr); + + /* Dump iasl's output to stdout */ + strlcpy(tmpext, "dsl", sizeof(tmpstr) - len); + fp = fopen(tmpstr, "r"); + unlink(tmpstr); + if (fp == NULL) { + perror("iasl tmp file (read)"); + return; + } + while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) + fwrite(buf, 1, len, stdout); + fclose(fp); } -u_int32_t -aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value) +void +sdt_print_all(ACPI_TABLE_HEADER *rsdp) { - return (0); + acpi_handle_rsdt(rsdp); } -int -aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value, - struct aml_region_handle *h) +/* Fetch a table matching the given signature via the RSDT. */ +ACPI_TABLE_HEADER * +sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) { - return (0); + ACPI_TABLE_HEADER *sdt; + ACPI_TABLE_RSDT *rsdt; + ACPI_TABLE_XSDT *xsdt; + vm_offset_t addr; + int entries, i; + + rsdt = (ACPI_TABLE_RSDT *)rsdp; + xsdt = (ACPI_TABLE_XSDT *)rsdp; + entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; + for (i = 0; i < entries; i++) { + switch (addr_size) { + case 4: + addr = le32toh(rsdt->TableOffsetEntry[i]); + break; + case 8: + addr = le64toh(xsdt->TableOffsetEntry[i]); + break; + default: + assert((addr = 0)); + } + sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); + if (last != NULL) { + if (sdt == last) + last = NULL; + continue; + } + if (memcmp(sdt->Signature, sig, strlen(sig))) + continue; + if (acpi_checksum(sdt, sdt->Length)) + errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i); + return (sdt); + } + + return (NULL); } -u_int32_t -aml_region_read(struct aml_environ *env, int regtype, u_int32_t flags, - u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen) +ACPI_TABLE_HEADER * +dsdt_from_fadt(ACPI_TABLE_FADT *fadt) { - return (0); + ACPI_TABLE_HEADER *sdt; + + /* Use the DSDT address if it is version 1, otherwise use XDSDT. */ + if (acpi_get_fadt_revision(fadt) == 1) + sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt); + else + sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt); + if (acpi_checksum(sdt, sdt->Length)) + errx(EXIT_FAILURE, "DSDT is corrupt\n"); + return (sdt); } - -int -aml_region_write(struct aml_environ *env, int regtype, u_int32_t flags, - u_int32_t value, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen) -{ - return (0); -} - -int -aml_region_write_from_buffer(struct aml_environ *env, int regtype, - u_int32_t flags, u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset, - u_int32_t bitlen) -{ - return (0); -} - -int -aml_region_bcopy(struct aml_environ *env, int regtype, u_int32_t flags, - u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen, - u_int32_t dflags, u_int32_t daddr, - u_int32_t dbitoffset, u_int32_t dbitlen) -{ - return (0); -} - -int -aml_region_read_into_buffer(struct aml_environ *env, int regtype, - u_int32_t flags, u_int32_t addr, u_int32_t bitoffset, - u_int32_t bitlen, u_int8_t *buffer) -{ - return (0); -} diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/acpi_user.c --- a/usr.sbin/acpitools/acpidump/acpi_user.c +++ b/usr.sbin/acpitools/acpidump/acpi_user.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_user.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */ +/* $NetBSD: $ */ /*- * Copyright (c) 1999 Doug Rabson @@ -26,16 +26,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: acpi_user.c,v 1.5 2000/08/09 14:47:52 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.4 2001/10/22 17:25:25 iwasaki Exp $ + * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.15 2009/08/25 20:35:57 jhb Exp $ */ + #include -__RCSID("$NetBSD: acpi_user.c,v 1.1 2007/01/14 04:36:13 christos Exp $"); +__RCSID("$NetBSD: acpi.c,v 1.4 2008/02/13 18:59:18 drochner Exp $"); #include #include #include #include +#include #include #include @@ -43,7 +44,6 @@ __RCSID("$NetBSD: acpi_user.c,v 1.1 2007 #include #include -#include #include "acpidump.h" static int acpi_mem_fd = -1; @@ -64,7 +64,7 @@ acpi_user_init(void) if (acpi_mem_fd == -1) { acpi_mem_fd = open("/dev/mem", O_RDONLY); if (acpi_mem_fd == -1) - err(1, "opening /dev/mem"); + err(EXIT_FAILURE, "opening /dev/mem"); LIST_INIT(&maplist); } } @@ -77,7 +77,7 @@ acpi_user_find_mapping(vm_offset_t pa, s /* First search for an existing mapping */ for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) { if (map->pa <= pa && map->size >= pa + size - map->pa) - return (map); + return map; } /* Then create a new one */ @@ -85,42 +85,103 @@ acpi_user_find_mapping(vm_offset_t pa, s pa = trunc_page(pa); map = malloc(sizeof(struct acpi_user_mapping)); if (!map) - errx(1, "out of memory"); + errx(EXIT_FAILURE, "out of memory"); map->pa = pa; map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa); map->size = size; if ((intptr_t) map->va == -1) - err(1, "can't map address"); + err(EXIT_FAILURE, "can't map address"); LIST_INSERT_HEAD(&maplist, map, link); - return (map); + return map; +} + +static ACPI_TABLE_RSDP * +acpi_get_rsdp(u_long addr) +{ + ACPI_TABLE_RSDP rsdp; + size_t len; + + /* Read in the table signature and check it. */ + pread(acpi_mem_fd, &rsdp, 8, addr); + if (memcmp(rsdp.Signature, "RSD PTR ", 8)) + return (NULL); + + /* Read the entire table. */ + pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); + + /* Check the standard checksum. */ + if (acpi_checksum(&rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) + return (NULL); + + /* Check extended checksum if table version >= 2. */ + if (rsdp.Revision >= 2 && + acpi_checksum(&rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) + return (NULL); + + /* If the revision is 0, assume a version 1 length. */ + if (rsdp.Revision == 0) + len = ACPI_RSDP_REV0_SIZE; + else + len = rsdp.Length; + + return (acpi_map_physical(addr, len)); +} + +static ACPI_TABLE_RSDP * +acpi_scan_rsd_ptr(void) +{ +#if defined(__amd64__) || defined(__i386__) + ACPI_TABLE_RSDP *rsdp; + u_long addr, end; + + /* + * On ia32, scan physical memory for the RSD PTR if above failed. + * According to section 5.2.2 of the ACPI spec, we only consider + * two regions for the base address: + * 1. EBDA (1 KB area addressed by the 16 bit pointer at 0x40E + * 2. High memory (0xE0000 - 0xFFFFF) + */ + addr = ACPI_EBDA_PTR_LOCATION; + pread(acpi_mem_fd, &addr, sizeof(uint16_t), addr); + addr <<= 4; + end = addr + ACPI_EBDA_WINDOW_SIZE; + for (; addr < end; addr += 16) + if ((rsdp = acpi_get_rsdp(addr)) != NULL) + return rsdp; + addr = ACPI_HI_RSDP_WINDOW_BASE; + end = addr + ACPI_HI_RSDP_WINDOW_SIZE; + for (; addr < end; addr += 16) + if ((rsdp = acpi_get_rsdp(addr)) != NULL) + return rsdp; +#endif /* __amd64__ || __i386__ */ + return NULL; } /* * Public interfaces */ - -struct ACPIrsdp * -acpi_find_rsd_ptr() +ACPI_TABLE_RSDP * +acpi_find_rsd_ptr(void) { - int i; - u_int8_t buf[sizeof(struct ACPIrsdp)]; + int i; + uint8_t buf[sizeof(ACPI_TABLE_RSDP)]; acpi_user_init(); for (i = 0; i < 1024 * 1024; i += 16) { read(acpi_mem_fd, buf, 16); if (!memcmp(buf, "RSD PTR ", 8)) { /* Read the rest of the structure */ - read(acpi_mem_fd, buf + 16, sizeof(struct ACPIrsdp) - 16); + read(acpi_mem_fd, buf + 16, sizeof(ACPI_TABLE_RSDP) - 16); /* Verify checksum before accepting it. */ - if (acpi_checksum(buf, sizeof(struct ACPIrsdp))) + if (acpi_checksum(buf, sizeof(ACPI_TABLE_RSDP))) continue; - return (acpi_map_physical(i, sizeof(struct ACPIrsdp))); + return (acpi_map_physical(i, sizeof(ACPI_TABLE_RSDP))); } } - return (0); + return acpi_scan_rsd_ptr(); } void * @@ -132,35 +193,37 @@ acpi_map_physical(vm_offset_t pa, size_t return (map->va + (pa - map->pa)); } -void -acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp) +ACPI_TABLE_HEADER * +dsdt_load_file(char *infile) { - u_int8_t *dp; - u_int8_t *end; - struct stat sb; + ACPI_TABLE_HEADER *sdt; + uint8_t *dp; + struct stat sb; - if ((acpi_mem_fd = open(dumpfile, O_RDONLY)) == -1) { - errx(1, "opening %s\n", dumpfile); - } + if ((acpi_mem_fd = open(infile, O_RDONLY)) == -1) + errx(EXIT_FAILURE, "opening %s", infile); LIST_INIT(&maplist); - if (fstat(acpi_mem_fd, &sb) == -1) { - errx(1, "fstat %s\n", dumpfile); - } + if (fstat(acpi_mem_fd, &sb) == -1) + errx(EXIT_FAILURE, "fstat %s", infile); dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0); - if (dp == NULL) { - errx(1, "mmap %s\n", dumpfile); - } + if (dp == NULL) + errx(EXIT_FAILURE, "mmap %s", infile); - if (strncmp((const char *)dp, "DSDT", 4) == 0) { - memcpy(&dsdt_header, dp, SIZEOF_SDT_HDR); - dp += SIZEOF_SDT_HDR; - sb.st_size -= SIZEOF_SDT_HDR; - } + sdt = (ACPI_TABLE_HEADER *)dp; + if (strncmp((char *)dp, ACPI_SIG_DSDT, 4) != 0) + errx(EXIT_FAILURE, "DSDT signature mismatch"); - end = (u_int8_t *) dp + sb.st_size; - *dpp = dp; - *endp = end; + if (sdt->Length > sb.st_size) + errx(EXIT_FAILURE, + "corrupt DSDT: table size (%"PRIu32" bytes), file size " + "(%"PRIu64" bytes)", + sdt->Length, sb.st_size); + + if (acpi_checksum(sdt, sdt->Length) != 0) + errx(EXIT_FAILURE, "DSDT checksum mismatch"); + + return sdt; } diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/acpidump.8 --- a/usr.sbin/acpitools/acpidump/acpidump.8 +++ b/usr.sbin/acpitools/acpidump/acpidump.8 @@ -28,54 +28,55 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.8,v 1.13 2002/07/14 14:42:07 charnier Exp $ +.\" $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.8,v 1.24 2007/03/14 22:55:30 njl Exp $ .\" -.Dd August 31, 2000 +.Dd February 14, 2005 .Dt ACPIDUMP 8 .Os .Sh NAME .Nm acpidump -.Nd dump ACPI tables +.Nd dump ACPI tables and ASL .Sh SYNOPSIS .Nm -.Op Fl r -.Nm -.Op Fl r -.Op Fl o Ar dsdt_file_for_output -.Nm -.Op Fl r -.Op Fl f Ar dsdt_file_for_input +.Op Fl d +.Op Fl t +.Op Fl h +.Op Fl v +.Op Fl f Ar dsdt_input +.Op Fl o Ar dsdt_output .Sh DESCRIPTION The .Nm -utility analyzes ACPI tables in physical memory and dumps them to -standard output. +utility analyzes ACPI tables in physical memory and can dump them to a file. In addition, .Nm -can disassemble AML +can call +.Xr iasl 8 +to disassemble AML (ACPI Machine Language) found in these tables and dump them as ASL -(ACPI Source Language). +(ACPI Source Language) +to stdout. .Pp ACPI tables have an essential data block (the DSDT, -Differentiated System Description Table), +Differentiated System Description Table) that includes information used on the kernel side such as detailed information about PnP hardware, procedures for controlling -power management support and so on. +power management support, and so on. The .Nm utility can extract the DSDT data block from physical memory and store it into -a DSDT data file, and also can generate an output in ASL -from a given DSDT data file. +an output file and optionally also disassemble it. +If any Secondary System Description Table +(SSDT) +entries exist, they will also be included in the output file and disassembly. .Pp When .Nm is invoked without the .Fl f -option, it will read ACPI tables from physical -memory via a special file -.Pa /dev/mem -and dump them. +option, it will read ACPI tables from physical memory via +.Pa /dev/mem . First it searches for the RSDP (Root System Description Pointer), which has the signature @@ -90,87 +91,110 @@ called SDTs and their header has a common format which consists of items such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID, OEM Revision, Creator ID and Creator Revision. -The +When invoked with the +.Fl t +flag, the .Nm -utility dumps contents of these SDTs. -For further information about formats of each table, -see chapter 5: -.Dq ACPI Software Programming Model -from the ACPI specifications referenced below. +utility dumps contents of the following tables: .Pp -There is always a pointer to a physical memory address in RSDT for FACP +.Bl -tag -offset indent -width 12345 -compact +.It APIC +.It BOOT +.It DBGP +.It DSDT +.It ECDT +.It FACS +.It FADT +.It HPET +.It MADT +.It MCFG +.It RSD PTR +.It RSDT +.It SBST +.It SLIT +.It SPCR +.It SRAT +.It TCPA +.It WDAT +.It WDRT +.El +.Pp +The RSDT contains a pointer to the physical memory address of the FACP (Fixed ACPI Description Table). The FACP defines static system information about power management support (ACPI Hardware Register Implementation) -such as interrupt mode -(INT_MODEL), -SCI interrupt number, SMI command port -(SMI_CMD) -and location of ACPI registers. -The FACP also has a pointer to a physical memory address for DSDT, -which includes information used on the kernel side such as -PnP, power management support and so on. -While the other tables are described in fixed format, -the DSDT consists of AML data which is compiled from sources -written in free formated ASL, which is the description language for ACPI. -When -.Nm -outputs DSDT, it disassembles the AML data and -formats it as ASL. +such as interrupt mode (INT_MODEL), +SCI interrupt number, SMI command port (SMI_CMD) +and the location of ACPI registers. +The FACP also has a pointer to a physical memory address for the DSDT. +While the other tables are fixed format, +the DSDT consists of free-formatted AML data. .Sh OPTIONS The following options are supported by .Nm : .Bl -tag -width indent -.It Fl f Ar dsdt_file_for_input -Interprets AML data in DSDT from a file specified in -.Ar dsdt_file_for_input -and dumps them in ASL to standard output. +.It Fl d +Disassemble the DSDT into ASL using +.Xr iasl 8 +and print the results to stdout. +.It Fl t +Dump the contents of the various fixed tables listed above. .It Fl h -Displays usage and exits. -.It Fl o Ar dsdt_file_for_output -Stores DSDT data block from physical memory into a file specified in -.Ar dsdt_file_for_output -in addition to behavior with no option. -.It Fl r -Additionally outputs commented -.Fn ResourceTemplate -macros for Buffer -objects that contain valid resource streams. -These macros are defined in the ACPI 2.0 specification section -16.2.4. +Displays usage and exit. +.It Fl v +Enable verbose messages. +.It Fl f Ar dsdt_input +Load the DSDT from the specified file instead of physical memory. +Since only the DSDT is stored in the file, the +.Fl t +flag may not be used with this option. +.It Fl o Ar dsdt_output +Store the DSDT data block from physical memory into the specified file. .El .Sh FILES .Bl -tag -width /dev/mem .It Pa /dev/mem .El .Sh EXAMPLES -This is an example to get a dump of SDTs and a DSDT data file -simultaneously on a machine that supports ACPI BIOS. +If a developer requests a copy of your ASL, please use the following +command to dump all tables and compress the result. .Bd -literal -offset indent -# acpidump -o foo.dsdt \*[Gt] foo.asl +# acpidump -dt | gzip -c9 > my_computer.asl.gz +.Ed +.Pp +This example dumps the DSDT from physical memory to foo.dsdt. +It also prints the contents of various system tables and disassembles +the AML contained in the DSDT to stdout, redirecting the output +to foo.asl. +.Bd -literal -offset indent +# acpidump -t -d -o foo.dsdt > foo.asl +.Ed +.Pp +This example reads a DSDT file and disassembles it to stdout. +Verbose messages are enabled. +.Bd -literal -offset indent +# acpidump -v -d -f foo.dsdt .Ed .Sh SEE ALSO .Xr acpi 4 , .\" .Xr mem 4 , .\" .Xr acpiconf 8 , -.Xr amldb 8 -.Pp -.Rs -.%T Advanced Configuration and Power Interface Specification -.%Q Intel -.%Q Microsoft -.%Q Toshiba -.%O Revision 1.0b, 2.0 -.Re +.Xr amldb 8 , +.Xr iasl 8 .Sh HISTORY The .Nm -utility appeared in -.Fx 5.0 . +utility first appeared in +.Fx 5.0 +and was rewritten to use +.Xr iasl 8 +for +.Fx 5.2 . .Sh AUTHORS .An Doug Rabson Aq dfr@FreeBSD.org .An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org .An Yasuo YOKOYAMA Aq yokoyama@jp.FreeBSD.org +.An Nate Lawson Aq njl@FreeBSD.org .Pp .An -nosplit Some contributions made by @@ -182,8 +206,5 @@ Some contributions made by and .An Michael Smith Aq msmith@FreeBSD.org . .Sh BUGS -In the current implementation, -.Nm -doesn't dump any information of Firmware ACPI Control Structure -(FACS) -specified by a pointer in FACP. +The current implementation does not dump the BOOT structure or +other miscellaneous tables. diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/acpidump.c --- a/usr.sbin/acpitools/acpidump/acpidump.c +++ b/usr.sbin/acpitools/acpidump/acpidump.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpidump.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */ +/* $NetBSD: $ */ /*- * Copyright (c) 2000 Mitsuru IWASAKI @@ -25,89 +25,126 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: acpidump.c,v 1.3 2000/08/08 14:12:21 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.c,v 1.5 2002/01/02 07:01:34 msmith Exp $ + * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.c,v 1.13 2009/08/25 20:35:57 jhb Exp $ */ + #include -__RCSID("$NetBSD: acpidump.c,v 1.1 2007/01/14 04:36:13 christos Exp $"); +__RCSID("$NetBSD: acpi.c,v 1.4 2008/02/13 18:59:18 drochner Exp $"); + #include - #include #include #include -#include #include #include +#include -#include #include "acpidump.h" -static void -asl_dump_from_file(char *file) -{ - u_int8_t *dp; - u_int8_t *end; - - acpi_load_dsdt(file, &dp, &end); - acpi_dump_dsdt(dp, end); -} +int dflag; /* Disassemble AML using iasl(8) */ +int tflag; /* Dump contents of SDT tables */ +int vflag; /* Use verbose messages */ static void -asl_dump_from_devmem(void) +usage(void) { - struct ACPIrsdp *rp; - struct ACPIsdt *rsdp; + const char *progname = getprogname(); - rp = acpi_find_rsd_ptr(); - if (!rp) - errx(1, "Can't find ACPI information\n"); - - acpi_print_rsd_ptr(rp); - rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->addr); - if (memcmp(rsdp->signature, "RSDT", 4) || - acpi_checksum(rsdp, rsdp->len)) - errx(1, "RSDT is corrupted\n"); - - acpi_handle_rsdt(rsdp); -} - -static void -usage(const char *progname) -{ - - printf("usage:\t%s [-r] [-o dsdt_file_for_output]\n", progname); - printf("\t%s [-r] [-f dsdt_file_for_input]\n", progname); - printf("\t%s [-h]\n", progname); - exit(1); + fprintf(stderr, "usage: %s [-d] [-t] [-h] [-v] [-f dsdt_input] " + "[-o dsdt_output]\n", progname); + fprintf(stderr, "To send ASL:\n\t%s -dt | gzip -c9 > foo.asl.gz\n", + progname); + exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { - char c, *progname; + ACPI_TABLE_HEADER *rsdt, *sdt; + char c; + char *dsdt_input_file, *dsdt_output_file; - progname = argv[0]; - while ((c = getopt(argc, argv, "f:o:hr")) != -1) { + dsdt_input_file = dsdt_output_file = NULL; + + if (argc < 2) + usage(); + + while ((c = getopt(argc, argv, "dhtvf:o:")) != -1) { switch (c) { + case 'd': + dflag = 1; + break; + case 't': + tflag = 1; + break; + case 'v': + vflag = 1; + break; case 'f': - asl_dump_from_file(optarg); - return (0); + dsdt_input_file = optarg; + break; case 'o': - aml_dumpfile = optarg; + dsdt_output_file = optarg; break; case 'h': - usage(progname); - break; - case 'r': - rflag++; - break; default: - argc -= optind; - argv += optind; + usage(); + /* NOTREACHED */ } } + argc -= optind; + argv += optind; - asl_dump_from_devmem(); - return (0); + /* Get input either from file or /dev/mem */ + if (dsdt_input_file != NULL) { + if (dflag == 0 && tflag == 0) { + warnx("Need to specify -d or -t with DSDT input file"); + usage(); + } else if (tflag != 0) { + warnx("Can't use -t with DSDT input file"); + usage(); + } + if (vflag) + warnx("loading DSDT file: %s", dsdt_input_file); + rsdt = dsdt_load_file(dsdt_input_file); + } else { + if (vflag) + warnx("loading RSD PTR from /dev/mem"); + rsdt = sdt_load_devmem(); + } + + /* Display misc. SDT tables (only available when using /dev/mem) */ + if (tflag) { + if (vflag) + warnx("printing various SDT tables"); + sdt_print_all(rsdt); + } + + /* Translate RSDT to DSDT pointer */ + if (dsdt_input_file == NULL) { + sdt = sdt_from_rsdt(rsdt, ACPI_SIG_FADT, NULL); + sdt = dsdt_from_fadt((ACPI_TABLE_FADT *)sdt); + } else { + sdt = rsdt; + rsdt = NULL; + } + + /* Dump the DSDT and SSDTs to a file */ + if (dsdt_output_file != NULL) { + if (vflag) + warnx("saving DSDT file: %s", dsdt_output_file); + dsdt_save_file(dsdt_output_file, rsdt, sdt); + } + + /* Disassemble the DSDT into ASL */ + if (dflag) { + if (vflag) + warnx("disassembling DSDT, iasl messages follow"); + aml_disassemble(rsdt, sdt); + if (vflag) + warnx("iasl processing complete"); + } + + exit(EXIT_SUCCESS); } diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/acpidump.h --- a/usr.sbin/acpitools/acpidump/acpidump.h +++ b/usr.sbin/acpitools/acpidump/acpidump.h @@ -1,4 +1,4 @@ -/* $NetBSD: acpidump.h,v 1.1 2007/01/14 04:36:13 christos Exp $ */ +/* $NetBSD: $ */ /*- * Copyright (c) 1999 Doug Rabson @@ -26,158 +26,63 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: acpidump.h,v 1.3 2000/08/09 14:47:52 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.h,v 1.5 2002/10/09 19:46:09 jhb Exp $ + * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.h,v 1.24 2009/08/25 20:35:57 jhb Exp $ */ #ifndef _ACPIDUMP_H_ -#define _ACPIDUMP_H_ +#define _ACPIDUMP_H_ -/* Generic Address structure */ -struct ACPIgas { - u_int8_t address_space_id; -#define ACPI_GAS_MEMORY 0 -#define ACPI_GAS_IO 1 -#define ACPI_GAS_PCI 2 -#define ACPI_GAS_EMBEDDED 3 -#define ACPI_GAS_SMBUS 4 -#define ACPI_GAS_FIXED 0x7f - u_int8_t register_bit_width; - u_int8_t register_bit_offset; - u_int8_t res; - u_int64_t address; -} __packed; +#include /* for size_t */ +#include +#include -/* Root System Description Pointer */ -struct ACPIrsdp { - u_char signature[8]; - u_char sum; - u_char oem[6]; - u_char res; - u_int32_t addr; -} __packed; +/* GAS address space ID constants. */ +#define ACPI_GAS_MEMORY 0 +#define ACPI_GAS_IO 1 +#define ACPI_GAS_PCI 2 +#define ACPI_GAS_EMBEDDED 3 +#define ACPI_GAS_SMBUS 4 +#define ACPI_GAS_CMOS 5 +#define ACPI_GAS_PCIBAR 6 +#define ACPI_GAS_DATATABLE 7 +#define ACPI_GAS_FIXED 0x7f -/* System Description Table */ -struct ACPIsdt { - u_char signature[4]; - u_int32_t len; - u_char rev; - u_char check; - u_char oemid[6]; - u_char oemtblid[8]; - u_int32_t oemrev; - u_char creator[4]; - u_int32_t crerev; -#define SIZEOF_SDT_HDR 36 /* struct size except body */ - u_int32_t body[1];/* This member should be casted */ -} __packed; +/* Subfields in the HPET Id member. */ +#define ACPI_HPET_ID_HARDWARE_REV_ID 0x000000ff +#define ACPI_HPET_ID_COMPARATORS 0x00001f00 +#define ACPI_HPET_ID_COUNT_SIZE_CAP 0x00002000 +#define ACPI_HPET_ID_LEGACY_CAPABLE 0x00008000 +#define ACPI_HPET_ID_PCI_VENDOR_ID 0xffff0000 -/* Fixed ACPI Description Table (body) */ -struct FACPbody { - u_int32_t facs_ptr; - u_int32_t dsdt_ptr; - u_int8_t int_model; -#define ACPI_FACP_INTMODEL_PIC 0 /* Standard PC-AT PIC */ -#define ACPI_FACP_INTMODEL_APIC 1 /* Multiple APIC */ - u_char reserved1; - u_int16_t sci_int; - u_int32_t smi_cmd; - u_int8_t acpi_enable; - u_int8_t acpi_disable; - u_int8_t s4biosreq; - u_int8_t reserved2; - u_int32_t pm1a_evt_blk; - u_int32_t pm1b_evt_blk; - u_int32_t pm1a_cnt_blk; - u_int32_t pm1b_cnt_blk; - u_int32_t pm2_cnt_blk; - u_int32_t pm_tmr_blk; - u_int32_t gpe0_blk; - u_int32_t gpe1_blk; - u_int8_t pm1_evt_len; - u_int8_t pm1_cnt_len; - u_int8_t pm2_cnt_len; - u_int8_t pm_tmr_len; - u_int8_t gpe0_len; - u_int8_t gpe1_len; - u_int8_t gpe1_base; - u_int8_t reserved3; - u_int16_t p_lvl2_lat; - u_int16_t p_lvl3_lat; - u_int16_t flush_size; - u_int16_t flush_stride; - u_int8_t duty_off; - u_int8_t duty_width; - u_int8_t day_alrm; - u_int8_t mon_alrm; - u_int8_t century; - u_int16_t iapc_boot_arch; - u_char reserved4[1]; - u_int32_t flags; -#define ACPI_FACP_FLAG_WBINVD 1 /* WBINVD is correctly supported */ -#define ACPI_FACP_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */ -#define ACPI_FACP_FLAG_PROC_C1 4 /* C1 power state supported */ -#define ACPI_FACP_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */ -#define ACPI_FACP_FLAG_PWR_BUTTON 16 /* Power button uses control method */ -#define ACPI_FACP_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */ -#define ACPI_FACP_FLAG_FIX_RTC 64 /* RTC wakeup not supported */ -#define ACPI_FACP_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */ -#define ACPI_FACP_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */ -#define ACPI_FACP_FLAG_DCK_CAP 512 /* Can support docking */ - struct ACPIgas reset_reg; - u_int8_t reset_value; - u_int8_t reserved5[3]; - u_int64_t x_firmware_ctrl; - u_int64_t x_dsdt; - struct ACPIgas x_pm1a_evt_blk; - struct ACPIgas x_pm1b_evt_blk; - struct ACPIgas x_pm1a_cnt_blk; - struct ACPIgas x_pm1b_cnt_blk; - struct ACPIgas x_pm2_cnt_blk; - struct ACPIgas x_pm_tmr_blk; - struct ACPIgas x_gpe0_blk; - struct ACPIgas x_gpe1_blk; -} __packed; +/* Find and map the RSD PTR structure and return it for parsing */ +ACPI_TABLE_HEADER *sdt_load_devmem(void); -/* Firmware ACPI Control Structure */ -struct FACS { - u_char signature[4]; - u_int32_t len; - u_char hard_sig[4]; - /* - * NOTE This should be filled with physical address below 1MB!! - * sigh.... - */ - u_int32_t firm_wake_vec; - u_int32_t g_lock; /* bit field */ - /* 5.2.6.1 Global Lock */ -#define ACPI_GLOBAL_LOCK_PENDING 1 -#define ACPI_GLOBAL_LOCK_OWNED 2 - u_int32_t flags; /* bit field */ -#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */ - char reserved[40]; -} __packed; +/* + * Load the DSDT from a previous save file. Note that other tables are + * not saved (i.e. FADT) + */ +ACPI_TABLE_HEADER *dsdt_load_file(char *); -void *acpi_map_physical(vm_offset_t, size_t); -struct ACPIrsdp *acpi_find_rsd_ptr(void); -int acpi_checksum(void *, size_t); -struct ACPIsdt *acpi_map_sdt(vm_offset_t); -void acpi_print_rsd_ptr(struct ACPIrsdp *); -void acpi_print_sdt(struct ACPIsdt *); -void acpi_print_rsdt(struct ACPIsdt *); -void acpi_print_facp(struct FACPbody *); -void acpi_print_dsdt(struct ACPIsdt *); +/* Save the DSDT to a file */ +void dsdt_save_file(char *, ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *); -void asl_dump_termobj(u_int8_t **, int); -void asl_dump_objectlist(u_int8_t **, u_int8_t *, int); +/* Print out as many fixed tables as possible, given the RSD PTR */ +void sdt_print_all(ACPI_TABLE_HEADER *); -void aml_dump(struct ACPIsdt *); +/* Disassemble the AML in the DSDT */ +void aml_disassemble(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *); -void acpi_handle_rsdt(struct ACPIsdt *); -void acpi_load_dsdt(char *, u_int8_t **, u_int8_t **); -void acpi_dump_dsdt(u_int8_t *, u_int8_t *); -extern char *aml_dumpfile; -extern struct ACPIsdt dsdt_header; -extern int rflag; +/* Routines for accessing tables in physical memory */ +ACPI_TABLE_RSDP *acpi_find_rsd_ptr(void); +void *acpi_map_physical(vm_offset_t, size_t); +ACPI_TABLE_HEADER *sdt_from_rsdt(ACPI_TABLE_HEADER *, const char *, + ACPI_TABLE_HEADER *); +ACPI_TABLE_HEADER *dsdt_from_fadt(ACPI_TABLE_FADT *); +int acpi_checksum(void *, size_t); + +/* Command line flags */ +extern int dflag; +extern int tflag; +extern int vflag; #endif /* !_ACPIDUMP_H_ */ diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/aml_dump.c --- a/usr.sbin/acpitools/acpidump/aml_dump.c +++ /dev/null @@ -1,65 +0,0 @@ -/* $NetBSD: aml_dump.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */ - -/*- - * Copyright (c) 2000 Mitsuru IWASAKI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Id: aml_dump.c,v 1.3 2000/08/08 14:12:21 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/aml_dump.c,v 1.4 2001/10/22 17:25:25 iwasaki Exp $ - */ -#include -__RCSID("$NetBSD: aml_dump.c,v 1.1 2007/01/14 04:36:13 christos Exp $"); - -#include -#include - -#include -#include -#include - -#include -#include "acpidump.h" - -char *aml_dumpfile = NULL; - -void -aml_dump(struct ACPIsdt *dsdp) -{ - int fd; - mode_t mode; - - if (aml_dumpfile == NULL) { - return; - } - - mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - fd = open(aml_dumpfile, O_WRONLY | O_CREAT | O_TRUNC, mode); - if (fd == -1) { - return; - } - write(fd, dsdp, SIZEOF_SDT_HDR); - write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR); - close(fd); -} - diff -r 9360ee4a4687 -r 065cebe63e80 usr.sbin/acpitools/acpidump/asl_dump.c --- a/usr.sbin/acpitools/acpidump/asl_dump.c +++ /dev/null @@ -1,1779 +0,0 @@ -/* $NetBSD: asl_dump.c,v 1.5 2008/02/13 11:47:36 joerg Exp $ */ - -/*- - * Copyright (c) 1999 Doug Rabson - * Copyright (c) 2000 Mitsuru IWASAKI - * Copyright (c) 2008 Joerg Sonnenberger - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Id: asl_dump.c,v 1.6 2000/08/09 14:47:52 iwasaki Exp - * $FreeBSD: src/usr.sbin/acpi/acpidump/asl_dump.c,v 1.7 2002/03/02 15:05:26 takawata Exp $ - */ -#include -__RCSID("$NetBSD: asl_dump.c,v 1.5 2008/02/13 11:47:36 joerg Exp $"); - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include "acpidump.h" - -#include "aml/aml_env.h" - -#ifdef DEBUG -#define ASSERT(a) assert(a) -#else -#define ASSERT(a) ; -#endif - -struct aml_environ asl_env; -int rflag; - -static u_int32_t -asl_dump_pkglength(u_int8_t **dpp) -{ - u_int8_t *dp; - u_int32_t pkglength; - - dp = *dpp; - pkglength = *dp++; - switch (pkglength >> 6) { - case 0: - break; - case 1: - pkglength = (pkglength & 0xf) + (dp[0] << 4); - dp += 1; - break; - case 2: - pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12); - dp += 2; - break; - case 3: - pkglength = (pkglength & 0xf) - + (dp[0] << 4) + (dp[1] << 12) + (dp[2] << 20); - dp += 3; - break; - } - - *dpp = dp; - return (pkglength); -} - -static void -print_nameseg(u_int8_t *dp) -{ - - if (dp[3] != '_') - printf("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]); - else if (dp[2] != '_') - printf("%c%c%c", dp[0], dp[1], dp[2]); - else if (dp[1] != '_') - printf("%c%c", dp[0], dp[1]); - else if (dp[0] != '_') - printf("%c", dp[0]); -} - -static u_int8_t -asl_dump_bytedata(u_int8_t **dpp) -{ - u_int8_t *dp; - u_int8_t data; - - dp = *dpp; - data = dp[0]; - *dpp = dp + 1; - return (data); -} - -static u_int16_t -asl_dump_worddata(u_int8_t **dpp) -{ - u_int8_t *dp; - - dp = *dpp; - *dpp = dp + 2; - return le16dec(dp); -} - -static u_int32_t -asl_dump_dworddata(u_int8_t **dpp) -{ - u_int8_t *dp; - - dp = *dpp; - *dpp = dp + 4; - return le32dec(dp); -} - -static u_int64_t -asl_dump_qworddata(u_int8_t **dpp) -{ - u_int8_t *dp; - - dp = *dpp; - *dpp = dp + 8; - return le64dec(dp); -} - -static u_int8_t * -asl_dump_namestring(u_int8_t **dpp) -{ - u_int8_t *dp; - u_int8_t *name; - - dp = *dpp; - name = dp; - if (dp[0] == '\\') - dp++; - else if (dp[0] == '^') - while (dp[0] == '^') - dp++; - if (dp[0] == 0x00) /* NullName */ - dp++; - else if (dp[0] == 0x2e) /* DualNamePrefix */ - dp += 1 + 4 + 4;/* NameSeg, NameSeg */ - else if (dp[0] == 0x2f) { /* MultiNamePrefix */ - int segcount = dp[1]; - dp += 1 + 1 + segcount * 4; /* segcount * NameSeg */ - } else - dp += 4; /* NameSeg */ - - *dpp = dp; - return (name); -} - -static void -print_namestring(u_int8_t *dp) -{ - - if (dp[0] == '\\') { - putchar(dp[0]); - dp++; - } else if (dp[0] == '^') { - while (dp[0] == '^') { - putchar(dp[0]); - dp++; - } - } - if (dp[0] == 0x00) { /* NullName */ - /* printf(""); */ - dp++; - } else if (dp[0] == 0x2e) { /* DualNamePrefix */ - print_nameseg(dp + 1); - putchar('.'); - print_nameseg(dp + 5); - } else if (dp[0] == 0x2f) { /* MultiNamePrefix */ - int segcount = dp[1]; - int i; - for (i = 0, dp += 2; i < segcount; i++, dp += 4) { - if (i > 0) - putchar('.'); - print_nameseg(dp); - } - } else /* NameSeg */ - print_nameseg(dp); -} - -static void -print_indent(int indent) -{ - int i; - - for (i = 0; i < indent; i++) - printf(" "); -} - -#define ASL_ENTER_SCOPE(dp_orig, old_name) do { \ - u_int8_t *dp_copy; \ - u_int8_t *name; \ - old_name = asl_env.curname; \ - dp_copy = dp_orig; \ - name = asl_dump_namestring(&dp_copy); \ - asl_env.curname = aml_search_name(&asl_env, name); \ -} while(0) - -#define ASL_LEAVE_SCOPE(old_name) do { \ - asl_env.curname = old_name; \ -} while(0) - -#define ASL_CREATE_LOCALNAMEOBJ(dp) do { \ - if(scope_within_method){ \ - aml_create_name(&asl_env, dp); \ - } \ -}while(0); - -static void -asl_dump_defscope(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - - printf("Scope("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - printf(") {\n"); - end = start + pkglength; - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - -static void -asl_dump_resourcebuffer(u_int8_t *dp, u_int8_t *end, int indent) -{ - u_int8_t *p; - int print, len, name, indep, ofs; - - print = 0; - indep = 0; -restart: - if (print) { - printf("\n"); - print_indent(indent); - printf("/* ResourceTemplate() {\n"); - } - for (p = dp; p < end; ) { - ofs = p - dp; - if (*p & 0x80) { /* large resource */ - if ((end - p) < 3) { - return; - } - name = *p; - len = ((int)*(p + 2) << 8) + *(p + 1); - p += 3; - } else { /* small resource */ - name = (*p >> 3) & 0x0f; - len = *p & 0x7; - p++; - } - if (name == 0xf) { /* end tag */ - if (print == 0) { - print = 1; - goto restart; - } else { - print_indent(indent); - printf("} */\n"); - print_indent(indent); - break; - } - } - - if (print) { - print_indent(indent); - switch (name) { - case 0x06: - if (indep) { - printf(" }\n"); - print_indent(indent); - } - printf(" StartDependentFn("); - if (len == 1) - printf("%d, %d", - *p & 0x3, - (*p >> 2) & 0x3); - printf(") {\n"); - indep = 1; - continue; - case 0x07: - if (indep) - printf(" }\n"); - print_indent(indent); - printf(" EndDependentFn() {}\n"); - indep = 0; - continue; - } - - printf("%s 0x%-4.4x ", indep ? " " : "", ofs); - switch (name) { - case 0x04: /* IRQ() { } */ - { - int i, first; - - printf("IRQ("); - if (len == 3) { - printf("%s, Active%s, %s", - *(p + 2) & 0x01 ? "Edge" : "Level", - *(p + 2) & 0x08 ? "Low" : "High", - *(p + 2) & 0x10 ? "Shared" : - "Exclusive"); - } - printf(")"); - first = 1; - for (i = 0; i < 16; i++) { - if (*(p + (i / 8)) & (1 << (i % 8))) { - if (first) { - printf(" {"); - first = 0; - } else { - printf(", "); - } - printf("%d", i); - } - } - if (!first) - printf("}"); - printf("\n"); - break; - } - - case 0x05: /* DMA() { } */ - { - int i, first; - - printf("DMA(%s, %sBusMaster, Transfer%s)", - (*(p + 1) & 0x60) == 0 ? "Compatibility" : - (*(p + 1) & 0x60) == 1 ? "TypeA" : - (*(p + 1) & 0x60) == 2 ? "TypeB" : "TypeF", - *(p + 1) & 0x04 ? "" : "Not", - (*(p + 1) & 0x03) == 0 ? "8" : - (*(p + 1) & 0x03) == 1 ? "8_16" : "16"); - first = 1; - for (i = 0; i < 8; i++) { - if (*p & (1 << i)) { - if (first) { - printf(" {"); - first = 0; - } else { - printf(", "); - } - printf("%d", i); - } - } - if (!first) - printf("}"); - printf("\n"); - break; - } - case 0x08: /* IO() */ - printf("IO(Decode%s, 0x%x, 0x%x, 0x%x, 0x%x)\n", - *p & 0x01 ? "16" : "10", - (int)*(u_int16_t *)(p + 1), - (int)*(u_int16_t *)(p + 3), - *(p + 5), - *(p + 6)); - break; - - case 0x09: /* FixedIO() */ - printf("FixedIO(0x%x, 0x%x)\n", - *p + ((int)*(p + 1) << 8), - *(p + 2)); - break; - - case 0x0e: /* VendorShort() { }*/ - case 0x84: /* VendorLong() { } */ - { - int i, first; - - printf("Vendor%s()", name == 0x0e ? "Short" : "Long"); - first = 0; - for (i = 0; i < len; i++) { - if (first) { - printf(" {"); - first = 0; - } else { - printf(", "); - } - printf("0x%02x", *(p + i)); - } - if (!first) - printf("}"); - printf("\n"); - break; - } - case 0x81: /* Memory24() */ - printf("Memory24(Read%s, 0x%06x, 0x%06x, 0x%x, 0x%x)\n", - *p & 0x01 ? "Write" : "Only", - (u_int32_t)*(u_int16_t *)(p + 1) << 8, - (u_int32_t)*(u_int16_t *)(p + 3) << 8, - (int)*(u_int16_t *)(p + 5), - (int)*(u_int16_t *)(p + 7)); - break; - - case 0x82: /* Register() */ - printf("Register(%s, %d, %d, 0x%016" - PRIx64 "\n", - *p == 0x00 ? "SystemMemory" : - *p == 0x01 ? "SystemIO" : - *p == 0x02 ? "PCIConfigSpace" : - *p == 0x03 ? "EmbeddedController" : - *p == 0x04 ? "SMBus" : - *p == 0x7f ? "FunctionalFixedHardware" : "Unknown", - *(p + 1), - *(p + 2), - *(u_int64_t *)(p + 3)); - break; - - case 0x85: /* Memory32() */ - printf("Memory32(Read%s, 0x%08x, 0x%08x, 0x%x, 0x%x)\n", - *p & 0x01 ? "Write" : "Only", - *(u_int32_t *)(p + 1), - *(u_int32_t *)(p + 5), - *(u_int32_t *)(p + 9), - *(u_int32_t *)(p + 13)); - break; - - case 0x86: /* Memory32Fixed() */ - printf("Memory32Fixed(Read%s, 0x%08x, 0x%x)\n", - *p & 0x01 ? "Write" : "Only", - *(u_int32_t *)(p + 1), - *(u_int32_t *)(p + 5)); - break; - - case 0x87: /* DWordMemory() / DWordIO() */ - case 0x88: /* WordMemory() / WordIO() */ - case 0x8a: /* QWordMemory() / QWordIO() */ - { - u_int64_t granularity=0, minimum=0, maximum=0, translation=0, length=0; - const char *size = NULL, *source=NULL; - int index=0, slen=0; - - switch (name) { - case 0x87: - size = "D"; - granularity = *(u_int32_t *)(p + 3); - minimum = *(u_int32_t *)(p + 7); - maximum = *(u_int32_t *)(p + 11); - translation = *(u_int32_t *)(p + 15); - length = *(u_int32_t *)(p + 19); - index = *(p + 23); - source = (char *)(p + 24); - slen = len - 24; - break; - case 0x88: - size = ""; - granularity = *(u_int16_t *)(p + 3); - minimum = *(u_int16_t *)(p + 5); - maximum = *(u_int16_t *)(p + 7); - translation = *(u_int16_t *)(p + 9); - length = *(u_int16_t *)(p + 11); - index = *(p + 13); - source = (char *)(p + 14); - slen = len - 14; - break; - case 0x8a: - size = "Q"; - granularity = *(u_int64_t *)(p + 3); - minimum = *(u_int64_t *)(p + 11); - maximum = *(u_int64_t *)(p + 19); - translation = *(u_int64_t *)(p + 27); - length = *(u_int64_t *)(p + 35); - index = *(p + 43); - source = (char *)(p + 44); - slen = len - 44; - break; - } - switch(*p) { - case 0: - printf("%sWordMemory(" - "Resource%s, " - "%sDecode, " - "Min%sFixed, " - "Max%sFixed, " - "%s, " - "Read%s, " - "0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", " - "%d, '%.*s', " - "AddressRange%s, " - "Type%s)\n", - size, - *(p + 1) & 0x01 ? "Consumer" : "Producer", - *(p + 1) & 0x02 ? "Sub" : "Pos", - *(p + 1) & 0x04 ? "" : "Not", - *(p + 1) & 0x08 ? "" : "Not", - (*(p + 2) >> 1) == 0 ? "NonCacheable" : - (*(p + 2) >> 1) == 1 ? "Cacheable" : - (*(p + 2) >> 1) == 2 ? "WriteCombining" : - "Prefetchable", - *(p + 2) & 0x01 ? "Write" : "Only", - granularity, minimum, maximum, translation, length, - index, slen, source, - ((*(p + 2) >> 3) & 0x03) == 0 ? "Memory" : - ((*(p + 2) >> 3) & 0x03) == 1 ? "Reserved" : - ((*(p + 2) >> 3) & 0x03) == 2 ? "ACPI" : "NVS", - *(p + 2) & 0x20 ? "Translation" : "Static"); - break; - case 1: - printf("%sWordIO(" - "Resource%s, " - "Min%sFixed, " - "Max%sFixed, " - "%sDecode, " - "%s, " - "0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", " - "%d, '%.*s', " - "Type%s, " - "%sTranslation)\n", - size, - *(p + 1) & 0x01 ? "Consumer" : "Producer", - *(p + 1) & 0x04 ? "" : "Not", - *(p + 1) & 0x08 ? "" : "Not", - *(p + 1) & 0x02 ? "Sub" : "Pos", - (*(p + 2) & 0x03) == 0 ? "EntireRange" : - (*(p + 2) & 0x03) == 1 ? "NonISAOnlyRanges" : - (*(p + 2) & 0x03) == 2 ? "ISAOnlyRanges" : "EntireRange", - granularity, minimum, maximum, translation, length, - index, slen, source, - *(p + 2) & 0x10 ? "Translation" : "Static", - *(p + 2) & 0x20 ? "Sparse" : "Dense"); - break; - case 2: - printf("%sWordBus(" - "Resource%s, " - "%sDecode, " - "Min%sFixed, " - "Max%sFixed, " - "0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", " - "%d, '%.*s')\n", - size, - *(p + 1) & 0x01 ? "Consumer" : "Producer", - *(p + 1) & 0x02 ? "Sub" : "Pos", - *(p + 1) & 0x04 ? "" : "Not", - *(p + 1) & 0x08 ? "" : "Not", - granularity, minimum, maximum, translation, length, - index, slen, source); - break; - default: - printf("%sWordUnknown()\n", size); - } - break; - } - case 0x89: /* Interrupt() { } */ - { - int i, first, pad, sl; - char *rp; - - pad = *(p + 1) * 4; - rp = (char *)(p + 1 + pad); - sl = len - pad - 3; - printf("Interrupt(Resource%s, %s, Active%s, %s, %d, %.*s)", - *p & 0x01 ? "Producer" : "Consumer", - *p & 0x02 ? "Edge" : "Level", - *p & 0x04 ? "Low" : "High", - *p & 0x08 ? "Shared" : "Exclusive", - (int)*(p + 1 + pad), - sl, - rp); - first = 1; - for (i = 0; i < *(p + 1); i++) { - if (first) { - printf(" {"); - first = 0; - } else { - printf(", "); - } - printf("%u", *(u_int32_t *)(p + 2 + (i * 4))); - } - if (!first) - printf("}"); - printf("\n"); - break; - } - default: - printf("Unknown(0x%x, %d)\n", name, len); - break; - } - } - p += len; - } -} - -static void -asl_dump_defbuffer(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - printf("Buffer("); - asl_dump_termobj(&dp, indent); - start = dp; - printf(") {"); - while (dp < end) { - printf("0x%x", *dp++); - if (dp < end) - printf(", "); - } - if (rflag) - asl_dump_resourcebuffer(start, end, indent); - printf(" }"); - - *dpp = dp; -} - -static void -asl_dump_defpackage(u_int8_t **dpp, int indent, bool variable) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t numelements; - u_int32_t pkglength; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - if (variable) { - printf("VarPackage("); - print_indent(indent + 1); - asl_dump_termobj(&dp, indent + 1); - printf(",) {\n"); - } else { - numelements = asl_dump_bytedata(&dp); - printf("Package(0x%02" PRIx8 ") {\n", numelements); - } - - while (dp < end) { - print_indent(indent + 1); - asl_dump_termobj(&dp, indent + 1); - printf(",\n"); - } - - print_indent(indent); - printf("}"); - - dp = end; - - *dpp = dp; -} - -int scope_within_method = 0; - -static void -asl_dump_defmethod(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t flags; - u_int32_t pkglength; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - - printf("Method("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - flags = *dp++; - if (flags) { - printf(", %d", flags & 7); - if (flags & 8) { - printf(", Serialized"); - } - } - printf(") {\n"); - end = start + pkglength; - scope_within_method = 1; - asl_dump_objectlist(&dp, end, indent + 1); - scope_within_method = 0; - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - - -static void -asl_dump_defopregion(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - const char *regions[] = { - "SystemMemory", - "SystemIO", - "PCI_Config", - "EmbeddedControl", - "SMBus", - }; - - dp = *dpp; - printf("OperationRegion("); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); /* Name */ - printf(", %s, ", regions[*dp++]); /* Space */ - asl_dump_termobj(&dp, indent); /* Offset */ - printf(", "); - asl_dump_termobj(&dp, indent); /* Length */ - printf(")"); - - *dpp = dp; -} - -static const char *accessnames[] = { - "AnyAcc", - "ByteAcc", - "WordAcc", - "DWordAcc", - "BlockAcc", - "SMBSendRecvAcc", - "SMBQuickAcc" -}; - -static int -asl_dump_field(u_int8_t **dpp, u_int32_t offset) -{ - u_int8_t *dp; - u_int8_t *name; - u_int8_t access, attribute; - u_int32_t width; - - dp = *dpp; - switch (*dp) { - case '\\': - case '^': - case 'A' ... 'Z': - case '_': - case '.': - case '/': - ASL_CREATE_LOCALNAMEOBJ(dp); - name = asl_dump_namestring(&dp); - width = asl_dump_pkglength(&dp); - offset += width; - print_namestring(name); - printf(",\t%d", width); - break; - case 0x00: - dp++; - width = asl_dump_pkglength(&dp); - offset += width; - if ((offset % 8) == 0) { - printf("Offset(0x%x)", offset / 8); - } else { - printf(",\t%d", width); - } - break; - case 0x01: - access = dp[1]; - attribute = dp[2]; - dp += 3; - printf("AccessAs(%s, %d)", accessnames[access], attribute); - break; - } - - *dpp = dp; - return (offset); -} - -static void -asl_dump_fieldlist(u_int8_t **dpp, u_int8_t *end, int indent) -{ - u_int8_t *dp; - u_int32_t offset; - - dp = *dpp; - offset = 0; - while (dp < end) { - print_indent(indent); - offset = asl_dump_field(&dp, offset); - if (dp < end) - printf(",\n"); - else - printf("\n"); - } - - *dpp = dp; -} - -static void -asl_dump_deffield(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t flags; - u_int32_t pkglength; - static const char *lockrules[] = {"NoLock", "Lock"}; - static const char *updaterules[] = {"Preserve", "WriteAsOnes", - "WriteAsZeros", "*Error*"}; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("Field("); - asl_dump_termobj(&dp, indent); /* Name */ - flags = asl_dump_bytedata(&dp); - printf(", %s, %s, %s) {\n", - accessnames[flags & 0xf], - lockrules[(flags >> 4) & 1], - updaterules[(flags >> 5) & 3]); - asl_dump_fieldlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -static void -asl_dump_defindexfield(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t flags; - u_int32_t pkglength; - static const char *lockrules[] = {"NoLock", "Lock"}; - static const char *updaterules[] = {"Preserve", "WriteAsOnes", - "WriteAsZeros", "*Error*"}; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("IndexField("); - asl_dump_termobj(&dp, indent); /* Name1 */ - printf(", "); - asl_dump_termobj(&dp, indent); /* Name2 */ - flags = asl_dump_bytedata(&dp); - printf(", %s, %s, %s) {\n", - accessnames[flags & 0xf], - lockrules[(flags >> 4) & 1], - updaterules[(flags >> 5) & 3]); - asl_dump_fieldlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -static void -asl_dump_defbankfield(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t flags; - u_int32_t pkglength; - static const char *lockrules[] = {"NoLock", "Lock"}; - static const char *updaterules[] = {"Preserve", "WriteAsOnes", - "WriteAsZeros", "*Error*"}; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("BankField("); - asl_dump_termobj(&dp, indent); /* Name1 */ - printf(", "); - asl_dump_termobj(&dp, indent); /* Name2 */ - printf(", "); - asl_dump_termobj(&dp, indent); /* BankValue */ - flags = asl_dump_bytedata(&dp); - printf(", %s, %s, %s) {\n", - accessnames[flags & 0xf], - lockrules[(flags >> 4) & 1], - updaterules[(flags >> 5) & 3]); - asl_dump_fieldlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -static void -asl_dump_defdevice(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("Device("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - printf(") {\n"); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - -static void -asl_dump_defprocessor(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t procid; - u_int8_t pblklen; - u_int32_t pkglength; - u_int32_t pblkaddr; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("Processor("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - procid = asl_dump_bytedata(&dp); - pblkaddr = asl_dump_dworddata(&dp); - pblklen = asl_dump_bytedata(&dp); - printf(", %d, 0x%x, 0x%x) {\n", procid, pblkaddr, pblklen); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - -static void -asl_dump_defpowerres(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int8_t systemlevel; - u_int16_t resourceorder; - u_int32_t pkglength; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("PowerResource("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - systemlevel = asl_dump_bytedata(&dp); - resourceorder = asl_dump_worddata(&dp); - printf(", %d, %d) {\n", systemlevel, resourceorder); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - -static void -asl_dump_defthermalzone(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - struct aml_name *oname; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("ThermalZone("); - ASL_ENTER_SCOPE(dp, oname); - asl_dump_termobj(&dp, indent); - printf(") {\n"); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - ASL_LEAVE_SCOPE(oname); - *dpp = dp; -} - -static void -asl_dump_defif(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("If("); - asl_dump_termobj(&dp, indent); - printf(") {\n"); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -static void -asl_dump_defelse(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("Else {\n"); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -static void -asl_dump_defwhile(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *start; - u_int8_t *end; - u_int32_t pkglength; - - dp = *dpp; - start = dp; - pkglength = asl_dump_pkglength(&dp); - end = start + pkglength; - - printf("While("); - asl_dump_termobj(&dp, indent); - printf(") {\n"); - asl_dump_objectlist(&dp, end, indent + 1); - print_indent(indent); - printf("}"); - - ASSERT(dp == end); - - *dpp = dp; -} - -/* - * Public interfaces - */ - -void -asl_dump_termobj(u_int8_t **dpp, int indent) -{ - u_int8_t *dp; - u_int8_t *name; - u_int8_t opcode; - struct aml_name *method; - const char *matchstr[] = { - "MTR", "MEQ", "MLE", "MLT", "MGE", "MGT", - }; - -#define OPTARG() do { \ - printf(", "); \ - if (*dp == 0x00) { \ - dp++; \ - } else { \ - asl_dump_termobj(&dp, indent); \ - } \ -} while (0) - - dp = *dpp; - opcode = *dp++; - switch (opcode) { - case '\\': - case '^': - case 'A' ... 'Z': - case '_': - case '.': - case '/': - dp--; - print_namestring((name = asl_dump_namestring(&dp))); - if (scope_within_method == 1) { - method = aml_search_name(&asl_env, name); - if (method != NULL && method->property != NULL && - method->property->type == aml_t_method) { - int i, argnum; - - argnum = method->property->meth.argnum & 7; - printf("("); - for (i = 0; i < argnum; i++) { - asl_dump_termobj(&dp, indent); - if (i < (argnum-1)) { - printf(", "); - } - } - printf(")"); - } - } - break; - case 0x0a: /* BytePrefix */ - printf("0x%02" PRIx8, asl_dump_bytedata(&dp)); - break; - case 0x0b: /* WordPrefix */ - printf("0x%04" PRIx16, asl_dump_worddata(&dp)); - break; - case 0x0c: /* DWordPrefix */ - printf("0x%08" PRIx32, asl_dump_dworddata(&dp)); - break; - case 0x0d: /* StringPrefix */ - putchar('"'); - while (*dp) { - switch (*dp) { - case '\\': - fputs("\\\\", stdout); - break; - case 'A'...'Z': - case 'a'...'z': - case '0'...'9': - case '.': - case '^': - case ',': - case ';': - putchar(*dp); - break; - default: - printf("\\x%02x", (int)(unsigned char)*dp); - break; - } - ++dp; - } - putchar('"'); - dp++; /* NUL terminate */ - break; - case 0x0e: /* QWordPrefix */ - printf("0x%016" PRIx64, asl_dump_qworddata(&dp)); - break; - case 0x00: /* ZeroOp */ - printf("Zero"); - break; - case 0x01: /* OneOp */ - printf("One"); - break; - case 0xff: /* OnesOp */ - printf("Ones"); - break; - case 0x06: /* AliasOp */ - printf("Alias("); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x08: /* NameOp */ - printf("Name("); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x10: /* ScopeOp */ - asl_dump_defscope(&dp, indent); - break; - case 0x11: /* BufferOp */ - asl_dump_defbuffer(&dp, indent); - break; - case 0x12: /* PackageOp */ - asl_dump_defpackage(&dp, indent, false); - break; - case 0x13: /* VarPackageOp */ - asl_dump_defpackage(&dp, indent, true); - break; - case 0x14: /* MethodOp */ - asl_dump_defmethod(&dp, indent); - break; - case 0x5b: /* ExtOpPrefix */ - opcode = *dp++; - switch (opcode) { - case 0x01: /* MutexOp */ - printf("Mutex("); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(", %d)", *dp++); - break; - case 0x02: /* EventOp */ - printf("Event("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x12: /* CondRefOfOp */ - printf("CondRefOf("); - print_namestring(asl_dump_namestring(&dp)); - //asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x13: /* CreateFieldOp */ - printf("CreateField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x20: /* LoadOp */ - printf("Load("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x21: /* StallOp */ - printf("Stall("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x22: /* SleepOp */ - printf("Sleep("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x23: /* AcquireOp */ - printf("Acquire("); - asl_dump_termobj(&dp, indent); - printf(", 0x%x)", asl_dump_worddata(&dp)); - break; - case 0x24: /* SignalOp */ - printf("Signal("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x25: /* WaitOp */ - printf("Wait("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x26: /* ResetOp */ - printf("Reset("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x27: /* ReleaseOp */ - printf("Release("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x28: /* FromBCDOp */ - printf("FromBCD("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x29: /* ToBCDOp */ - printf("ToBCD("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x2a: /* UnloadOp */ - printf("Unload("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x30: - printf("Revision"); - break; - case 0x31: - printf("Debug"); - break; - case 0x32: /* FatalOp */ - printf("Fatal("); - printf("0x%x, ", asl_dump_bytedata(&dp)); - printf("0x%x, ", asl_dump_dworddata(&dp)); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x80: /* OpRegionOp */ - asl_dump_defopregion(&dp, indent); - break; - case 0x81: /* FieldOp */ - asl_dump_deffield(&dp, indent); - break; - case 0x82: /* DeviceOp */ - asl_dump_defdevice(&dp, indent); - break; - case 0x83: /* ProcessorOp */ - asl_dump_defprocessor(&dp, indent); - break; - case 0x84: /* PowerResOp */ - asl_dump_defpowerres(&dp, indent); - break; - case 0x85: /* ThermalZoneOp */ - asl_dump_defthermalzone(&dp, indent); - break; - case 0x86: /* IndexFieldOp */ - asl_dump_defindexfield(&dp, indent); - break; - case 0x87: /* BankFieldOp */ - asl_dump_defbankfield(&dp, indent); - break; - default: - errx(1, "strange opcode 0x5b, 0x%x\n", opcode); - } - break; - case 0x68 ... 0x6e: /* ArgN */ - printf("Arg%d", opcode - 0x68); - break; - case 0x60 ... 0x67: - printf("Local%d", opcode - 0x60); - break; - case 0x70: /* StoreOp */ - printf("Store("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x71: /* RefOfOp */ - printf("RefOf("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x72: /* AddOp */ - printf("Add("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x73: /* ConcatenateOp */ - printf("Concatenate("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x74: /* SubtractOp */ - printf("Subtract("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x75: /* IncrementOp */ - printf("Increment("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x76: /* DecrementOp */ - printf("Decrement("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x77: /* MultiplyOp */ - printf("Multiply("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x78: /* DivideOp */ - printf("Divide("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - OPTARG(); - printf(")"); - break; - case 0x79: /* ShiftLeftOp */ - printf("ShiftLeft("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7a: /* ShiftRightOp */ - printf("ShiftRight("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7b: /* AndOp */ - printf("And("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7c: /* NAndOp */ - printf("NAnd("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7d: /* OrOp */ - printf("Or("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7e: /* NOrOp */ - printf("NOr("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x7f: /* XOrOp */ - printf("XOr("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x80: /* NotOp */ - printf("Not("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x81: /* FindSetLeftBitOp */ - printf("FindSetLeftBit("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x82: /* FindSetRightBitOp */ - printf("FindSetRightBit("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x83: /* DerefOp */ - printf("DerefOf("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x84: /* ConcatenateResOp */ - printf("ConcatenateRes("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x85: /* ModOp */ - printf("Mod("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x86: /* NotifyOp */ - printf("Notify("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x87: /* SizeOfOp */ - printf("SizeOf("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x88: /* IndexOp */ - printf("Index("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x89: /* MatchOp */ - printf("Match("); - asl_dump_termobj(&dp, indent); - printf(", %s, ", matchstr[*dp++]); - asl_dump_termobj(&dp, indent); - printf(", %s, ", matchstr[*dp++]); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8a: /* CreateDWordFieldOp */ - printf("CreateDWordField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8b: /* CreateWordFieldOp */ - printf("CreateWordField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8c: /* CreateByteFieldOp */ - printf("CreateByteField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8d: /* CreateBitFieldOp */ - printf("CreateBitField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8e: /* ObjectTypeOp */ - printf("ObjectType("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x8f: /* CreateQWordFieldOp */ - printf("CreateQWordField("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(", "); - ASL_CREATE_LOCALNAMEOBJ(dp); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x90: - printf("LAnd("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x91: - printf("LOr("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x92: - printf("LNot("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x93: - printf("LEqual("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x94: - printf("LGreater("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x95: - printf("LLess("); - asl_dump_termobj(&dp, indent); - printf(", "); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x96: /* ToBufferOp */ - printf("ToBuffer("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x97: /* ToDecimalStringOp */ - printf("ToDecimalString("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x98: /* ToHexStringOp */ - printf("ToHexString("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x99: /* ToIntegerOp */ - printf("ToInteger("); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x9c: /* ToStringOp */ - printf("ToString("); - asl_dump_termobj(&dp, indent); - printf(","); - asl_dump_termobj(&dp, indent); - OPTARG(); - printf(")"); - break; - case 0x9d: /* CopyObjectOp */ - printf("CopyObject"); - /* asl_dump_termobj(&dp, indent); */ - errx(1, "cannot decode opcode 0x9d"); - break; - case 0x9e: /* MidOp */ - printf("Mid("); - asl_dump_termobj(&dp, indent); - printf(","); - asl_dump_termobj(&dp, indent); - printf(","); - asl_dump_termobj(&dp, indent); - printf(","); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0x9f: /* ContinueOp */ - printf("Continue"); - break; - case 0xa0: /* IfOp */ - asl_dump_defif(&dp, indent); - break; - case 0xa1: /* ElseOp */ - asl_dump_defelse(&dp, indent); - break; - case 0xa2: /* WhileOp */ - asl_dump_defwhile(&dp, indent); - break; - case 0xa3: /* NoopOp */ - printf("Noop"); - break; - case 0xa5: /* BreakOp */ - printf("Break"); - break; - case 0xa4: /* ReturnOp */ - printf("Return("); - asl_dump_termobj(&dp, indent); - printf(")"); - break; - case 0xcc: /* BreakPointOp */ - printf("BreakPoint"); - break; - default: - errx(1, "strange opcode 0x%x\n", opcode); - } - - *dpp = dp; -} - -void -asl_dump_objectlist(u_int8_t **dpp, u_int8_t *end, int indent) -{ - u_int8_t *dp; - - dp = *dpp; - while (dp < end) { - print_indent(indent); - asl_dump_termobj(&dp, indent); - printf("\n"); - } - - *dpp = dp; -}