diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index c273e26..0e80a0a 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -70,6 +70,7 @@ 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_print_sdt(ACPI_TABLE_HEADER *sdp); +static void acpi_print_sdt_raw(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); @@ -228,6 +229,35 @@ acpi_handle_fadt(ACPI_TABLE_HEADER *sdp) } static void +acpi_handle_fadt_raw(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_HEADER *dsdp; + ACPI_TABLE_FACS *facs; + ACPI_TABLE_FADT *fadt; + int fadt_revision; + + fadt = (ACPI_TABLE_FADT *)sdp; + acpi_print_sdt_raw(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) + warnx("FACS is corrupt"); + acpi_print_sdt_raw((ACPI_TABLE_HEADER*)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)) + warnx("DSDT is corrupt"); + acpi_print_sdt_raw((ACPI_TABLE_HEADER*)dsdp); +} + +static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, void (*action)(ACPI_SUBTABLE_HEADER *)) { @@ -439,6 +469,8 @@ acpi_handle_madt(ACPI_TABLE_HEADER *sdp) { ACPI_TABLE_MADT *madt; + if (rflag) { + } printf(BEGIN_COMMENT); acpi_print_sdt(sdp); madt = (ACPI_TABLE_MADT *)sdp; @@ -773,6 +805,58 @@ acpi_print_sdt(ACPI_TABLE_HEADER *sdp) printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision); } +static int +print_buf(char *buf, size_t *pos, size_t max, const char *fmt, ...) +{ + va_list ap; + int ret; + + if (*pos >= max) + return 0; + + va_start(ap, fmt); + ret = vsnprintf(&buf[*pos], max - *pos, fmt, ap); + va_end(ap); + + if (ret > 0) + *pos += ret; + return ret; +} + +static void +acpi_dump_table(const uint8_t *data, size_t size) +{ + static const size_t BYTES_PER_LINE = 16; + + char buf[256]; + size_t off; + size_t i; + size_t j; + + for (i = 0; i < size; i += BYTES_PER_LINE, data += BYTES_PER_LINE) { + off = 0; + print_buf(buf, &off, sizeof(buf), " %04x:", i); + for (j = 0; j < BYTES_PER_LINE && j < (size - i); j++) + print_buf(buf, &off, sizeof(buf), " %02x", data[j]); + for (; j < BYTES_PER_LINE; j++) + print_buf(buf, &off, sizeof(buf), " "); + print_buf(buf, &off, sizeof(buf), " "); + for (j = 0; j < BYTES_PER_LINE && j < (size -i); j++) + print_buf(buf, &off, sizeof(buf), "%c", + isprint(data[j]) ? data[j] : '.'); + printf("%s\n", buf); + } +} + +static void +acpi_print_sdt_raw(ACPI_TABLE_HEADER *sdp) +{ + acpi_print_string(sdp->Signature, ACPI_NAME_SIZE); + printf(" @ %p\n", sdp); + acpi_dump_table((uint8_t *)sdp, sdp->Length); + printf("\n"); +} + static void acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) { @@ -781,6 +865,10 @@ acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) int i, entries; u_long addr; + if (rflag) { + acpi_print_sdt_raw(rsdp); + return; + } rsdt = (ACPI_TABLE_RSDT *)rsdp; xsdt = (ACPI_TABLE_XSDT *)rsdp; printf(BEGIN_COMMENT); @@ -1027,6 +1115,12 @@ acpi_map_sdt(vm_offset_t pa) static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) { + if (rflag) { + printf("RSD PTR @ %p\n", rp); /*XXX*/ + acpi_dump_table((uint8_t*)rp, sizeof(ACPI_TABLE_RSDP)); + printf("\n"); + return; + } printf(BEGIN_COMMENT); printf(" RSD PTR: OEM="); acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE); @@ -1091,11 +1185,49 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) else { printf(BEGIN_COMMENT); acpi_print_sdt(sdp); + acpi_dump_table((uint8_t*)sdp + sizeof(ACPI_TABLE_HEADER), sdp->Length - sizeof(ACPI_TABLE_HEADER)); printf(END_COMMENT); } } } +static void +acpi_handle_rsdt_raw(ACPI_TABLE_HEADER *rsdp) +{ + ACPI_TABLE_HEADER *sdp; + ACPI_TABLE_RSDT *rsdt; + ACPI_TABLE_XSDT *xsdt; + vm_offset_t addr; + int entries, i; + + acpi_print_sdt_raw(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++) { + 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); + } + if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4)) + acpi_handle_fadt_raw(sdp); + else + acpi_print_sdt_raw(sdp); + } +} + ACPI_TABLE_HEADER * sdt_load_devmem(void) { @@ -1106,7 +1238,7 @@ sdt_load_devmem(void) if (!rp) errx(1, "Can't find ACPI information"); - if (tflag) + if (tflag || rflag) acpi_print_rsd_ptr(rp); if (rp->Revision < 2) { rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress); @@ -1244,6 +1376,13 @@ sdt_print_all(ACPI_TABLE_HEADER *rsdp) acpi_handle_rsdt(rsdp); } +void +sdt_print_all_raw(ACPI_TABLE_HEADER *rsdp) +{ + acpi_handle_rsdt_raw(rsdp); + //acpi_handle_rsdt(rsdp); +} + /* 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) diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c index 38844b6..6501e11 100644 --- a/usr.sbin/acpi/acpidump/acpidump.c +++ b/usr.sbin/acpi/acpidump/acpidump.c @@ -37,6 +37,7 @@ #include "acpidump.h" int dflag; /* Disassemble AML using iasl(8) */ +int rflag; /* Dump raw contents of SDT tables */ int tflag; /* Dump contents of SDT tables */ int vflag; /* Use verbose messages */ @@ -64,11 +65,14 @@ main(int argc, char *argv[]) if (argc < 2) usage(progname); - while ((c = getopt(argc, argv, "dhtvf:o:")) != -1) { + while ((c = getopt(argc, argv, "dhrtvf:o:")) != -1) { switch (c) { case 'd': dflag = 1; break; + case 'r': + rflag = 1; + break; case 't': tflag = 1; break; @@ -92,11 +96,11 @@ main(int argc, char *argv[]) /* 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"); + if (dflag == 0) { + warnx("Need to specify -d with DSDT input file"); usage(progname); - } else if (tflag != 0) { - warnx("Can't use -t with DSDT input file"); + } else if (rflag != 0 || tflag != 0) { + warnx("Can't use -r or -t with DSDT input file"); usage(progname); } if (vflag) @@ -108,6 +112,17 @@ main(int argc, char *argv[]) rsdt = sdt_load_devmem(); } + /* + * Display all SDT tables in raw format + * (only available when using /dev/mem) + */ + if (rflag) { + if (vflag) + warnx("printing various SDT tables"); + sdt_print_all_raw(rsdt); + exit(0); + } + /* Display misc. SDT tables (only available when using /dev/mem) */ if (tflag) { if (vflag) diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 3421519..e7c3f04 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -138,6 +138,7 @@ void dsdt_save_file(char *, ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *); /* Print out as many fixed tables as possible, given the RSD PTR */ void sdt_print_all(ACPI_TABLE_HEADER *); +void sdt_print_all_raw(ACPI_TABLE_HEADER *); /* Disassemble the AML in the DSDT */ void aml_disassemble(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *); @@ -152,6 +153,7 @@ int acpi_checksum(void *, size_t); /* Command line flags */ extern int dflag; +extern int rflag; extern int tflag; extern int vflag;