diff options
author | 2007-02-06 18:56:31 +0000 | |
---|---|---|
committer | 2007-02-06 18:56:31 +0000 | |
commit | 048d6e7c85aa66240e9ba8932fd02a50fcc96852 (patch) | |
tree | 8b7eec7ffefbf57ed45e421a39b45d6cf337e8d0 | |
parent | Use atomic.h operation for manipulating p_siglist in struct proc. Solves (diff) | |
download | wireguard-openbsd-048d6e7c85aa66240e9ba8932fd02a50fcc96852.tar.xz wireguard-openbsd-048d6e7c85aa66240e9ba8932fd02a50fcc96852.zip |
Added support for calling _OSI method
Display byte/word/string/nameref for aml_mnem function
ok marco@
-rw-r--r-- | sys/dev/acpi/acpidebug.c | 12 | ||||
-rw-r--r-- | sys/dev/acpi/amltypes.h | 4 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 111 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.h | 4 |
4 files changed, 105 insertions, 26 deletions
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c index f11b1cf7934..795837bd8de 100644 --- a/sys/dev/acpi/acpidebug.c +++ b/sys/dev/acpi/acpidebug.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpidebug.c,v 1.14 2006/12/21 19:59:02 deraadt Exp $ */ +/* $OpenBSD: acpidebug.c,v 1.15 2007/02/06 18:56:31 jordan Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@openbsd.org> * @@ -42,7 +42,7 @@ 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_mnem(int opcode, uint8_t *); extern const char *aml_args(int opcode); extern const char *aml_getname(uint8_t *); extern const char *aml_nodename(struct aml_node *); @@ -159,7 +159,7 @@ db_aml_showvalue(struct aml_value *value) case AML_OBJTYPE_FIELDUNIT: db_printf("%s: access=%x,lock=%x,update=%x pos=%.4x " "len=%.4x\n", - aml_mnem(value->v_field.type), + aml_mnem(value->v_field.type, NULL), AML_FIELD_ACCESS(value->v_field.flags), AML_FIELD_LOCK(value->v_field.flags), AML_FIELD_UPDATE(value->v_field.flags), @@ -171,7 +171,7 @@ db_aml_showvalue(struct aml_value *value) break; case AML_OBJTYPE_BUFFERFIELD: db_printf("%s: pos=%.4x len=%.4x ", - aml_mnem(value->v_field.type), + aml_mnem(value->v_field.type, NULL), value->v_field.bitpos, value->v_field.bitlen); @@ -236,7 +236,7 @@ db_aml_objtype(struct aml_value *val) return "refof"; case AML_OBJTYPE_FIELDUNIT: case AML_OBJTYPE_BUFFERFIELD: - return aml_mnem(val->v_field.type); + return aml_mnem(val->v_field.type, NULL); } return (""); @@ -416,7 +416,7 @@ db_aml_disasm(struct aml_node *root, uint8_t *start, uint8_t *end, start = scope->pos; opcode = aml_parseopcode(scope); - mnem = aml_mnem(opcode); + mnem = aml_mnem(opcode, scope->pos); args = aml_args(opcode); if (*args == 'p') { diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h index 0d38b7b0fd9..e7d7913868f 100644 --- a/sys/dev/acpi/amltypes.h +++ b/sys/dev/acpi/amltypes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amltypes.h,v 1.24 2007/01/23 04:05:58 jordan Exp $ */ +/* $OpenBSD: amltypes.h,v 1.25 2007/02/06 18:56:31 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -236,6 +236,7 @@ enum aml_objecttype { /* XXX fix this name */ #define AML_FIELD_ATTR__ 0x01 +struct aml_scope; struct aml_node; /* AML Object Value */ @@ -259,6 +260,7 @@ struct aml_value { int flags; u_int8_t *start; u_int8_t *end; + struct aml_value *(*fneval)(struct aml_scope *, struct aml_value *); } vmethod; struct { u_int16_t type; diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index 16cfdb2eee5..4924d4c99de 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.77 2007/01/23 04:05:58 jordan Exp $ */ +/* $OpenBSD: dsdt.c,v 1.78 2007/02/06 18:56:31 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -100,9 +100,12 @@ void _acpi_os_free(void *, const char *, int); void acpi_sleep(int); void acpi_stall(int); +struct aml_value *aml_callosi(struct aml_scope *, struct aml_value *); +struct aml_value *aml_callmethod(struct aml_scope *, struct aml_value *); struct aml_value *aml_evalmethod(struct aml_scope *, struct aml_node *, int, struct aml_value *, struct aml_value *); +const char *aml_getname(const char *); void aml_dump(int, u_int8_t *); void _aml_die(const char *fn, int line, const char *fmt, ...); #define aml_die(x...) _aml_die(__FUNCTION__, __LINE__, x) @@ -323,12 +326,37 @@ aml_findopcode(int opcode) } const char * -aml_mnem(int opcode) +aml_mnem(int opcode, uint8_t *pos) { struct aml_opcode *tab; - - if ((tab = aml_findopcode(opcode)) != NULL) - return tab->mnem; + static char mnemstr[32]; + + if ((tab = aml_findopcode(opcode)) != NULL) { + strlcpy(mnemstr, tab->mnem, sizeof(mnemstr)); + if (pos != NULL) { + switch (opcode) { + case AMLOP_STRINGPREFIX: + snprintf(mnemstr, sizeof(mnemstr), "\"%s\"", pos); + break; + case AMLOP_BYTEPREFIX: + snprintf(mnemstr, sizeof(mnemstr), "0x%.2x", + *(uint8_t *)pos); + break; + case AMLOP_WORDPREFIX: + snprintf(mnemstr, sizeof(mnemstr), "0x%.4x", + *(uint16_t *)pos); + break; + case AMLOP_DWORDPREFIX: + snprintf(mnemstr, sizeof(mnemstr), "0x%.4x", + *(uint16_t *)pos); + break; + case AMLOP_NAMECHAR: + strlcpy(mnemstr, aml_getname(pos), sizeof(mnemstr)); + break; + } + } + return mnemstr; + } return ("xxx"); } @@ -529,7 +557,7 @@ aml_gasio(struct acpi_softc *sc, int type, uint64_t base, uint64_t length, int bitpos, int bitlen, int size, void *buf, int mode) { dnprintf(10, "-- aml_gasio: %.2x" - " base:%llx len:%llx bitpos:%.4x bitlen:%.4x sz:%.2x mode=%s\n", + " base:%llx len:%llx bpos:%.4x blen:%.4x sz:%.2x mode=%s\n", type, base, length, bitpos, bitlen, size, mode==ACPI_IOREAD?"read":"write"); acpi_gasio(sc, mode, type, base+(bitpos>>3), @@ -623,7 +651,6 @@ void acpi_poll_notify(void) struct aml_node *__aml_search(struct aml_node *, uint8_t *); void aml_delchildren(struct aml_node *); -const char *aml_getname(const char *); /* Search for a name in children nodes */ @@ -1165,7 +1192,7 @@ aml_showvalue(struct aml_value *val, int lvl) printf(" field: bitpos=%.4x bitlen=%.4x ref1:%x ref2:%x [%s]\n", val->v_field.bitpos, val->v_field.bitlen, val->v_field.ref1, val->v_field.ref2, - aml_mnem(val->v_field.type)); + aml_mnem(val->v_field.type, NULL)); aml_showvalue(val->v_field.ref1, lvl); aml_showvalue(val->v_field.ref2, lvl); break; @@ -1354,6 +1381,7 @@ _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval) break; case AML_OBJTYPE_METHOD: lhs->v_method.flags = ival; + lhs->v_method.fneval = bval; break; case AML_OBJTYPE_NAMEREF: lhs->v_nameref = (uint8_t *)bval; @@ -1463,6 +1491,9 @@ aml_setvalue(struct aml_scope *scope, struct aml_value *lhs, aml_showvalue(rhs, 50); break; case AML_OBJTYPE_STATICINT: + if (lhs->node) { + lhs->v_integer = aml_val2int(rhs); + } break; case AML_OBJTYPE_INTEGER: lhs->v_integer = aml_val2int(rhs); @@ -1737,7 +1768,7 @@ aml_evalexpr(int64_t lhs, int64_t rhs, int opcode) } dnprintf(50,"aml_evalexpr: %s %llx %llx = %llx\n", - aml_mnem(opcode), lhs, rhs, res); + aml_mnem(opcode, NULL), lhs, rhs, res); return res; } @@ -1802,6 +1833,14 @@ aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos, int len) aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos)); } +struct aml_value * +aml_callmethod(struct aml_scope *scope, struct aml_value *val) +{ + while (scope->pos < scope->end) + aml_parseterm(scope, val); + return val; +} + /* * Evaluate an AML method * @@ -1827,13 +1866,11 @@ aml_evalmethod(struct aml_scope *parent, struct aml_node *node, dnprintf(10, " arg%d: ", argc); aml_showvalue(&scope->args[argc], 10); } - while (scope->pos < scope->end) - aml_parseterm(scope, res); + node->value->v_method.fneval(scope, res); dnprintf(10, "[%s] returns: ", aml_nodename(node)); aml_showvalue(res, 10); #else - while (scope->pos < scope->end) - aml_parseterm(scope, res); + node->value->v_method.fneval(scope, res); #endif /* Free any temporary children nodes */ aml_delchildren(node); @@ -2230,7 +2267,7 @@ aml_parseint(struct aml_scope *scope, int opcode) return aml_val2int(tmpval); } dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)), - aml_nodename(scope->node), aml_mnem(opcode)); + aml_nodename(scope->node), aml_mnem(opcode, NULL)); return rval; } @@ -2543,6 +2580,7 @@ aml_parsemethod(struct aml_scope *scope, int opcode, struct aml_value *res) res->v_method.flags = aml_parseint(scope, AMLOP_BYTEPREFIX); res->v_method.start = scope->pos; res->v_method.end = end; + res->v_method.fneval = aml_callmethod; aml_createname(scope->node, name, res); scope->pos = end; @@ -2911,7 +2949,7 @@ aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res) case AMLOP_CONDREFOF: /* Returns true if object exists */ tmparg = aml_alloctmp(scope, 2); - aml_parseterm(scope, &tmparg[0]); + aml_parsetarget(scope, &tmparg[0], NULL); aml_parsetarget(scope, &tmparg[1], NULL); if (tmparg[0].type != AML_OBJTYPE_NAMEREF) { /* Object exists */ @@ -3034,8 +3072,7 @@ aml_parseop(struct aml_scope *scope, struct aml_value *res) aml_freevalue(res); opcode = aml_parseopcode(scope); dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)), - aml_nodename(scope->node), aml_mnem(opcode)); - + aml_nodename(scope->node), aml_mnem(opcode, scope->pos)); delay(amlop_delay); htab = aml_findopcode(opcode); @@ -3122,9 +3159,49 @@ struct aml_defval { { "_OS_", AML_OBJTYPE_STRING, -1, "OpenBSD" }, { "_REV", AML_OBJTYPE_INTEGER, 2, NULL }, { "_GL", AML_OBJTYPE_MUTEX, 1, NULL, &aml_global_lock }, + { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi }, { NULL } }; +/* _OSI Default Method: + * Returns True if string argument matches list of known OS strings + * We return True for Windows to fake out nasty bad AML + */ +char *aml_valid_osi[] = { + "OpenBSD", + "Windows 2000", + "Windows 2001", + "Windows 2001.1", + "Windows 2001 SP0", + "Windows 2001 SP1", + "Windows 2001 SP2", + "Windows 2001 SP3", + "Windows 2001 SP4", + NULL +}; + +struct aml_value * +aml_callosi(struct aml_scope *scope, struct aml_value *val) +{ + struct aml_value tmpstr, *arg; + int idx, result; + + /* Perform comparison with valid strings */ + result = 0; + memset(&tmpstr, 0, sizeof(tmpstr)); + tmpstr.type = AML_OBJTYPE_STRING; + arg = aml_derefvalue(scope, &scope->args[0], ACPI_IOREAD); + + for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) { + tmpstr.v_string = aml_valid_osi[idx]; + tmpstr.length = strlen(tmpstr.v_string); + + result = aml_cmpvalue(arg, &tmpstr, AMLOP_LEQUAL); + } + aml_setvalue(scope, val, NULL, result); + return val; +} + void aml_create_defaultobjects() { diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h index 546cf2350e9..9b5e0641fbc 100644 --- a/sys/dev/acpi/dsdt.h +++ b/sys/dev/acpi/dsdt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.h,v 1.24 2006/12/26 23:58:08 marco Exp $ */ +/* $OpenBSD: dsdt.h,v 1.25 2007/02/06 18:56:31 jordan Exp $ */ /* * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org> * @@ -47,7 +47,7 @@ struct aml_opcode { const char *aml_eisaid(u_int32_t); const char *aml_args(int); -const char *aml_mnem(int); +const char *aml_mnem(int, uint8_t *); int64_t aml_val2int(struct aml_value *); struct aml_node *aml_searchname(struct aml_node *, const void *); struct aml_node *aml_createname(struct aml_node *, const void *, |