summaryrefslogtreecommitdiffstats
path: root/usr.sbin/acpi/acpidump
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2002-01-02 07:01:34 +0000
committermsmith <msmith@FreeBSD.org>2002-01-02 07:01:34 +0000
commit78b1a73890307166147096c327641fdcc31b348a (patch)
tree019d53943934a302f4c574f86097568184a52567 /usr.sbin/acpi/acpidump
parentf22e9b26c0321c0ace5feb66e3e20053193a3e27 (diff)
downloadFreeBSD-src-78b1a73890307166147096c327641fdcc31b348a.zip
FreeBSD-src-78b1a73890307166147096c327641fdcc31b348a.tar.gz
Add support for decoding Buffer objects that contain PnP/ACPI resource
streams. Since the output is bulky, it's controlled by the '-r' option. Document this in the manpage, and clean up some awkward English a little.
Diffstat (limited to 'usr.sbin/acpi/acpidump')
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.862
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.c9
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.h1
-rw-r--r--usr.sbin/acpi/acpidump/asl_dump.c362
4 files changed, 406 insertions, 28 deletions
diff --git a/usr.sbin/acpi/acpidump/acpidump.8 b/usr.sbin/acpi/acpidump/acpidump.8
index f37ae54..2081f1d 100644
--- a/usr.sbin/acpi/acpidump/acpidump.8
+++ b/usr.sbin/acpi/acpidump/acpidump.8
@@ -37,9 +37,12 @@
.Nd dump ACPI tables
.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
.Sh DESCRIPTION
The
@@ -47,65 +50,68 @@ The
command analyzes ACPI tables in physical memory and dumps them to standard output.
In addition,
.Nm
-can disassemble some contents of the tables in AML
+can disassemble AML
(ACPI Machine Language)
-and dump them in ASL
+found in these tables and dump them as ASL
(ACPI Source Language).
.Pp
-ACPI tables have an notably essential data block called DSDT
-(Differentiated System Description Table),
+ACPI tables have an essential data block (the DSDT,
+Differentiated System Description Table),
that includes information used on the kernel side such as
-detail information about PnP hardware, procedures for controlling
-a power management support and so on.
+detailed information about PnP hardware, procedures for controlling
+power management support and so on.
.Nm
-can extract a DSDT data block from physical memory and store it into
+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.
.Pp
When
.Nm
-is invoked with no option, it will search ACPI tables from physical
+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. First, it searches Root System Description Pointer,
-that has a signature
+and dump them. First it searches for the RSDP
+(Root System Description Pointer),
+which has the signature
.Qq RSD PTR\ \& ,
-and then gets RSDT
+and then gets the RSDT
(Root System Description Table),
which includes a list of pointers to physical memory addresses
for other tables.
-RSDT itself and all other tables linked from RSDT are generically
-called SDT
-(System Description Table)
-and their header has the common format which consists of items
+The RSDT itself and all other tables linked from RSDT are generically
+called SDTs
+(System Description Tables)
+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.
.Nm
dumps contents of these SDTs.
For further information about formats of each table,
-see chapter 5: ACPI Software Programming Model,
-.Dq Advanced Configuration and Power Interface Specification Revision 1.0b
-from Intel/Microsoft/Toshiba.
+see chapter 5:
+.Dq ACPI Software Programming Model
+from the ACPI specifications referenced below.
.Pp
There is always a pointer to a physical memory address in RSDT for FACP
(Fixed ACPI Description Table).
-FACP defines static system information about power management support
+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.
-FACP also has a pointer to a physical memory address for DSDT,
+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,
-DSDT consists of AML data which compiled from sources
-written in free formated ASL, description language for ACPI.
+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
-translates them into ASL.
+formats it as ASL.
.Sh OPTIONS
The following options are supported by
.Nm :
@@ -118,6 +124,11 @@ in addition to behavior with no option.
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 r
+Additionally outputs commented ResourceTemplate() macros for Buffer
+objects that contain valid resource streams.
+These macros are defined in the ACPI 2.0 specification section
+16.2.4.
.It Fl h
Displays usage and exit.
.El
@@ -148,7 +159,7 @@ specified by a pointer in FACP.
Intel
Microsoft
Toshiba
-Revision 1.0b
+Revision 1.0b, 2.0
.Ed
<URL:http://www.teleport.com/~acpi/>
.Sh AUTHORS
@@ -161,8 +172,9 @@ Some contributions made by
.An Takayasu IWANASHI Aq takayasu@wendy.a.perfect-liberty.or.jp ,
.An Yoshihiko SARUMARU Aq mistral@imasy.or.jp ,
.An Hiroki Sato Aq hrs@FreeBSD.org ,
+.An Michael Lucas Aq mwlucas@blackhelicopters.org
and
-.An Michael Lucas Aq mwlucas@blackhelicopters.org .
+.An Michael Smith Aq msmith@freebsd.org .
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c
index c7ca5d2..a687568 100644
--- a/usr.sbin/acpi/acpidump/acpidump.c
+++ b/usr.sbin/acpi/acpidump/acpidump.c
@@ -70,8 +70,8 @@ static void
usage(const char *progname)
{
- printf("usage:\t%s [-o dsdt_file_for_output]\n", progname);
- printf("\t%s [-f dsdt_file_for_input]\n", 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);
}
@@ -82,7 +82,7 @@ main(int argc, char *argv[])
char c, *progname;
progname = argv[0];
- while ((c = getopt(argc, argv, "f:o:h")) != -1) {
+ while ((c = getopt(argc, argv, "f:o:hr")) != -1) {
switch (c) {
case 'f':
asl_dump_from_file(optarg);
@@ -93,6 +93,9 @@ main(int argc, char *argv[])
case 'h':
usage(progname);
break;
+ case 'r':
+ rflag++;
+ break;
default:
argc -= optind;
argv += optind;
diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h
index 29905ed..dd27f89 100644
--- a/usr.sbin/acpi/acpidump/acpidump.h
+++ b/usr.sbin/acpi/acpidump/acpidump.h
@@ -176,5 +176,6 @@ 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;
#endif /* !_ACPIDUMP_H_ */
diff --git a/usr.sbin/acpi/acpidump/asl_dump.c b/usr.sbin/acpi/acpidump/asl_dump.c
index 25f6777..123fd5d3 100644
--- a/usr.sbin/acpi/acpidump/asl_dump.c
+++ b/usr.sbin/acpi/acpidump/asl_dump.c
@@ -39,6 +39,7 @@
#include "aml/aml_env.h"
struct aml_environ asl_env;
+int rflag;
static u_int32_t
asl_dump_pkglength(u_int8_t **dpp)
@@ -229,6 +230,364 @@ asl_dump_defscope(u_int8_t **dpp, int indent)
}
static void
+asl_dump_resourcebuffer(u_int8_t *dp, u_int8_t *end, int indent)
+{
+ u_int8_t *p;
+ int print, len, name, indep, i, 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%-04.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%016llx)\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, minimum, maximum, translation, length;
+ char *size, *source;
+ int index, slen;
+
+ 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 = 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 = 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 = p + 44;
+ slen = len - 44;
+ break;
+ }
+ switch(*p) {
+ case 0:
+ printf("%sWordMemory("
+ "Resource%s, "
+ "%sDecode, "
+ "Min%sFixed, "
+ "Max%sFixed, "
+ "%s, "
+ "Read%s, "
+ "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
+ "%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%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
+ "%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%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
+ "%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 = 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;
@@ -242,12 +601,15 @@ asl_dump_defbuffer(u_int8_t **dpp, int indent)
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;
OpenPOWER on IntegriCloud