summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2006-03-08 21:04:19 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2006-03-08 21:04:19 +0000
commit61142f8bfdf6a3c0f9530fc468935a8290b01906 (patch)
tree295e9e5e196174a907f8051b37e7e10220034ef2 /sys
parent4519dbd916ab3a3a910f99da50044791deca8d08 (diff)
Add showval to ddb interface. Now we can pretty much debug anything AML
from ddb. Very useful. Help jordan.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpidebug.c195
-rw-r--r--sys/dev/acpi/acpidebug.h3
2 files changed, 192 insertions, 6 deletions
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c
index fd09f254822..ad3da66325f 100644
--- a/sys/dev/acpi/acpidebug.c
+++ b/sys/dev/acpi/acpidebug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.2 2006/03/07 23:13:28 marco Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.3 2006/03/08 21:04:18 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -29,14 +29,17 @@
#include <dev/acpi/acpidebug.h>
#include <dev/acpi/dsdt.h>
+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_dump(int, u_int8_t *);
void db_aml_walktree(struct aml_node *);
void db_aml_shownode(struct aml_node *);
-void db_aml_disline(uint8_t *, int, const char *, ...);
-void db_aml_disint(struct acpi_context *, int, int);
-void db_aml_disasm(struct acpi_context *, int);
+void db_aml_showvalue(struct aml_value *);
void db_spaceit(int);
const char *db_aml_objtype(struct aml_value *);
const char *db_aml_opname(int);
+const char *db_opregion(int);
struct aml_opcode *db_findem(int);
int db_aml_nodetype(struct aml_node *);
@@ -55,6 +58,142 @@ char buf[128];
/* name of scope for lexer */
char scope[80];
+const char *
+db_opregion(int id)
+{
+ switch(id) {
+ case 0:
+ return "SystemMemory";
+ case 1:
+ return "SystemIO";
+ case 2:
+ return "PCIConfig";
+ case 3:
+ return "Embedded";
+ case 4:
+ return "SMBus";
+ case 5:
+ return "CMOS";
+ case 6:
+ return "PCIBAR";
+ }
+ return "";
+}
+void
+db_aml_dump(int len, u_int8_t *buf)
+{
+ int idx;
+
+ db_printf("{ ");
+ for (idx = 0; idx < len; idx++) {
+ db_printf("%s0x%.2x", idx ? ", " : "", buf[idx]);
+ }
+ db_printf(" }\n");
+}
+
+void
+db_aml_showvalue(struct aml_value *value)
+{
+ int idx;
+
+ if (value == NULL)
+ return;
+
+ if (value->node)
+ db_printf("node:%.8x ", value->node);
+
+ if (value->name)
+ db_printf("name:%s ", value->name);
+
+ switch (value->type) {
+ case AML_OBJTYPE_OBJREF:
+ db_printf("refof: %x {\n", value->v_objref.index);
+ db_aml_showvalue(value->v_objref.ref);
+ db_printf("}\n");
+ break;
+ case AML_OBJTYPE_NAMEREF:
+ db_printf("nameref: %s %.8x\n", value->name,
+ value->v_objref.ref);
+ break;
+ case AML_OBJTYPE_STATICINT:
+ case AML_OBJTYPE_INTEGER:
+ db_printf("integer: %llx %s\n", value->v_integer,
+ (value->type == AML_OBJTYPE_STATICINT) ? "(static)" : "");
+ break;
+ case AML_OBJTYPE_STRING:
+ db_printf("string: %s\n", value->v_string);
+ break;
+ case AML_OBJTYPE_PACKAGE:
+ db_printf("package: %d {\n", value->length);
+ for (idx = 0; idx < value->length; idx++)
+ db_aml_showvalue(value->v_package[idx]);
+ db_printf("}\n");
+ break;
+ case AML_OBJTYPE_BUFFER:
+ db_printf("buffer: %d ", value->length);
+ db_aml_dump(value->length, value->v_buffer);
+ break;
+ case AML_OBJTYPE_DEBUGOBJ:
+ db_printf("debug");
+ break;
+ case AML_OBJTYPE_MUTEX:
+ db_printf("mutex : %llx\n", value->v_integer);
+ break;
+ case AML_OBJTYPE_DEVICE:
+ db_printf("device\n");
+ break;
+ case AML_OBJTYPE_EVENT:
+ db_printf("event\n");
+ break;
+ case AML_OBJTYPE_PROCESSOR:
+ db_printf("cpu: %x,%x,%x\n",
+ value->v_processor.proc_id,
+ value->v_processor.proc_addr,
+ value->v_processor.proc_len);
+ break;
+ case AML_OBJTYPE_METHOD:
+ db_printf("method: args=%d, serialized=%d, synclevel=%d\n",
+ AML_METHOD_ARGCOUNT(value->v_method.flags),
+ AML_METHOD_SERIALIZED(value->v_method.flags),
+ AML_METHOD_SYNCLEVEL(value->v_method.flags));
+ break;
+ case AML_OBJTYPE_FIELDUNIT:
+ db_printf("%s: access=%x,lock=%x,update=%x pos=%.4x "
+ "len=%.4x\n",
+ db_aml_opname(value->v_field.type),
+ AML_FIELD_ACCESS(value->v_field.flags),
+ AML_FIELD_LOCK(value->v_field.flags),
+ AML_FIELD_UPDATE(value->v_field.flags),
+ value->v_field.bitpos,
+ value->v_field.bitlen);
+
+ db_aml_showvalue(value->v_field.ref1);
+ db_aml_showvalue(value->v_field.ref2);
+ break;
+ case AML_OBJTYPE_BUFFERFIELD:
+ db_printf("%s: pos=%.4x len=%.4x ",
+ db_aml_opname(value->v_field.type),
+ value->v_field.bitpos,
+ value->v_field.bitlen);
+
+ db_aml_dump(aml_bytelen(value->v_field.bitlen),
+ value->v_field.ref1->v_buffer +
+ aml_bytepos(value->v_field.bitpos));
+
+ db_aml_showvalue(value->v_field.ref1);
+ break;
+ case AML_OBJTYPE_OPREGION:
+ db_printf("opregion: %s,0x%llx,0x%x\n",
+ db_opregion(value->v_opregion.iospace),
+ value->v_opregion.iobase,
+ value->v_opregion.iolen);
+ break;
+ default:
+ db_printf("unknown: %d\n", value->type);
+ break;
+ }
+}
+
/* Output disassembled line */
void
db_spaceit(int len)
@@ -349,6 +488,50 @@ db_aml_walktree(struct aml_node *node)
/* ddb interface */
void
+db_acpi_showval(db_expr_t addr, int haddr, db_expr_t count, char *modif)
+{
+ struct aml_node *node;
+ int t;
+
+ memset(scope, 0, sizeof scope);
+ do {
+ t = db_read_token();
+ if (t == tIDENT) {
+ if (strlcat(scope, db_tok_string, sizeof scope) >=
+ sizeof scope) {
+ printf("Input too long\n");
+ goto error;
+ }
+ t = db_read_token();
+ if (t == tDOT)
+ if (strlcat(scope, ".", sizeof scope) >=
+ sizeof scope) {
+ printf("Input too long 2\n");
+ goto error;
+ }
+ }
+ }
+ while (t != tEOL);
+
+ if (!strlen(scope)) {
+ db_printf("Invalid input\n");
+ goto error;
+ }
+
+ /* get rid of the rest of input */
+ db_flush_lex();
+
+ node = aml_searchname(&aml_root, scope);
+ if (node)
+ db_aml_showvalue(node->value);
+ else
+ db_printf("Not a valid value\n");
+
+error:
+ db_flush_lex();
+}
+
+void
db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
extern struct acpi_softc *acpi_softc;
@@ -391,7 +574,9 @@ db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif)
ctx->pos = node->value->v_method.start;
while (ctx->pos < node->value->v_method.end)
db_aml_disasm(ctx, 0);
- }
+ } else
+ db_printf("Not a valid method\n");
+
acpi_freecontext(ctx);
error:
diff --git a/sys/dev/acpi/acpidebug.h b/sys/dev/acpi/acpidebug.h
index b57b6c72fe5..fd8f5cbfa07 100644
--- a/sys/dev/acpi/acpidebug.h
+++ b/sys/dev/acpi/acpidebug.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.h,v 1.2 2006/03/07 23:13:28 marco Exp $ */
+/* $OpenBSD: acpidebug.h,v 1.3 2006/03/08 21:04:18 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -15,5 +15,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+void db_acpi_showval(db_expr_t, int, db_expr_t, char *);
void db_acpi_disasm(db_expr_t, int, db_expr_t, char *);
void db_acpi_tree(db_expr_t, int, db_expr_t, char *);