1*e6117b4fSderaadt /* $OpenBSD: acpidebug.c,v 1.13 2006/12/21 11:29:58 deraadt Exp $ */ 2559cf7adSmarco /* 3559cf7adSmarco * Copyright (c) 2006 Marco Peereboom <marco@openbsd.org> 4559cf7adSmarco * 5559cf7adSmarco * Permission to use, copy, modify, and distribute this software for any 6559cf7adSmarco * purpose with or without fee is hereby granted, provided that the above 7559cf7adSmarco * copyright notice and this permission notice appear in all copies. 8559cf7adSmarco * 9559cf7adSmarco * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10559cf7adSmarco * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11559cf7adSmarco * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12559cf7adSmarco * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13559cf7adSmarco * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14559cf7adSmarco * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15559cf7adSmarco * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16559cf7adSmarco */ 17559cf7adSmarco 18559cf7adSmarco #include <machine/db_machdep.h> 19559cf7adSmarco #include <ddb/db_command.h> 20559cf7adSmarco #include <ddb/db_output.h> 21cda98319Smarco #include <ddb/db_extern.h> 22cda98319Smarco #include <ddb/db_lex.h> 23559cf7adSmarco 24559cf7adSmarco #include <machine/bus.h> 2530a01ff4Sjordan #include <sys/malloc.h> 26559cf7adSmarco 27559cf7adSmarco #include <dev/acpi/acpireg.h> 28559cf7adSmarco #include <dev/acpi/acpivar.h> 29559cf7adSmarco #include <dev/acpi/amltypes.h> 30559cf7adSmarco #include <dev/acpi/acpidebug.h> 31559cf7adSmarco #include <dev/acpi/dsdt.h> 32559cf7adSmarco 3330a01ff4Sjordan void db_aml_disline(uint8_t *, int, const char *, ...); 3430a01ff4Sjordan void db_aml_disint(struct aml_scope *, int, int); 3530a01ff4Sjordan uint8_t *db_aml_disasm(struct aml_node *, uint8_t *, uint8_t *, int, int); 3630a01ff4Sjordan 3730a01ff4Sjordan extern int aml_pc(uint8_t *); 3830a01ff4Sjordan extern struct aml_scope *aml_pushscope(struct aml_scope *, uint8_t *, uint8_t *, struct aml_node *); 3930a01ff4Sjordan extern struct aml_scope *aml_popscope(struct aml_scope *); 4030a01ff4Sjordan extern uint8_t *aml_parsename(struct aml_scope *); 4130a01ff4Sjordan extern uint8_t *aml_parseend(struct aml_scope *); 4230a01ff4Sjordan extern int aml_parselength(struct aml_scope *); 4330a01ff4Sjordan extern int aml_parseopcode(struct aml_scope *); 4430a01ff4Sjordan 4530a01ff4Sjordan extern const char *aml_mnem(int opcode); 4630a01ff4Sjordan extern const char *aml_args(int opcode); 4730a01ff4Sjordan extern const char *aml_getname(uint8_t *); 4830a01ff4Sjordan extern const char *aml_nodename(struct aml_node *); 4930a01ff4Sjordan 50127317ceSmarco const char *db_aml_objtype(struct aml_value *); 51127317ceSmarco const char *db_opregion(int); 52127317ceSmarco int db_parse_name(void); 534e3126f2Smarco void db_aml_dump(int, u_int8_t *); 544e3126f2Smarco void db_aml_showvalue(struct aml_value *); 55127317ceSmarco void db_aml_walktree(struct aml_node *); 56d478d440Sjordan 57d478d440Sjordan const char *db_aml_fieldacc(int); 58d478d440Sjordan const char *db_aml_fieldlock(int); 59d478d440Sjordan const char *db_aml_fieldupdate(int); 60cda98319Smarco 61cda98319Smarco extern struct aml_node aml_root; 62cda98319Smarco 63cda98319Smarco /* name of scope for lexer */ 64cda98319Smarco char scope[80]; 65cda98319Smarco 664e3126f2Smarco const char * 674e3126f2Smarco db_opregion(int id) 684e3126f2Smarco { 694e3126f2Smarco switch (id) { 704e3126f2Smarco case 0: 714e3126f2Smarco return "SystemMemory"; 724e3126f2Smarco case 1: 734e3126f2Smarco return "SystemIO"; 744e3126f2Smarco case 2: 754e3126f2Smarco return "PCIConfig"; 764e3126f2Smarco case 3: 774e3126f2Smarco return "Embedded"; 784e3126f2Smarco case 4: 794e3126f2Smarco return "SMBus"; 804e3126f2Smarco case 5: 814e3126f2Smarco return "CMOS"; 824e3126f2Smarco case 6: 834e3126f2Smarco return "PCIBAR"; 844e3126f2Smarco } 854e3126f2Smarco return ""; 864e3126f2Smarco } 874e3126f2Smarco void 884e3126f2Smarco db_aml_dump(int len, u_int8_t *buf) 894e3126f2Smarco { 904e3126f2Smarco int idx; 914e3126f2Smarco 924e3126f2Smarco db_printf("{ "); 937d03a03dSmarco for (idx = 0; idx < len; idx++) 944e3126f2Smarco db_printf("%s0x%.2x", idx ? ", " : "", buf[idx]); 954e3126f2Smarco db_printf(" }\n"); 964e3126f2Smarco } 974e3126f2Smarco 984e3126f2Smarco void 994e3126f2Smarco db_aml_showvalue(struct aml_value *value) 1004e3126f2Smarco { 1014e3126f2Smarco int idx; 1024e3126f2Smarco 1034e3126f2Smarco if (value == NULL) 1044e3126f2Smarco return; 1054e3126f2Smarco 1064e3126f2Smarco if (value->node) 10730a01ff4Sjordan db_printf("[%s] ", aml_nodename(value->node)); 1084e3126f2Smarco 10930a01ff4Sjordan switch (value->type & ~AML_STATIC) { 1104e3126f2Smarco case AML_OBJTYPE_OBJREF: 1114e3126f2Smarco db_printf("refof: %x {\n", value->v_objref.index); 1124e3126f2Smarco db_aml_showvalue(value->v_objref.ref); 1134e3126f2Smarco db_printf("}\n"); 1144e3126f2Smarco break; 1154e3126f2Smarco case AML_OBJTYPE_NAMEREF: 1166ab98c39Sjordan db_printf("nameref: %s\n", value->v_nameref); 1174e3126f2Smarco break; 1184e3126f2Smarco case AML_OBJTYPE_INTEGER: 1194e3126f2Smarco db_printf("integer: %llx %s\n", value->v_integer, 1206ab98c39Sjordan (value->type & AML_STATIC) ? "(static)" : ""); 1214e3126f2Smarco break; 1224e3126f2Smarco case AML_OBJTYPE_STRING: 1234e3126f2Smarco db_printf("string: %s\n", value->v_string); 1244e3126f2Smarco break; 1254e3126f2Smarco case AML_OBJTYPE_PACKAGE: 1264e3126f2Smarco db_printf("package: %d {\n", value->length); 1274e3126f2Smarco for (idx = 0; idx < value->length; idx++) 1284e3126f2Smarco db_aml_showvalue(value->v_package[idx]); 1294e3126f2Smarco db_printf("}\n"); 1304e3126f2Smarco break; 1314e3126f2Smarco case AML_OBJTYPE_BUFFER: 1324e3126f2Smarco db_printf("buffer: %d ", value->length); 1334e3126f2Smarco db_aml_dump(value->length, value->v_buffer); 1344e3126f2Smarco break; 1354e3126f2Smarco case AML_OBJTYPE_DEBUGOBJ: 1364e3126f2Smarco db_printf("debug"); 1374e3126f2Smarco break; 1384e3126f2Smarco case AML_OBJTYPE_MUTEX: 1394e3126f2Smarco db_printf("mutex : %llx\n", value->v_integer); 1404e3126f2Smarco break; 1414e3126f2Smarco case AML_OBJTYPE_DEVICE: 1424e3126f2Smarco db_printf("device\n"); 1434e3126f2Smarco break; 1444e3126f2Smarco case AML_OBJTYPE_EVENT: 1454e3126f2Smarco db_printf("event\n"); 1464e3126f2Smarco break; 1474e3126f2Smarco case AML_OBJTYPE_PROCESSOR: 1484e3126f2Smarco db_printf("cpu: %x,%x,%x\n", 1494e3126f2Smarco value->v_processor.proc_id, 1504e3126f2Smarco value->v_processor.proc_addr, 1514e3126f2Smarco value->v_processor.proc_len); 1524e3126f2Smarco break; 1534e3126f2Smarco case AML_OBJTYPE_METHOD: 1544e3126f2Smarco db_printf("method: args=%d, serialized=%d, synclevel=%d\n", 1554e3126f2Smarco AML_METHOD_ARGCOUNT(value->v_method.flags), 1564e3126f2Smarco AML_METHOD_SERIALIZED(value->v_method.flags), 1574e3126f2Smarco AML_METHOD_SYNCLEVEL(value->v_method.flags)); 1584e3126f2Smarco break; 1594e3126f2Smarco case AML_OBJTYPE_FIELDUNIT: 1604e3126f2Smarco db_printf("%s: access=%x,lock=%x,update=%x pos=%.4x " 1614e3126f2Smarco "len=%.4x\n", 1626ab98c39Sjordan aml_mnem(value->v_field.type), 1634e3126f2Smarco AML_FIELD_ACCESS(value->v_field.flags), 1644e3126f2Smarco AML_FIELD_LOCK(value->v_field.flags), 1654e3126f2Smarco AML_FIELD_UPDATE(value->v_field.flags), 1664e3126f2Smarco value->v_field.bitpos, 1674e3126f2Smarco value->v_field.bitlen); 1684e3126f2Smarco 1694e3126f2Smarco db_aml_showvalue(value->v_field.ref1); 1704e3126f2Smarco db_aml_showvalue(value->v_field.ref2); 1714e3126f2Smarco break; 1724e3126f2Smarco case AML_OBJTYPE_BUFFERFIELD: 1734e3126f2Smarco db_printf("%s: pos=%.4x len=%.4x ", 1746ab98c39Sjordan aml_mnem(value->v_field.type), 1754e3126f2Smarco value->v_field.bitpos, 1764e3126f2Smarco value->v_field.bitlen); 1774e3126f2Smarco 1784e3126f2Smarco db_aml_dump(aml_bytelen(value->v_field.bitlen), 1794e3126f2Smarco value->v_field.ref1->v_buffer + 1804e3126f2Smarco aml_bytepos(value->v_field.bitpos)); 1814e3126f2Smarco 1824e3126f2Smarco db_aml_showvalue(value->v_field.ref1); 1834e3126f2Smarco break; 1844e3126f2Smarco case AML_OBJTYPE_OPREGION: 1854e3126f2Smarco db_printf("opregion: %s,0x%llx,0x%x\n", 1864e3126f2Smarco db_opregion(value->v_opregion.iospace), 1874e3126f2Smarco value->v_opregion.iobase, 1884e3126f2Smarco value->v_opregion.iolen); 1894e3126f2Smarco break; 1904e3126f2Smarco default: 1914e3126f2Smarco db_printf("unknown: %d\n", value->type); 1924e3126f2Smarco break; 1934e3126f2Smarco } 1944e3126f2Smarco } 1954e3126f2Smarco 196cda98319Smarco const char * 197cda98319Smarco db_aml_objtype(struct aml_value *val) 198cda98319Smarco { 199cda98319Smarco if (val == NULL) 200cda98319Smarco return "nil"; 201cda98319Smarco 202cda98319Smarco switch (val->type) { 2036ab98c39Sjordan case AML_OBJTYPE_INTEGER+AML_STATIC: 204cda98319Smarco return "staticint"; 205cda98319Smarco case AML_OBJTYPE_INTEGER: 206cda98319Smarco return "integer"; 207cda98319Smarco case AML_OBJTYPE_STRING: 208cda98319Smarco return "string"; 209cda98319Smarco case AML_OBJTYPE_BUFFER: 210cda98319Smarco return "buffer"; 211cda98319Smarco case AML_OBJTYPE_PACKAGE: 212cda98319Smarco return "package"; 213cda98319Smarco case AML_OBJTYPE_DEVICE: 214cda98319Smarco return "device"; 215cda98319Smarco case AML_OBJTYPE_EVENT: 216cda98319Smarco return "event"; 217cda98319Smarco case AML_OBJTYPE_METHOD: 218cda98319Smarco return "method"; 219cda98319Smarco case AML_OBJTYPE_MUTEX: 220cda98319Smarco return "mutex"; 221cda98319Smarco case AML_OBJTYPE_OPREGION: 222cda98319Smarco return "opregion"; 223cda98319Smarco case AML_OBJTYPE_POWERRSRC: 224cda98319Smarco return "powerrsrc"; 225cda98319Smarco case AML_OBJTYPE_PROCESSOR: 226cda98319Smarco return "processor"; 227cda98319Smarco case AML_OBJTYPE_THERMZONE: 228cda98319Smarco return "thermzone"; 229cda98319Smarco case AML_OBJTYPE_DDBHANDLE: 230cda98319Smarco return "ddbhandle"; 231cda98319Smarco case AML_OBJTYPE_DEBUGOBJ: 232cda98319Smarco return "debugobj"; 233cda98319Smarco case AML_OBJTYPE_NAMEREF: 234cda98319Smarco return "nameref"; 235cda98319Smarco case AML_OBJTYPE_OBJREF: 236cda98319Smarco return "refof"; 237cda98319Smarco case AML_OBJTYPE_FIELDUNIT: 238cda98319Smarco case AML_OBJTYPE_BUFFERFIELD: 2396ab98c39Sjordan return aml_mnem(val->v_field.type); 240*e6117b4fSderaadt } 241cda98319Smarco 242cda98319Smarco return (""); 243cda98319Smarco } 244cda98319Smarco 245cda98319Smarco void 246559cf7adSmarco db_aml_walktree(struct aml_node *node) 247559cf7adSmarco { 248559cf7adSmarco while (node) { 24930a01ff4Sjordan db_aml_showvalue(node->value); 250559cf7adSmarco db_aml_walktree(node->child); 25130a01ff4Sjordan 252559cf7adSmarco node = node->sibling; 253559cf7adSmarco } 254559cf7adSmarco } 255559cf7adSmarco 256fc0379faSmarco int 257fc0379faSmarco db_parse_name(void) 2584e3126f2Smarco { 259fc0379faSmarco int t, rv = 1; 2604e3126f2Smarco 2614e3126f2Smarco memset(scope, 0, sizeof scope); 2624e3126f2Smarco do { 2634e3126f2Smarco t = db_read_token(); 2644e3126f2Smarco if (t == tIDENT) { 2654e3126f2Smarco if (strlcat(scope, db_tok_string, sizeof scope) >= 2664e3126f2Smarco sizeof scope) { 2674e3126f2Smarco printf("Input too long\n"); 2684e3126f2Smarco goto error; 2694e3126f2Smarco } 2704e3126f2Smarco t = db_read_token(); 2714e3126f2Smarco if (t == tDOT) 2724e3126f2Smarco if (strlcat(scope, ".", sizeof scope) >= 2734e3126f2Smarco sizeof scope) { 2744e3126f2Smarco printf("Input too long 2\n"); 2754e3126f2Smarco goto error; 2764e3126f2Smarco } 2774e3126f2Smarco } 278*e6117b4fSderaadt } while (t != tEOL); 2794e3126f2Smarco 2804e3126f2Smarco if (!strlen(scope)) { 2814e3126f2Smarco db_printf("Invalid input\n"); 2824e3126f2Smarco goto error; 2834e3126f2Smarco } 2844e3126f2Smarco 285fc0379faSmarco rv = 0; 286fc0379faSmarco error: 2874e3126f2Smarco /* get rid of the rest of input */ 2884e3126f2Smarco db_flush_lex(); 289fc0379faSmarco return (rv); 290fc0379faSmarco } 291fc0379faSmarco 292fc0379faSmarco /* ddb interface */ 293fc0379faSmarco void 294fc0379faSmarco db_acpi_showval(db_expr_t addr, int haddr, db_expr_t count, char *modif) 295fc0379faSmarco { 296fc0379faSmarco struct aml_node *node; 297fc0379faSmarco 298fc0379faSmarco if (db_parse_name()) 299fc0379faSmarco return; 3004e3126f2Smarco 3014e3126f2Smarco node = aml_searchname(&aml_root, scope); 3024e3126f2Smarco if (node) 3034e3126f2Smarco db_aml_showvalue(node->value); 3044e3126f2Smarco else 3054e3126f2Smarco db_printf("Not a valid value\n"); 3064e3126f2Smarco } 3074e3126f2Smarco 3084e3126f2Smarco void 309cda98319Smarco db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif) 310cda98319Smarco { 311cda98319Smarco struct aml_node *node; 312cda98319Smarco 313fc0379faSmarco if (db_parse_name()) 314fc0379faSmarco return; 315cda98319Smarco 316cda98319Smarco node = aml_searchname(&aml_root, scope); 317cda98319Smarco if (node && node->value && node->value->type == AML_OBJTYPE_METHOD) { 318*e6117b4fSderaadt db_aml_disasm(node, node->value->v_method.start, 319*e6117b4fSderaadt node->value->v_method.end, -1, 0); 3204e3126f2Smarco } else 3214e3126f2Smarco db_printf("Not a valid method\n"); 322cda98319Smarco } 323cda98319Smarco 324cda98319Smarco void 325559cf7adSmarco db_acpi_tree(db_expr_t addr, int haddr, db_expr_t count, char *modif) 326559cf7adSmarco { 327559cf7adSmarco db_aml_walktree(aml_root.child); 328559cf7adSmarco } 32930a01ff4Sjordan 3306c53ca5eSjordan void 3316c53ca5eSjordan db_acpi_trace(db_expr_t addr, int haddr, db_expr_t count, char *modif) 3326c53ca5eSjordan { 3336c53ca5eSjordan struct aml_scope *root; 3346c53ca5eSjordan int idx; 3356c53ca5eSjordan extern struct aml_scope *aml_lastscope; 3366c53ca5eSjordan 3376c53ca5eSjordan for (root=aml_lastscope; root && root->pos; root=root->parent) { 3386c53ca5eSjordan db_printf("%.4x Called: %s\n", aml_pc(root->pos), 3396c53ca5eSjordan aml_nodename(root->node)); 3406c53ca5eSjordan for (idx = 0; idx<root->nargs; idx++) { 3416c53ca5eSjordan db_printf(" arg%d: ", idx); 3426c53ca5eSjordan db_aml_showvalue(&root->args[idx]); 3436c53ca5eSjordan } 3446c53ca5eSjordan for (idx = 0; root->locals && idx < AML_MAX_LOCAL; idx++) { 3456c53ca5eSjordan if (root->locals[idx].type) { 3466c53ca5eSjordan db_printf(" local%d: ", idx); 3476c53ca5eSjordan db_aml_showvalue(&root->locals[idx]); 3486c53ca5eSjordan } 3496c53ca5eSjordan } 3506c53ca5eSjordan } 3516c53ca5eSjordan } 3526c53ca5eSjordan 35330a01ff4Sjordan void 35430a01ff4Sjordan db_aml_disline(uint8_t *pos, int depth, const char *fmt, ...) 3556ab98c39Sjordan { 35630a01ff4Sjordan va_list ap; 35730a01ff4Sjordan char line[128]; 35830a01ff4Sjordan 35930a01ff4Sjordan db_printf("%.6x: ", aml_pc(pos)); 36030a01ff4Sjordan while (depth--) 36130a01ff4Sjordan db_printf(" "); 36230a01ff4Sjordan 36330a01ff4Sjordan va_start(ap, fmt); 36430a01ff4Sjordan vsnprintf(line, sizeof(line), fmt, ap); 36530a01ff4Sjordan db_printf(line); 36630a01ff4Sjordan va_end(ap); 3676ab98c39Sjordan } 36830a01ff4Sjordan 36930a01ff4Sjordan void 37030a01ff4Sjordan db_aml_disint(struct aml_scope *scope, int opcode, int depth) 3716ab98c39Sjordan { 37230a01ff4Sjordan switch (opcode) { 37330a01ff4Sjordan case AML_ANYINT: 37430a01ff4Sjordan db_aml_disasm(scope->node, scope->pos, scope->end, -1, depth); 37530a01ff4Sjordan break; 37630a01ff4Sjordan case AMLOP_BYTEPREFIX: 377*e6117b4fSderaadt db_aml_disline(scope->pos, depth, "0x%.2x\n", 378*e6117b4fSderaadt *(uint8_t *)(scope->pos)); 37930a01ff4Sjordan scope->pos += 1; 38030a01ff4Sjordan break; 38130a01ff4Sjordan case AMLOP_WORDPREFIX: 382*e6117b4fSderaadt db_aml_disline(scope->pos, depth, "0x%.4x\n", 383*e6117b4fSderaadt *(uint16_t *)(scope->pos)); 38430a01ff4Sjordan scope->pos += 2; 38530a01ff4Sjordan break; 38630a01ff4Sjordan case AMLOP_DWORDPREFIX: 387*e6117b4fSderaadt db_aml_disline(scope->pos, depth, "0x%.8x\n", 388*e6117b4fSderaadt *(uint32_t *)(scope->pos)); 38930a01ff4Sjordan scope->pos += 4; 39030a01ff4Sjordan break; 39130a01ff4Sjordan case AMLOP_QWORDPREFIX: 392*e6117b4fSderaadt db_aml_disline(scope->pos, depth, "0x%.4llx\n", 393*e6117b4fSderaadt *(uint64_t *)(scope->pos)); 39430a01ff4Sjordan scope->pos += 8; 39530a01ff4Sjordan break; 39630a01ff4Sjordan } 39730a01ff4Sjordan } 39830a01ff4Sjordan 39930a01ff4Sjordan uint8_t * 40030a01ff4Sjordan db_aml_disasm(struct aml_node *root, uint8_t *start, uint8_t *end, 40130a01ff4Sjordan int count, int depth) 40230a01ff4Sjordan { 40330a01ff4Sjordan int idx, opcode, len, off=0; 40430a01ff4Sjordan struct aml_scope *scope; 40530a01ff4Sjordan uint8_t *name, *pos; 40630a01ff4Sjordan const char *mnem, *args; 40730a01ff4Sjordan struct aml_node *node; 40830a01ff4Sjordan char *tmpstr; 40930a01ff4Sjordan 41030a01ff4Sjordan if (start == end) 41130a01ff4Sjordan return end; 41230a01ff4Sjordan 41330a01ff4Sjordan scope = aml_pushscope(NULL, start, end, root); 41430a01ff4Sjordan while (scope->pos < scope->end && count--) { 41530a01ff4Sjordan pos = scope->pos; 41630a01ff4Sjordan start = scope->pos; 41730a01ff4Sjordan opcode = aml_parseopcode(scope); 41830a01ff4Sjordan 41930a01ff4Sjordan mnem = aml_mnem(opcode); 42030a01ff4Sjordan args = aml_args(opcode); 42130a01ff4Sjordan 42230a01ff4Sjordan if (*args == 'p') { 42330a01ff4Sjordan end = aml_parseend(scope); 42430a01ff4Sjordan args++; 42530a01ff4Sjordan } 42630a01ff4Sjordan node = scope->node; 42730a01ff4Sjordan if (*args == 'N') { 42830a01ff4Sjordan name = aml_parsename(scope); 42930a01ff4Sjordan node = aml_searchname(scope->node, name); 43030a01ff4Sjordan db_aml_disline(pos, depth, "%s %s (%s)\n", 431*e6117b4fSderaadt mnem, aml_getname(name), aml_nodename(node)); 43230a01ff4Sjordan args++; 433*e6117b4fSderaadt } else if (mnem[0] != '.') { 43430a01ff4Sjordan db_aml_disline(pos, depth, "%s\n", mnem); 43530a01ff4Sjordan } 43630a01ff4Sjordan while (*args) { 43730a01ff4Sjordan pos = scope->pos; 43830a01ff4Sjordan switch (*args) { 43930a01ff4Sjordan case 'k': 44030a01ff4Sjordan case 'c': 44130a01ff4Sjordan case 'D': 44230a01ff4Sjordan case 'L': 44330a01ff4Sjordan case 'A': 44430a01ff4Sjordan break; 44530a01ff4Sjordan case 'i': 44630a01ff4Sjordan case 't': 44730a01ff4Sjordan case 'S': 44830a01ff4Sjordan case 'r': 449*e6117b4fSderaadt scope->pos = db_aml_disasm(node, scope->pos, 450*e6117b4fSderaadt scope->end, 1, depth+1); 45130a01ff4Sjordan break; 45230a01ff4Sjordan case 'T': 45330a01ff4Sjordan case 'M': 454*e6117b4fSderaadt scope->pos = db_aml_disasm(node, scope->pos, 455*e6117b4fSderaadt end, -1, depth+1); 45630a01ff4Sjordan break; 45730a01ff4Sjordan case 'I': 45830a01ff4Sjordan /* Special case: if */ 459*e6117b4fSderaadt scope->pos = db_aml_disasm(node, scope->pos, 460*e6117b4fSderaadt end, -1, depth+1); 46130a01ff4Sjordan if (scope->pos >= scope->end) 46230a01ff4Sjordan break; 46330a01ff4Sjordan if (*scope->pos == AMLOP_ELSE) { 46430a01ff4Sjordan ++scope->pos; 46530a01ff4Sjordan end = aml_parseend(scope); 46630a01ff4Sjordan db_aml_disline(scope->pos, depth, "Else\n"); 467*e6117b4fSderaadt scope->pos = db_aml_disasm(node, scope->pos, 468*e6117b4fSderaadt end, -1, depth+1); 46930a01ff4Sjordan } 47030a01ff4Sjordan break; 47130a01ff4Sjordan case 'N': 47230a01ff4Sjordan name = aml_parsename(scope); 47330a01ff4Sjordan db_aml_disline(pos, depth+1, "%s\n", aml_getname(name)); 47430a01ff4Sjordan break; 47530a01ff4Sjordan case 'n': 47630a01ff4Sjordan off = (opcode != AMLOP_NAMECHAR); 47730a01ff4Sjordan name = aml_parsename(scope); 47830a01ff4Sjordan node = aml_searchname(scope->node, name); 47930a01ff4Sjordan db_aml_disline(pos, depth+off, "%s <%s>\n", 48030a01ff4Sjordan aml_getname(name), 48130a01ff4Sjordan aml_nodename(node)); 48230a01ff4Sjordan 483*e6117b4fSderaadt if (!node || !node->value || 484*e6117b4fSderaadt node->value->type != AML_OBJTYPE_METHOD) 48530a01ff4Sjordan break; 48630a01ff4Sjordan 48730a01ff4Sjordan /* Method calls */ 48830a01ff4Sjordan for (idx=0; 48930a01ff4Sjordan idx<AML_METHOD_ARGCOUNT(node->value->v_method.flags); 49030a01ff4Sjordan idx++) { 491*e6117b4fSderaadt scope->pos = db_aml_disasm(node, scope->pos, 492*e6117b4fSderaadt scope->end, 1, depth+1); 49330a01ff4Sjordan } 49430a01ff4Sjordan break; 49530a01ff4Sjordan case 'b': 49630a01ff4Sjordan off = (opcode != AMLOP_BYTEPREFIX); 49730a01ff4Sjordan db_aml_disint(scope, AMLOP_BYTEPREFIX, depth+off); 49830a01ff4Sjordan break; 49930a01ff4Sjordan case 'w': 50030a01ff4Sjordan off = (opcode != AMLOP_WORDPREFIX); 50130a01ff4Sjordan db_aml_disint(scope, AMLOP_WORDPREFIX, depth+off); 50230a01ff4Sjordan break; 50330a01ff4Sjordan case 'd': 50430a01ff4Sjordan off = (opcode != AMLOP_DWORDPREFIX); 50530a01ff4Sjordan db_aml_disint(scope, AMLOP_DWORDPREFIX, depth+off); 50630a01ff4Sjordan break; 50730a01ff4Sjordan case 's': 50830a01ff4Sjordan db_aml_disline(pos, depth, "\"%s\"\n", scope->pos); 50930a01ff4Sjordan scope->pos += strlen(scope->pos)+1; 51030a01ff4Sjordan break; 51130a01ff4Sjordan case 'B': 51230a01ff4Sjordan tmpstr = malloc(16 * 6 + 1, M_DEVBUF, M_WAITOK); 51330a01ff4Sjordan for (idx=0; idx<min(end-scope->pos, 8); idx++) 514*e6117b4fSderaadt snprintf(tmpstr+idx*6, 7, "0x%.2x, ", 515*e6117b4fSderaadt scope->pos[idx]); 51630a01ff4Sjordan db_aml_disline(pos, depth+1, "ByteList <%s>\n", tmpstr); 51730a01ff4Sjordan free(tmpstr, M_DEVBUF); 51830a01ff4Sjordan scope->pos = end; 51930a01ff4Sjordan break; 52030a01ff4Sjordan case 'F': 52130a01ff4Sjordan off = 0; 52230a01ff4Sjordan while (scope->pos < end) { 52330a01ff4Sjordan len = 0; 52430a01ff4Sjordan pos = scope->pos; 52530a01ff4Sjordan switch (*scope->pos) { 52630a01ff4Sjordan case 0x00: // reserved 52730a01ff4Sjordan scope->pos++; 52830a01ff4Sjordan len = aml_parselength(scope); 529*e6117b4fSderaadt db_aml_disline(pos, depth+1, 530*e6117b4fSderaadt "Reserved\t%.4x,%.4x\n", 53130a01ff4Sjordan off, len); 53230a01ff4Sjordan break; 53330a01ff4Sjordan case 0x01: // attr 534*e6117b4fSderaadt db_aml_disline(pos, depth+1, 535*e6117b4fSderaadt "Attr:%.2x,%.2x\n", 53630a01ff4Sjordan scope->pos[1], scope->pos[2]); 53730a01ff4Sjordan scope->pos += 3; 53830a01ff4Sjordan break; 53930a01ff4Sjordan default: 54030a01ff4Sjordan name = aml_parsename(scope); 54130a01ff4Sjordan len = aml_parselength(scope); 542*e6117b4fSderaadt db_aml_disline(pos, depth+1, 543*e6117b4fSderaadt "NamedField\t%.4x,%.4x %s\n", 54430a01ff4Sjordan off, len, aml_getname(name)); 54530a01ff4Sjordan } 54630a01ff4Sjordan off += len; 54730a01ff4Sjordan } 54830a01ff4Sjordan scope->pos = end; 54930a01ff4Sjordan break; 55030a01ff4Sjordan default: 55130a01ff4Sjordan db_printf("remaining args: '%s'\n", args); 55230a01ff4Sjordan } 55330a01ff4Sjordan args++; 55430a01ff4Sjordan } 55530a01ff4Sjordan } 55630a01ff4Sjordan pos = scope->pos; 55730a01ff4Sjordan aml_popscope(scope); 55830a01ff4Sjordan return pos; 5596ab98c39Sjordan } 560