summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2006-03-21 21:11:11 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2006-03-21 21:11:11 +0000
commit90c0d62bbb4eb2188b20de1ffb3916a645d5b018 (patch)
tree02955b613c3bd24342cabb5fe0fc6d7efb02a4f2 /sys/dev/acpi
parent602da2fa5b1519e33942feea1be9e3fa72c06a39 (diff)
Disassembler now pretty prints AML code (like acpidump)
ok marco@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpidebug.c247
-rw-r--r--sys/dev/acpi/dsdt.c14
2 files changed, 160 insertions, 101 deletions
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c
index adba63f59d6..60c5717425b 100644
--- a/sys/dev/acpi/acpidebug.c
+++ b/sys/dev/acpi/acpidebug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.7 2006/03/09 05:38:12 jordan Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.8 2006/03/21 21:11:10 jordan Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -34,13 +34,18 @@ const char *db_opregion(int);
int db_aml_nodetype(struct aml_node *);
int db_parse_name(void);
void db_aml_disasm(struct acpi_context *, int);
-void db_aml_disint(struct acpi_context *, int, int);
-void db_aml_disline(uint8_t *, int, const char *, ...);
+void db_aml_disint(struct acpi_context *, int);
+void db_aml_disline(int, const char *, ...);
void db_aml_dump(int, u_int8_t *);
void db_aml_shownode(struct aml_node *);
void db_aml_showvalue(struct aml_value *);
void db_aml_walktree(struct aml_node *);
void db_spaceit(int);
+int db_aml_issimplearg(char);
+
+const char *db_aml_fieldacc(int);
+const char *db_aml_fieldlock(int);
+const char *db_aml_fieldupdate(int);
extern struct aml_node aml_root;
@@ -51,6 +56,37 @@ char buf[128];
char scope[80];
const char *
+db_aml_fieldacc(int key)
+{
+ switch (key) {
+ case AML_FIELD_ANYACC: return "any";
+ case AML_FIELD_BYTEACC: return "byte";
+ case AML_FIELD_WORDACC: return "word";
+ case AML_FIELD_DWORDACC: return "dword";
+ case AML_FIELD_QWORDACC: return "qword";
+ case AML_FIELD_BUFFERACC: return "buffer";
+ }
+ return "";
+}
+
+const char *
+db_aml_fieldlock(int key)
+{
+ return (key ? "lock" : "nolock");
+}
+
+const char *
+db_aml_fieldupdate(int key)
+{
+ switch (key) {
+ case AML_FIELD_PRESERVE: return "preserve";
+ case AML_FIELD_WRITEASONES: return "writeasones";
+ case AML_FIELD_WRITEASZEROES: return "writeaszeroes";
+ }
+ return "";
+}
+
+const char *
db_opregion(int id)
{
switch(id) {
@@ -250,31 +286,41 @@ db_aml_objtype(struct aml_value *val)
}
void
-db_aml_disline(uint8_t *pos, int level, const char *fmt, ...)
+db_aml_disline(int level, const char *fmt, ...)
{
va_list ap;
- db_printf("%.4x %.2x ", pos - aml_root.start, level);
db_spaceit(level);
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
db_printf(buf);
va_end(ap);
-
- db_printf("\n");
}
/* Output disassembled integer */
void
-db_aml_disint(struct acpi_context *ctx, int level, int type)
+db_aml_disint(struct acpi_context *ctx, int type)
{
- u_int8_t *pos;
int64_t i1;
- pos = ctx->pos;
i1 = aml_eparseint(ctx, type);
- db_aml_disline(pos, level, "%c:0x%.8llx (%lld)", type, i1, i1);
+ db_aml_disline(0, "0x%.8llx", i1);
+}
+
+int
+db_aml_issimplearg(char arg)
+{
+ switch (arg) {
+ case AML_ARG_DATAOBJLIST:
+ case AML_ARG_TERMOBJLIST:
+ case AML_ARG_METHOD:
+ case AML_ARG_BYTELIST:
+ case AML_ARG_FIELDLIST:
+ case '\0': // end of list
+ return (0);
+ }
+ return (1);
}
/* Disassemble AML Opcode */
@@ -282,45 +328,58 @@ void
db_aml_disasm(struct acpi_context *ctx, int level)
{
struct aml_opcode *opc;
- uint8_t *end, *np;
- const char *arg, *fname;
+ uint8_t *end;
+ const char *arg, *fname, *pfx;
struct aml_node *node;
- int idx, len;
-
-#if 0
- /* if we want separators */
- if (level == 0)
- db_printf("<<<<<<<<<<<<<<\n");
-#endif
- np = ctx->pos;
+ int idx, len, narg;
+
+ narg = 0;
opc = aml_getopcode(ctx);
- db_aml_disline(np, level, opc->mnem);
- for (arg = opc->args; *arg; arg++) {
- np = ctx->pos;
+ arg = opc->args;
+ pfx = "";
+ if (opc->mnem[0] != '.') {
+ /* Don't display implied opcodes */
+ db_aml_disline(0, opc->mnem);
+ pfx = "(";
+ narg++;
+ }
+ if (*arg == AML_ARG_OBJLEN) {
+ ++arg;
+ end = aml_eparselen(ctx);
+ }
+ if (*arg == AML_ARG_IMPBYTE)
+ ++arg;
+ while (db_aml_issimplearg(*arg)) {
+ narg++;
+ db_aml_disline(0, pfx);
switch (*arg) {
case AML_ARG_BYTE:
case AML_ARG_WORD:
case AML_ARG_DWORD:
case AML_ARG_QWORD:
- db_aml_disint(ctx, level + 1, *arg);
+ db_aml_disint(ctx, *arg);
break;
case AML_ARG_STRING:
- db_aml_disline(np, level + 1, ctx->pos);
+ db_aml_disline(0, ctx->pos);
ctx->pos += strlen(ctx->pos) + 1;
break;
case AML_ARG_NAMESTRING:
fname = aml_parse_name(ctx);
- db_aml_disline(np, level + 1, fname);
+ db_aml_disline(0, fname);
break;
case AML_ARG_NAMEREF:
fname = aml_parse_name(ctx);
node = aml_searchname(ctx->scope, fname);
- db_aml_disline(np, level + 1, "%s:%s", fname,
- node ? db_aml_objtype(node->value) : "none");
- if (db_aml_nodetype(node) == AML_OBJTYPE_METHOD)
+ db_aml_disline(0, fname);
+ if (db_aml_nodetype(node) == AML_OBJTYPE_METHOD) {
/* Parse method arguments */
- for (idx = 0; idx < AML_METHOD_ARGCOUNT(node->value->v_method.flags); idx++)
+ db_aml_disline(0, "(");
+ for (idx = 0; idx < AML_METHOD_ARGCOUNT(node->value->v_method.flags); idx++) {
+ db_aml_disline(0, idx ? ", " : "");
db_aml_disasm(ctx, level + 1);
+ }
+ db_aml_disline(0, ")");
+ }
break;
case AML_ARG_INTEGER:
case AML_ARG_TERMOBJ:
@@ -329,75 +388,75 @@ db_aml_disasm(struct acpi_context *ctx, int level)
case AML_ARG_SUPERNAME:
db_aml_disasm(ctx, level + 1);
break;
- case AML_ARG_DATAOBJLIST:
- case AML_ARG_TERMOBJLIST:
- case AML_ARG_METHOD:
- while (ctx->pos < end)
- db_aml_disasm(ctx, level + 1);
- break;
- case AML_ARG_BYTELIST:
- for (idx = 0; idx < end - ctx->pos - 7; idx += 8)
- db_aml_disline(np, level + 1, "buf %.4x: %.2x "
- "%.2x %.2x %.2x %.2x %.2x %.2x %.2x",
- idx, ctx->pos[idx],
- ctx->pos[idx + 1],
- ctx->pos[idx + 2], ctx->pos[idx + 3],
- ctx->pos[idx + 4], ctx->pos[idx + 5],
- ctx->pos[idx + 6], ctx->pos[idx + 7]);
-
- ctx->pos = end;
- break;
case AML_ARG_FLAG:
/* Flags */
- idx = aml_eparseint(ctx, AML_ARG_BYTE);
- if (opc->opcode == AMLOP_METHOD)
- db_aml_disline(np, level + 1,
- "args:%d serialized:%d synclevel:%d",
- AML_METHOD_ARGCOUNT(idx),
- AML_METHOD_SERIALIZED(idx),
- AML_METHOD_SYNCLEVEL(idx));
- else
- db_aml_disline(np, level + 1,
- "acc:%d lock:%d update:%d",
- AML_FIELD_ACCESS(idx),
- AML_FIELD_LOCK(idx),
- AML_FIELD_UPDATE(idx));
- break;
- case AML_ARG_FIELDLIST:
- for (idx = 0; ctx->pos < end; idx += len) {
- np = ctx->pos;
- switch (*ctx->pos) {
- case AML_FIELD_RESERVED:
- ctx->pos++;
- len = aml_parse_length(ctx);
- break;
- case AML_FIELD_ATTR__:
- db_aml_disline(np, level + 1,
- "-- attr %.2x %.2x",
- ctx->pos[1], ctx->pos[2]);
- ctx->pos += 3;
- len = 0;
- break;
- default:
- fname = aml_parse_name(ctx);
- len = aml_parse_length(ctx);
- db_aml_disline(np, level + 1,
- "pos:%.4x len:%.4x name:%s",
- idx, len, fname);
- break;
- }
+ if (opc->opcode == AMLOP_METHOD)
+ db_aml_disint(ctx, AML_ARG_BYTE);
+ else {
+ idx = aml_eparseint(ctx, AML_ARG_BYTE);
+ db_aml_disline(0,
+ "%s, %s, %s",
+ db_aml_fieldacc(AML_FIELD_ACCESS(idx)),
+ db_aml_fieldlock(AML_FIELD_LOCK(idx)),
+ db_aml_fieldupdate(AML_FIELD_UPDATE(idx)));
}
break;
- case AML_ARG_OBJLEN:
- end = aml_eparselen(ctx);
- break;
}
+ pfx = ", ";
+ arg++;
+ }
+ if (narg > 1)
+ db_aml_disline(0, ")");
+
+ /* Parse remaining argument */
+ switch (*arg) {
+ case AML_ARG_DATAOBJLIST:
+ case AML_ARG_TERMOBJLIST:
+ case AML_ARG_METHOD:
+ db_aml_disline(0, " {\n");
+ while (ctx->pos < end) {
+ db_aml_disline(level + 1, "");
+ db_aml_disasm(ctx, level + 1);
+ db_aml_disline(0, "\n");
+ }
+ db_aml_disline(level, "}");
+ break;
+ case AML_ARG_BYTELIST:
+ db_aml_disline(0, " { ");
+ for (idx = 0; idx < end - ctx->pos; idx++)
+ db_aml_disline(0, "%s0x%.2x", (idx ? ", " : ""),
+ ctx->pos[idx]);
+ db_aml_disline(0, " }");
+ ctx->pos = end;
+ break;
+ case AML_ARG_FIELDLIST:
+ db_aml_disline(0, " {\n");
+ for (idx = 0; ctx->pos < end; idx += len) {
+ switch (*ctx->pos) {
+ case AML_FIELD_RESERVED:
+ ctx->pos++;
+ len = aml_parse_length(ctx);
+ db_aml_disline(level + 1, "Offset(%x),\n", (idx+len)>>3);
+ break;
+ case AML_FIELD_ATTR__:
+ db_aml_disline(level + 1,
+ "-- attr %.2x %.2x",
+ ctx->pos[1], ctx->pos[2]);
+ ctx->pos += 3;
+ len = 0;
+ break;
+ default:
+ fname = aml_parse_name(ctx);
+ len = aml_parse_length(ctx);
+ db_aml_disline(level + 1, "%s, %d,\n", fname, len);
+ break;
+ }
+ }
+ db_aml_disline(level, "}");
+ break;
}
-#if 0
- /* if we want separators */
- if (level == 0)
- db_printf(">>>>>>>>>>>>>>\n");
-#endif
+ if (level == 0)
+ db_aml_disline(0, "\n");
}
void
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 5f845084be1..9a6b3d58f89 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.38 2006/03/09 05:38:12 jordan Exp $ */
+/* $OpenBSD: dsdt.c,v 1.39 2006/03/21 21:11:10 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -163,12 +163,12 @@ struct aml_opcode aml_table[] = {
{ AMLOP_ZERO, "Zero", "!" },
{ AMLOP_ONE, "One", "!" },
{ AMLOP_ONES, "Ones", "!" },
- { AMLOP_BYTEPREFIX, "Byte", "b" },
- { AMLOP_WORDPREFIX, "Word", "w" },
- { AMLOP_DWORDPREFIX, "DWord", "d" },
- { AMLOP_QWORDPREFIX, "QWord", "q" },
+ { AMLOP_BYTEPREFIX, ".Byte", "b" },
+ { AMLOP_WORDPREFIX, ".Word", "w" },
+ { AMLOP_DWORDPREFIX, ".DWord", "d" },
+ { AMLOP_QWORDPREFIX, ".QWord", "q" },
{ AMLOP_REVISION, "Revision", "" },
- { AMLOP_STRINGPREFIX, "String", "a" },
+ { AMLOP_STRINGPREFIX, ".String", "a" },
{ AMLOP_DEBUG, "DebugOp", "", },
{ AMLOP_BUFFER, "Buffer", "piB" },
{ AMLOP_PACKAGE, "Package", "pbT" },
@@ -233,7 +233,7 @@ struct aml_opcode aml_table[] = {
{ AMLOP_LLESS, "LLess", "tt", },
/* Named objects */
- { AMLOP_NAMECHAR, "NameRef", "n" },
+ { AMLOP_NAMECHAR, ".NameRef", "n" },
{ AMLOP_ALIAS, "Alias", "nN", },
{ AMLOP_NAME, "Name", "Nt", },
{ AMLOP_EVENT, "Event", "N", },