summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpi/acpidebug.c
diff options
context:
space:
mode:
authorjordan <jordan@openbsd.org>2006-10-19 07:02:20 +0000
committerjordan <jordan@openbsd.org>2006-10-19 07:02:20 +0000
commit30a01ff4443eeb77ef02ede8c4aa37c4cceea250 (patch)
tree9661dfae72cfe74c18179d7c7186e7a0be3e6dbe /sys/dev/acpi/acpidebug.c
parentFix capacity calculations. Tested on Dell C610, D810, Lenovo X60s. (diff)
downloadwireguard-openbsd-30a01ff4443eeb77ef02ede8c4aa37c4cceea250.tar.xz
wireguard-openbsd-30a01ff4443eeb77ef02ede8c4aa37c4cceea250.zip
Fixed AML debugger code to use new interface
ok marco@
Diffstat (limited to 'sys/dev/acpi/acpidebug.c')
-rw-r--r--sys/dev/acpi/acpidebug.c504
1 files changed, 218 insertions, 286 deletions
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c
index 63e123b32ed..7dc1b51314f 100644
--- a/sys/dev/acpi/acpidebug.c
+++ b/sys/dev/acpi/acpidebug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.9 2006/10/12 16:38:21 jordan Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.10 2006/10/19 07:02:20 jordan Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -22,6 +22,7 @@
#include <ddb/db_lex.h>
#include <machine/bus.h>
+#include <sys/malloc.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
@@ -29,19 +30,29 @@
#include <dev/acpi/acpidebug.h>
#include <dev/acpi/dsdt.h>
+void db_aml_disline(uint8_t *, int, const char *, ...);
+void db_aml_disint(struct aml_scope *, int, int);
+uint8_t *db_aml_disasm(struct aml_node *, uint8_t *, uint8_t *, int, int);
+
+extern int aml_pc(uint8_t *);
+extern struct aml_scope *aml_pushscope(struct aml_scope *, uint8_t *, uint8_t *, struct aml_node *);
+extern struct aml_scope *aml_popscope(struct aml_scope *);
+extern uint8_t *aml_parsename(struct aml_scope *);
+extern uint8_t *aml_parseend(struct aml_scope *);
+extern int aml_parselength(struct aml_scope *);
+extern int aml_parseopcode(struct aml_scope *);
+
+extern const char *aml_mnem(int opcode);
+extern const char *aml_args(int opcode);
+extern const char *aml_getname(uint8_t *);
+extern const char *aml_nodename(struct aml_node *);
+
const char *db_aml_objtype(struct aml_value *);
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);
-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);
@@ -56,37 +67,6 @@ 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) {
@@ -128,9 +108,9 @@ db_aml_showvalue(struct aml_value *value)
return;
if (value->node)
- db_printf("node:%.8x name:%s ", value->node, value->node->name);
+ db_printf("[%s] ", aml_nodename(value->node));
- switch (value->type) {
+ switch (value->type & ~AML_STATIC) {
case AML_OBJTYPE_OBJREF:
db_printf("refof: %x {\n", value->v_objref.index);
db_aml_showvalue(value->v_objref.ref);
@@ -139,7 +119,6 @@ db_aml_showvalue(struct aml_value *value)
case AML_OBJTYPE_NAMEREF:
db_printf("nameref: %s\n", value->v_nameref);
break;
- case AML_OBJTYPE_INTEGER+AML_STATIC:
case AML_OBJTYPE_INTEGER:
db_printf("integer: %llx %s\n", value->v_integer,
(value->type & AML_STATIC) ? "(static)" : "");
@@ -218,20 +197,6 @@ db_aml_showvalue(struct aml_value *value)
}
}
-/* Output disassembled line */
-void
-db_spaceit(int len)
-{
- while (len--)
- db_printf("..");
-}
-
-int
-db_aml_nodetype(struct aml_node *node)
-{
- return (node && node->value) ? node->value->type : -1;
-}
-
const char *
db_aml_objtype(struct aml_value *val)
{
@@ -282,226 +247,12 @@ db_aml_objtype(struct aml_value *val)
}
void
-db_aml_disline(int level, const char *fmt, ...)
-{
- va_list ap;
-
- db_spaceit(level);
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof buf, fmt, ap);
- db_printf(buf);
- va_end(ap);
-}
-
-/* Output disassembled integer */
-void
-db_aml_disint(struct acpi_context *ctx, int type)
-{
- int64_t i1;
-
- i1 = aml_eparseint(ctx, type);
- 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 */
-void
-db_aml_disasm(struct acpi_context *ctx, int level)
-{
- struct aml_opcode *opc;
- uint8_t *end;
- const char *arg, *fname, *pfx;
- struct aml_node *node;
- int idx, len, narg;
-
- narg = 0;
- opc = aml_getopcode(ctx);
- 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, *arg);
- break;
- case AML_ARG_STRING:
- 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(0, fname);
- break;
- case AML_ARG_NAMEREF:
- fname = aml_parse_name(ctx);
- node = aml_searchname(ctx->scope, fname);
- db_aml_disline(0, fname);
- if (db_aml_nodetype(node) == AML_OBJTYPE_METHOD) {
- /* Parse method arguments */
- 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:
- case AML_ARG_DATAOBJ:
- case AML_ARG_SIMPLENAME:
- case AML_ARG_SUPERNAME:
- db_aml_disasm(ctx, level + 1);
- break;
- case AML_ARG_FLAG:
- /* Flags */
- 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;
- }
- 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 (level == 0)
- db_aml_disline(0, "\n");
-}
-
-void
-db_aml_shownode(struct aml_node *node)
-{
- db_printf(" opcode:%.4x mnem:%s %s ",
- node->opcode, aml_mnem(node->opcode), node->name ? node->name : "");
-
- switch(node->opcode) {
- case AMLOP_METHOD:
- break;
-
- case AMLOP_NAMECHAR:
- db_printf("%s", node->name);
- break;
-
- case AMLOP_FIELD:
- case AMLOP_BANKFIELD:
- case AMLOP_INDEXFIELD:
- break;
-
- case AMLOP_BYTEPREFIX:
- db_printf("byte: %.2x", node->value->v_integer);
- break;
- case AMLOP_WORDPREFIX:
- db_printf("word: %.4x", node->value->v_integer);
- break;
- case AMLOP_DWORDPREFIX:
- db_printf("dword: %.8x", node->value->v_integer);
- break;
- case AMLOP_STRINGPREFIX:
- db_printf("string: %s", node->value->v_string);
- break;
- }
- db_printf("\n");
-}
-
-void
db_aml_walktree(struct aml_node *node)
{
- int i;
-
while(node) {
- db_printf(" %d ", node->depth);
- for(i = 0; i < node->depth; i++)
- db_printf("..");
-
- db_aml_shownode(node);
+ db_aml_showvalue(node->value);
db_aml_walktree(node->child);
+
node = node->sibling;
}
}
@@ -562,24 +313,16 @@ db_acpi_showval(db_expr_t addr, int haddr, db_expr_t count, char *modif)
void
db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
- extern struct acpi_softc *acpi_softc;
- struct acpi_softc *sc = acpi_softc;
- struct acpi_context *ctx;
struct aml_node *node;
if (db_parse_name())
return;
- ctx = acpi_alloccontext(sc, &aml_root, 0, NULL);
node = aml_searchname(&aml_root, scope);
if (node && node->value && node->value->type == AML_OBJTYPE_METHOD) {
- ctx->pos = node->value->v_method.start;
- while (ctx->pos < node->value->v_method.end)
- db_aml_disasm(ctx, 0);
+ db_aml_disasm(node, node->value->v_method.start, node->value->v_method.end, -1, 0);
} else
db_printf("Not a valid method\n");
-
- acpi_freecontext(ctx);
}
void
@@ -587,12 +330,201 @@ db_acpi_tree(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
db_aml_walktree(aml_root.child);
}
-u_int8_t *aml_eparselen(struct acpi_context *ctx)
+
+/* New Disasm Code */
+void
+db_aml_disline(uint8_t *pos, int depth, const char *fmt, ...)
{
- return 0;
+ va_list ap;
+ char line[128];
+
+ db_printf("%.6x: ", aml_pc(pos));
+ while (depth--)
+ db_printf(" ");
+
+ va_start(ap, fmt);
+ vsnprintf(line, sizeof(line), fmt, ap);
+ db_printf(line);
+ va_end(ap);
+}
+
+void
+db_aml_disint(struct aml_scope *scope, int opcode, int depth)
+{
+ switch(opcode) {
+ case AML_ANYINT:
+ db_aml_disasm(scope->node, scope->pos, scope->end, -1, depth);
+ break;
+ case AMLOP_BYTEPREFIX:
+ db_aml_disline(scope->pos, depth, "0x%.2x\n", *(uint8_t *)(scope->pos));
+ scope->pos += 1;
+ break;
+ case AMLOP_WORDPREFIX:
+ db_aml_disline(scope->pos, depth, "0x%.4x\n", *(uint16_t *)(scope->pos));
+ scope->pos += 2;
+ break;
+ case AMLOP_DWORDPREFIX:
+ db_aml_disline(scope->pos, depth, "0x%.8x\n", *(uint32_t *)(scope->pos));
+ scope->pos += 4;
+ break;
+ case AMLOP_QWORDPREFIX:
+ db_aml_disline(scope->pos, depth, "0x%.4llx\n", *(uint64_t *)(scope->pos));
+ scope->pos += 8;
+ break;
+ }
}
-struct acpi_context *acpi_alloccontext(struct acpi_softc *s,
- struct aml_node *n, int c, struct aml_value *v)
+
+uint8_t *
+db_aml_disasm(struct aml_node *root, uint8_t *start, uint8_t *end,
+ int count, int depth)
{
- return NULL;
+ int idx, opcode, len, off=0;
+ struct aml_scope *scope;
+ uint8_t *name, *pos;
+ const char *mnem, *args;
+ struct aml_node *node;
+ char *tmpstr;
+
+ if (start == end)
+ return end;
+
+ scope = aml_pushscope(NULL, start, end, root);
+ while (scope->pos < scope->end && count--) {
+ pos = scope->pos;
+ start = scope->pos;
+ opcode = aml_parseopcode(scope);
+
+ mnem = aml_mnem(opcode);
+ args = aml_args(opcode);
+
+ if (*args == 'p') {
+ end = aml_parseend(scope);
+ args++;
+ }
+ node = scope->node;
+ if (*args == 'N') {
+ name = aml_parsename(scope);
+ node = aml_searchname(scope->node, name);
+ db_aml_disline(pos, depth, "%s %s (%s)\n",
+ mnem,
+ aml_getname(name),
+ aml_nodename(node));
+ args++;
+ }
+ else if (mnem[0] != '.') {
+ db_aml_disline(pos, depth, "%s\n", mnem);
+ }
+ while (*args) {
+ pos = scope->pos;
+ switch (*args) {
+ case 'k':
+ case 'c':
+ case 'D':
+ case 'L':
+ case 'A':
+ break;
+ case 'i':
+ case 't':
+ case 'S':
+ case 'r':
+ scope->pos = db_aml_disasm(node, scope->pos, scope->end, 1, depth+1);
+ break;
+ case 'T':
+ case 'M':
+ scope->pos = db_aml_disasm(node, scope->pos, end, -1, depth+1);
+ break;
+ case 'I':
+ /* Special case: if */
+ scope->pos = db_aml_disasm(node, scope->pos, end, -1, depth+1);
+ if (scope->pos >= scope->end)
+ break;
+ if (*scope->pos == AMLOP_ELSE) {
+ ++scope->pos;
+ end = aml_parseend(scope);
+ db_aml_disline(scope->pos, depth, "Else\n");
+ scope->pos = db_aml_disasm(node, scope->pos, end, -1, depth+1);
+ }
+ break;
+ case 'N':
+ name = aml_parsename(scope);
+ db_aml_disline(pos, depth+1, "%s\n", aml_getname(name));
+ break;
+ case 'n':
+ off = (opcode != AMLOP_NAMECHAR);
+ name = aml_parsename(scope);
+ node = aml_searchname(scope->node, name);
+ db_aml_disline(pos, depth+off, "%s <%s>\n",
+ aml_getname(name),
+ aml_nodename(node));
+
+ if (!node || !node->value || node->value->type != AML_OBJTYPE_METHOD)
+ break;
+
+ /* Method calls */
+ for (idx=0;
+ idx<AML_METHOD_ARGCOUNT(node->value->v_method.flags);
+ idx++) {
+ scope->pos = db_aml_disasm(node, scope->pos, scope->end, 1, depth+1);
+ }
+ break;
+ case 'b':
+ off = (opcode != AMLOP_BYTEPREFIX);
+ db_aml_disint(scope, AMLOP_BYTEPREFIX, depth+off);
+ break;
+ case 'w':
+ off = (opcode != AMLOP_WORDPREFIX);
+ db_aml_disint(scope, AMLOP_WORDPREFIX, depth+off);
+ break;
+ case 'd':
+ off = (opcode != AMLOP_DWORDPREFIX);
+ db_aml_disint(scope, AMLOP_DWORDPREFIX, depth+off);
+ break;
+ case 's':
+ db_aml_disline(pos, depth, "\"%s\"\n", scope->pos);
+ scope->pos += strlen(scope->pos)+1;
+ break;
+ case 'B':
+ tmpstr = malloc(16 * 6 + 1, M_DEVBUF, M_WAITOK);
+ for (idx=0; idx<min(end-scope->pos, 8); idx++)
+ snprintf(tmpstr+idx*6, 7, "0x%.2x, ", scope->pos[idx]);
+ db_aml_disline(pos, depth+1, "ByteList <%s>\n", tmpstr);
+ free(tmpstr, M_DEVBUF);
+ scope->pos = end;
+ break;
+ case 'F':
+ off = 0;
+ while (scope->pos < end) {
+ len = 0;
+ pos = scope->pos;
+ switch (*scope->pos) {
+ case 0x00: // reserved
+ scope->pos++;
+ len = aml_parselength(scope);
+ db_aml_disline(pos, depth+1, "Reserved\t%.4x,%.4x\n",
+ off, len);
+ break;
+ case 0x01: // attr
+ db_aml_disline(pos, depth+1, "Attr:%.2x,%.2x\n",
+ scope->pos[1], scope->pos[2]);
+ scope->pos += 3;
+ break;
+ default:
+ name = aml_parsename(scope);
+ len = aml_parselength(scope);
+ db_aml_disline(pos, depth+1, "NamedField\t%.4x,%.4x %s\n",
+ off, len, aml_getname(name));
+ }
+ off += len;
+ }
+ scope->pos = end;
+ break;
+ default:
+ db_printf("remaining args: '%s'\n", args);
+ }
+ args++;
+ }
+ }
+ pos = scope->pos;
+ aml_popscope(scope);
+ return pos;
}