diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-02-16 21:11:14 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-02-16 21:11:14 +0000 |
commit | 0248e07840b78acc2579c7a1d030b3726fd9e3bd (patch) | |
tree | e3470120e6b1762e5b2d2aedffd83ac642fd47eb /sys/dev/acpi | |
parent | 41dfbb0d48423e637687ee40cbc528760b617c96 (diff) |
Fixed parser/evaluator to retrieve battery info+state
Cleanup of parser
Dell laptops return battery status
ok marco@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r-- | sys/dev/acpi/acpi.c | 21 | ||||
-rw-r--r-- | sys/dev/acpi/amltypes.h | 13 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 1523 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.h | 14 |
4 files changed, 852 insertions, 719 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 144beab8c27..e53d7a11603 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.26 2006/02/06 23:12:09 brad Exp $ */ +/* $OpenBSD: acpi.c,v 1.27 2006/02/16 21:11:13 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -36,7 +36,7 @@ #include <dev/acpi/dsdt.h> #ifdef ACPI_DEBUG -int acpi_debug = 60; +int acpi_debug = 11; #endif #define ACPIEN_RETRIES 15 @@ -95,6 +95,8 @@ int acpi_s5, acpi_evindex, icount; #error ACPI supported on i386/amd64 only #endif +#define pch(x) (((x)>=' ' && (x)<='z') ? (x) : ' ') + int acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, int access_size, int len, void *buffer) @@ -107,7 +109,8 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, bus_addr_t ioaddr; int reg, idx, ival, sval; - dnprintf(10, "gasio: %x %llx %x %x %p\n", iospace, address, access_size, len, buffer); + dnprintf(30, "gasio: %.2x 0x%.8llx %s\n", + iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read"); pb = (u_int8_t *)buffer; switch (iospace) { @@ -449,12 +452,12 @@ acpi_foundhid(struct aml_node *node, void *arg) const char *dev; struct aml_value res; - dnprintf(10, "found hid device: %s ", node->parent->name); + dnprintf(20, "found hid device: %s ", node->parent->name); aml_eval_object(sc, node, &res, 0, NULL); switch (res.type) { case AML_OBJTYPE_STRING: - dev = res.v_string; + dev = aml_strval(&res); break; case AML_OBJTYPE_INTEGER: dev = aml_eisaid(res.v_integer); @@ -463,7 +466,7 @@ acpi_foundhid(struct aml_node *node, void *arg) dev = "unknown"; break; } - dnprintf(10, " device: %s\n", dev); + dnprintf(20, " device: %s\n", dev); if (!strcmp(dev, ACPI_DEV_AC)) { struct acpi_attach_args aaa; @@ -937,10 +940,12 @@ acpi_softintr(void *arg) void acpi_init_states(struct acpi_softc *sc) { + struct acpi_context *ctx; struct aml_value res, env; char name[8]; int i; + ctx = NULL; for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { snprintf(name, sizeof(name), "_S%d_", i); sc->sc_sleeptype[i].slp_typa = -1; @@ -948,8 +953,8 @@ acpi_init_states(struct acpi_softc *sc) if (aml_eval_name(sc, aml_root.child, name, &res, &env)) continue; if (res.type == AML_OBJTYPE_PACKAGE) { - sc->sc_sleeptype[i].slp_typa = aml_intval(res.v_package[0]); - sc->sc_sleeptype[i].slp_typb = aml_intval(res.v_package[1]); + sc->sc_sleeptype[i].slp_typa = aml_val2int(ctx, res.v_package[0]); + sc->sc_sleeptype[i].slp_typb = aml_val2int(ctx, res.v_package[1]); } } } diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h index b3a16c0cae3..62c55a2b79b 100644 --- a/sys/dev/acpi/amltypes.h +++ b/sys/dev/acpi/amltypes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amltypes.h,v 1.12 2006/02/03 23:55:47 jordan Exp $ */ +/* $OpenBSD: amltypes.h,v 1.13 2006/02/16 21:11:13 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -177,7 +177,8 @@ enum aml_objecttype { AML_OBJTYPE_DEBUGOBJ, AML_OBJTYPE_NAMEREF = 0x100, - AML_OBJTYPE_OBJREF + AML_OBJTYPE_OBJREF, + AML_OBJTYPE_STATICINT, }; /* AML Opcode Arguments */ @@ -232,6 +233,7 @@ struct aml_value int length; int refcnt; const char *name; + struct aml_node *node; union { int64_t vinteger; char *vstring; @@ -241,9 +243,6 @@ struct aml_value u_int8_t iospace; u_int64_t iobase; u_int32_t iolen; -#if 0 - u_int8_t *buf; -#endif } vopregion; struct { int flags; @@ -258,7 +257,6 @@ struct aml_value struct aml_value *ref1; struct aml_value *ref2; int ref3; - const char *ftyp; } vfield; struct { u_int8_t proc_id; @@ -286,9 +284,8 @@ struct aml_value #define v_method _.vmethod #define v_processor _.vprocessor #define v_powerrsrc _.vpowerrsrc -#define v_thrmzone _.vthrmzone -#define aml_intval(v) ((v)->v_integer) +#define xaml_intval(v) ((v)->v_integer) #define aml_strlen(v) ((v)->length) #define aml_strval(v) ((v)->v_string) #define aml_buflen(v) ((v)->length) diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index f84d58bf20a..9108693c76b 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.19 2006/02/03 23:55:47 jordan Exp $ */ +/* $OpenBSD: dsdt.c,v 1.20 2006/02/16 21:11:13 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -27,7 +27,28 @@ #include <dev/acpi/amltypes.h> #include <dev/acpi/dsdt.h> -void *stacktop; +#define AML_FIELD_RESERVED 0x00 +#define AML_FIELD_ATTRIB 0x01 + +#define AML_REVISION 0x01 +#define AML_INTSTRLEN 16 +#define AML_NAMESEG_LEN 4 + +#define AML_MAX_ARG 8 +#define AML_MAX_LOCAL 8 + +#define AML_BYTE 'b' +#define AML_WORD 'w' +#define AML_DWORD 'd' +#define AML_QWORD 'q' +#define AML_ANYINT 'i' + +#define aml_valid(pv) ((pv) != NULL) + +#define acpi_mutex_acquire(ctx,lock,iv) dnprintf(60,"ACQUIRE: %x" #lock "\n", (short)iv) +#define acpi_mutex_release(ctx,lock) dnprintf(60,"RELEASE: " #lock "\n") + +#define aml_ipaddr(n) ((n)-aml_root.start) struct aml_opcode { @@ -66,8 +87,7 @@ opregion(int id) } #endif - -int aml_parse_length(struct acpi_context *); +int aml_parse_length(struct acpi_context *); u_int64_t aml_parse_int(struct acpi_context *, int); const char *aml_parse_string(struct acpi_context *); const char *aml_parse_name(struct acpi_context *); @@ -79,9 +99,10 @@ void aml_shownode(struct aml_node *); u_int64_t aml_bcd2dec(u_int64_t); u_int64_t aml_dec2bcd(u_int64_t); +int aml_lsb(u_int64_t); +int aml_msb(u_int64_t); -int aml_lsb(u_int64_t val); -int aml_msb(u_int64_t val); +int _aml_freevalue(struct aml_value *); void acpi_freecontext(struct acpi_context *ctx); struct acpi_context *acpi_alloccontext(struct acpi_softc *sc, @@ -94,42 +115,74 @@ struct aml_node *aml_find_name(struct acpi_softc *, struct aml_node *, const cha int64_t aml_str2int(const char *, int, int); int64_t aml_evalmath(u_int16_t, int64_t, int64_t); -int aml_testlogical(u_int16_t, long, long); +int aml_logicalcmp(u_int16_t, int64_t, int64_t); int aml_strcmp(u_int16_t opcode, const char *lhs, const char *rhs); int64_t _aml_evalint(struct acpi_context *, struct aml_node *); struct aml_value *aml_getnodevalue(struct acpi_context *, struct aml_node *); struct aml_value *_aml_evalref(struct acpi_context *, struct aml_node *); struct aml_value *aml_evalnode(struct acpi_context *, struct aml_node *); -struct aml_value *_aml_setnodevalue(struct acpi_context *, struct aml_node *, struct aml_value *, uint64_t); +struct aml_value *_aml_setnodevalue(struct acpi_context *, struct aml_node *, struct aml_value *, u_int64_t); -struct aml_node *aml_create_node(struct aml_node *parent, - int opc, const char *mnem, - uint8_t *start); +struct aml_node *aml_create_node(struct aml_node *, + int, const char *, + u_int8_t *); int aml_match(int64_t, int, int64_t); -struct aml_node *childOf(struct aml_node *, int); - int aml_tstbit(const u_int8_t *, int); void aml_setbit(u_int8_t *, int, int); void aml_bufcpy(u_int8_t *, int, const u_int8_t *, int, int); -void aml_create_bufferunit(struct acpi_context *, struct aml_node *, int, int); -void aml_create_fieldunit(struct acpi_context *, struct aml_node *, const char *, int, int, int); -struct aml_value *aml_bufferio(struct acpi_context *ctx, struct aml_value *pfield, struct aml_value *rhs); -struct aml_value *aml_fieldio(struct acpi_context *ctx, struct aml_value *pfield, struct aml_value *rhs); +struct aml_value *aml_ederef(struct acpi_context *ctx, struct aml_value *val); +void aml_resizevalue(struct aml_value *, int); +int aml_parse_length(struct acpi_context *ctx); +struct aml_value *aml_eparseval(struct acpi_context *, int deref); +struct aml_opcode *aml_getopcode(struct acpi_context *); +struct aml_value *aml_esetnodevalue(struct acpi_context *, struct aml_value *lhs, + struct aml_value *rhs, int64_t rval); +struct aml_value *aml_eparselist(struct acpi_context *, u_int8_t *end, int); + +struct aml_node *_aml_searchname(struct aml_node *, const char *); +struct aml_node *aml_doname(struct aml_node *, const char *, int); +struct aml_node *aml_searchname(struct aml_node *, const char *); +struct aml_node *aml_createname(struct aml_node *, const char *); +struct aml_value *aml_eparsescope(struct acpi_context *, const char *, u_int8_t *, + struct aml_opcode *, struct aml_value *); +int64_t aml_eparseint(struct acpi_context *, int type); +struct aml_value *aml_efieldunit(struct acpi_context *, int opcode); +struct aml_value *aml_ebufferfield(struct acpi_context *, int bitlen, int size, int opcode); +u_int8_t *aml_eparselen(struct acpi_context *); +struct aml_value *aml_efield(struct acpi_context *, struct aml_value *e_fld, + struct aml_value *rhs); +struct aml_node *aml_addvname(struct acpi_context *, const char *name, int opcode, + struct aml_value *val); +struct aml_value *aml_eparsenode(struct acpi_context *, struct aml_node *node); +void aml_delchildren(struct acpi_context *, struct aml_node *node); + +int64_t aml_val2int(struct acpi_context *, struct aml_value *); +struct aml_value *aml_val2buf(struct acpi_context *, struct aml_value *, int); + +struct aml_value *aml_domethod(struct acpi_context *, struct aml_value *, + int, struct aml_value **); +struct aml_value *aml_dowhile(struct acpi_context *); +struct aml_value *aml_doif(struct acpi_context *); +struct aml_value *aml_doloadtable(struct acpi_context *); +struct aml_value *aml_domatch(struct acpi_context *); +struct aml_value *aml_doconcat(struct acpi_context *); +struct aml_value *aml_domid(struct acpi_context *); void *acpi_os_allocmem(size_t); void acpi_os_freemem(void *); void aml_addchildnode(struct aml_node *, struct aml_node *); +const char *aml_opname(int); +void aml_dump(int, u_int8_t *); + struct aml_node aml_root; struct aml_value *aml_global_lock; - -#define acpi_mutex_acquire(ctx,lock,iv) dnprintf(10,"ACQUIRE: %x" #lock "\n", (short)iv) -#define acpi_mutex_release(ctx,lock) dnprintf(10,"RELEASE: " #lock "\n") +struct aml_value *aml_edebugobj; void * acpi_os_allocmem(size_t size) @@ -148,6 +201,18 @@ acpi_os_freemem(void *ptr) //free(ptr, M_DEVBUF); } +void +aml_dump(int len, u_int8_t *buf) +{ + int idx; + + dnprintf(50, "{ "); + for (idx=0; idx<len; idx++) { + dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]); + } + dnprintf(50, " }\n"); +} + /* Bit mangling code */ int aml_tstbit(const u_int8_t *pb, int bit) @@ -168,13 +233,6 @@ aml_setbit(u_int8_t *pb, int bit, int val) } } -#define aml_ipaddr(n) ((n)-aml_root.start) - -#define AML_REVISION 0x01 -#define AML_NUM_LOCALS 8 -#define AML_INTSTRLEN 16 -#define AML_NAMESEG_LEN 4 - void aml_addchildnode(struct aml_node *parent, struct aml_node *child) { @@ -189,7 +247,7 @@ void aml_addchildnode(struct aml_node *parent, } struct aml_node *aml_create_node(struct aml_node *parent, int opcode, - const char *mnem, uint8_t *start) + const char *mnem, u_int8_t *start) { struct aml_node *node; @@ -213,11 +271,9 @@ struct aml_node *aml_create_node(struct aml_node *parent, int opcode, * type : Type of object to allocate (AML_OBJTYPE_XXXX) * ival : Integer value (action depends on type) * bval : Buffer value (action depends on type) - * lbl : Debugging label */ struct aml_value * -aml_allocvalue(int type, int64_t ival, void *bval, - const char *lbl) +aml_allocvalue(int type, int64_t ival, void *bval) { struct aml_value *rv; struct aml_value **pv; @@ -225,36 +281,38 @@ aml_allocvalue(int type, int64_t ival, void *bval, rv = (struct aml_value *)acpi_os_allocmem(sizeof(struct aml_value)); rv->type = type; - rv->refcnt = 1; switch (type) { + case AML_OBJTYPE_UNINITIALIZED: + break; + case AML_OBJTYPE_NAMEREF: + rv->name = bval; + rv->v_objref.index = -1; + break; case AML_OBJTYPE_OBJREF: rv->v_objref.index = ival; rv->v_objref.ref = (struct aml_value *)bval; break; + case AML_OBJTYPE_STATICINT: case AML_OBJTYPE_INTEGER: rv->v_integer = ival; break; case AML_OBJTYPE_STRING: /* Allocate string: if pointer valid, copy data */ rv->length = ival; - rv->v_string = NULL; if (ival) { rv->v_string = acpi_os_allocmem(ival+1); - if (bval) { + if (bval) strncpy(rv->v_string, bval, ival); - } } break; case AML_OBJTYPE_BUFFER: /* Allocate buffer: if pointer valid, copy data */ rv->length = ival; - rv->v_buffer = NULL; if (ival) { rv->v_buffer = acpi_os_allocmem(ival); - if (bval) { + if (bval) memcpy(rv->v_buffer, bval, ival); - } } break; case AML_OBJTYPE_PACKAGE: @@ -263,65 +321,62 @@ aml_allocvalue(int type, int64_t ival, void *bval, rv->v_package = (struct aml_value **)acpi_os_allocmem(rv->length * sizeof(struct aml_value *)); if (bval != NULL) { pv = (struct aml_value **)bval; - dnprintf(10, "alloc package..\n"); + dnprintf(40, "alloc package.. %lld\n", ival); for (idx=0; idx<ival; idx++) { rv->v_package[idx] = aml_copyvalue(pv[idx]); } } break; case AML_OBJTYPE_METHOD: - rv->name = bval; rv->v_method.flags = ival; break; case AML_OBJTYPE_MUTEX: - rv->name = bval; rv->v_integer = ival; break; - case AML_OBJTYPE_NAMEREF: case AML_OBJTYPE_OPREGION: case AML_OBJTYPE_DEVICE: case AML_OBJTYPE_EVENT: case AML_OBJTYPE_POWERRSRC: case AML_OBJTYPE_PROCESSOR: case AML_OBJTYPE_THERMZONE: - rv->name = bval; - break; case AML_OBJTYPE_BUFFERFIELD: case AML_OBJTYPE_FIELDUNIT: break; default: - dnprintf(10, "Unknown aml_allocvalue: %.2x\n", type); + dnprintf(40, "Unknown aml_allocvalue: %.2x\n", type); } return rv; } struct aml_value * -aml_allocint(uint64_t ival, int sc) +aml_allocint(u_int64_t ival) { - return aml_allocvalue(AML_OBJTYPE_INTEGER, ival, &sc, "integer"); + return aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL); } struct aml_value * aml_allocstr(const char *str) { - return aml_allocvalue(AML_OBJTYPE_STRING, strlen(str), (void *)str, "string"); + return aml_allocvalue(AML_OBJTYPE_STRING, strlen(str), (void *)str); } int -aml_freevalue(struct aml_value **pv) +_aml_freevalue(struct aml_value *v) { - struct aml_value *v = *pv; int idx; /* Don't free static values */ if (v == NULL) - return (0); - if (v->refcnt < 0) - return (0); - if (--v->refcnt > 0) - return (0); + return (-1); + if (v->node || v->refcnt) + return (-1); + +#if 0 + dnprintf(50, "freeing value : %4x %s\n", v->type, + v->node ? "attached" : "freeable"); +#endif + return -1; - //dnprintf(50, "freeing value : %x\n", v->type); switch (v->type) { case AML_OBJTYPE_STRING: if (v->v_string) { @@ -343,27 +398,21 @@ aml_freevalue(struct aml_value **pv) v->v_package = NULL; break; case AML_OBJTYPE_METHOD: + acpi_os_freemem(v->v_method.start); break; } + v->length = 0; v->type = 0; - acpi_os_freemem(v); - *pv = NULL; - - return (1); + return (0); } -void aml_dump(int len, u_int8_t *buf); - void -aml_dump(int len, u_int8_t *buf) +aml_freevalue(struct aml_value **pv) { - int idx; - - dnprintf(50, "{ "); - for (idx=0; idx<len; idx++) { - dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]); + if (_aml_freevalue(*pv) == 0) { + acpi_os_freemem(*pv); + *pv = NULL; } - dnprintf(50, " }\n"); } void @@ -373,30 +422,43 @@ aml_showvalue(struct aml_value *value) if (value == NULL) return; + if (value->node) + dnprintf(50, "node:%.8x ", value->node); if (value->name) dnprintf(50, "name:%s ", value->name); switch (value->type) { + case AML_OBJTYPE_OBJREF: + dnprintf(50, "refof: %x {\n", value->v_objref.index); + aml_showvalue(value->v_objref.ref); + dnprintf(50, "}\n"); + break; + case AML_OBJTYPE_NAMEREF: + dnprintf(50, "nameref: %s %.8x\n", value->name, + value->v_objref.ref); + break; + case AML_OBJTYPE_STATICINT: case AML_OBJTYPE_INTEGER: - dnprintf(50, "integer: %x\n", value->v_integer); + dnprintf(50, "integer: %llx %s\n", value->v_integer, + (value->type == AML_OBJTYPE_STATICINT) ? "(static)" : ""); break; case AML_OBJTYPE_STRING: dnprintf(50, "string: %s\n", value->v_string); break; - case AML_OBJTYPE_BUFFER: - dnprintf(50, "buffer: %d ", value->length); - aml_dump(value->length, value->v_buffer); - break; case AML_OBJTYPE_PACKAGE: dnprintf(50, "package: %d {\n", value->length); for (idx=0; idx<value->length; idx++) aml_showvalue(value->v_package[idx]); dnprintf(50, "}\n"); break; + case AML_OBJTYPE_BUFFER: + dnprintf(50, "buffer: %d ", value->length); + aml_dump(value->length, value->v_buffer); + break; case AML_OBJTYPE_DEBUGOBJ: dnprintf(50, "debug"); break; case AML_OBJTYPE_MUTEX: - dnprintf(50, "mutex : %x\n", value->v_integer); + dnprintf(50, "mutex : %llx\n", value->v_integer); break; case AML_OBJTYPE_DEVICE: dnprintf(50, "device\n"); @@ -417,19 +479,19 @@ aml_showvalue(struct aml_value *value) AML_METHOD_SYNCLEVEL(value->v_method.flags)); break; case AML_OBJTYPE_FIELDUNIT: - dnprintf(50, "field: access=%x,lock=%x,update=%x type=%6s pos=%.4x len=%.4x\n", + dnprintf(50, "%s: access=%x,lock=%x,update=%x pos=%.4x len=%.4x\n", + 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.ftyp, value->v_field.bitpos, value->v_field.bitlen); aml_showvalue(value->v_field.ref1); aml_showvalue(value->v_field.ref2); break; case AML_OBJTYPE_BUFFERFIELD: - dnprintf(50, "bufferfield: type=%.4x pos=%.4x len=%.4x ", - value->v_field.type, + dnprintf(50, "%s: pos=%.4x len=%.4x ", + aml_opname(value->v_field.type), value->v_field.bitpos, value->v_field.bitlen); aml_dump(aml_bytelen(value->v_field.bitlen), @@ -449,22 +511,17 @@ aml_showvalue(struct aml_value *value) } int -aml_comparevalue(int opcode, const struct aml_value *lhs, const struct aml_value *rhs) +aml_comparevalue(struct acpi_context *ctx, int opcode, struct aml_value *lhs, + struct aml_value *rhs) { - if (lhs->type != rhs->type) { - dnprintf(50, "aml_compare: type mismatch: %x,%x\n", - lhs->type, rhs->type); - return (0); + if (lhs->type == AML_OBJTYPE_INTEGER) { + return aml_logicalcmp(opcode, lhs->v_integer, aml_val2int(ctx, rhs)); } - switch (lhs->type) { - case AML_OBJTYPE_INTEGER: - return aml_testlogical(opcode, lhs->v_integer, rhs->v_integer); - case AML_OBJTYPE_STRING: - case AML_OBJTYPE_BUFFER: - /* XXX: implement buffer/string compare */ - break; + if (rhs->type == AML_OBJTYPE_INTEGER) { + return aml_logicalcmp(opcode, aml_val2int(ctx, lhs), rhs->v_integer); } - return (0); + dnprintf(40,"comparevalue: %.2x %.2x\n", lhs->type, rhs->type); + return 0; } struct aml_value * @@ -473,27 +530,27 @@ aml_copyvalue(const struct aml_value *rhs) struct aml_value *rv; switch (rhs->type) { + case AML_OBJTYPE_STATICINT: case AML_OBJTYPE_INTEGER: - return aml_allocint(rhs->v_integer, rhs->length); + return aml_allocvalue(rhs->type, + rhs->v_integer, + NULL); case AML_OBJTYPE_STRING: - return aml_allocvalue(AML_OBJTYPE_STRING, + return aml_allocvalue(rhs->type, rhs->length, - rhs->v_string, - "copystr"); + rhs->v_string); case AML_OBJTYPE_BUFFER: - return aml_allocvalue(AML_OBJTYPE_BUFFER, + return aml_allocvalue(rhs->type, rhs->length, - rhs->v_buffer, - "copybuf"); + rhs->v_buffer); case AML_OBJTYPE_PACKAGE: - return aml_allocvalue(AML_OBJTYPE_PACKAGE, + return aml_allocvalue(rhs->type, rhs->length, - rhs->v_package, - "copypkg"); + rhs->v_package); case AML_OBJTYPE_BUFFERFIELD: case AML_OBJTYPE_FIELDUNIT: - rv = aml_allocvalue(rhs->type, 0, NULL, "field"); + rv = aml_allocvalue(rhs->type, 0, NULL); if (rv != NULL) { rv->name = rhs->name; rv->length = rhs->length; @@ -502,14 +559,55 @@ aml_copyvalue(const struct aml_value *rhs) return rv; default: - dnprintf(10,"copy unknown : %x\n", rhs->type); - rv = aml_allocvalue(rhs->type, 0, NULL, "any"); + dnprintf(40,"copy unknown : %x\n", rhs->type); + rv = aml_allocvalue(rhs->type, 0, NULL); *rv = *rhs; break; } return rv; } +/* Resize buffer/string/package if out-of-bounds access */ +void +aml_resizevalue(struct aml_value *pv, int newlen) +{ + struct aml_value **newpkg; + u_int8_t *newbuf; + int i1; + + ++newlen; + dnprintf(40, "supersizeme\n"); + switch (pv->type) { + case AML_OBJTYPE_BUFFER: + newbuf = (u_int8_t *)acpi_os_allocmem(newlen); + memcpy(newbuf, pv->v_buffer, pv->length); + + /* Free old buffer */ + acpi_os_freemem(pv->v_buffer); + + pv->v_buffer = newbuf; + pv->length = newlen; + break; + + case AML_OBJTYPE_PACKAGE: + newpkg = (struct aml_value **)acpi_os_allocmem(newlen * sizeof(struct aml_value *)); + + /* Assign old package values */ + for (i1 = 0; i1 < pv->length; i1++) { + newpkg[i1] = pv->v_package[i1]; + } + + /* Free old package */ + acpi_os_freemem(pv->v_package); + + /* Set new length */ + pv->v_package = newpkg; + pv->length = newlen-1; + + break; + } +} + /* * AML Parsing routines */ @@ -523,20 +621,23 @@ aml_parse_string(struct acpi_context *ctx) } /* Read value from AML bytestream */ -uint64_t +u_int64_t aml_parse_int(struct acpi_context *ctx, int size) { u_int8_t *pc = ctx->pos; - ctx->pos += size; switch (size) { - case 1: + case AML_BYTE: + ctx->pos += 1; return *(u_int8_t *)pc; - case 2: + case AML_WORD: + ctx->pos += 2; return *(u_int16_t *)pc; - case 4: + case AML_DWORD: + ctx->pos += 4; return *(u_int32_t *)pc; - case 8: + case AML_QWORD: + ctx->pos += 8; return *(u_int64_t *)pc; } @@ -556,15 +657,15 @@ aml_parse_length(struct acpi_context *ctx) u_int8_t lcode; int ival; - lcode = aml_parse_int(ctx, 1); + lcode = aml_parse_int(ctx, AML_BYTE); if (lcode <= 0x3F) { return lcode; } ival = lcode & 0xF; - if (lcode >= 0x40) ival |= aml_parse_int(ctx, 1) << 4; - if (lcode >= 0x80) ival |= aml_parse_int(ctx, 1) << 12; - if (lcode >= 0xC0) ival |= aml_parse_int(ctx, 1) << 20; + if (lcode >= 0x40) ival |= aml_parse_int(ctx, AML_BYTE) << 4; + if (lcode >= 0x80) ival |= aml_parse_int(ctx, AML_BYTE) << 12; + if (lcode >= 0xC0) ival |= aml_parse_int(ctx, AML_BYTE) << 20; return ival; } @@ -715,6 +816,7 @@ aml_msb(u_int64_t val) int64_t aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs) { + dnprintf(50, "evalmath: %s %lld %lld\n", aml_opname(opcode), lhs, rhs); switch (opcode) { case AMLOP_ADD: return (lhs + rhs); @@ -750,6 +852,12 @@ aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs) return aml_lsb(lhs); case AMLOP_NOT: return ~(lhs); + case AMLOP_TOINTEGER: + return (lhs); + case AMLOP_FROMBCD: + return aml_bcd2dec(lhs); + case AMLOP_TOBCD: + return aml_dec2bcd(lhs); } return (0); @@ -757,8 +865,9 @@ aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs) /* Evaluate logical test operands */ int -aml_testlogical(u_int16_t opcode, long lhs, long rhs) +aml_logicalcmp(u_int16_t opcode, int64_t lhs, int64_t rhs) { + dnprintf(50, "logicalcmp: %s %lld %lld\n", aml_opname(opcode), lhs, rhs); switch(opcode) { case AMLOP_LAND: return (lhs && rhs); @@ -864,8 +973,8 @@ struct aml_opcode aml_table[] = { { AMLOP_MUTEX, "Mutex", "Nb", }, { AMLOP_DATAREGION, "DataRegion", "Nttt" }, { AMLOP_OPREGION, "OpRegion", "Nbii" }, - { AMLOP_SCOPE, "Scope", "pNT" }, - { AMLOP_DEVICE, "Device", "pNT" }, + { AMLOP_SCOPE, "Scope", "pNT" }, + { AMLOP_DEVICE, "Device", "pNT" }, { AMLOP_POWERRSRC, "Power Resource", "pNbwT" }, { AMLOP_THERMALZONE, "ThermalZone", "pNT" }, { AMLOP_PROCESSOR, "Processor", "pNbdbT", }, @@ -920,6 +1029,18 @@ struct aml_opcode aml_table[] = { { 0xFFFF } }; +const char * +aml_opname(int opcode) +{ + struct aml_opcode *ptab = aml_table; + + while (ptab->opcode != 0xFFFF) { + if (ptab->opcode == opcode) return ptab->mnem; + ptab++; + } + return ""; +} + /* Extract opcode from AML bytestream * * Some opcodes are multibyte @@ -927,17 +1048,15 @@ struct aml_opcode aml_table[] = { */ struct aml_opcode *aml_getopcode(struct acpi_context *ctx) { - uint8_t *pc; struct aml_opcode *ptab; - uint16_t twocode, opcode; + u_int16_t twocode, opcode; /* Check if this is a name object */ - pc = ctx->pos; - if (aml_isnamedop(*pc)) { + if (aml_isnamedop(*ctx->pos)) { opcode = AMLOP_NAMECHAR; } else { - opcode = aml_parse_int(ctx, 1); + opcode = aml_parse_int(ctx, AML_BYTE); twocode = (opcode << 8L) + *ctx->pos; /* Check multi-byte opcodes */ @@ -953,22 +1072,10 @@ struct aml_opcode *aml_getopcode(struct acpi_context *ctx) if (ptab->opcode == opcode) return ptab; } + dnprintf(40, "aml_getopcode: Unknown opcode %.4x\n", opcode); return NULL; } -struct aml_node * -childOf(struct aml_node *parent, int child) -{ - struct aml_node *node = parent->child; - - while(node && child--) { - node = node->sibling; - } - return node; -} - -struct aml_value aml_debugobj; - /* Test AML_MATCH operation */ int aml_match(int64_t lhs, int mtype, int64_t rhs) @@ -1074,42 +1181,6 @@ aml_bufcpy(u_int8_t *pDst, int dstPos, const u_int8_t *pSrc, int srcPos, } } -struct aml_value *aml_econcat(struct acpi_context *ctx); -struct aml_value *aml_ederef(struct acpi_context *ctx, struct aml_value *val); -void aml_resizeval(struct aml_value *pv, int newlen); -int aml_parse_length(struct acpi_context *ctx); -struct aml_value *aml_edebugobj; -struct aml_value *aml_eparseval(struct acpi_context *ctx); -struct aml_opcode *aml_getopcode(struct acpi_context *ctx); -struct aml_value *aml_domethod(struct acpi_context *ctx, struct aml_value *val); -struct aml_value *aml_esetnodevalue(struct acpi_context *ctx, struct aml_value *lhs, - struct aml_value *rhs, int64_t rval); -struct aml_value *aml_eparselist(struct acpi_context *ctx, uint8_t *end); - -struct aml_node *_aml_searchname(struct aml_node *, const char *); -struct aml_node *aml_doname(struct aml_node *, const char *, int); -struct aml_node *aml_searchname(struct aml_node *, const char *); -struct aml_node *aml_createname(struct aml_node *, const char *); -struct aml_value *aml_doif(struct acpi_context *ctx); -struct aml_value *aml_eparsescope(struct acpi_context *ctx, const char *name, uint8_t *end, - struct aml_opcode *opc); -struct aml_value *aml_dowhile(struct acpi_context *ctx); -int64_t aml_eparseint(struct acpi_context *ctx); -struct aml_value *aml_efieldunit(struct acpi_context *ctx, int opcode); -struct aml_value *aml_ebufferfield(struct acpi_context *ctx, int bitlen, int size, int opcode); -uint8_t *aml_eparselen(struct acpi_context *ctx); -struct aml_value *aml_eparseref(struct acpi_context *ctx); -int64_t aml_val2int(struct acpi_context *ctx, struct aml_value *val); -struct aml_value *aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, - struct aml_value *rhs); -struct aml_value *aml_val2buf(struct acpi_context *ctx, struct aml_value *val); -void aml_addvname(struct acpi_context *ctx, const char *name, int opcode, - struct aml_value *val); -struct aml_value *aml_eparsenode(struct acpi_context *ctx, struct aml_node *node); -void aml_delchildren(struct acpi_context *ctx, struct aml_node *node); -struct aml_value *aml_doloadtable(struct acpi_context *ctx); -struct aml_value *aml_domatch(struct acpi_context *ctx); - /* Search list of objects for a name match * Special case for fields: search children only */ @@ -1220,20 +1291,18 @@ struct aml_value *aml_ederef(struct acpi_context *ctx, struct aml_value *val) return aml_ederef(ctx, ref); } if (i1 > ref->length) { - aml_resizeval(ref, i1); + aml_resizevalue(ref, i1); } switch (ref->type) { case AML_OBJTYPE_PACKAGE: -#if 1 if (ref->v_package[i1] == NULL) { /* Lazy allocate package */ - dnprintf(10, "LazyPkg: %lld/%d\n", i1, ref->length); - ref->v_package[i1] = aml_allocint(0, 0); + dnprintf(40, "LazyPkg: %lld/%d\n", i1, ref->length); + ref->v_package[i1] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL); } -#endif return ref->v_package[i1]; case AML_OBJTYPE_BUFFER: - return aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 8, ref->v_buffer+i1, "test"); + return aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 8, ref->v_buffer+i1); default: dnprintf(50,"Unknown refof\n"); } @@ -1242,18 +1311,6 @@ struct aml_value *aml_ederef(struct acpi_context *ctx, struct aml_value *val) return val; } -struct aml_value *aml_eparseref(struct acpi_context *ctx) -{ - struct aml_value *lhs, *rhs; - - lhs = aml_eparseval(ctx); - rhs = aml_ederef(ctx, lhs); - if (lhs != rhs) { - aml_freevalue(&lhs); - } - return rhs; -} - struct aml_value * aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, struct aml_value *rhs) @@ -1261,19 +1318,23 @@ aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, struct aml_value *e_rgn; struct aml_value *rv; struct aml_value tmp; + uint8_t *pb; + int blen; - dnprintf(10, "efield %s: ", rhs ? "set" : "get"); +#if 0 + dnprintf(40, "efield %s: ", rhs ? "set" : "get"); aml_showvalue(e_fld); aml_showvalue(rhs); +#endif tmp.type = AML_OBJTYPE_INTEGER; switch (e_fld->v_field.type) { case AMLOP_INDEXFIELD: /* Set INDEX value to FIELD position byte, then write RHS to DATA */ - if (e_fld->v_field.bitpos & 7) { - dnprintf(10, "aml_efield: INDEXFIELD not byte-aligned..\n"); + if (!aml_bytealigned(e_fld->v_field.bitpos)) { + dnprintf(40, "aml_efield: INDEXFIELD not byte-aligned..\n"); } - tmp.v_integer = e_fld->v_field.bitpos >> 3; + tmp.v_integer = aml_bytepos(e_fld->v_field.bitpos); aml_efield(ctx, e_fld->v_field.ref1, &tmp); return aml_efield(ctx, e_fld->v_field.ref2, rhs); @@ -1287,74 +1348,96 @@ aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, /* e_rgn should be OPREGION */ e_rgn = aml_ederef(ctx, e_fld->v_field.ref1); if (e_rgn->type != AML_OBJTYPE_OPREGION) { - dnprintf(10, "aml_efield: Wrong FIELD type!\n"); + dnprintf(40, "aml_efield: Wrong FIELD type!\n"); return NULL; } - if (AML_FIELD_LOCK(e_fld->v_field.flags)) { - acpi_mutex_acquire(ctx, aml_global_lock, -1); - } - rv = aml_allocvalue(AML_OBJTYPE_BUFFER, aml_bytelen(e_fld->v_field.bitlen), NULL, 0); + + blen = aml_bytelen(e_fld->v_field.bitlen); + pb = acpi_os_allocmem(blen+8); // padded space if (rhs == NULL) { - /* Read field */ - if (rv != NULL) { + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, blen, NULL); + + /* Read field + * XXX: don't need pb if aligned + */ + if (aml_valid(rv)) { + if (AML_FIELD_LOCK(e_fld->v_field.flags)) { + acpi_mutex_acquire(ctx, aml_global_lock, -1); + } acpi_gasio(ctx->sc, ACPI_IOREAD, e_rgn->v_opregion.iospace, e_rgn->v_opregion.iobase + aml_bytepos(e_fld->v_field.bitpos), AML_FIELD_ACCESS(e_fld->v_field.flags), - aml_bytelen(e_fld->v_field.bitlen), rv->v_buffer); + blen, pb); + if (AML_FIELD_LOCK(e_fld->v_field.flags)) { + acpi_mutex_release(ctx, aml_global_lock); + } } - if (AML_FIELD_LOCK(e_fld->v_field.flags)) { - acpi_mutex_release(ctx, aml_global_lock); + if (pb != rv->v_buffer) { + aml_bufcpy(rv->v_buffer, 0, + pb, e_fld->v_field.bitpos, + e_fld->v_field.bitlen); + acpi_os_freemem(pb); } return rv; } /* Write field */ - rhs = aml_val2buf(ctx, rhs); - aml_showvalue(rhs); - + if (AML_FIELD_LOCK(e_fld->v_field.flags)) { + acpi_mutex_acquire(ctx, aml_global_lock, -1); + } switch (AML_FIELD_UPDATE(e_fld->v_field.flags)) { case AML_FIELD_PRESERVE: +#if 0 /* XXX: fix length, don't read if whole length */ - dnprintf(10, "old iobase = %llx,%lx\n", e_rgn->v_opregion.iobase, aml_bytepos(e_fld->v_field.bitpos)); + dnprintf(40, "old iobase = %llx,%lx\n", + e_rgn->v_opregion.iobase, aml_bytepos(e_fld->v_field.bitpos)); acpi_gasio(ctx->sc, ACPI_IOREAD, e_rgn->v_opregion.iospace, e_rgn->v_opregion.iobase + aml_bytepos(e_fld->v_field.bitpos), AML_FIELD_ACCESS(e_fld->v_field.flags), - aml_bytelen(e_fld->v_field.bitlen), rv->v_buffer); + blen, pb); +#if 0 aml_showvalue(rv); +#endif +#endif break; case AML_FIELD_WRITEASONES: - memset(rv->v_buffer, 0xFF, rv->length); + memset(pb, 0xFF, blen+8); break; case AML_FIELD_WRITEASZEROES: - memset(rv->v_buffer, 0x00, rv->length); + memset(pb, 0x00, blen+8); break; } - aml_bufcpy(rv->v_buffer, e_fld->v_field.bitpos, - rhs->v_buffer, 0, + rv = aml_val2buf(ctx, rhs, blen); + aml_bufcpy(pb, e_fld->v_field.bitpos, + rv->v_buffer, 0, e_fld->v_field.bitlen); + if (rv != rhs) { + aml_freevalue(&rv); + } acpi_gasio(ctx->sc, ACPI_IOWRITE, e_rgn->v_opregion.iospace, e_rgn->v_opregion.iobase + aml_bytepos(e_fld->v_field.bitpos), AML_FIELD_ACCESS(e_fld->v_field.flags), - aml_bytelen(e_fld->v_field.bitlen), rv->v_buffer); + blen, pb); if (AML_FIELD_LOCK(e_fld->v_field.flags)) { acpi_mutex_release(ctx, aml_global_lock); } + acpi_os_freemem(pb); break; default: /* This is a buffer field */ e_rgn = aml_ederef(ctx, e_fld->v_field.ref1); if (e_rgn->type != AML_OBJTYPE_BUFFER) { - dnprintf(10, "aml_efield: Wrong type!\n"); + dnprintf(40, "aml_efield: Wrong type!\n"); return NULL; } + blen = aml_bytelen(e_fld->v_field.bitlen); if (rhs == NULL) { /* Read buffer */ - rv = aml_allocvalue(AML_OBJTYPE_BUFFER, aml_bytelen(e_fld->v_field.bitlen), - NULL, 0); - if (rv != NULL) { + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, blen, NULL); + if (aml_valid(rv)) { aml_bufcpy(rv->v_buffer, 0, e_rgn->v_buffer, e_fld->v_field.bitpos, e_fld->v_field.bitlen); @@ -1363,127 +1446,182 @@ aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, } /* Write buffer */ - rhs = aml_val2buf(ctx, rhs); + rv = aml_val2buf(ctx, rhs, blen); aml_bufcpy(e_rgn->v_buffer, e_fld->v_field.bitpos, - rhs->v_buffer, 0, + rv->v_buffer, 0, e_fld->v_field.bitlen); + if (rv != rhs) { + aml_freevalue(&rv); + } break; } return NULL; } struct aml_value * -aml_val2buf(struct acpi_context *ctx, struct aml_value *val) +aml_val2buf(struct acpi_context *ctx, struct aml_value *oval, int mlen) { + struct aml_value *pb, *val; + if (val == NULL) return NULL; + + val = aml_ederef(ctx, oval); switch (val->type) { case AML_OBJTYPE_BUFFER: - return val; + if (mlen < val->length) { + mlen = val->length; + } + pb = aml_allocvalue(AML_OBJTYPE_BUFFER, mlen, NULL); + if (val->v_buffer && val->length) { + memcpy(pb->v_buffer, val->v_buffer, val->length); + } + return pb; case AML_OBJTYPE_BUFFERFIELD: case AML_OBJTYPE_FIELDUNIT: return aml_efield(ctx, val, NULL); - case AML_OBJTYPE_NAMEREF: - return aml_val2buf(ctx, aml_ederef(ctx, val)); + case AML_OBJTYPE_STATICINT: case AML_OBJTYPE_INTEGER: - return aml_allocvalue(AML_OBJTYPE_BUFFER, 8, &val->v_integer, ""); + return aml_allocvalue(AML_OBJTYPE_BUFFER, 8, &val->v_integer); case AML_OBJTYPE_STRING: - return aml_allocvalue(AML_OBJTYPE_BUFFER, val->length, val->v_string, ""); + return aml_allocvalue(AML_OBJTYPE_BUFFER, val->length, val->v_string); default: - dnprintf(10, "Unknown val2buf : %d\n", val->type); + dnprintf(40, "Unknown val2buf : %d\n", val->type); return NULL; - } + } } int64_t aml_val2int(struct acpi_context *ctx, struct aml_value *val) { + struct aml_value *pb; int64_t rval; + pb = NULL; if (val == NULL) { - dnprintf(10, "null val2int\n"); + dnprintf(40, "null val2int\n"); return 0; } + rval = 0; switch (val->type) { case AML_OBJTYPE_BUFFER: - rval = 0; if (val->length < 8) { memcpy(&rval, val->v_buffer, val->length); } return rval; + case AML_OBJTYPE_STATICINT: case AML_OBJTYPE_INTEGER: return val->v_integer; case AML_OBJTYPE_STRING: -/* XXX: fix me - -if (val->v_string == NULL) { -rval = 0; -} -else if (!strncmp(val->v_string, "0x", 2)) { -sscanf(val->v_string+2, "%Lx", &rval); -} -else { -rval = strtol(val->v_string); -} -*/ + if (val->v_string != NULL) { + if (!strncmp(val->v_string, "0x", 2)) + rval = aml_str2int(val->v_string+2, val->length, 16); + else + rval = aml_str2int(val->v_string, val->length, 10); + } return rval; case AML_OBJTYPE_NAMEREF: case AML_OBJTYPE_OBJREF: - val = aml_ederef(ctx, val); + if (ctx == NULL) return 0; + pb = aml_ederef(ctx, val); break; case AML_OBJTYPE_BUFFERFIELD: case AML_OBJTYPE_FIELDUNIT: - val = aml_efield(ctx, val, NULL); + if (ctx == NULL) return 0; + pb = aml_efield(ctx, val, NULL); break; case AML_OBJTYPE_METHOD: - val = aml_domethod(ctx, val); + if (ctx == NULL) return 0; + pb = aml_domethod(ctx, val, -1, NULL); break; default: - dnprintf(10, "Unknown val2int: %x\n", val->type); - return 0x0; + dnprintf(40, "Unknown val2int: %x\n", val->type); + break; } - return aml_val2int(ctx, val); + if (pb != NULL) { + return aml_val2int(ctx, pb); + } + return 0x00; } -void +struct aml_node * aml_addvname(struct acpi_context *ctx, const char *name, int opcode, struct aml_value *val) { struct aml_node *pn; - val->name = name; - val->refcnt = -1; pn = aml_createname(ctx->scope, name); - if (pn != NULL) { - pn->opcode = opcode; - if (!pn->value) { - pn->value = val; - } - aml_showvalue(val); + pn->opcode = opcode; + pn->mnem = aml_opname(opcode); + if (val != NULL) { + val->name = name; + val->node = pn; + } + if (pn->value) { + dnprintf(40, "addvname: error, already set!\n"); + aml_freevalue(&pn->value); } - dnprintf(10, "\n"); + pn->value = val; +#if 0 + aml_showvalue(val); + dnprintf(40, "\n"); +#endif + return pn; } /* Parse package length & return pointer to end of package */ -uint8_t * +u_int8_t * aml_eparselen(struct acpi_context *ctx) { - uint8_t *pos = ctx->pos; + u_int8_t *pos = ctx->pos; return pos + aml_parse_length(ctx); } -/* Return integer value */ +/* Parse integer value */ int64_t -aml_eparseint(struct acpi_context *ctx) +aml_eparseint(struct acpi_context *ctx, int type) { struct aml_value *rv; int64_t rval; - rv = aml_eparseval(ctx); - rval = aml_val2int(ctx, rv); - aml_freevalue(&rv); - + if (type == AML_ANYINT) { + /* special case: parse integers directly from bytestream + * this saves an additional alloc/free + */ + switch (*ctx->pos) { + case AMLOP_ZERO: + case AMLOP_ONE: + case AMLOP_ONES: + type = AML_BYTE; + break; + case AMLOP_BYTEPREFIX: + ctx->pos++; + type = AML_BYTE; + break; + case AMLOP_WORDPREFIX: + ctx->pos++; + type = AML_WORD; + break; + case AMLOP_DWORDPREFIX: + ctx->pos++; + type = AML_DWORD; + break; + case AMLOP_QWORDPREFIX: + ctx->pos++; + type = AML_QWORD; + break; + default: + rv = aml_eparseval(ctx, 1); + rval = aml_val2int(ctx, rv); + aml_freevalue(&rv); + break; + } + } + if (type != AML_ANYINT) { + /* Type may have changed here parse byte directly */ + rval = aml_parse_int(ctx, type); + } return rval; } @@ -1492,13 +1630,11 @@ aml_eparseint(struct acpi_context *ctx) * AMLOP_INDEXFIELD * AMLOP_BANKFIELD */ -#define AML_FIELD_RESERVED 0x00 -#define AML_FIELD_ATTRIB 0x01 struct aml_value * aml_efieldunit(struct acpi_context *ctx, int opcode) { - uint8_t *end; + u_int8_t *end; int attr, access; struct aml_value *rv, tmp; @@ -1510,22 +1646,19 @@ aml_efieldunit(struct acpi_context *ctx, int opcode) end = aml_eparselen(ctx); switch (opcode) { case AMLOP_FIELD: - tmp.v_field.ftyp = "field"; - tmp.v_field.ref1 = aml_eparseval(ctx); + tmp.v_field.ref1 = aml_eparseval(ctx, 1); break; case AMLOP_INDEXFIELD: - tmp.v_field.ftyp = "index"; - tmp.v_field.ref1 = aml_eparseval(ctx); - tmp.v_field.ref2 = aml_eparseval(ctx); + tmp.v_field.ref1 = aml_eparseval(ctx, 0); + tmp.v_field.ref2 = aml_eparseval(ctx, 0); break; case AMLOP_BANKFIELD: - tmp.v_field.ftyp = "bank"; - tmp.v_field.ref1 = aml_eparseval(ctx); - tmp.v_field.ref2 = aml_eparseval(ctx); - tmp.v_field.ref3 = aml_eparseint(ctx); + tmp.v_field.ref1 = aml_eparseval(ctx, 0); + tmp.v_field.ref2 = aml_eparseval(ctx, 0); + tmp.v_field.ref3 = aml_eparseint(ctx, AML_ANYINT); break; } - tmp.v_field.flags = aml_parse_int(ctx, 1); + tmp.v_field.flags = aml_parse_int(ctx, AML_BYTE); while (ctx->pos < end) { switch (*ctx->pos) { @@ -1535,8 +1668,8 @@ aml_efieldunit(struct acpi_context *ctx, int opcode) break; case AML_FIELD_ATTRIB: ctx->pos++; - access = aml_parse_int(ctx, 1); - attr = aml_parse_int(ctx, 1); + access = aml_parse_int(ctx, AML_BYTE); + attr = aml_parse_int(ctx, AML_BYTE); tmp.v_field.flags &= ~AML_FIELD_ACCESSMASK; tmp.v_field.flags |= (access & AML_FIELD_ACCESSMASK); @@ -1545,9 +1678,7 @@ aml_efieldunit(struct acpi_context *ctx, int opcode) tmp.name = aml_parse_name(ctx); tmp.v_field.bitlen = aml_parse_length(ctx); rv = aml_copyvalue(&tmp); - if (rv != NULL) { - aml_addvname(ctx, tmp.name, opcode, rv); - } + aml_addvname(ctx, tmp.name, opcode, rv); break; } tmp.v_field.bitpos += tmp.v_field.bitlen; @@ -1555,33 +1686,28 @@ aml_efieldunit(struct acpi_context *ctx, int opcode) return NULL; } -/* - * Create buffer field object - * - * AMLOP_CREATEFIELD - * AMLOP_CREATEBITFIELD - * AMLOP_CREATEBYTEFIELD - * AMLOP_CREATEWORDFIELD - * AMLOP_CREATEDWORDFIELD - * AMLOP_CREATEQWORDFIELD +/* Create buffer field object + * AMLOP_CREATEFIELD + * AMLOP_CREATEBITFIELD + * AMLOP_CREATEBYTEFIELD + * AMLOP_CREATEWORDFIELD + * AMLOP_CREATEDWORDFIELD + * AMLOP_CREATEQWORDFIELD */ struct aml_value * -aml_ebufferfield(struct acpi_context *ctx, int bitlen, int size, int opcode) +aml_ebufferfield(struct acpi_context *ctx, int size, int bitlen, int opcode) { struct aml_value *rv; - rv = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL, "createbf"); - if (rv != NULL) { + rv = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL); + if (aml_valid(rv)) { rv->v_field.type = opcode; - rv->v_field.ref1 = aml_eparseval(ctx); - rv->v_field.bitpos = aml_eparseint(ctx) * size; - if (opcode == AMLOP_CREATEFIELD) { - bitlen = aml_eparseint(ctx); - } - rv->name = aml_parse_name(ctx); - rv->v_field.bitlen = bitlen; + rv->v_field.ref1 = aml_eparseval(ctx, 1); + rv->v_field.bitpos = aml_eparseint(ctx, AML_ANYINT) * size; + rv->v_field.bitlen = (opcode == AMLOP_CREATEFIELD) ? + aml_eparseint(ctx, AML_ANYINT) : bitlen; - aml_addvname(ctx, rv->name, opcode, rv); + aml_addvname(ctx, aml_parse_name(ctx), opcode, rv); } return rv; } @@ -1591,98 +1717,100 @@ struct aml_value * aml_esetnodevalue(struct acpi_context *ctx, struct aml_value *lhs, struct aml_value *rhs, int64_t rval) { - struct aml_value *tmp; - if (rhs == NULL) { - rhs = aml_allocint(rval, 0); + rhs = aml_allocint(rval); } - /* Eval RHS */ - switch (rhs->type) { - case AML_OBJTYPE_FIELDUNIT: - case AML_OBJTYPE_BUFFERFIELD: - rhs = aml_efield(ctx, rhs, NULL); - break; - case AML_OBJTYPE_NAMEREF: - case AML_OBJTYPE_OBJREF: - tmp = aml_ederef(ctx, rhs); - if (tmp == rhs) { - dnprintf(10, "No deref!\n"); - } - rhs = tmp; - break; +#if 0 + dnprintf(50, "------------ SET NODE VALUE -------------\n"); + dnprintf(50, "new : "); + aml_showvalue(rhs); + dnprintf(50, "current: "); + aml_showvalue(lhs); +#endif + + while (lhs->type == AML_OBJTYPE_OBJREF) { + lhs = aml_ederef(ctx, lhs); } - /* Eval LHS */ switch (lhs->type) { - case AML_OBJTYPE_INTEGER: - if (lhs->length == 0) { - lhs->v_integer = aml_val2int(ctx, rhs); - } - break; - case AML_OBJTYPE_STRING: - if (rhs->type != AML_OBJTYPE_STRING) { - dnprintf(10, "no string...\n"); - } - else { - lhs->length = rhs->length; - lhs->v_string = rhs->v_string; - } - break; - case AML_OBJTYPE_BUFFER: - rhs = aml_val2buf(ctx, rhs); - lhs->length = rhs->length; - lhs->v_buffer = rhs->v_buffer; - break; - case AML_OBJTYPE_BUFFERFIELD: - case AML_OBJTYPE_FIELDUNIT: - aml_efield(ctx, lhs, rhs); - break; case AML_OBJTYPE_UNINITIALIZED: + /* Object is not initialized */ *lhs = *rhs; break; - case AML_OBJTYPE_OBJREF: - rhs = aml_esetnodevalue(ctx, aml_ederef(ctx, lhs), rhs, 0); + case AML_OBJTYPE_FIELDUNIT: + case AML_OBJTYPE_BUFFERFIELD: + aml_efield(ctx, lhs, rhs); break; - case AML_OBJTYPE_DEBUGOBJ: - //aml_freevalue(&lhs->v_debug); - //lhs->v_debug = aml_copyvalue(rhs); + case AML_OBJTYPE_STATICINT: + /* Read-only */ break; default: - dnprintf(10, "Unknown set value: %x\n", lhs->type); + /* Object is already initialized, free old value */ + _aml_freevalue(lhs); + *lhs = *rhs; } - +#if 0 + dnprintf(50, "post : "); + aml_showvalue(lhs); +#endif return rhs; } +/* Parse scoped object + * AMLOP_SCOPE + * AMLOP_DEVICE + * AMLOP_POWERRSRC + * AMLOP_PROCESSOR + * AMLOP_THERMALZONE + */ +struct aml_value * +aml_eparsescope(struct acpi_context *ctx, const char *name, u_int8_t *end, + struct aml_opcode *opc, + struct aml_value *val) +{ + struct aml_node *oldscope; + struct aml_value *rv; + + oldscope = ctx->scope; + ctx->scope = aml_addvname(ctx, name, opc->opcode, val); + + rv = aml_eparselist(ctx, end, 0); + + ctx->scope = oldscope; + return rv; +} + /* Parse list of objects */ -struct aml_value *aml_eparselist(struct acpi_context *ctx, uint8_t *end) +struct aml_value * +aml_eparselist(struct acpi_context *ctx, u_int8_t *end, int deref) { struct aml_value *rv; rv = NULL; while (ctx->pos && ctx->pos < end) { aml_freevalue(&rv); - rv = aml_eparseval(ctx); + rv = aml_eparseval(ctx, deref); } return rv; } -/* Concatenate results */ -struct aml_value *aml_econcat(struct acpi_context *ctx) +/* Parse AMLOP_CONCAT */ +struct aml_value * +aml_doconcat(struct acpi_context *ctx) { struct aml_value *lhs, *rhs, *set, *tmp; - lhs = aml_eparseval(ctx); - rhs = aml_eparseval(ctx); - set = aml_eparseval(ctx); + lhs = aml_eparseval(ctx, 1); + rhs = aml_eparseval(ctx, 1); + set = aml_eparseval(ctx, 1); if (lhs == NULL || rhs == NULL || lhs->type != rhs->type) { return NULL; } switch (lhs->type) { case AML_OBJTYPE_STRING: tmp = aml_allocvalue(AML_OBJTYPE_STRING, - lhs->length+rhs->length, NULL, "concat"); + lhs->length+rhs->length, NULL); if (tmp != NULL) { strlcpy(tmp->v_string, lhs->v_string, lhs->length); strlcat(tmp->v_string, rhs->v_string, rhs->length); @@ -1691,65 +1819,58 @@ struct aml_value *aml_econcat(struct acpi_context *ctx) break; case AML_OBJTYPE_BUFFER: tmp = aml_allocvalue(AML_OBJTYPE_BUFFER, - lhs->length+rhs->length, NULL, "concat"); + lhs->length+rhs->length, NULL); if (tmp != NULL) { memcpy(tmp->v_buffer, lhs->v_buffer, lhs->length); memcpy(tmp->v_buffer+lhs->length, rhs->v_buffer, rhs->length); return aml_esetnodevalue(ctx, set, tmp, 0); } break; + default: + dnprintf(50, "aml_doconcat: wrong type %.4x\n", lhs->type); + break; } return NULL; } -struct aml_value *aml_eparsescope(struct acpi_context *ctx, const char *name, uint8_t *end, - struct aml_opcode *opc) -{ - struct aml_node *oldscope; - struct aml_value *rv; - - oldscope = ctx->scope; - ctx->scope = aml_createname(ctx->scope, name); - ctx->scope->mnem = opc->mnem; - ctx->scope->opcode = opc->opcode; - rv = aml_eparselist(ctx, end); - ctx->scope = oldscope; - return rv; -} - /* Parse AMLOP_IF/AMLOP_ELSE block */ -struct aml_value *aml_doif(struct acpi_context *ctx) +struct aml_value * +aml_doif(struct acpi_context *ctx) { struct aml_value *rv; - uint8_t *end; + u_int8_t *end; int64_t i1; rv = NULL; end = aml_eparselen(ctx); - i1 = aml_eparseint(ctx); - dnprintf(10,"evalif: %lld\n", i1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "evalif: %lld\n", i1); + if (i1 != 0) { /* Parse IF block */ - rv = aml_eparselist(ctx, end); + rv = aml_eparselist(ctx, end, 1); } if (*end == AMLOP_ELSE) { /* Parse ELSE block */ ctx->pos = ++end; end = aml_eparselen(ctx); if (i1 == 0) { - rv = aml_eparselist(ctx, end); + rv = aml_eparselist(ctx, end, 1); } } - ctx->pos = end; + if (ctx->pos != NULL) { + ctx->pos = end; + } return rv; } /* Parse AMLOP_WHILE/AMLOP_BREAK/AMLOP_CONTINUE block */ -struct aml_value *aml_dowhile(struct acpi_context *ctx) +struct aml_value * +aml_dowhile(struct acpi_context *ctx) { - uint8_t *start, *end; + u_int8_t *start, *end; struct aml_value *rv; - int64_t i1, iw=0; + int64_t i1; end = aml_eparselen(ctx); start = ctx->pos; @@ -1761,67 +1882,89 @@ struct aml_value *aml_dowhile(struct acpi_context *ctx) } /* Perform test condition */ if (ctx->pos == start) { - i1 = aml_eparseint(ctx); - dnprintf(10, "whiletest: %lld\n", i1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "whiletest: %lld\n", i1); if (i1 == 0) { break; } } if (*ctx->pos == AMLOP_BREAK) { - dnprintf(10,"break\n"); + dnprintf(40, "break\n"); break; } else if (*ctx->pos == AMLOP_CONTINUE) { - dnprintf(10,"continue\n"); + dnprintf(40, "continue\n"); ctx->pos = start; } else { aml_freevalue(&rv); - rv = aml_eparseval(ctx); + rv = aml_eparseval(ctx, 1); } - if (iw++ > 10) break; + } + if (ctx->pos != NULL) { + ctx->pos = end; } return rv; } -struct aml_value *aml_domethod(struct acpi_context *ctx, struct aml_value *val) +/* Call AML Method */ +struct aml_value * +aml_domethod(struct acpi_context *ctx, struct aml_value *val, + int argc, struct aml_value **argv) { int64_t i1, i2; struct aml_value **newarg, **oldarg; struct aml_value **newloc, **oldloc; + struct aml_node *oldscope; struct aml_value *rv; - uint8_t *oldpos; - - oldarg = ctx->args; - oldloc = ctx->locals; + u_int8_t *oldpos; if (val->type != AML_OBJTYPE_METHOD) { - dnprintf(10, "aml_domethod: Invalid type\n"); + dnprintf(40, "aml_domethod: Invalid type\n"); } i2 = AML_METHOD_ARGCOUNT(val->v_method.flags); - newarg = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *)*8); - newloc = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *)*8); + newarg = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *) * AML_MAX_ARG); + newloc = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *) * AML_MAX_LOCAL); /* Parse arguments */ + dnprintf(40, "Get %lld arguments for %s\n", i2, val->name); for (i1 = 0; i1<i2; i1++) { - newarg[i1] = aml_eparseval(ctx); - } - dnprintf(10,"\nCall %s: (%lld args)\n", val->name, i2); - for (i1 = 0; i1<i2; i1++) { - dnprintf(10," arg%lld: ", i1); - aml_showvalue(newarg[i1]); + newarg[i1] = aml_eparseval(ctx, 0); } /* Save old parse position, call method */ + oldscope = ctx->scope; + oldarg = ctx->args; + oldloc = ctx->locals; oldpos = ctx->pos; + ctx->pos = val->v_method.start; ctx->args = newarg; ctx->locals = newloc; - rv = aml_eparselist(ctx, val->v_method.end); + ctx->scope = val->node; + +#if 0 + dnprintf(40,"\nCall %s: (%lld args)\n", val->name, i2); + for (i1 = 0; i1<i2; i1++) { + dnprintf(40," arg%lld: ", i1); + aml_showvalue(newarg[i1]); + } +#endif + + rv = aml_eparselist(ctx, val->v_method.end, 1); + ctx->pos = oldpos; ctx->args = oldarg; ctx->locals = oldloc; + ctx->scope = oldscope; + +#if 0 + dnprintf(40, "Returned from %s\n", val->name); + aml_showvalue(rv); +#endif + + aml_delchildren(ctx, val->node); for (i1=0; i1<8; i1++) { aml_freevalue(&newloc[i1]); @@ -1833,64 +1976,83 @@ struct aml_value *aml_domethod(struct acpi_context *ctx, struct aml_value *val) } -/* Resize buffer/string/package if out-of-bounds access */ -void aml_resizeval(struct aml_value *pv, int newlen) -{ - struct aml_value **oldpkg; - int i1; +/* Handle AMLOP_LOAD + * XXX: Implement this + */ +struct aml_value * +aml_doloadtable(struct acpi_context *ctx) +{ + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + aml_eparseval(ctx, 1); + return NULL; +} - ++newlen; - dnprintf(10, "supersizeme\n"); - switch (pv->type) { - case AML_OBJTYPE_PACKAGE: - oldpkg = pv->v_package; - pv->v_package = (struct aml_value **)acpi_os_allocmem(newlen * sizeof(struct aml_value *)); +/* Handle AMLOP_MID */ +struct aml_value * +aml_domid(struct acpi_context *ctx) +{ + struct aml_value *rhs, *lhs, *rv; + int64_t i1, i2; - /* Assign old package values */ - for (i1 = 0; i1 < pv->length; i1++) { - pv->v_package[i1] = oldpkg[i1]; + rhs = aml_eparseval(ctx, 1); + i1 = aml_eparseint(ctx, AML_ANYINT); // index + i2 = aml_eparseint(ctx, AML_ANYINT); // length + lhs = aml_eparseval(ctx, 1); + if (aml_valid(rhs)) { + switch (rhs->type) { + case AML_OBJTYPE_STRING: + /* Validate index is within range */ + if (i1 >= rhs->length) + i1 = i2 = 0; + if (i1+i2 >= rhs->length) + i2 = rhs->length - i1; + rv = aml_allocvalue(AML_OBJTYPE_STRING, i2, rhs->v_string + i1); + aml_esetnodevalue(ctx, lhs, rv, 0); + break; + case AML_OBJTYPE_BUFFER: + if (i1 >= rhs->length) + i1 = i2 = 0; + if (i1+i2 >= rhs->length) + i2 = rhs->length - i1; + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, i2, rhs->v_buffer + i1); + aml_esetnodevalue(ctx, lhs, rv, 0); + break; } - - /* Free old package */ - acpi_os_freemem(oldpkg); - - /* Set new length */ - pv->length = newlen-1; - - break; } + aml_freevalue(&lhs); + aml_freevalue(&rhs); + return rv; } -struct aml_value *aml_doloadtable(struct acpi_context *ctx) -{ - aml_eparseval(ctx); - aml_eparseval(ctx); - aml_eparseval(ctx); - aml_eparseval(ctx); - aml_eparseval(ctx); - aml_eparseval(ctx); - aml_eparseval(ctx); - return NULL; -} - -struct aml_value *aml_domatch(struct acpi_context *ctx) +/* Handle AMLOP_MATCH + * + * AMLOP_MATCH searches a package for an integer match + */ +struct aml_value * +aml_domatch(struct acpi_context *ctx) { struct aml_value *lhs, *rv; int64_t op1, op2, mv1, mv2, idx, mval; - lhs = aml_eparseval(ctx); - op1 = aml_parse_int(ctx,1); - mv1 = aml_eparseint(ctx); - op2 = aml_parse_int(ctx,1); - mv2 = aml_eparseint(ctx); - idx = aml_eparseint(ctx); + lhs = aml_eparseval(ctx, 1); + op1 = aml_eparseint(ctx, AML_BYTE); + mv1 = aml_eparseint(ctx, AML_ANYINT); + op2 = aml_eparseint(ctx, AML_BYTE); + mv2 = aml_eparseint(ctx, AML_ANYINT); + idx = aml_eparseint(ctx, AML_ANYINT); /* ASSERT: lhs is package */ - rv = aml_allocint(-1, 0); + rv = aml_allocint(-1); if (lhs->type == AML_OBJTYPE_PACKAGE) { for (; idx < lhs->length; idx++) { - mval = aml_val2int(ctx,lhs->v_package[idx]); + mval = aml_val2int(ctx, lhs->v_package[idx]); if (aml_match(mval, op1, mv1) && aml_match(mval, op2, mv2)) { + /* Found match.. set index into result */ rv->v_integer = idx; break; } @@ -1900,12 +2062,16 @@ struct aml_value *aml_domatch(struct acpi_context *ctx) return rv; } +/* Parse AMLOP_XXXX + * + * This is the guts of the evaluator + */ struct aml_value * -aml_eparseval(struct acpi_context *ctx) +aml_eparseval(struct acpi_context *ctx, int deref) { struct aml_opcode *opc; struct aml_value *lhs, *rhs, *tmp, *rv; - uint8_t *end, *start; + u_int8_t *end, *start; const char *name; int64_t i1, i2; @@ -1918,18 +2084,21 @@ aml_eparseval(struct acpi_context *ctx) start = ctx->pos; opc = aml_getopcode(ctx); - dnprintf(10, "### %2d %.4x %s\n", +#if 0 + dnprintf(40, "### %2d %.4x %s\n", ctx->depth, opc->opcode, opc->mnem); +#endif ctx->depth++; end = NULL; switch (opc->opcode) { case AMLOP_NAMECHAR: name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, (char *)name, "nameref"); + rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, (char *)name); if ((rhs = aml_ederef(ctx, rv)) != NULL) { if (rhs->type == AML_OBJTYPE_METHOD) { - rv = aml_domethod(ctx, rhs); + lhs = rhs; + rv = aml_domethod(ctx, rhs, -1, NULL); } else { rv = rhs; @@ -1940,43 +2109,31 @@ aml_eparseval(struct acpi_context *ctx) case AMLOP_NOP: break; case AMLOP_ZERO: - rv = aml_allocint(0,1); - aml_showvalue(rv); + rv = aml_allocvalue(AML_OBJTYPE_STATICINT, 0, NULL); break; case AMLOP_ONE: - rv = aml_allocint(1,1); - aml_showvalue(rv); + rv = aml_allocvalue(AML_OBJTYPE_STATICINT, 1, NULL); break; case AMLOP_ONES: - rv = aml_allocint(-1LL, 1); - aml_showvalue(rv); + rv = aml_allocvalue(AML_OBJTYPE_STATICINT, -1, NULL); break; case AMLOP_REVISION: - rv = aml_allocint(AML_REVISION, 1); - aml_showvalue(rv); + rv = aml_allocvalue(AML_OBJTYPE_STATICINT, AML_REVISION, NULL); break; case AMLOP_BYTEPREFIX: - rv = aml_allocint(aml_parse_int(ctx, 1), 0); - aml_showvalue(rv); + rv = aml_allocint(aml_eparseint(ctx, AML_BYTE)); break; case AMLOP_WORDPREFIX: - rv = aml_allocint(aml_parse_int(ctx, 2), 0); - aml_showvalue(rv); + rv = aml_allocint(aml_eparseint(ctx, AML_WORD)); break; case AMLOP_DWORDPREFIX: - rv = aml_allocint(aml_parse_int(ctx, 4), 0); - aml_showvalue(rv); + rv = aml_allocint(aml_eparseint(ctx, AML_DWORD)); break; case AMLOP_QWORDPREFIX: - rv = aml_allocint(aml_parse_int(ctx, 8), 0); - aml_showvalue(rv); + rv = aml_allocint(aml_eparseint(ctx, AML_QWORD)); break; case AMLOP_STRINGPREFIX: - rv = aml_allocstr(ctx->pos); - if (rv != NULL){ - ctx->pos += rv->length+1; - } - aml_showvalue(rv); + rv = aml_allocstr(aml_parse_string(ctx)); break; case AMLOP_FIELD: case AMLOP_INDEXFIELD: @@ -1984,7 +2141,7 @@ aml_eparseval(struct acpi_context *ctx) rv = aml_efieldunit(ctx, opc->opcode); break; case AMLOP_CREATEFIELD: - rv = aml_ebufferfield(ctx, -1, 1, opc->opcode); + rv = aml_ebufferfield(ctx, 1, -1, opc->opcode); break; case AMLOP_CREATEBITFIELD: rv = aml_ebufferfield(ctx, 1, 1, opc->opcode); @@ -2003,39 +2160,34 @@ aml_eparseval(struct acpi_context *ctx) break; case AMLOP_DEBUG: if (aml_edebugobj == NULL) { - aml_edebugobj = aml_allocvalue(AML_OBJTYPE_DEBUGOBJ, 0, NULL, "debug"); + aml_edebugobj = aml_allocvalue(AML_OBJTYPE_DEBUGOBJ, 0, NULL); } rv = aml_edebugobj; break; case AMLOP_BUFFER: end = aml_eparselen(ctx); - i2 = aml_eparseint(ctx); // requested length - i1 = end - ctx->pos; // supplied length + i2 = aml_eparseint(ctx, AML_ANYINT); // requested length + i1 = end - ctx->pos; // supplied length - rv = aml_allocvalue(AML_OBJTYPE_BUFFER, i2, NULL, "buffer"); + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, i2, NULL); if (i1 > 0) { memcpy(rv->v_buffer, ctx->pos, i1); } + dnprintf(40, "buffer: %lld of %lld\n", i1, i2); break; case AMLOP_PACKAGE: case AMLOP_VARPACKAGE: end = aml_eparselen(ctx); - /* Packages have fixed length, varpkg is variable */ - i2 = (opc->opcode == AMLOP_PACKAGE) ? - aml_parse_int(ctx, 1) : - aml_eparseint(ctx); + /* AMLOP_PACKAGE has fixed length, AMLOP_VARPACKAGE is variable */ + i2 = aml_eparseint(ctx, (opc->opcode == AMLOP_PACKAGE) ? + AML_BYTE : AML_ANYINT); - rv = aml_allocvalue(AML_OBJTYPE_PACKAGE, i2, NULL, "package"); + rv = aml_allocvalue(AML_OBJTYPE_PACKAGE, i2, NULL); for (i1=0; i1 < i2 && ctx->pos < end; i1++) { - rv->v_package[i1] = aml_eparseval(ctx); - } -#if 0 - for (; i1 < rv->length; i1++) { - rv->v_package[i1] = aml_allocint(0,0); + rv->v_package[i1] = aml_eparseval(ctx, 0); } -#endif - dnprintf(10, "package: %lld of %lld parsed\n", i1, i2); + dnprintf(40, "package: %lld of %lld parsed\n", i1, i2); break; case AMLOP_LOCAL0: case AMLOP_LOCAL1: @@ -2048,11 +2200,8 @@ aml_eparseval(struct acpi_context *ctx) i1 = opc->opcode - AMLOP_LOCAL0; if (ctx->locals[i1] == NULL) { /* Lazy allocate LocalX */ - dnprintf(10, "LazyLocal%lld\n", i1); - ctx->locals[i1] = aml_allocint(0, 0); - } - else { - ctx->locals[i1]->refcnt++; + dnprintf(40, "LazyLocal%lld\n", i1); + ctx->locals[i1] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL); } rv = ctx->locals[i1]; break; @@ -2066,34 +2215,38 @@ aml_eparseval(struct acpi_context *ctx) i1 = opc->opcode - AMLOP_ARG0; if (ctx->args[i1] == NULL) { /* Lazy allocate ArgX - shouldn't happen? */ - dnprintf(10, "LazyArg%lld\n", i1); - ctx->args[i1] = aml_allocint(0, 0); + dnprintf(40, "LazyArg%lld\n", i1); + ctx->args[i1] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL); } rv = ctx->args[i1]; break; case AMLOP_INCREMENT: case AMLOP_DECREMENT: - lhs = aml_eparseval(ctx); + lhs = aml_eparseval(ctx, 1); i1 = aml_val2int(ctx, lhs); rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(opc->opcode, i1, 1)); break; case AMLOP_FINDSETLEFTBIT: case AMLOP_FINDSETRIGHTBIT: + case AMLOP_TOINTEGER: + case AMLOP_FROMBCD: + case AMLOP_TOBCD: case AMLOP_NOT: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); + i1 = aml_eparseint(ctx, AML_ANYINT); + lhs = aml_eparseval(ctx, 1); rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(opc->opcode, i1, 0)); break; case AMLOP_DIVIDE: - i1 = aml_eparseint(ctx); - i2 = aml_eparseint(ctx); + i1 = aml_eparseint(ctx, AML_ANYINT); + i2 = aml_eparseint(ctx, AML_ANYINT); - lhs = aml_eparseval(ctx); - rhs = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(AMLOP_MOD, i1, i2)); - aml_freevalue(&lhs); + /* Set remainder */ + tmp = aml_eparseval(ctx, 1); + rhs = aml_esetnodevalue(ctx, tmp, NULL, aml_evalmath(AMLOP_MOD, i1, i2)); - lhs = aml_eparseval(ctx); + /* Set quotient */ + lhs = aml_eparseval(ctx, 1); rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(AMLOP_DIVIDE, i1, i2)); break; case AMLOP_ADD: @@ -2107,20 +2260,20 @@ aml_eparseval(struct acpi_context *ctx) case AMLOP_XOR: case AMLOP_NOR: case AMLOP_MOD: - i1 = aml_eparseint(ctx); - i2 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); + i1 = aml_eparseint(ctx, AML_ANYINT); + i2 = aml_eparseint(ctx, AML_ANYINT); + lhs = aml_eparseval(ctx, 1); rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(opc->opcode, i1, i2)); break; case AMLOP_LAND: case AMLOP_LOR: - i1 = aml_eparseint(ctx); - i2 = aml_eparseint(ctx); - rv = aml_allocint(aml_testlogical(opc->opcode, i1, i2),0); + i1 = aml_eparseint(ctx, AML_ANYINT); + i2 = aml_eparseint(ctx, AML_ANYINT); + rv = aml_allocint(aml_logicalcmp(opc->opcode, i1, i2)); break; case AMLOP_LNOT: - i1 = aml_eparseint(ctx); - rv = aml_allocint(!i1, 1); + i1 = aml_eparseint(ctx, AML_ANYINT); + rv = aml_allocint(aml_logicalcmp(opc->opcode, i1, 0)); break; case AMLOP_LLESS: case AMLOP_LLESSEQUAL: @@ -2128,58 +2281,16 @@ aml_eparseval(struct acpi_context *ctx) case AMLOP_LNOTEQUAL: case AMLOP_LGREATEREQUAL: case AMLOP_LGREATER: - lhs = aml_eparseval(ctx); - rhs = aml_eparseval(ctx); - i1 = aml_comparevalue(opc->opcode, lhs, rhs); - rv = aml_allocint(i1, 0); - break; - case AMLOP_TOINTEGER: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_esetnodevalue(ctx, lhs, NULL, i1); - break; - case AMLOP_FROMBCD: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_esetnodevalue(ctx, lhs, NULL, aml_bcd2dec(i1)); - break; - case AMLOP_TOBCD: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_esetnodevalue(ctx, lhs, NULL, aml_dec2bcd(i1)); - break; - case AMLOP_MID: - rhs = aml_eparseval(ctx); - i1 = aml_eparseint(ctx); // index - i2 = aml_eparseint(ctx); // length - if (rhs != NULL) { - switch (rhs->type) { - case AML_OBJTYPE_STRING: - /* Validate index is within range */ - if (i1 >= lhs->length) - i1 = i2 = 0; - if (i1+i2 >= lhs->length) - i2 = lhs->length - i1; - rv = aml_allocvalue(AML_OBJTYPE_STRING, i2, lhs->v_string + i1, "mid"); - aml_esetnodevalue(ctx, lhs, rv, 0); - break; - case AML_OBJTYPE_BUFFER: - if (i1 >= lhs->length) - i1 = i2 = 0; - if (i1+i2 >= lhs->length) - i2 = lhs->length - i1; - rv = aml_allocvalue(AML_OBJTYPE_BUFFER, i2, lhs->v_buffer + i1, "mid"); - aml_esetnodevalue(ctx, lhs, rv, 0); - break; - } - } + lhs = aml_eparseval(ctx, 1); + rhs = aml_eparseval(ctx, 1); + rv = aml_allocint(aml_comparevalue(ctx, opc->opcode, lhs, rhs)); break; case AMLOP_TOSTRING: - rhs = aml_eparseval(ctx); - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); + rhs = aml_eparseval(ctx, 1); + i1 = aml_eparseint(ctx, AML_ANYINT); // maximum length + lhs = aml_eparseval(ctx, 1); - tmp = aml_val2buf(ctx, rhs); + tmp = aml_val2buf(ctx, rhs, 0); if (i1 > tmp->length) { i1 = tmp->length; } @@ -2188,137 +2299,126 @@ aml_eparseval(struct acpi_context *ctx) break; } } - rv = aml_allocvalue(AML_OBJTYPE_STRING, i2, tmp->v_buffer, ""); + rv = aml_allocvalue(AML_OBJTYPE_STRING, i2, tmp->v_buffer); aml_esetnodevalue(ctx, lhs, rv, 0); break; case AMLOP_TOBUFFER: - rhs = aml_eparseval(ctx); - lhs = aml_eparseval(ctx); - rv = aml_val2buf(ctx, lhs); + rhs = aml_eparseval(ctx, 1); + lhs = aml_eparseval(ctx, 1); + rv = aml_val2buf(ctx, lhs, 0); aml_esetnodevalue(ctx, lhs, rv, 0); break; case AMLOP_TODECSTRING: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_allocvalue(AML_OBJTYPE_STRING, AML_INTSTRLEN, NULL, "todec"); - if (rhs != NULL) { - snprintf(rhs->v_string, AML_INTSTRLEN, "%lld", i1); - aml_esetnodevalue(ctx, lhs, rv, 0); - } - break; case AMLOP_TOHEXSTRING: - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_allocvalue(AML_OBJTYPE_STRING, AML_INTSTRLEN, NULL, "todec"); - if (rhs != NULL) { - snprintf(rhs->v_string, AML_INTSTRLEN, "0x%Lx", i1); + i1 = aml_eparseint(ctx, AML_ANYINT); + lhs = aml_eparseval(ctx, 1); + rv = aml_allocvalue(AML_OBJTYPE_STRING, AML_INTSTRLEN, NULL); + if (aml_valid(rv)) { + snprintf(rv->v_string, AML_INTSTRLEN, + (opc->opcode == AMLOP_TODECSTRING) ? "%lld" : "0x%llx" , i1); aml_esetnodevalue(ctx, lhs, rv, 0); } break; case AMLOP_STALL: - i1 = aml_eparseint(ctx); - dnprintf(10, "stall %lld usecs\n", i1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "stall %lld usecs\n", i1); break; case AMLOP_SLEEP: - i1 = aml_eparseint(ctx); - dnprintf(10, "sleep %lld msecs\n", i1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "sleep %lld msecs\n", i1); break; case AMLOP_MUTEX: name = aml_parse_name(ctx); - i1 = aml_parse_int(ctx, 1); - rv = aml_allocvalue(AML_OBJTYPE_MUTEX, i1, (char *)name, "mutex"); - if (rv != NULL) { - aml_addvname(ctx, name, opc->opcode, rv); - } + i1 = aml_eparseint(ctx, AML_BYTE); + rv = aml_allocvalue(AML_OBJTYPE_MUTEX, i1, NULL); + aml_addvname(ctx, name, opc->opcode, rv); break; case AMLOP_ACQUIRE: - lhs = aml_eparseref(ctx); - i1 = aml_parse_int(ctx, 2); + i2 = 0; + lhs = aml_eparseval(ctx, 1); + i1 = aml_eparseint(ctx, AML_WORD); // timeout (0xffff = infinite) acpi_mutex_acquire(ctx, &lhs->v_mutex, i1); - rv = aml_allocint(0,0); + + /* Returns true for timeout */ + rv = aml_allocint(i2); break; case AMLOP_RELEASE: - lhs = aml_eparseref(ctx); + lhs = aml_eparseval(ctx, 1); acpi_mutex_release(ctx, &lhs->v_mutex); break; case AMLOP_EVENT: name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_EVENT, 0, (char *)name, "event"); - if (rv != NULL) { - aml_addvname(ctx, name, opc->opcode, rv); - } + rv = aml_allocvalue(AML_OBJTYPE_EVENT, 0, NULL); + aml_addvname(ctx, name, opc->opcode, rv); break; case AMLOP_SIGNAL: - lhs = aml_eparseref(ctx); - dnprintf(10,"signal: %s\n", lhs->v_string); + lhs = aml_eparseval(ctx, 1); + dnprintf(40, "signal: %s\n", lhs->v_string); break; case AMLOP_WAIT: - lhs = aml_eparseref(ctx); - i1 = aml_eparseint(ctx); - dnprintf(10, "wait: %s %Lx\n", lhs->v_string, i1); + lhs = aml_eparseval(ctx, 1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "wait: %s %llx\n", lhs->v_string, i1); break; case AMLOP_RESET: - lhs = aml_eparseref(ctx); - dnprintf(10, "reset: %s\n", lhs->v_string); + lhs = aml_eparseval(ctx, 1); + dnprintf(40, "reset: %s\n", lhs->v_string); break; case AMLOP_NOTIFY: - lhs = aml_eparseval(ctx); - i1 = aml_eparseint(ctx); - dnprintf(10,"NOTIFY: %Lx %s\n", i1, lhs->name); + lhs = aml_eparseval(ctx, 1); + i1 = aml_eparseint(ctx, AML_ANYINT); + dnprintf(40, "NOTIFY: %llx %s\n", i1, lhs->name); break; case AMLOP_LOAD: case AMLOP_STORE: - rhs = aml_eparseval(ctx); - lhs = aml_eparseval(ctx); + rhs = aml_eparseval(ctx, 1); + lhs = aml_eparseval(ctx, 0); rv = aml_esetnodevalue(ctx, lhs, rhs, 0); break; case AMLOP_COPYOBJECT: - rhs = aml_eparseval(ctx); - lhs = aml_eparseval(ctx); + rhs = aml_eparseval(ctx, 1); + lhs = aml_eparseval(ctx, 1); rv = aml_copyvalue(rhs); aml_esetnodevalue(ctx, lhs, rv, 0); break; case AMLOP_OPREGION: name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_OPREGION, 0, (char *)name, "opregion"); - if (rv != NULL) { - rv->v_opregion.iospace = aml_parse_int(ctx, 1); - rv->v_opregion.iobase = aml_eparseint(ctx); - rv->v_opregion.iolen = aml_eparseint(ctx); -#if 0 - rv->v_opregion.buf = acpi_os_allocmem(rv->v_opregion.iolen); - memset(rv->v_opregion.buf, 0xFF, rv->v_opregion.iolen); - acpi_gasio(ctx->sc, ACPI_IOREAD, - rv->v_opregion.iospace, - rv->v_opregion.iobase, - 1, - rv->v_opregion.iolen, - rv->v_opregion.buf); -#endif + rv = aml_allocvalue(AML_OBJTYPE_OPREGION, 0, NULL); + if (aml_valid(rv)) { + rv->v_opregion.iospace = aml_eparseint(ctx, AML_BYTE); + rv->v_opregion.iobase = aml_eparseint(ctx, AML_ANYINT); + rv->v_opregion.iolen = aml_eparseint(ctx, AML_ANYINT); + aml_addvname(ctx, name, opc->opcode, rv); } break; case AMLOP_ALIAS: - name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, (void *)name, "alias"); - if (rv != NULL) { - name = aml_parse_name(ctx); - aml_addvname(ctx, name, opc->opcode, rv); - } + name = aml_parse_name(ctx); // alias + dnprintf(50, "alias0: %s\n", name); + rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, (void *)name); + + name = aml_parse_name(ctx); // new name + dnprintf(50, "alias1: %s\n", name); + aml_addvname(ctx, name, opc->opcode, rv); break; case AMLOP_NAME: name = aml_parse_name(ctx); - rv = aml_eparseval(ctx); - if (rv != NULL) { - aml_addvname(ctx, name, opc->opcode, rv); - } + rv = aml_eparseval(ctx, 0); + aml_addvname(ctx, name, opc->opcode, rv); break; case AMLOP_RETURN: - rv = aml_eparseref(ctx); + rv = aml_eparseval(ctx, 1); +#if 0 + dnprintf(40, "RETURNING: "); + aml_showvalue(rv); +#endif ctx->pos = NULL; break; + case AMLOP_MID: + rv = aml_domid(ctx); + break; case AMLOP_CONCAT: - rv = aml_econcat(ctx); + rv = aml_doconcat(ctx); break; case AMLOP_SCOPE: @@ -2326,67 +2426,63 @@ aml_eparseval(struct acpi_context *ctx) name = aml_parse_name(ctx); /* Save old scope, create new scope */ - rv = aml_eparsescope(ctx, name, end, opc); + rv = aml_eparsescope(ctx, name, end, opc, NULL); break; case AMLOP_DEVICE: end = aml_eparselen(ctx); name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, (char *)name, "device"); - /* Save old scope, create new scope */ - lhs = aml_eparsescope(ctx, name, end, opc); + rv = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, NULL); + lhs = aml_eparsescope(ctx, name, end, opc, rv); break; case AMLOP_POWERRSRC: end = aml_eparselen(ctx); name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, (char *)name, "power"); - if (rv != NULL) { - rv->v_powerrsrc.pwr_level = aml_parse_int(ctx, 1); - rv->v_powerrsrc.pwr_order = aml_parse_int(ctx, 2); - - lhs = aml_eparsescope(ctx, name, end, opc); + rv = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, NULL); + if (aml_valid(rv)) { + rv->v_powerrsrc.pwr_level = aml_eparseint(ctx, AML_BYTE); + rv->v_powerrsrc.pwr_order = aml_eparseint(ctx, AML_WORD); } + lhs = aml_eparsescope(ctx, name, end, opc, rv); break; case AMLOP_PROCESSOR: end = aml_eparselen(ctx); name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, (char *)name, "processor"); - if (rv != NULL) { - rv->v_processor.proc_id = aml_parse_int(ctx, 1); - rv->v_processor.proc_addr = aml_parse_int(ctx, 4); - rv->v_processor.proc_len = aml_parse_int(ctx, 1); - - lhs = aml_eparsescope(ctx, name, end, opc); + rv = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, NULL); + if (aml_valid(rv)) { + rv->v_processor.proc_id = aml_eparseint(ctx, AML_BYTE); + rv->v_processor.proc_addr = aml_eparseint(ctx, AML_DWORD); + rv->v_processor.proc_len = aml_eparseint(ctx, AML_BYTE); } + + lhs = aml_eparsescope(ctx, name, end, opc, rv); break; case AMLOP_THERMALZONE: end = aml_eparselen(ctx); name = aml_parse_name(ctx); - rv = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, (char *)name, "tzone"); - if (rv != NULL) { - lhs = aml_eparsescope(ctx, name, end, opc); - } + rv = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, NULL); + lhs = aml_eparsescope(ctx, name, end, opc, rv); break; case AMLOP_OBJECTTYPE: - lhs = aml_eparseval(ctx); - rv = aml_allocint(lhs->type,1); + lhs = aml_eparseval(ctx, 1); + rv = aml_allocint(lhs->type); break; case AMLOP_SIZEOF: - lhs = aml_eparseval(ctx); - if (lhs != NULL) { - rv = aml_allocint(lhs->length, 1); + lhs = aml_eparseval(ctx, 1); + if (aml_valid(lhs)) { + rv = aml_allocint(lhs->length); } break; case AMLOP_METHOD: end = aml_eparselen(ctx); name = aml_parse_name(ctx); - i1 = aml_parse_int(ctx, 1); - rv = aml_allocvalue(AML_OBJTYPE_METHOD, i1, (char *)name, "method"); - if (rv != NULL) { + i1 = aml_eparseint(ctx, AML_BYTE); + rv = aml_allocvalue(AML_OBJTYPE_METHOD, i1, NULL); + if (aml_valid(rv)) { /* Allocate method block */ rv->length = end - ctx->pos; rv->v_method.start = acpi_os_allocmem(rv->length); @@ -2397,31 +2493,38 @@ aml_eparseval(struct acpi_context *ctx) } break; case AMLOP_CONDREFOF: - rhs = aml_eparseval(ctx); - lhs = aml_eparseval(ctx); - rv = aml_allocint(0, 1); + rhs = aml_eparseval(ctx, 0); + lhs = aml_eparseval(ctx, 1); + rv = aml_allocint(0); if (aml_ederef(ctx, rhs) != NULL) { - tmp = aml_allocvalue(AML_OBJTYPE_OBJREF, -1, rhs, "condref"); + tmp = aml_allocvalue(AML_OBJTYPE_OBJREF, -1, rhs); aml_esetnodevalue(ctx, lhs, tmp, 0); rv->v_integer = 1; } - dnprintf(10,"condrefof: %lld\n", rv->v_integer); + dnprintf(40,"condrefof: %lld\n", rv->v_integer); break; case AMLOP_REFOF: - rhs = aml_eparseval(ctx); - lhs = aml_eparseval(ctx); - rv = aml_allocvalue(AML_OBJTYPE_OBJREF, -1, rhs, "refof"); - aml_esetnodevalue(ctx, lhs, rv, 0); + rv = aml_allocvalue(AML_OBJTYPE_OBJREF, 0, NULL); + if (aml_valid(rv)) { + rv->v_objref.ref = aml_eparseval(ctx, 0); + rv->v_objref.index = -1; + + lhs = aml_eparseval(ctx, 1); + aml_esetnodevalue(ctx, lhs, rv, 0); + } break; case AMLOP_INDEX: - rhs = aml_eparseval(ctx); - i1 = aml_eparseint(ctx); - lhs = aml_eparseval(ctx); - rv = aml_allocvalue(AML_OBJTYPE_OBJREF, i1, rhs, "index"); - aml_esetnodevalue(ctx, lhs, rv, 0); + rv = aml_allocvalue(AML_OBJTYPE_OBJREF, 0, NULL); + if (aml_valid(rv)) { + rv->v_objref.ref = aml_eparseval(ctx, 0); + rv->v_objref.index = aml_eparseint(ctx, AML_ANYINT); + + lhs = aml_eparseval(ctx, 1); + aml_esetnodevalue(ctx, lhs, rv, 0); + } break; case AMLOP_DEREFOF: - rv = aml_eparseref(ctx); + rv = aml_eparseval(ctx, 1); break; case AMLOP_LOADTABLE: rv = aml_doloadtable(ctx); @@ -2437,9 +2540,27 @@ aml_eparseval(struct acpi_context *ctx) break; default: - dnprintf(10,"Unknown opcode: %.4x %s\n", opc->opcode, opc->mnem); + dnprintf(40,"Unknown opcode: %.4x %s\n", opc->opcode, opc->mnem); break; } + if (deref && rv) { + switch (rv->type) { + case AML_OBJTYPE_FIELDUNIT: + case AML_OBJTYPE_BUFFERFIELD: + rhs = rv; + rv = aml_efield(ctx, rhs, NULL); + aml_freevalue(&rhs); + break; + case AML_OBJTYPE_OBJREF: + break; + } + } + + /* Free temp variables */ + if (rv != lhs) aml_freevalue(&lhs); + if (rv != rhs) aml_freevalue(&rhs); + if (rv != tmp) aml_freevalue(&tmp); + if (end > ctx->pos) { ctx->pos = end; } @@ -2449,7 +2570,8 @@ aml_eparseval(struct acpi_context *ctx) } /* Remove all children nodes */ -void aml_delchildren(struct acpi_context *ctx, struct aml_node *node) +void +aml_delchildren(struct acpi_context *ctx, struct aml_node *node) { struct aml_node *pn; @@ -2457,6 +2579,10 @@ void aml_delchildren(struct acpi_context *ctx, struct aml_node *node) return; } while ((pn = node->child) != NULL) { + dnprintf(40, "deleting node..\n"); + if (pn->value) { + pn->value->node = NULL; + } node->child = node->child->sibling; aml_delchildren(ctx, pn); acpi_os_freemem(pn); @@ -2464,7 +2590,8 @@ void aml_delchildren(struct acpi_context *ctx, struct aml_node *node) } /* Ok.. we have a node and hopefully its value.. call value */ -struct aml_value *aml_eparsenode(struct acpi_context *ctx, struct aml_node *node) +struct aml_value * +aml_eparsenode(struct acpi_context *ctx, struct aml_node *node) { struct aml_node *oldscope; struct aml_value *rv; @@ -2487,10 +2614,10 @@ struct aml_value *aml_eparsenode(struct acpi_context *ctx, struct aml_node *node oldscope = ctx->scope; ctx->scope = node->parent; - dnprintf(10, "Call function: %s\n", node->name); + dnprintf(40, "Call function: %s\n", node->name); ctx->pos = node->value->v_method.start; - rv = aml_eparselist(ctx, node->value->v_method.end); + rv = aml_eparselist(ctx, node->value->v_method.end, 1); /* Delete dynamic names */ aml_delchildren(ctx, node); @@ -2498,26 +2625,28 @@ struct aml_value *aml_eparsenode(struct acpi_context *ctx, struct aml_node *node ctx->scope = oldscope; return rv; default: - dnprintf(10, "Unknown node value: %d\n", node->value->type); + dnprintf(40, "Unknown node value: %d\n", node->value->type); } return NULL; } -int aml_eval_object(struct acpi_softc *sc, struct aml_node *node, - struct aml_value *ret, int argc, struct aml_value *argv) +int +aml_eval_object(struct acpi_softc *sc, struct aml_node *node, + struct aml_value *ret, int argc, struct aml_value *argv) { struct acpi_context *ctx; struct aml_value *rv; ctx = acpi_alloccontext(sc, node, argc, argv); rv = aml_eparsenode(ctx, node); + dnprintf(40, "###### RETURNING #####\n"); aml_showvalue(rv); *ret = *rv; /* XXX: must free rv */ acpi_freecontext(ctx); - return -1; + return 0; } void @@ -2667,21 +2796,19 @@ acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length) struct acpi_context *ctx; struct aml_value *rv; - stacktop = ≻ - aml_root.depth = -1; aml_root.mnem = "ROOT"; aml_root.start = start; aml_root.end = start + length; ctx = acpi_alloccontext(sc, &aml_root, 0, NULL); - rv = aml_eparselist(ctx, aml_root.end); + rv = aml_eparselist(ctx, aml_root.end, 0); aml_freevalue(&rv); acpi_freecontext(ctx); dnprintf(50, " : parsed %d AML bytes\n", length); - //aml_walktree(&aml_root); + aml_walktree(&aml_root); return (0); } diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h index 34a04715741..47dfbfae6a7 100644 --- a/sys/dev/acpi/dsdt.h +++ b/sys/dev/acpi/dsdt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.h,v 1.5 2006/02/03 23:55:47 jordan Exp $ */ +/* $OpenBSD: dsdt.h,v 1.6 2006/02/16 21:11:13 jordan Exp $ */ /* * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org> * @@ -31,12 +31,16 @@ void aml_showvalue(struct aml_value *); void aml_walktree(struct aml_node *); -struct aml_value *aml_allocint(uint64_t, int); +struct aml_value *aml_allocint(uint64_t); struct aml_value *aml_allocstr(const char *); -struct aml_value *aml_allocvalue(int, int64_t, void *, const char *); +struct aml_value *aml_allocvalue(int, int64_t, void *); struct aml_value *aml_copyvalue(const struct aml_value *); -int aml_freevalue(struct aml_value **); -int aml_comparevalue(int, const struct aml_value *, const struct aml_value *); +struct acpi_context; + +void aml_freevalue(struct aml_value **); +int aml_comparevalue(struct acpi_context *, int, struct aml_value *, struct aml_value *); + +int64_t aml_val2int(struct acpi_context *, struct aml_value *); #endif /* __DEV_ACPI_DSDT_H__ */ |