diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-01-18 22:25:45 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-01-18 22:25:45 +0000 |
commit | 692e73fadabe759f8814dda668273f20082e8cdb (patch) | |
tree | 89c64a97fd833d1871170763807e8fb15839093d | |
parent | 2c23476f87cb8e899f2d8feb5eadf61075350f7e (diff) |
Added new evaluation routines
Added helper methods for buffer/field evaluation
Fixed broken indentation on dsdt.c
ok marco@
-rw-r--r-- | sys/dev/acpi/acpi.c | 64 | ||||
-rw-r--r-- | sys/dev/acpi/acpivar.h | 8 | ||||
-rw-r--r-- | sys/dev/acpi/amltypes.h | 4 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 3296 |
4 files changed, 1933 insertions, 1439 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index e69d73c823e..c078719f397 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.20 2006/01/17 23:42:14 jordan Exp $ */ +/* $OpenBSD: acpi.c,v 1.21 2006/01/18 22:25:44 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -84,6 +84,68 @@ struct cfdriver acpi_cd = { struct acpi_softc *acpi_softc; int acpi_s5, acpi_evindex, icount; +void +acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, + int access_size, int len, void *buffer) +{ + void *pb; + bus_space_handle_t ioh; + struct acpi_mem_map mh; + + switch (iospace) { + case GAS_SYSTEM_MEMORY: + /* copy to/from system memory */ + acpi_map(address, len, &mh); + if (iodir == ACPI_IOREAD) { + memcpy(buffer, mh.va, len); + } + else { + memcpy(mh.va, buffer, len); + } + acpi_unmap(&mh); + break; + + case GAS_SYSTEM_IOSPACE: + /* read/write from I/O registers */ + pb = buffer; + bus_space_map(sc->sc_iot, address, len, 0, &ioh); + while (pb < buffer+len) { + if (iodir == ACPI_IOREAD) { + switch (access_size) { + case 1: + *(uint8_t *)pb = bus_space_read_1(sc->sc_iot, ioh, 0); + break; + case 2: + *(uint16_t *)pb = bus_space_read_2(sc->sc_iot, ioh, 0); + break; + case 4: + *(uint32_t *)pb = bus_space_read_4(sc->sc_iot, ioh, 0); + break; + } + } + else { + switch (access_size) { + case 1: + bus_space_write_1(sc->sc_iot, ioh, 0, *(uint8_t *)pb); + break; + case 2: + bus_space_write_2(sc->sc_iot, ioh, 0, *(uint16_t *)pb); + break; + case 4: + bus_space_write_4(sc->sc_iot, ioh, 0, *(uint32_t *)pb); + break; + } + } + pb += access_size; + } + bus_space_unmap(sc->sc_iot, ioh, len); + break; + + case GAS_PCI_CFG_SPACE: + break; + } +} + /* Map Power Management registers */ void acpi_map_pmregs(struct acpi_softc *sc) diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index 31abd0ded15..2c82484d7fb 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.12 2006/01/17 23:42:14 jordan Exp $ */ +/* $OpenBSD: acpivar.h,v 1.13 2006/01/18 22:25:44 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -159,6 +159,12 @@ void acpi_attach_machdep(struct acpi_softc *); int acpi_interrupt(void *); void acpi_enter_sleep_state(struct acpi_softc *, int); void acpi_powerdown(void); + +#define ACPI_IOREAD 0 +#define ACPI_IOWRITE 1 + +void acpi_gasio(struct acpi_softc *, int, int, uint64_t, int, int, void *); + #endif #endif /* !_DEV_ACPI_ACPIVAR_H_ */ diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h index 800c5cb37ed..007162e57ec 100644 --- a/sys/dev/acpi/amltypes.h +++ b/sys/dev/acpi/amltypes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amltypes.h,v 1.9 2006/01/17 23:42:14 jordan Exp $ */ +/* $OpenBSD: amltypes.h,v 1.10 2006/01/18 22:25:44 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -142,6 +142,8 @@ #define AMLOP_BREAKPOINT 0xCC #define AMLOP_ONES 0xFF +#define AMLOP_FIELDUNIT 0xFE00 + /* * Comparison types for Match() * diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index 6c00853a1f2..e97eec36d68 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.16 2006/01/17 23:42:14 jordan Exp $ */ +/* $OpenBSD: dsdt.c,v 1.17 2006/01/18 22:25:44 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -29,34 +29,34 @@ struct aml_optable { - u_int16_t opcode; - const char *mnem; - const char *args; + u_int16_t opcode; + const char *mnem; + const char *args; }; struct aml_stream { - u_int8_t *start; - u_int8_t *end; - u_int8_t *pos; + u_int8_t *start; + u_int8_t *end; + u_int8_t *pos; }; struct acpi_stack { - struct aml_value *locals; - struct aml_value *args; - struct aml_value result; - struct acpi_stack *next; + struct aml_value *locals; + struct aml_value *args; + struct aml_value result; + struct acpi_stack *next; }; struct acpi_context { - struct acpi_softc *sc; - struct acpi_stack *stack; + struct acpi_softc *sc; + struct acpi_stack *stack; - u_int8_t *start; - u_int8_t *end; - u_int8_t *pos; + u_int8_t *start; + u_int8_t *end; + u_int8_t *pos; }; #ifdef ACPI_DEBUG @@ -65,26 +65,28 @@ const char *opregion(int id); const char * opregion(int id) { - switch(id) { - case 0: return "SystemMemory"; - case 1: return "SystemIO"; - case 2: return "PCIConfig"; - case 3: return "Embedded"; - case 4: return "SMBus"; - case 5: return "CMOS"; - case 6: return "PCIBAR"; - } - return ""; + switch(id) { + case 0: return "SystemMemory"; + case 1: return "SystemIO"; + case 2: return "PCIConfig"; + case 3: return "Embedded"; + case 4: return "SMBus"; + case 5: return "CMOS"; + case 6: return "PCIBAR"; + } + return ""; } #endif +void aml_addname(const char *); + int aml_isnamedop(u_int16_t); -void aml_parsefieldlist(struct acpi_context *, struct aml_node *parent); int aml_parselength(struct acpi_context *); -const char *aml_parsename(struct acpi_context *, const char *); u_int16_t aml_getopcode(struct acpi_context *); int aml_parseargs(struct acpi_context *, struct aml_node *, const char *); +const char *aml_parsename(struct acpi_context *, const char *); +int aml_parse_fieldlist(struct acpi_context *, struct aml_node *); int aml_parse_objlist(struct acpi_context *, struct aml_node *); struct aml_node *aml_parse_object(struct acpi_context *, struct aml_node *); void aml_shownode(struct aml_node *); @@ -129,21 +131,39 @@ u_int64_t aml_parseint(struct acpi_context *, int); struct aml_value *aml_allocvalue(int, int64_t, const void *, const char *); struct aml_value *aml_copyvalue(const struct aml_value *); -void aml_freevalue(struct aml_value **); +void aml_freevalue(struct aml_value *); struct aml_value *aml_allocint(uint64_t); struct aml_value *aml_allocstr(const char *); +struct aml_node *childOf(struct aml_node *, int); + +#define aml_bitpos(n) ((n)&0x7) +#define aml_bytepos(n) ((n)>>3) +#define aml_bytelen(n) (((n)+7)>>3) +#define aml_bytealigned(x) !((x)&0x7) + +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); + +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); + +void aml_addname(const char *name) +{ +} + struct aml_value * aml_allocint(uint64_t ival) { - return aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL, "integer"); + return aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL, "integer"); } struct aml_value * aml_allocstr(const char *str) { - return aml_allocvalue(AML_OBJTYPE_STRING, strlen(str), str, "string"); + return aml_allocvalue(AML_OBJTYPE_STRING, strlen(str), str, "string"); } void *acpi_os_allocmem(size_t); @@ -154,15 +174,74 @@ struct aml_node aml_root; void * acpi_os_allocmem(size_t size) { - return malloc(size, M_DEVBUF, M_WAITOK); + return malloc(size, M_DEVBUF, M_WAITOK); } void acpi_os_freemem(void *ptr) { - free(ptr, M_DEVBUF); + free(ptr, M_DEVBUF); } +#define AML_NAMESEG_LEN 4 + +struct aml_node *_aml_searchname(struct aml_node *list, const char *name); +struct aml_node *_aml_findname(struct aml_node *root, const char *name); + +struct aml_node *_aml_searchname(struct aml_node *list, const char *name) +{ + if (list->opcode == AMLOP_FIELD || + list->opcode == AMLOP_INDEXFIELD || + list->opcode == AMLOP_BANKFIELD) { + dnprintf(50, "search field objects\n"); + list = list->child; + } + while (list != NULL) { + if (list->name && !strncmp(list->name, name, AML_NAMESEG_LEN)) { + return list; + } + } + return NULL; +} + +struct aml_node *_aml_findname(struct aml_node *root, const char *name) +{ + struct aml_node *node; + + if (root == NULL) { + root = &aml_root; + } + if (*name == AMLOP_ROOTCHAR) { + name++; + root = &aml_root; + } + while (*name == AMLOP_PARENTPREFIX) { + name++; + root = root->parent; + if (root == NULL) { + dnprintf(50, "_aml_find_node: Bad parent!!\n"); + return NULL; + } + } + + /* Ok... name is parsed.. now search all siblings of parent */ + for (node=NULL; *name && root && !node;) { + if (*name == '.') name++; + if ((node = _aml_searchname(root->child, name)) == NULL) { + /* search parent */ + root = root->parent; + } + else if (name[AML_NAMESEG_LEN] == '\0') { + /* found it */ + return node; + } + else { + root = node; + name += AML_NAMESEG_LEN; + } + } + return node; +} /* Allocate dynamic AML value * type : Type of object to allocate (AML_OBJTYPE_XXXX) @@ -174,225 +253,203 @@ struct aml_value * aml_allocvalue(int type, int64_t ival, const void *bval, const char *lbl) { - struct aml_value *rv; + struct aml_value *rv; - //printf("alloc value: %.2x : %s (%llx)\n", type, lbl, ival); + //printf("alloc value: %.2x : %s (%llx)\n", type, lbl, ival); - rv = (struct aml_value *)acpi_os_allocmem(sizeof(struct aml_value)); - memset(rv, 0, sizeof(struct aml_value)); - rv->type = type; - rv->dynamic = 1; + rv = (struct aml_value *)acpi_os_allocmem(sizeof(struct aml_value)); + memset(rv, 0, sizeof(struct aml_value)); + rv->type = type; + rv->dynamic = 1; - switch (type) { + switch (type) { #if 0 - xxx - case AML_OBJTYPE_REFOF: - rv->v_index.index = ival; - rv->v_index.refobj = bval; - break; - case AML_OBJTYPE_ERROR: - rv->v_error.error = ival; - rv->v_error.errobj = bval; - break; + xxx + case AML_OBJTYPE_REFOF: + rv->v_index.index = ival; + rv->v_index.refobj = bval; + break; + case AML_OBJTYPE_ERROR: + rv->v_error.error = ival; + rv->v_error.errobj = bval; + break; #endif - 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); - memset(rv->v_string, 0, ival+1); - 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); - memset(rv->v_buffer, 0, ival); - if (bval) { - memcpy(rv->v_buffer, bval, ival); - } - } - break; - case AML_OBJTYPE_PACKAGE: - /* Allocate package pointers */ - rv->length = ival; - rv->v_package = (struct aml_value **)acpi_os_allocmem(rv->length * sizeof(struct aml_value *)); - memset(rv->v_package, 0, rv->length * sizeof(struct aml_value *)); - break; - case AML_OBJTYPE_METHOD: - /* Allocate method stack */ - rv->v_method.locals = (struct aml_value *)acpi_os_allocmem(8 * sizeof(struct aml_value)); - rv->v_method.args = (struct aml_value *)acpi_os_allocmem(ival * sizeof(struct aml_value)); - memset(rv->v_method.locals, 0, 8 * sizeof(struct aml_value)); - memset(rv->v_method.args, 0, ival * sizeof(struct aml_value)); - break; + 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); + memset(rv->v_string, 0, ival+1); + 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); + memset(rv->v_buffer, 0, ival); + if (bval) { + memcpy(rv->v_buffer, bval, ival); + } + } + break; + case AML_OBJTYPE_PACKAGE: + /* Allocate package pointers */ + rv->length = ival; + rv->v_package = (struct aml_value **)acpi_os_allocmem(rv->length * sizeof(struct aml_value *)); + memset(rv->v_package, 0, rv->length * sizeof(struct aml_value *)); + break; + case AML_OBJTYPE_METHOD: + /* Allocate method stack */ + rv->v_method.locals = (struct aml_value *)acpi_os_allocmem(8 * sizeof(struct aml_value)); + rv->v_method.args = (struct aml_value *)acpi_os_allocmem(ival * sizeof(struct aml_value)); + memset(rv->v_method.locals, 0, 8 * sizeof(struct aml_value)); + memset(rv->v_method.args, 0, ival * sizeof(struct aml_value)); + break; #if 0 - xxx - case AML_OBJTYPE_MUTEX: - case AML_OBJTYPE_DEVICE: - case AML_OBJTYPE_EVENT: - rv->v_device = bval; - break; + xxx + case AML_OBJTYPE_DEVICE: + case AML_OBJTYPE_EVENT: + rv->v_device = bval; + break; #endif - } - return rv; -} - -void aml_freevalue(struct aml_value **pv) -{ - int idx; - struct aml_value *v = *pv; - - /* Don't free static values */ - if (v == NULL || !v->dynamic) - return; - - printf("freeing value : %x\n", v->type); - switch (v->type) { - case AML_OBJTYPE_STRING: - if (v->v_string) { - acpi_os_freemem((void *)v->v_string); - v->v_string = NULL; - } - break; - case AML_OBJTYPE_BUFFER: - if (v->v_buffer) { - acpi_os_freemem(v->v_buffer); - v->v_buffer = NULL; - } - break; - case AML_OBJTYPE_PACKAGE: - for (idx=0; idx<v->length; idx++) { - aml_freevalue(&v->v_package[idx]); - } - acpi_os_freemem(v->v_package); - break; - case AML_OBJTYPE_METHOD: - for (idx=0; idx<8; idx++) { -#if 0 - xxx - aml_freevalue(v->v_method.locals[idx]); - aml_freevalue(v->v_method.args[idx]); -#endif - } - acpi_os_freemem(v->v_method.locals); - acpi_os_freemem(v->v_method.args); - } - v->type = 0; - acpi_os_freemem(v); - *pv = 0; + case AML_OBJTYPE_MUTEX: + rv->v_integer = ival; + break; + } + return rv; } -#if 0 -xxx -void -aml_showvalue(struct aml_value *val) -{ - int idx; - - if (val == NULL) - return; - switch(val->type) { - case AML_OBJTYPE_INTEGER: - dnprintf("integer: 0x%x", val->v_integer); - break; - case AML_OBJTYPE_STRING: - dnprintf("string: %s", val->v_string); - break; - case AML_OBJTYPE_PACKAGE: - printf("package: len = %ld {\n", (unsigned long)val->length); - for(idx=0; idx<val->length; idx++) { - aml_showvalue(val->v_package[idx]); - } - printf("}\n"); - break; - case AML_OBJTYPE_BUFFER: - printf("buffer: len = %ld { ", (unsigned long)val->length); - for(idx=0; idx<val->length; idx++) { - printf("%s0x%.2x", (idx ? ", " : ""), val->v_buffer[idx]); - } - printf(" }\n"); - break; - default: - printf("xxx"); - break; - } - printf("\n"); +void aml_freevalue(struct aml_value *v) +{ + int idx; + + /* Don't free static values */ + if (v == NULL || !v->dynamic) + return; + + dnprintf(50, "freeing value : %x\n", v->type); + switch (v->type) { + case AML_OBJTYPE_STRING: + if (v->v_string) { + acpi_os_freemem((void *)v->v_string); + v->v_string = NULL; + } + break; + case AML_OBJTYPE_BUFFER: + if (v->v_buffer) { + acpi_os_freemem(v->v_buffer); + v->v_buffer = NULL; + } + break; + case AML_OBJTYPE_PACKAGE: + for (idx=0; idx<v->length; idx++) { + aml_freevalue(v->v_package[idx]); + } + acpi_os_freemem(v->v_package); + v->v_package = NULL; + break; + case AML_OBJTYPE_METHOD: + break; + } + v->type = 0; } -#endif const char * aml_parsestr(struct acpi_context *ctx) { - const char *str = ctx->pos; + const char *str = ctx->pos; - ctx->pos += strlen(str)+1; - return str; + ctx->pos += strlen(str)+1; + return str; } /* Read value from AML bytestream */ uint64_t aml_parseint(struct acpi_context *ctx, int size) { - u_int8_t *pc = ctx->pos; - - ctx->pos += size; - switch (size) { - case 1: - return *(u_int8_t *)pc; - case 2: - return *(u_int16_t *)pc; - case 4: - return *(u_int32_t *)pc; - case 8: - return *(u_int64_t *)pc; - } + u_int8_t *pc = ctx->pos; + + ctx->pos += size; + switch (size) { + case 1: + return *(u_int8_t *)pc; + case 2: + return *(u_int16_t *)pc; + case 4: + return *(u_int32_t *)pc; + case 8: + return *(u_int64_t *)pc; + } - return (0); + return (0); } void aml_setinteger(struct aml_value *val, int64_t value) { - val->type = AML_OBJTYPE_INTEGER; - val->v_integer = value; - val->length = 0; + val->type = AML_OBJTYPE_INTEGER; + val->v_integer = value; + val->length = 0; } void aml_setstring(struct aml_value *val, const char *str) { - val->type = AML_OBJTYPE_STRING; - val->length = strlen(str); - val->v_string = (char *)str; + val->type = AML_OBJTYPE_STRING; + val->length = strlen(str); + val->v_string = (char *)str; } void aml_setbuffer(struct aml_value *val, int size, u_int8_t *ptr) { - val->type = AML_OBJTYPE_STRING; - val->length = size; - val->v_buffer = ptr; + val->type = AML_OBJTYPE_STRING; + val->length = size; + val->v_buffer = ptr; } void aml_setfield(struct aml_value *val, int bitpos, int bitlen, struct aml_node *ref, struct aml_node *node) { - dnprintf(50, "setfield: pos=%.8x len=%.8x ref=%s name=%s\n", bitpos, bitlen, ref->name, node->name); - val->type = AML_OBJTYPE_FIELDUNIT; - val->length = (bitlen + 7) / 8; - val->v_field.bitpos = bitpos; - val->v_field.bitlen = bitlen; - val->v_field.ref = ref; + dnprintf(50, "setfield: pos=%.8x len=%.8x ref=%s name=%s\n", bitpos, bitlen, ref->name, node->name); + val->type = AML_OBJTYPE_FIELDUNIT; + val->length = (bitlen + 7) / 8; + val->v_field.bitpos = bitpos; + val->v_field.bitlen = bitlen; + val->v_field.ref = ref; +} + +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); + +void +aml_create_fieldunit(struct acpi_context *ctx, struct aml_node *parent, const char *name, int bitpos, int bitlen, int flags) +{ + struct aml_node *pfield; + + dnprintf(50, "create_fieldunit: name=%s pos=%.8x len=%.8x\n", name, bitpos, bitlen); + + pfield = aml_create_node(ctx, parent, AMLOP_FIELDUNIT); + pfield->name = name; + + /* Setup Field Unit object: point to OpRegion NameRef in parent field */ + pfield->value = aml_allocvalue(AML_OBJTYPE_FIELDUNIT, 0, NULL, "FieldUnit"); + if (pfield->value != NULL) { + pfield->value->v_field.flags = flags; + pfield->value->v_field.ftype = parent->opcode; + pfield->value->v_field.bitpos = bitpos; + pfield->value->v_field.bitlen = bitlen; + pfield->value->v_field.ref = childOf(parent, 0); + } } void @@ -403,10 +460,10 @@ aml_setpackage(struct aml_value *val, struct aml_node *node) void aml_setprocessor(struct aml_value *val, u_int8_t id, u_int32_t addr, u_int8_t len) { - val->type = AML_OBJTYPE_PROCESSOR; - val->v_processor.proc_id = id; - val->v_processor.proc_addr = addr; - val->v_processor.proc_len = len; + val->type = AML_OBJTYPE_PROCESSOR; + val->v_processor.proc_id = id; + val->v_processor.proc_addr = addr; + val->v_processor.proc_len = len; } /* SetOpRegion addresses @@ -418,11 +475,11 @@ aml_setprocessor(struct aml_value *val, u_int8_t id, u_int32_t addr, u_int8_t le void aml_setopregion(struct aml_value *val, int addrtype, int size, u_int64_t addr) { - dnprintf(50, "setopregion: %.2x %.4x %.8x\n", addrtype, size, addr); - val->type = AML_OBJTYPE_OPREGION; - val->v_opregion.iospace = addrtype; - val->v_opregion.iobase = addr; - val->v_opregion.iolen = size; + dnprintf(50, "setopregion: %.2x %.4x %.8x\n", addrtype, size, addr); + val->type = AML_OBJTYPE_OPREGION; + val->v_opregion.iospace = addrtype; + val->v_opregion.iobase = addr; + val->v_opregion.iolen = size; } /* Decode AML Package length @@ -435,270 +492,277 @@ aml_setopregion(struct aml_value *val, int addrtype, int size, u_int64_t addr) int aml_parselength(struct acpi_context *ctx) { - u_int8_t lcode; - int ival; + u_int8_t lcode; + int ival; - lcode = aml_parseint(ctx, 1); - if (lcode <= 0x3F) { - return lcode; - } + lcode = aml_parseint(ctx, 1); + if (lcode <= 0x3F) { + return lcode; + } - ival = lcode & 0xF; - if (lcode >= 0x40) ival |= aml_parseint(ctx, 1) << 4; - if (lcode >= 0x80) ival |= aml_parseint(ctx, 1) << 12; - if (lcode >= 0xC0) ival |= aml_parseint(ctx, 1) << 20; + ival = lcode & 0xF; + if (lcode >= 0x40) ival |= aml_parseint(ctx, 1) << 4; + if (lcode >= 0x80) ival |= aml_parseint(ctx, 1) << 12; + if (lcode >= 0xC0) ival |= aml_parseint(ctx, 1) << 20; - return ival; + return ival; } -void -aml_parsefieldlist(struct acpi_context *ctx, struct aml_node *node) -{ - u_int8_t type, attr; - int len, start; - struct aml_node *pf; - - start = 0; - dnprintf(50, "-- parsefield\n"); - while (ctx->pos < node->end) { - switch (aml_parseint(ctx, 1)) { - case 0x00: /* reserved */ - len = aml_parselength(ctx); - start += len; - break; - case 0x01: /* access field */ - type = aml_parseint(ctx, 1); - attr = aml_parseint(ctx, 1); - dnprintf(50, " type=%.2x attr=%.2x\n", type, attr); - break; - default: /* named field */ - --ctx->pos; - pf = aml_create_node(ctx, node, AMLOP_CREATEFIELD); - pf->name = aml_parsename(ctx, "field"); - len = aml_parselength(ctx); - - //aml_setfield(pf->value, start, len, node, pf); - start += len; - } - } +int +aml_parse_fieldlist(struct acpi_context *ctx, struct aml_node *parent) +{ + u_int8_t type, attr; + int bitpos, bitlen; + const char *name; + + bitpos = 0; + attr = 0; + type = AML_FIELD_ACCESS(parent->flag); + + dnprintf(50, "-- parse_fieldlist\n"); + while (ctx->pos < parent->end) { + bitlen = 0; + switch (aml_parseint(ctx, 1)) { + case 0x00: /* reserved */ + bitlen = aml_parselength(ctx); + break; + case 0x01: /* access field */ + type = aml_parseint(ctx, 1); + attr = aml_parseint(ctx, 1); + dnprintf(50, " type=%.2x attr=%.2x\n", type, attr); + break; + default: /* named field */ + --ctx->pos; + name = aml_parsename(ctx, "field"); + bitlen = aml_parselength(ctx); + aml_create_fieldunit(ctx, parent, name, bitpos, bitlen, (attr<<8) | type); + } + bitpos += bitlen; + } + if (ctx->pos != parent->end) { + dnprintf(50, "parse_fieldlist: invalid end!\n"); + ctx->pos = parent->end; + return (1); + } + return (0); } /* Decode AML Namestring from stream */ const char * aml_parsename(struct acpi_context *ctx, const char *lbl) { - int count, pfxlen; - char *name, *pn; - u_int8_t *base; - - pfxlen = 0; - if (ctx->pos[pfxlen] == AMLOP_ROOTCHAR) { - pfxlen++; - } - while (ctx->pos[pfxlen] == AMLOP_PARENTPREFIX) { - pfxlen++; - } - - switch (ctx->pos[pfxlen]) { - case 0x00: - count = 0; - base = ctx->pos + pfxlen + 1; - break; - case AMLOP_MULTINAMEPREFIX: - count = ctx->pos[pfxlen+1]; - base = ctx->pos + pfxlen + 2; - break; - case AMLOP_DUALNAMEPREFIX: - count = 2; - base = ctx->pos + pfxlen + 1; - break; - default: - count = 1; - base = ctx->pos + pfxlen; - break; - } - - name = acpi_os_allocmem(pfxlen + count * 5); - pn = name; - - while (pfxlen--) - *(pn++) = *(ctx->pos++); + int count, pfxlen; + char *name, *pn; + u_int8_t *base; + + pfxlen = 0; + if (ctx->pos[pfxlen] == AMLOP_ROOTCHAR) { + pfxlen++; + } + while (ctx->pos[pfxlen] == AMLOP_PARENTPREFIX) { + pfxlen++; + } + + switch (ctx->pos[pfxlen]) { + case 0x00: + count = 0; + base = ctx->pos + pfxlen + 1; + break; + case AMLOP_MULTINAMEPREFIX: + count = ctx->pos[pfxlen+1]; + base = ctx->pos + pfxlen + 2; + break; + case AMLOP_DUALNAMEPREFIX: + count = 2; + base = ctx->pos + pfxlen + 1; + break; + default: + count = 1; + base = ctx->pos + pfxlen; + break; + } + + name = acpi_os_allocmem(pfxlen + count * 5); + pn = name; + + while (pfxlen--) + *(pn++) = *(ctx->pos++); - /* Copy name segments in chunks of 4 bytes */ - while (count--) { - memcpy(pn, base, 4); - if (count) { - *(pn + 4) = '.'; - pn++; - } - pn += 4; - base += 4; - } - *pn = 0; + /* Copy name segments in chunks of 4 bytes */ + while (count--) { + memcpy(pn, base, 4); + if (count) { + *(pn + 4) = '.'; + pn++; + } + pn += 4; + base += 4; + } + *pn = 0; - dnprintf(50, " acpi_name (%s): %s\n", lbl, name); + dnprintf(50, " acpi_name (%s): %s\n", lbl, name); - ctx->pos = base; + ctx->pos = base; - return name; + return name; } /* Is this opcode an encoded name? */ int aml_isnamedop(u_int16_t opcode) { - switch (opcode) { - case AMLOP_ROOTCHAR: - case AMLOP_PARENTPREFIX: - case AMLOP_MULTINAMEPREFIX: - case AMLOP_DUALNAMEPREFIX: - case AMLOP_NAMECHAR: - return (1); - } + switch (opcode) { + case AMLOP_ROOTCHAR: + case AMLOP_PARENTPREFIX: + case AMLOP_MULTINAMEPREFIX: + case AMLOP_DUALNAMEPREFIX: + case AMLOP_NAMECHAR: + return (1); + } - if (opcode >= 'A' && opcode <= 'Z') - return (1); + if (opcode >= 'A' && opcode <= 'Z') + return (1); - return (0); + return (0); } u_int64_t aml_bcd2dec(u_int64_t val) { - u_int64_t rval; - int n,pos; + u_int64_t rval; + int n,pos; - pos=1; - for (rval=0; val; val >>= 4) { - n = (val & 0xF); - if (n > 9) - return (0); + pos=1; + for (rval=0; val; val >>= 4) { + n = (val & 0xF); + if (n > 9) + return (0); - rval += (n * pos); - pos *= 10; - } - return rval; + rval += (n * pos); + pos *= 10; + } + return rval; } u_int64_t aml_dec2bcd(u_int64_t val) { - u_int64_t rval; - int n,pos; + u_int64_t rval; + int n,pos; - pos=0; - for (rval=0; val; val /= 10) { - n = (val % 10); + pos=0; + for (rval=0; val; val /= 10) { + n = (val % 10); - rval += (n << pos); - pos += 4; - } - return rval; + rval += (n << pos); + pos += 4; + } + return rval; } /* Calculate LSB */ int aml_lsb(u_int32_t val) { - int n = 31; - - if (!val) return -1; - if (val & 0x0000FFFF) { val <<= 16; n -= 16; }; - if (val & 0x00FF0000) { val <<= 8; n -= 8; }; - if (val & 0x0F000000) { val <<= 4; n -= 4; }; - if (val & 0x30000000) { val <<= 2; n -= 2; }; - return (val & 0x40000000) ? n-1 : n; + int n = 31; + + if (!val) return -1; + if (val & 0x0000FFFF) { val <<= 16; n -= 16; }; + if (val & 0x00FF0000) { val <<= 8; n -= 8; }; + if (val & 0x0F000000) { val <<= 4; n -= 4; }; + if (val & 0x30000000) { val <<= 2; n -= 2; }; + return (val & 0x40000000) ? n-1 : n; } /* Calculate MSB */ int aml_msb(u_int32_t val) { - int n=0; - - if (!val) return -1; - if (val & 0xFFFF0000) { val >>= 16; n += 16; }; - if (val & 0x0000FF00) { val >>= 8; n += 8; }; - if (val & 0x000000F0) { val >>= 4; n += 4; }; - if (val & 0x0000000C) { val >>= 2; n += 2; }; - return (val & 0x00000002) ? n+1 : n; + int n=0; + + if (!val) return -1; + if (val & 0xFFFF0000) { val >>= 16; n += 16; }; + if (val & 0x0000FF00) { val >>= 8; n += 8; }; + if (val & 0x000000F0) { val >>= 4; n += 4; }; + if (val & 0x0000000C) { val >>= 2; n += 2; }; + return (val & 0x00000002) ? n+1 : n; } /* Evaluate Math operands */ int64_t aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs) { - switch (opcode) { - case AMLOP_ADD: - return (lhs + rhs); - case AMLOP_SUBTRACT: - return (lhs - rhs); - case AMLOP_MULTIPLY: - return (lhs * rhs); - case AMLOP_DIVIDE: - return (lhs / rhs); - case AMLOP_MOD: - return (lhs % rhs); - case AMLOP_SHL: - return (lhs << rhs); - case AMLOP_SHR: - return (lhs >> rhs); - case AMLOP_AND: - return (lhs & rhs); - case AMLOP_NAND: - return ~(lhs & rhs); - case AMLOP_OR: - return (lhs | rhs); - case AMLOP_NOR: - return ~(lhs | rhs); - case AMLOP_XOR: - return (lhs ^ rhs); - case AMLOP_INCREMENT: - return (lhs + 1); - case AMLOP_DECREMENT: - return (lhs - 1); - case AMLOP_FINDSETLEFTBIT: - return aml_msb(lhs); - case AMLOP_FINDSETRIGHTBIT: - return aml_lsb(lhs); - case AMLOP_NOT: - return ~(lhs); - } - - return (0); + switch (opcode) { + case AMLOP_ADD: + return (lhs + rhs); + case AMLOP_SUBTRACT: + return (lhs - rhs); + case AMLOP_MULTIPLY: + return (lhs * rhs); + case AMLOP_DIVIDE: + return (lhs / rhs); + case AMLOP_MOD: + return (lhs % rhs); + case AMLOP_SHL: + return (lhs << rhs); + case AMLOP_SHR: + return (lhs >> rhs); + case AMLOP_AND: + return (lhs & rhs); + case AMLOP_NAND: + return ~(lhs & rhs); + case AMLOP_OR: + return (lhs | rhs); + case AMLOP_NOR: + return ~(lhs | rhs); + case AMLOP_XOR: + return (lhs ^ rhs); + case AMLOP_INCREMENT: + return (lhs + 1); + case AMLOP_DECREMENT: + return (lhs - 1); + case AMLOP_FINDSETLEFTBIT: + return aml_msb(lhs); + case AMLOP_FINDSETRIGHTBIT: + return aml_lsb(lhs); + case AMLOP_NOT: + return ~(lhs); + } + + return (0); } int aml_strcmp(u_int16_t opcode, const char *lhs, const char *rhs) { - return (0); + return (0); } /* Evaluate logical test operands */ int aml_testlogical(u_int16_t opcode, long lhs, long rhs) { - switch(opcode) { - case AMLOP_LAND: - return (lhs && rhs); - case AMLOP_LOR: - return (lhs || rhs); - case AMLOP_LNOT: - return (!lhs); - case AMLOP_LNOTEQUAL: - return (lhs != rhs); - case AMLOP_LLESSEQUAL: - return (lhs <= rhs); - case AMLOP_LGREATEREQUAL: - return (lhs >= rhs); - case AMLOP_LEQUAL: - return (lhs == rhs); - case AMLOP_LGREATER: - return (lhs > rhs); - case AMLOP_LLESS: - return (lhs < rhs); - } - return 0; + switch(opcode) { + case AMLOP_LAND: + return (lhs && rhs); + case AMLOP_LOR: + return (lhs || rhs); + case AMLOP_LNOT: + return (!lhs); + case AMLOP_LNOTEQUAL: + return (lhs != rhs); + case AMLOP_LLESSEQUAL: + return (lhs <= rhs); + case AMLOP_LGREATEREQUAL: + return (lhs >= rhs); + case AMLOP_LEQUAL: + return (lhs == rhs); + case AMLOP_LGREATER: + return (lhs > rhs); + case AMLOP_LLESS: + return (lhs < rhs); + } + return 0; } /* Extract opcode from AML bytestream @@ -709,165 +773,165 @@ aml_testlogical(u_int16_t opcode, long lhs, long rhs) u_int16_t aml_getopcode(struct acpi_context *ctx) { - u_int16_t twocode; - u_int16_t opcode; + u_int16_t twocode; + u_int16_t opcode; - /* Check for encoded name */ - if (aml_isnamedop(*ctx->pos)) { - return AMLOP_NAMECHAR; - } + /* Check for encoded name */ + if (aml_isnamedop(*ctx->pos)) { + return AMLOP_NAMECHAR; + } - opcode = aml_parseint(ctx, 1); - twocode = (opcode << 8L) + *ctx->pos; + opcode = aml_parseint(ctx, 1); + twocode = (opcode << 8L) + *ctx->pos; - /* Check multi-byte opcodes */ - if (twocode == AMLOP_LNOTEQUAL || - twocode == AMLOP_LLESSEQUAL || - twocode == AMLOP_LGREATEREQUAL || - opcode == AMLOP_EXTPREFIX) { - ctx->pos++; - return twocode; - } + /* Check multi-byte opcodes */ + if (twocode == AMLOP_LNOTEQUAL || + twocode == AMLOP_LLESSEQUAL || + twocode == AMLOP_LGREATEREQUAL || + opcode == AMLOP_EXTPREFIX) { + ctx->pos++; + return twocode; + } - return opcode; + return opcode; } struct aml_optable aml_table[] = { - /* Simple types */ - { AMLOP_ZERO, "Zero", "!" }, - { AMLOP_ONE, "One", "!" }, - { AMLOP_ONES, "Ones", "!" }, - { AMLOP_BYTEPREFIX, "Byte", "b" }, - { AMLOP_WORDPREFIX, "Word", "w" }, - { AMLOP_DWORDPREFIX, "DWord", "d" }, - { AMLOP_QWORDPREFIX, "QWord", "q" }, - { AMLOP_REVISION, "Revision", "" }, - { AMLOP_STRINGPREFIX, "String", "s" }, - { AMLOP_DEBUG, "DebugOp", "", }, - { AMLOP_BUFFER, "Buffer", "piB" }, - { AMLOP_PACKAGE, "Package", "pbT" }, - { AMLOP_VARPACKAGE, "VarPackage", "piT" }, - - /* Simple objects */ - { AMLOP_LOCAL0, "Local0", "", }, - { AMLOP_LOCAL1, "Local1", "", }, - { AMLOP_LOCAL2, "Local2", "", }, - { AMLOP_LOCAL3, "Local3", "", }, - { AMLOP_LOCAL4, "Local4", "", }, - { AMLOP_LOCAL5, "Local5", "", }, - { AMLOP_LOCAL6, "Local6", "", }, - { AMLOP_LOCAL7, "Local7", "", }, - { AMLOP_ARG0, "Arg0", "", }, - { AMLOP_ARG1, "Arg1", "", }, - { AMLOP_ARG2, "Arg2", "", }, - { AMLOP_ARG3, "Arg3", "", }, - { AMLOP_ARG4, "Arg4", "", }, - { AMLOP_ARG5, "Arg5", "", }, - { AMLOP_ARG6, "Arg6", "", }, - - /* Control flow */ - { AMLOP_IF, "If", "piT", }, - { AMLOP_ELSE, "Else", "pT", }, - { AMLOP_WHILE, "While", "piT", }, - { AMLOP_BREAK, "Break", "", }, - { AMLOP_CONTINUE, "Continue", "", }, - { AMLOP_RETURN, "Return", "t", }, - { AMLOP_FATAL, "Fatal", "bdi", }, - { AMLOP_NOP, "Nop", "", }, - { AMLOP_BREAKPOINT, "BreakPoint", "", }, - - /* Arithmetic operations */ - { AMLOP_INCREMENT, "Increment", "t", }, - { AMLOP_DECREMENT, "Decrement", "t", }, - { AMLOP_ADD, "Add", "iit", }, - { AMLOP_SUBTRACT, "Subtract", "iit", }, - { AMLOP_MULTIPLY, "Multiply", "iit", }, - { AMLOP_DIVIDE, "Divide", "iitt", }, - { AMLOP_SHL, "ShiftLeft", "iit", }, - { AMLOP_SHR, "ShiftRight", "iit", }, - { AMLOP_AND, "And", "iit", }, - { AMLOP_NAND, "Nand", "iit", }, - { AMLOP_OR, "Or", "iit", }, - { AMLOP_NOR, "Nor", "iit", }, - { AMLOP_XOR, "Xor", "iit", }, - { AMLOP_NOT, "Not", "it", }, - { AMLOP_MOD, "Mod", "iit", }, - { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "it", }, - { AMLOP_FINDSETRIGHTBIT, "FindSetRightBit", "it", }, - - /* Logical test operations */ - { AMLOP_LAND, "LAnd", "ii", }, - { AMLOP_LOR, "LOr", "ii", }, - { AMLOP_LNOT, "LNot", "i", }, - { AMLOP_LNOTEQUAL, "LNotEqual", "tt", }, - { AMLOP_LLESSEQUAL, "LLessEqual", "tt", }, - { AMLOP_LGREATEREQUAL, "LGreaterEqual", "tt", }, - { AMLOP_LEQUAL, "LEqual", "tt", }, - { AMLOP_LGREATER, "LGreater", "tt", }, - { AMLOP_LLESS, "LLess", "tt", }, - - /* Named objects */ - { AMLOP_NAMECHAR, "NameRef", "n" }, - { AMLOP_ALIAS, "Alias", "nN", }, - { AMLOP_NAME, "Name", "Nt", }, - { AMLOP_EVENT, "Event", "N", }, - { AMLOP_MUTEX, "Mutex", "Nb", }, - { AMLOP_DATAREGION, "DataRegion", "Nttt" }, - { AMLOP_OPREGION, "OpRegion", "Nbii" }, - { AMLOP_SCOPE, "Scope", "pNT" }, - { AMLOP_DEVICE, "Device", "pNT" }, - { AMLOP_POWERRSRC, "Power Resource", "pNbwT" }, - { AMLOP_THERMALZONE, "ThermalZone", "pNT" }, - { AMLOP_PROCESSOR, "Processor", "pNbdbT", }, - { AMLOP_METHOD, "Method", "pNfM", }, - - /* Field operations */ - { AMLOP_FIELD, "Field", "pnfF" }, - { AMLOP_INDEXFIELD, "IndexField", "pntfF" }, - { AMLOP_BANKFIELD, "BankField", "pnnifF" }, - { AMLOP_CREATEFIELD, "CreateField", "tiiN", }, - { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN", }, - { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN", }, - { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN", }, - { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN", }, - { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", }, - - /* Conversion operations */ - { AMLOP_TOINTEGER, "ToInteger", "tt", }, - { AMLOP_TOBUFFER, "ToBuffer", "tt", }, - { AMLOP_TODECSTRING, "ToDecString", "it", }, - { AMLOP_TOHEXSTRING, "ToHexString", "it", }, - { AMLOP_TOSTRING, "ToString", "t", }, - { AMLOP_FROMBCD, "FromBCD", "it", }, - { AMLOP_TOBCD, "ToBCD", "it", }, - { AMLOP_MID, "Mid", "tiit", }, - - /* Mutex/Signal operations */ - { AMLOP_ACQUIRE, "Acquire", "tw", }, - { AMLOP_RELEASE, "Release", "t", }, - { AMLOP_SIGNAL, "Signal", "t", }, - { AMLOP_WAIT, "Wait", "ti", }, - { AMLOP_RESET, "Reset", "t", }, + /* Simple types */ + { AMLOP_ZERO, "Zero", "!" }, + { AMLOP_ONE, "One", "!" }, + { AMLOP_ONES, "Ones", "!" }, + { AMLOP_BYTEPREFIX, "Byte", "b" }, + { AMLOP_WORDPREFIX, "Word", "w" }, + { AMLOP_DWORDPREFIX, "DWord", "d" }, + { AMLOP_QWORDPREFIX, "QWord", "q" }, + { AMLOP_REVISION, "Revision", "" }, + { AMLOP_STRINGPREFIX, "String", "s" }, + { AMLOP_DEBUG, "DebugOp", "", }, + { AMLOP_BUFFER, "Buffer", "piB" }, + { AMLOP_PACKAGE, "Package", "pbT" }, + { AMLOP_VARPACKAGE, "VarPackage", "piT" }, + + /* Simple objects */ + { AMLOP_LOCAL0, "Local0", "", }, + { AMLOP_LOCAL1, "Local1", "", }, + { AMLOP_LOCAL2, "Local2", "", }, + { AMLOP_LOCAL3, "Local3", "", }, + { AMLOP_LOCAL4, "Local4", "", }, + { AMLOP_LOCAL5, "Local5", "", }, + { AMLOP_LOCAL6, "Local6", "", }, + { AMLOP_LOCAL7, "Local7", "", }, + { AMLOP_ARG0, "Arg0", "", }, + { AMLOP_ARG1, "Arg1", "", }, + { AMLOP_ARG2, "Arg2", "", }, + { AMLOP_ARG3, "Arg3", "", }, + { AMLOP_ARG4, "Arg4", "", }, + { AMLOP_ARG5, "Arg5", "", }, + { AMLOP_ARG6, "Arg6", "", }, + + /* Control flow */ + { AMLOP_IF, "If", "piT", }, + { AMLOP_ELSE, "Else", "pT", }, + { AMLOP_WHILE, "While", "piT", }, + { AMLOP_BREAK, "Break", "", }, + { AMLOP_CONTINUE, "Continue", "", }, + { AMLOP_RETURN, "Return", "t", }, + { AMLOP_FATAL, "Fatal", "bdi", }, + { AMLOP_NOP, "Nop", "", }, + { AMLOP_BREAKPOINT, "BreakPoint", "", }, + + /* Arithmetic operations */ + { AMLOP_INCREMENT, "Increment", "t", }, + { AMLOP_DECREMENT, "Decrement", "t", }, + { AMLOP_ADD, "Add", "iit", }, + { AMLOP_SUBTRACT, "Subtract", "iit", }, + { AMLOP_MULTIPLY, "Multiply", "iit", }, + { AMLOP_DIVIDE, "Divide", "iitt", }, + { AMLOP_SHL, "ShiftLeft", "iit", }, + { AMLOP_SHR, "ShiftRight", "iit", }, + { AMLOP_AND, "And", "iit", }, + { AMLOP_NAND, "Nand", "iit", }, + { AMLOP_OR, "Or", "iit", }, + { AMLOP_NOR, "Nor", "iit", }, + { AMLOP_XOR, "Xor", "iit", }, + { AMLOP_NOT, "Not", "it", }, + { AMLOP_MOD, "Mod", "iit", }, + { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "it", }, + { AMLOP_FINDSETRIGHTBIT, "FindSetRightBit", "it", }, + + /* Logical test operations */ + { AMLOP_LAND, "LAnd", "ii", }, + { AMLOP_LOR, "LOr", "ii", }, + { AMLOP_LNOT, "LNot", "i", }, + { AMLOP_LNOTEQUAL, "LNotEqual", "tt", }, + { AMLOP_LLESSEQUAL, "LLessEqual", "tt", }, + { AMLOP_LGREATEREQUAL, "LGreaterEqual", "tt", }, + { AMLOP_LEQUAL, "LEqual", "tt", }, + { AMLOP_LGREATER, "LGreater", "tt", }, + { AMLOP_LLESS, "LLess", "tt", }, + + /* Named objects */ + { AMLOP_NAMECHAR, "NameRef", "n" }, + { AMLOP_ALIAS, "Alias", "nN", }, + { AMLOP_NAME, "Name", "Nt", }, + { AMLOP_EVENT, "Event", "N", }, + { AMLOP_MUTEX, "Mutex", "Nb", }, + { AMLOP_DATAREGION, "DataRegion", "Nttt" }, + { AMLOP_OPREGION, "OpRegion", "Nbii" }, + { AMLOP_SCOPE, "Scope", "pNT" }, + { AMLOP_DEVICE, "Device", "pNT" }, + { AMLOP_POWERRSRC, "Power Resource", "pNbwT" }, + { AMLOP_THERMALZONE, "ThermalZone", "pNT" }, + { AMLOP_PROCESSOR, "Processor", "pNbdbT", }, + { AMLOP_METHOD, "Method", "pNfM", }, + + /* Field operations */ + { AMLOP_FIELD, "Field", "pnfF" }, + { AMLOP_INDEXFIELD, "IndexField", "pntfF" }, + { AMLOP_BANKFIELD, "BankField", "pnnifF" }, + { AMLOP_CREATEFIELD, "CreateField", "tiiN", }, + { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN", }, + { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN", }, + { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN", }, + { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN", }, + { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", }, + + /* Conversion operations */ + { AMLOP_TOINTEGER, "ToInteger", "tt", }, + { AMLOP_TOBUFFER, "ToBuffer", "tt", }, + { AMLOP_TODECSTRING, "ToDecString", "it", }, + { AMLOP_TOHEXSTRING, "ToHexString", "it", }, + { AMLOP_TOSTRING, "ToString", "t", }, + { AMLOP_FROMBCD, "FromBCD", "it", }, + { AMLOP_TOBCD, "ToBCD", "it", }, + { AMLOP_MID, "Mid", "tiit", }, + + /* Mutex/Signal operations */ + { AMLOP_ACQUIRE, "Acquire", "tw", }, + { AMLOP_RELEASE, "Release", "t", }, + { AMLOP_SIGNAL, "Signal", "t", }, + { AMLOP_WAIT, "Wait", "ti", }, + { AMLOP_RESET, "Reset", "t", }, - { AMLOP_INDEX, "Index", "tit", }, - { AMLOP_DEREFOF, "DerefOf", "t", }, - { AMLOP_REFOF, "RefOf", "t", }, - { AMLOP_CONDREFOF, "CondRef", "tt", }, - - { AMLOP_LOADTABLE, "LoadTable", "tttttt" }, - { AMLOP_STALL, "Stall", "i", }, - { AMLOP_SLEEP, "Sleep", "i", }, - { AMLOP_LOAD, "Load", "nt" }, - { AMLOP_UNLOAD, "Unload", "t" }, - { AMLOP_STORE, "Store", "tt", }, - { AMLOP_CONCAT, "Concat", "ttt" }, - { AMLOP_CONCATRES, "ConcatRes", "ttt" }, - { AMLOP_NOTIFY, "Notify", "ti" }, - { AMLOP_SIZEOF, "Sizeof", "t", }, - { AMLOP_MATCH, "Match", "tbibii", }, - { AMLOP_OBJECTTYPE, "ObjectType", "t", }, - { AMLOP_COPYOBJECT, "CopyObject", "tt" }, - { 0xFFFF } + { AMLOP_INDEX, "Index", "tit", }, + { AMLOP_DEREFOF, "DerefOf", "t", }, + { AMLOP_REFOF, "RefOf", "t", }, + { AMLOP_CONDREFOF, "CondRef", "tt", }, + + { AMLOP_LOADTABLE, "LoadTable", "tttttt" }, + { AMLOP_STALL, "Stall", "i", }, + { AMLOP_SLEEP, "Sleep", "i", }, + { AMLOP_LOAD, "Load", "nt" }, + { AMLOP_UNLOAD, "Unload", "t" }, + { AMLOP_STORE, "Store", "tt", }, + { AMLOP_CONCAT, "Concat", "ttt" }, + { AMLOP_CONCATRES, "ConcatRes", "ttt" }, + { AMLOP_NOTIFY, "Notify", "ti" }, + { AMLOP_SIZEOF, "Sizeof", "t", }, + { AMLOP_MATCH, "Match", "tbibii", }, + { AMLOP_OBJECTTYPE, "ObjectType", "t", }, + { AMLOP_COPYOBJECT, "CopyObject", "tt" }, + { 0xFFFF } }; #if 0 @@ -875,37 +939,35 @@ xxx /* Copy an AML value object */ void aml_copyvalue(struct aml_value *dst, const struct aml_value *src) { - dst->type = src->type; - dst->length = src->length; - - switch (dst->type) { - case AML_OBJTYPE_INTEGER: - dst->v_integer = src->v_integer; - break; - case AML_OBJTYPE_STRING: - dst->v_string = src->v_string; - break; - case AML_OBJTYPE_BUFFER: - dst->v_buffer = src->v_buffer; - break; - case AML_OBJTYPE_PACKAGE: - dst->v_package = src->v_package; - break; - } + dst->type = src->type; + dst->length = src->length; + + switch (dst->type) { + case AML_OBJTYPE_INTEGER: + dst->v_integer = src->v_integer; + break; + case AML_OBJTYPE_STRING: + dst->v_string = src->v_string; + break; + case AML_OBJTYPE_BUFFER: + dst->v_buffer = src->v_buffer; + break; + case AML_OBJTYPE_PACKAGE: + dst->v_package = src->v_package; + break; + } } #endif -struct aml_node *childOf(struct aml_node *, int); - struct aml_node * childOf(struct aml_node *parent, int child) { - struct aml_node *node = parent->child; + struct aml_node *node = parent->child; - while(node && child--) { - node = node->sibling; - } - return node; + while(node && child--) { + node = node->sibling; + } + return node; } #define AML_NUM_LOCALS 8 @@ -917,917 +979,1279 @@ struct aml_value * aml_getnodevalue(struct acpi_softc *sc, struct aml_node *node, struct aml_value *env) { - int id; - - if (node == NULL) { - printf("aml_getnodevalue: null\n"); - return NULL; - } - switch (node->opcode) { - case AMLOP_DEBUG: - return &aml_debugobj; - - case AMLOP_LOCAL0: - case AMLOP_LOCAL1: - case AMLOP_LOCAL2: - case AMLOP_LOCAL3: - case AMLOP_LOCAL4: - case AMLOP_LOCAL5: - case AMLOP_LOCAL6: - case AMLOP_LOCAL7: - id = node->opcode - AMLOP_LOCAL0; - return &env->v_method.locals[id]; - - case AMLOP_ARG0: - case AMLOP_ARG1: - case AMLOP_ARG2: - case AMLOP_ARG3: - case AMLOP_ARG4: - case AMLOP_ARG5: - case AMLOP_ARG6: - id = node->opcode - AMLOP_ARG0; - return &env->v_method.args[id]; - - case AMLOP_ZERO: - case AMLOP_ONE: - case AMLOP_ONES: - case AMLOP_BYTEPREFIX: - case AMLOP_WORDPREFIX: - case AMLOP_DWORDPREFIX: - case AMLOP_QWORDPREFIX: - case AMLOP_STRINGPREFIX: - return node->value; - - default: - printf("aml_getnodevalue: no type: %.4x\n", node->opcode); - break; - } - return NULL; + int id; + + if (node == NULL) { + printf("aml_getnodevalue: null\n"); + return NULL; + } + switch (node->opcode) { + case AMLOP_DEBUG: + return &aml_debugobj; + + case AMLOP_LOCAL0: + case AMLOP_LOCAL1: + case AMLOP_LOCAL2: + case AMLOP_LOCAL3: + case AMLOP_LOCAL4: + case AMLOP_LOCAL5: + case AMLOP_LOCAL6: + case AMLOP_LOCAL7: + id = node->opcode - AMLOP_LOCAL0; + return &env->v_method.locals[id]; + + case AMLOP_ARG0: + case AMLOP_ARG1: + case AMLOP_ARG2: + case AMLOP_ARG3: + case AMLOP_ARG4: + case AMLOP_ARG5: + case AMLOP_ARG6: + id = node->opcode - AMLOP_ARG0; + return &env->v_method.args[id]; + + case AMLOP_ZERO: + case AMLOP_ONE: + case AMLOP_ONES: + case AMLOP_BYTEPREFIX: + case AMLOP_WORDPREFIX: + case AMLOP_DWORDPREFIX: + case AMLOP_QWORDPREFIX: + case AMLOP_STRINGPREFIX: + return node->value; + + default: + printf("aml_getnodevalue: no type: %.4x\n", node->opcode); + break; + } + return NULL; } void aml_setnodevalue(struct acpi_softc *sc, struct aml_node *node, const struct aml_value *val, struct aml_value *env) { - struct aml_value *dest = NULL; - struct aml_value lhs; - int id; - - if (node == NULL) { - printf("aml_setnodevalue: null\n"); - return; - } - dnprintf(50, "--- setnodevalue:\n"); - aml_shownode(node); - aml_showvalue((struct aml_value *)val); - switch (node->opcode) { - case AMLOP_DEBUG: - dest = &aml_debugobj; - break; - - case AMLOP_LOCAL0: - case AMLOP_LOCAL1: - case AMLOP_LOCAL2: - case AMLOP_LOCAL3: - case AMLOP_LOCAL4: - case AMLOP_LOCAL5: - case AMLOP_LOCAL6: - case AMLOP_LOCAL7: - id = node->opcode - AMLOP_LOCAL0; - dest = &env->v_method.locals[id]; - break; - - case AMLOP_ARG0: - case AMLOP_ARG1: - case AMLOP_ARG2: - case AMLOP_ARG3: - case AMLOP_ARG4: - case AMLOP_ARG5: - case AMLOP_ARG6: - id = node->opcode - AMLOP_ARG0; - dest = &env->v_method.args[id]; - break; - - case AMLOP_NAMECHAR: - return aml_setnodevalue(sc, aml_find_name(sc, NULL, node->name), val, env); - - case AMLOP_CREATEFIELD: - case AMLOP_CREATEBITFIELD: - case AMLOP_CREATEBYTEFIELD: - case AMLOP_CREATEWORDFIELD: - case AMLOP_CREATEDWORDFIELD: - case AMLOP_CREATEQWORDFIELD: - aml_eval_object(sc, node, &lhs, env); - aml_showvalue(&lhs); - for(;;); - break; - - case AMLOP_ZERO: - case AMLOP_ONE: - case AMLOP_ONES: - case AMLOP_REVISION: - case AMLOP_BYTEPREFIX: - case AMLOP_WORDPREFIX: - case AMLOP_DWORDPREFIX: - case AMLOP_QWORDPREFIX: - default: - printf("aml_setnodeval: read-only %.4x\n", node->opcode); - break; - } - if (dest) { - dnprintf(50, "aml_setnodeval: %.4x\n", node->opcode); + struct aml_value *dest = NULL; + struct aml_value lhs; + int id; + + if (node == NULL) { + printf("aml_setnodevalue: null\n"); + return; + } + dnprintf(50, "--- setnodevalue:\n"); + aml_shownode(node); + aml_showvalue((struct aml_value *)val); + switch (node->opcode) { + case AMLOP_DEBUG: + dest = &aml_debugobj; + break; + + case AMLOP_LOCAL0: + case AMLOP_LOCAL1: + case AMLOP_LOCAL2: + case AMLOP_LOCAL3: + case AMLOP_LOCAL4: + case AMLOP_LOCAL5: + case AMLOP_LOCAL6: + case AMLOP_LOCAL7: + id = node->opcode - AMLOP_LOCAL0; + dest = &env->v_method.locals[id]; + break; + + case AMLOP_ARG0: + case AMLOP_ARG1: + case AMLOP_ARG2: + case AMLOP_ARG3: + case AMLOP_ARG4: + case AMLOP_ARG5: + case AMLOP_ARG6: + id = node->opcode - AMLOP_ARG0; + dest = &env->v_method.args[id]; + break; + + case AMLOP_NAMECHAR: + return aml_setnodevalue(sc, aml_find_name(sc, NULL, node->name), val, env); + + case AMLOP_CREATEFIELD: + case AMLOP_CREATEBITFIELD: + case AMLOP_CREATEBYTEFIELD: + case AMLOP_CREATEWORDFIELD: + case AMLOP_CREATEDWORDFIELD: + case AMLOP_CREATEQWORDFIELD: + aml_eval_object(sc, node, &lhs, env); + aml_showvalue(&lhs); + for(;;); + break; + + case AMLOP_ZERO: + case AMLOP_ONE: + case AMLOP_ONES: + case AMLOP_REVISION: + case AMLOP_BYTEPREFIX: + case AMLOP_WORDPREFIX: + case AMLOP_DWORDPREFIX: + case AMLOP_QWORDPREFIX: + default: + printf("aml_setnodeval: read-only %.4x\n", node->opcode); + break; + } + if (dest) { + dnprintf(50, "aml_setnodeval: %.4x\n", node->opcode); #if 0 - xxx - aml_copyvalue(dest, val); + xxx + aml_copyvalue(dest, val); #endif - } + } } void aml_setnodeinteger(struct acpi_softc *sc, struct aml_node *node, int64_t value, struct aml_value *env) { - struct aml_value ival; + struct aml_value ival; - aml_setinteger(&ival, value); - aml_setnodevalue(sc, node, &ival, env); + aml_setinteger(&ival, value); + aml_setnodevalue(sc, node, &ival, env); } int aml_cmpobj(struct acpi_softc *sc, const struct aml_value *lhs, const struct aml_value *rhs) { - /* ASSERT: lhs and rhs are of same type */ - switch (lhs->type) { - case AML_OBJTYPE_INTEGER: - return (lhs->v_integer - rhs->v_integer); - case AML_OBJTYPE_STRING: - return strcmp(lhs->v_string, rhs->v_string); - default: - printf("Unknown compare type for cmpobj\n"); - break; - } + /* ASSERT: lhs and rhs are of same type */ + switch (lhs->type) { + case AML_OBJTYPE_INTEGER: + return (lhs->v_integer - rhs->v_integer); + case AML_OBJTYPE_STRING: + return strcmp(lhs->v_string, rhs->v_string); + default: + printf("Unknown compare type for cmpobj\n"); + break; + } - return (0); + return (0); } int aml_match(struct acpi_softc *sc, int mtype, const struct aml_value *lhs, const struct aml_value *rhs) { - int rc; - - if (mtype == AML_MATCH_TR) - return (1); - - if (lhs->type != rhs->type) - return (0); - - rc = aml_cmpobj(sc, lhs, rhs); - switch (mtype) { - case AML_MATCH_EQ: - return (rc == 0); - case AML_MATCH_LT: - return (rc < 0); - case AML_MATCH_LE: - return (rc <= 0); - case AML_MATCH_GE: - return (rc >= 0); - case AML_MATCH_GT: - return (rc > 0); - } + int rc; + + if (mtype == AML_MATCH_TR) + return (1); + + if (lhs->type != rhs->type) + return (0); + + rc = aml_cmpobj(sc, lhs, rhs); + switch (mtype) { + case AML_MATCH_EQ: + return (rc == 0); + case AML_MATCH_LT: + return (rc < 0); + case AML_MATCH_LE: + return (rc <= 0); + case AML_MATCH_GE: + return (rc >= 0); + case AML_MATCH_GT: + return (rc > 0); + } - return (0); + return (0); } struct aml_node * aml_create_node(struct acpi_context *ctx, struct aml_node *parent, int opcode) { - struct aml_node *node; + struct aml_node *node; - node = acpi_os_allocmem(sizeof(struct aml_node)); - memset(node, 0, sizeof(struct aml_node)); + node = acpi_os_allocmem(sizeof(struct aml_node)); + memset(node, 0, sizeof(struct aml_node)); - node->start = ctx->pos; - node->opcode = (opcode == -1) ? aml_getopcode(ctx) : opcode; - aml_addchildnode(parent, node); + node->start = ctx->pos; + node->opcode = (opcode == -1) ? aml_getopcode(ctx) : opcode; + aml_addchildnode(parent, node); - return node; + return node; } int aml_evalint(struct acpi_softc *sc, struct aml_node *node, struct aml_value *env) { - struct aml_value ival; + struct aml_value ival; - aml_eval_object(sc, node, &ival, env); - if (ival.type == AML_OBJTYPE_INTEGER) - return ival.v_integer; + aml_eval_object(sc, node, &ival, env); + if (ival.type == AML_OBJTYPE_INTEGER) + return ival.v_integer; - return (0); + return (0); } struct aml_node * aml_find_name(struct acpi_softc *sc, struct aml_node *root, const char *name) { - struct aml_node *ret; - const char *sname; - - if (*name == AMLOP_ROOTCHAR) { - root = &aml_root; - name++; - } - while (*name == AMLOP_PARENTPREFIX) { - if (root) root = root->parent; - name++; - } - if (root == NULL) - root = &aml_root; - - for (ret=NULL; root && !ret; root = root->sibling) { - if ((sname = root->name) != NULL) { - if (*sname == AMLOP_ROOTCHAR) - sname++; - while (*sname == AMLOP_PARENTPREFIX) - sname++; - if (!strcmp(name, sname)) { - return root; - } - } - if (root->child) - ret = aml_find_name(sc, root->child, name); - } - return ret; + struct aml_node *ret; + const char *sname; + + if (*name == AMLOP_ROOTCHAR) { + root = &aml_root; + name++; + } + while (*name == AMLOP_PARENTPREFIX) { + if (root) root = root->parent; + name++; + } + if (root == NULL) + root = &aml_root; + + for (ret=NULL; root && !ret; root = root->sibling) { + if ((sname = root->name) != NULL) { + if (*sname == AMLOP_ROOTCHAR) + sname++; + while (*sname == AMLOP_PARENTPREFIX) + sname++; + if (!strcmp(name, sname)) { + return root; + } + } + if (root->child) + ret = aml_find_name(sc, root->child, name); + } + return ret; } int aml_eval_name(struct acpi_softc *sc, struct aml_node *root, const char *name, struct aml_value *result, struct aml_value *env) { - root = aml_find_name(sc, root, name); + root = aml_find_name(sc, root, name); + + if (root != NULL) { + dnprintf(50, "found eval object : %s, %.4x\n", root->name, root->opcode); + return aml_eval_object(sc, root, result, env); + } + return (1); +} + +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_evalnode(struct acpi_context *, struct aml_node *); +struct aml_value *_aml_setnodevalue(struct acpi_context *, struct aml_node *, struct aml_value *, uint64_t); + +int64_t +_aml_evalint(struct acpi_context *ctx, struct aml_node *node) +{ + return 0; +} + +struct aml_value * +_aml_evalnode(struct acpi_context *ctx, struct aml_node *node) +{ + struct aml_value *rv; + uint64_t i1, i2; + + if ((rv = _aml_getnodevalue(ctx, node)) != NULL) { + return rv; + } + + switch (node->opcode) { + case AMLOP_ELSE: + case AMLOP_BREAK: + case AMLOP_CONTINUE: + break; + + case AMLOP_INCREMENT: + case AMLOP_DECREMENT: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = _aml_setnodevalue(ctx, childOf(node, 0), NULL, + aml_evalmath(node->opcode, i1, 1)); + break; + + case AMLOP_NOT: + case AMLOP_FINDSETLEFTBIT: + case AMLOP_FINDSETRIGHTBIT: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = _aml_setnodevalue(ctx, childOf(node, 1), NULL, + aml_evalmath(node->opcode, i1, 0)); + break; + + case AMLOP_DIVIDE: + i1 = _aml_evalint(ctx, childOf(node, 0)); + i2 = _aml_evalint(ctx, childOf(node, 1)); + _aml_setnodevalue(ctx, childOf(node, 2), NULL, + aml_evalmath(AMLOP_MOD, i1, i2)); + rv = _aml_setnodevalue(ctx, childOf(node, 3), NULL, + aml_evalmath(AMLOP_DIVIDE, i1, i2)); + break; + + case AMLOP_ADD: + case AMLOP_SUBTRACT: + case AMLOP_MULTIPLY: + case AMLOP_SHL: + case AMLOP_SHR: + case AMLOP_AND: + case AMLOP_NAND: + case AMLOP_OR: + case AMLOP_XOR: + case AMLOP_NOR: + case AMLOP_MOD: + i1 = _aml_evalint(ctx, childOf(node, 0)); + i2 = _aml_evalint(ctx, childOf(node, 1)); + rv = _aml_setnodevalue(ctx, childOf(node, 2), NULL, + aml_evalmath(node->opcode, i1, i2)); + break; + + case AMLOP_LNOT: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = aml_allocint(!i1); + break; + + case AMLOP_TOINTEGER: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = _aml_setnodevalue(ctx, childOf(node, 1), NULL, i1); + break; + + case AMLOP_FROMBCD: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = _aml_setnodevalue(ctx, childOf(node, 1), NULL, aml_bcd2dec(i1)); + break; + + case AMLOP_TOBCD: + i1 = _aml_evalint(ctx, childOf(node, 0)); + rv = _aml_setnodevalue(ctx, childOf(node, 1), NULL, aml_dec2bcd(i1)); + break; + + case AMLOP_STALL: + i1 = _aml_evalint(ctx, childOf(node, 0)); + dnprintf(50, "stall %d usecs\n", i1); + break; + + case AMLOP_SLEEP: + i1 = _aml_evalint(ctx, childOf(node, 0)); + dnprintf(50, "sleep %d msecs\n", i1); + break; + + } + return rv; +} + +void +aml_create_bufferunit(struct acpi_context *ctx, struct aml_node *node, int bitlen, int size) +{ + /* ASSERT: node->value is NULL */ + node->value = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL, "bufferunit"); + if (node->value != NULL) { + node->value->length = aml_bytelen(bitlen); + node->value->v_field.ftype = node->opcode; + node->value->v_field.bitpos = _aml_evalint(ctx, childOf(node, 1)) * size; + node->value->v_field.ref = childOf(node, 0); + + dnprintf(50, "create_bufferunit: name=%s pos=%.8x len=%.8x size=%.8x\n", + node->name, node->value->v_field.bitpos, + bitlen, size); + if (bitlen == -1) { + /* AMLOP_CREATEFIELD: decode bitlength */ + bitlen = _aml_evalint(ctx, childOf(node, 2)); + } + node->value->v_field.bitlen = bitlen; + } +} + +struct aml_value * +_aml_setnodevalue(struct acpi_context *ctx, struct aml_node *node, struct aml_value *rhs, uint64_t ival) +{ + return NULL; +} + +struct aml_value * +_aml_getnodevalue(struct acpi_context *ctx, struct aml_node *node) +{ + u_int64_t i1, i2; + + if (node->value != NULL) { + dnprintf(50, "returning cached object value: %.4x %s\n", node->opcode, node->mnem); + return node->value; + } - if (root != NULL) { - dnprintf(50, "found eval object : %s, %.4x\n", root->name, root->opcode); - return aml_eval_object(sc, root, result, env); - } - return (1); + switch (node->opcode) { + case AMLOP_LOCAL0: + case AMLOP_LOCAL1: + case AMLOP_LOCAL2: + case AMLOP_LOCAL3: + case AMLOP_LOCAL4: + case AMLOP_LOCAL5: + case AMLOP_LOCAL6: + case AMLOP_LOCAL7: + i1 = node->opcode - AMLOP_LOCAL0; + if (ctx->stack) { + node->value = &ctx->stack->locals[i1]; + } + break; + + case AMLOP_ARG0: + case AMLOP_ARG1: + case AMLOP_ARG2: + case AMLOP_ARG3: + case AMLOP_ARG4: + case AMLOP_ARG5: + case AMLOP_ARG6: + i1 = node->opcode - AMLOP_ARG0; + if (ctx->stack) { + node->value = &ctx->stack->args[i1]; + } + break; + + case AMLOP_CREATEFIELD: + aml_create_bufferunit(ctx, node, -1, 1); + break; + case AMLOP_CREATEBITFIELD: + aml_create_bufferunit(ctx, node, 1, 1); + break; + case AMLOP_CREATEBYTEFIELD: + aml_create_bufferunit(ctx, node, 8, 8); + break; + case AMLOP_CREATEWORDFIELD: + aml_create_bufferunit(ctx, node, 16, 8); + break; + case AMLOP_CREATEDWORDFIELD: + aml_create_bufferunit(ctx, node, 32, 8); + break; + case AMLOP_CREATEQWORDFIELD: + aml_create_bufferunit(ctx, node, 64, 8); + break; + + case AMLOP_DEBUG: + node->value = aml_allocvalue(AML_OBJTYPE_DEBUGOBJ, 0, NULL, "debugobj"); + break; + + case AMLOP_BUFFER: + /* Requested length of buffer can be greater than supplied bytes */ + i1 = _aml_evalint(ctx, childOf(node, 0)); + i2 = node->end - node->start; + + dnprintf(50, "allocate buffer: %d/%d\n", i2, i1); + node->value = aml_allocvalue(AML_OBJTYPE_BUFFER, i1, NULL, "buffer"); + if (node->value && i2 > 0) { + memcpy(node->value->v_buffer, node->start, i2); + } + break; + + case AMLOP_PACKAGE: + case AMLOP_VARPACKAGE: + i1 = _aml_evalint(ctx, childOf(node, 0)); + dnprintf(50, "allocate package: %d\n", i1); + node->value = aml_allocvalue(AML_OBJTYPE_PACKAGE, i1, NULL, "package"); + for (i2=0; node->value && i2 < i1; i2++) { + node->value->v_package[i2] = _aml_evalnode(ctx, childOf(node, 1+i2)); + } + break; + + case AMLOP_OPREGION: + node->value = aml_allocvalue(AML_OBJTYPE_OPREGION, 0, NULL, "opregion"); + if (node->value != NULL) { + node->value->v_opregion.iospace = _aml_evalint(ctx, childOf(node, 0)); + node->value->v_opregion.iobase = _aml_evalint(ctx, childOf(node, 1)); + node->value->v_opregion.iolen = _aml_evalint(ctx, childOf(node, 2)); + } + break; + + case AMLOP_PROCESSOR: + node->value = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, NULL, "processor"); + if (node->value != NULL) { + node->value->v_processor.proc_id = _aml_evalint(ctx, childOf(node, 0)); + node->value->v_processor.proc_addr = _aml_evalint(ctx, childOf(node, 1)); + node->value->v_processor.proc_len = _aml_evalint(ctx, childOf(node, 2)); + } + break; + + case AMLOP_THERMALZONE: + node->value = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, NULL, "thermzone"); + break; + + case AMLOP_EVENT: + node->value = aml_allocvalue(AML_OBJTYPE_EVENT, 0, NULL, "event"); + break; + + case AMLOP_DEVICE: + node->value = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, NULL, "device"); + break; + + case AMLOP_MUTEX: + i1 = _aml_evalint(ctx, childOf(node, 0)); + node->value = aml_allocvalue(AML_OBJTYPE_MUTEX, i1, NULL, "mutex"); + break; + + case AMLOP_POWERRSRC: + node->value = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, NULL, "powerrsrc"); + if (node->value != NULL) { + node->value->v_powerrsrc.pwr_level = _aml_evalint(ctx, childOf(node, 0)); + node->value->v_powerrsrc.pwr_order = _aml_evalint(ctx, childOf(node, 1)); + } + break; + + default: + return NULL; + } + return node->value; } int aml_eval_object(struct acpi_softc *sc, struct aml_node *node, struct aml_value *result, struct aml_value *env) { - memset(result, 0, sizeof(struct aml_value)); + memset(result, 0, sizeof(struct aml_value)); #if 0 - xxx - struct aml_value lhs, rhs, tmp, pkg; - struct aml_value *px; - int64_t iresult, id, idx; - struct aml_node *cflow = NULL; - int i1, i2, i3; - char *tmpstr; - - if (node == NULL) - return (-1); - - dnprintf(50, "--- Evaluating object:\n"); - aml_shownode(node); - - switch (node->opcode) { - case AMLOP_ZERO: - case AMLOP_ONE: - case AMLOP_ONES: - case AMLOP_BYTEPREFIX: - case AMLOP_WORDPREFIX: - case AMLOP_DWORDPREFIX: - case AMLOP_QWORDPREFIX: - case AMLOP_STRINGPREFIX: - case AMLOP_REVISION: + xxx + struct aml_value lhs, rhs, tmp, pkg; + struct aml_value *px; + int64_t iresult, id, idx; + struct aml_node *cflow = NULL; + int i1, i2, i3; + char *tmpstr; + + if (node == NULL) + return (-1); + + dnprintf(50, "--- Evaluating object:\n"); + aml_shownode(node); + + switch (node->opcode) { + case AMLOP_ZERO: + case AMLOP_ONE: + case AMLOP_ONES: + case AMLOP_BYTEPREFIX: + case AMLOP_WORDPREFIX: + case AMLOP_DWORDPREFIX: + case AMLOP_QWORDPREFIX: + case AMLOP_STRINGPREFIX: + case AMLOP_REVISION: #if 0 - aml_copyvalue(result, &node->value); + aml_copyvalue(result, &node->value); #endif - break; + break; - case AMLOP_BUFFER: - i1 = aml_evalint(sc, childOf(node, 0), env); - dnprintf(50, "@@@@@@@@@@@@@@ buffer: %.4x %.4x\n", i1, node->value->length); - break; + case AMLOP_BUFFER: + i1 = aml_evalint(sc, childOf(node, 0), env); + dnprintf(50, "@@@@@@@@@@@@@@ buffer: %.4x %.4x\n", i1, node->value->length); + break; - case AMLOP_STORE: - aml_eval_object(sc, childOf(node, 0), &lhs, env); - aml_setnodevalue(sc, childOf(node, 1), &lhs, env); - break; + case AMLOP_STORE: + aml_eval_object(sc, childOf(node, 0), &lhs, env); + aml_setnodevalue(sc, childOf(node, 1), &lhs, env); + break; - case AMLOP_DEBUG: + case AMLOP_DEBUG: #if 0 - aml_copyvalue(result, &aml_debugobj); + aml_copyvalue(result, &aml_debugobj); #endif - break; - - case AMLOP_NAME: - case AMLOP_ALIAS: - return aml_eval_object(sc, childOf(node, 0), result, env); - - case AMLOP_PROCESSOR: - i1 = aml_evalint(sc, childOf(node, 0), env); - i2 = aml_evalint(sc, childOf(node, 1), env); - i3 = aml_evalint(sc, childOf(node, 2), env); - aml_setprocessor(result, i1, i2, i3); - break; - - case AMLOP_OPREGION: - i1 = aml_evalint(sc, childOf(node, 0), env); - i2 = aml_evalint(sc, childOf(node, 1), env); - aml_setopregion(result, node->flag, i1, i2); - break; - - case AMLOP_IF: - i1 = aml_evalint(sc, childOf(node,0), env); - if (i1 != 0) { - /* Test true, select 'If' block */ - cflow = childOf(node, 1); - } - else if (node->sibling->opcode == AMLOP_ELSE) { - /* Test false, select 'Else' block */ - cflow = node->sibling->child; - } - while (cflow) { - /* Execute all instructions in scope block */ - aml_eval_object(sc, cflow, result, env); - cflow = cflow->sibling; - } - break; - - case AMLOP_WHILE: - for (;;) { - if (cflow == NULL) { - /* Perform While test */ - cflow = childOf(node, 1); - i1 = aml_evalint(sc, childOf(node, 0), env); - if (i1 == 0) - break; - } - else if (cflow->opcode == AMLOP_BREAK) - break; - else if (cflow->opcode == AMLOP_CONTINUE) - /* Reset cflow to NULL; restart block */ - cflow = NULL; - else { - /* Execute all instructions in scope block */ - aml_eval_object(sc, cflow, result, env); - cflow = cflow->sibling; - } - } - break; + break; + + case AMLOP_NAME: + case AMLOP_ALIAS: + return aml_eval_object(sc, childOf(node, 0), result, env); + + case AMLOP_PROCESSOR: + i1 = aml_evalint(sc, childOf(node, 0), env); + i2 = aml_evalint(sc, childOf(node, 1), env); + i3 = aml_evalint(sc, childOf(node, 2), env); + aml_setprocessor(result, i1, i2, i3); + break; + + case AMLOP_OPREGION: + i1 = aml_evalint(sc, childOf(node, 0), env); + i2 = aml_evalint(sc, childOf(node, 1), env); + aml_setopregion(result, node->flag, i1, i2); + break; + + case AMLOP_IF: + i1 = aml_evalint(sc, childOf(node,0), env); + if (i1 != 0) { + /* Test true, select 'If' block */ + cflow = childOf(node, 1); + } + else if (node->sibling->opcode == AMLOP_ELSE) { + /* Test false, select 'Else' block */ + cflow = node->sibling->child; + } + while (cflow) { + /* Execute all instructions in scope block */ + aml_eval_object(sc, cflow, result, env); + cflow = cflow->sibling; + } + break; + + case AMLOP_WHILE: + for (;;) { + if (cflow == NULL) { + /* Perform While test */ + cflow = childOf(node, 1); + i1 = aml_evalint(sc, childOf(node, 0), env); + if (i1 == 0) + break; + } + else if (cflow->opcode == AMLOP_BREAK) + break; + else if (cflow->opcode == AMLOP_CONTINUE) + /* Reset cflow to NULL; restart block */ + cflow = NULL; + else { + /* Execute all instructions in scope block */ + aml_eval_object(sc, cflow, result, env); + cflow = cflow->sibling; + } + } + break; - case AMLOP_RETURN: - aml_eval_object(sc, childOf(node, 0), result, env); - break; - - case AMLOP_ARG0: - case AMLOP_ARG1: - case AMLOP_ARG2: - case AMLOP_ARG3: - case AMLOP_ARG4: - case AMLOP_ARG5: - case AMLOP_ARG6: - id = node->opcode - AMLOP_ARG0; + case AMLOP_RETURN: + aml_eval_object(sc, childOf(node, 0), result, env); + break; + + case AMLOP_ARG0: + case AMLOP_ARG1: + case AMLOP_ARG2: + case AMLOP_ARG3: + case AMLOP_ARG4: + case AMLOP_ARG5: + case AMLOP_ARG6: + id = node->opcode - AMLOP_ARG0; #if 0 - if (id < env->length) - aml_copyvalue(result, &node->value->v_method.locals[id]); + if (id < env->length) + aml_copyvalue(result, &node->value->v_method.locals[id]); #endif - break; - - case AMLOP_LOCAL0: - case AMLOP_LOCAL1: - case AMLOP_LOCAL2: - case AMLOP_LOCAL3: - case AMLOP_LOCAL4: - case AMLOP_LOCAL5: - case AMLOP_LOCAL6: - case AMLOP_LOCAL7: - id = node->opcode - AMLOP_LOCAL0; + break; + + case AMLOP_LOCAL0: + case AMLOP_LOCAL1: + case AMLOP_LOCAL2: + case AMLOP_LOCAL3: + case AMLOP_LOCAL4: + case AMLOP_LOCAL5: + case AMLOP_LOCAL6: + case AMLOP_LOCAL7: + id = node->opcode - AMLOP_LOCAL0; #if 0 - aml_copyvalue(result, &env->v_method.locals[id]); + aml_copyvalue(result, &env->v_method.locals[id]); #endif - break; - - case AMLOP_PACKAGE: - case AMLOP_VARPACKAGE: - i1 = aml_evalint(sc, childOf(node, 0), env); - dnprintf(50, "package = %d\n", i1); - result->type = AML_OBJTYPE_PACKAGE; - result->length = i1; - - result->v_package = acpi_os_allocmem(i1 * sizeof(struct aml_value)); - for (i2=0; i2<i1; i2++) { - aml_eval_object(sc, childOf(node, i2+1), result->v_package[i2], env); - } - break; + break; + + case AMLOP_PACKAGE: + case AMLOP_VARPACKAGE: + i1 = aml_evalint(sc, childOf(node, 0), env); + dnprintf(50, "package = %d\n", i1); + result->type = AML_OBJTYPE_PACKAGE; + result->length = i1; + + result->v_package = acpi_os_allocmem(i1 * sizeof(struct aml_value)); + for (i2=0; i2<i1; i2++) { + aml_eval_object(sc, childOf(node, i2+1), result->v_package[i2], env); + } + break; - case AMLOP_INCREMENT: - case AMLOP_DECREMENT: - i1 = aml_evalint(sc, childOf(node, 0), env); - iresult = aml_evalmath(node->opcode, i1, 0); - aml_setnodeinteger(sc, childOf(node, 0), iresult, env); - break; - - case AMLOP_NOT: - case AMLOP_FINDSETLEFTBIT: - case AMLOP_FINDSETRIGHTBIT: - i1 = aml_evalint(sc, childOf(node, 0), env); - iresult = aml_evalmath(node->opcode, i1, 0); - aml_setnodeinteger(sc, childOf(node, 1), iresult, env); - break; - - case AMLOP_DIVIDE: - i1 = aml_evalint(sc, childOf(node, 0), env); - i2 = aml_evalint(sc, childOf(node, 1), env); - - /* Set remainder */ - iresult = aml_evalmath(AMLOP_MOD, i1, i2); - aml_setnodeinteger(sc, childOf(node, 2), iresult, env); - - /* Set quotient */ - iresult = aml_evalmath(node->opcode, i1, i2); - aml_setnodeinteger(sc, childOf(node, 3), iresult, env); - break; - - case AMLOP_ADD: - case AMLOP_SUBTRACT: - case AMLOP_MULTIPLY: - case AMLOP_SHL: - case AMLOP_SHR: - case AMLOP_AND: - case AMLOP_NAND: - case AMLOP_OR: - case AMLOP_NOR: - case AMLOP_XOR: - case AMLOP_MOD: - i1 = aml_evalint(sc, childOf(node, 0), env); - i2 = aml_evalint(sc, childOf(node, 1), env); - - iresult = aml_evalmath(node->opcode, i1, i2); - aml_setnodeinteger(sc, childOf(node, 2), iresult, env); - break; - - case AMLOP_LNOT: - i1 = aml_evalint(sc, childOf(node, 0), env); - iresult = aml_testlogical(node->opcode, i1, 0); - aml_setinteger(result, iresult); - break; - - case AMLOP_LAND: - case AMLOP_LOR: - i1 = aml_evalint(sc, childOf(node, 0), env); - i2 = aml_evalint(sc, childOf(node, 1), env); - iresult = aml_testlogical(node->opcode, i1, i2); - aml_setinteger(result, iresult); - break; - - case AMLOP_LEQUAL: - case AMLOP_LNOTEQUAL: - case AMLOP_LLESSEQUAL: - case AMLOP_LGREATEREQUAL: - case AMLOP_LGREATER: - case AMLOP_LLESS: - aml_eval_object(sc, childOf(node, 0), &lhs, env); - aml_eval_object(sc, childOf(node, 1), &rhs, env); - if (lhs.type == AML_OBJTYPE_INTEGER && rhs.type == AML_OBJTYPE_INTEGER) { - iresult = aml_testlogical(node->opcode, lhs.v_integer, rhs.v_integer); - } - else if (lhs.type == AML_OBJTYPE_STRING && rhs.type == AML_OBJTYPE_STRING) { - iresult = aml_strcmp(node->opcode, lhs.v_string, rhs.v_string); - } - aml_setinteger(result, iresult); - break; - - case AMLOP_CREATEFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - i2 = aml_evalint(sc, childOf(node, 2), env); - aml_setfield(&lhs, i1, i2, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 3), &lhs, env); - break; - case AMLOP_CREATEBITFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_setfield(&lhs, i1, 1, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 2), &lhs, env); - break; - case AMLOP_CREATEBYTEFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_setfield(&lhs, i1 * 8, 8, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 2), &lhs, env); - break; - case AMLOP_CREATEWORDFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_setfield(&lhs, i1 * 8, 16, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 2), &lhs, env); - break; - case AMLOP_CREATEDWORDFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_setfield(&lhs, i1 * 8, 32, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 2), &lhs, env); - break; - case AMLOP_CREATEQWORDFIELD: - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_setfield(&lhs, i1 * 8, 64, childOf(node, 0), node); - aml_setnodevalue(sc, childOf(node, 2), &lhs, env); - break; + case AMLOP_INCREMENT: + case AMLOP_DECREMENT: + i1 = aml_evalint(sc, childOf(node, 0), env); + iresult = aml_evalmath(node->opcode, i1, 0); + aml_setnodeinteger(sc, childOf(node, 0), iresult, env); + break; + + case AMLOP_NOT: + case AMLOP_FINDSETLEFTBIT: + case AMLOP_FINDSETRIGHTBIT: + i1 = aml_evalint(sc, childOf(node, 0), env); + iresult = aml_evalmath(node->opcode, i1, 0); + aml_setnodeinteger(sc, childOf(node, 1), iresult, env); + break; + + case AMLOP_DIVIDE: + i1 = aml_evalint(sc, childOf(node, 0), env); + i2 = aml_evalint(sc, childOf(node, 1), env); + + /* Set remainder */ + iresult = aml_evalmath(AMLOP_MOD, i1, i2); + aml_setnodeinteger(sc, childOf(node, 2), iresult, env); + + /* Set quotient */ + iresult = aml_evalmath(node->opcode, i1, i2); + aml_setnodeinteger(sc, childOf(node, 3), iresult, env); + break; + + case AMLOP_ADD: + case AMLOP_SUBTRACT: + case AMLOP_MULTIPLY: + case AMLOP_SHL: + case AMLOP_SHR: + case AMLOP_AND: + case AMLOP_NAND: + case AMLOP_OR: + case AMLOP_NOR: + case AMLOP_XOR: + case AMLOP_MOD: + i1 = aml_evalint(sc, childOf(node, 0), env); + i2 = aml_evalint(sc, childOf(node, 1), env); + + iresult = aml_evalmath(node->opcode, i1, i2); + aml_setnodeinteger(sc, childOf(node, 2), iresult, env); + break; + + case AMLOP_LNOT: + i1 = aml_evalint(sc, childOf(node, 0), env); + iresult = aml_testlogical(node->opcode, i1, 0); + aml_setinteger(result, iresult); + break; + + case AMLOP_LAND: + case AMLOP_LOR: + i1 = aml_evalint(sc, childOf(node, 0), env); + i2 = aml_evalint(sc, childOf(node, 1), env); + iresult = aml_testlogical(node->opcode, i1, i2); + aml_setinteger(result, iresult); + break; + + case AMLOP_LEQUAL: + case AMLOP_LNOTEQUAL: + case AMLOP_LLESSEQUAL: + case AMLOP_LGREATEREQUAL: + case AMLOP_LGREATER: + case AMLOP_LLESS: + aml_eval_object(sc, childOf(node, 0), &lhs, env); + aml_eval_object(sc, childOf(node, 1), &rhs, env); + if (lhs.type == AML_OBJTYPE_INTEGER && rhs.type == AML_OBJTYPE_INTEGER) { + iresult = aml_testlogical(node->opcode, lhs.v_integer, rhs.v_integer); + } + else if (lhs.type == AML_OBJTYPE_STRING && rhs.type == AML_OBJTYPE_STRING) { + iresult = aml_strcmp(node->opcode, lhs.v_string, rhs.v_string); + } + aml_setinteger(result, iresult); + break; + + case AMLOP_CREATEFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + i2 = aml_evalint(sc, childOf(node, 2), env); + aml_setfield(&lhs, i1, i2, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 3), &lhs, env); + break; + case AMLOP_CREATEBITFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_setfield(&lhs, i1, 1, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 2), &lhs, env); + break; + case AMLOP_CREATEBYTEFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_setfield(&lhs, i1 * 8, 8, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 2), &lhs, env); + break; + case AMLOP_CREATEWORDFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_setfield(&lhs, i1 * 8, 16, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 2), &lhs, env); + break; + case AMLOP_CREATEDWORDFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_setfield(&lhs, i1 * 8, 32, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 2), &lhs, env); + break; + case AMLOP_CREATEQWORDFIELD: + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_setfield(&lhs, i1 * 8, 64, childOf(node, 0), node); + aml_setnodevalue(sc, childOf(node, 2), &lhs, env); + break; - case AMLOP_TOBCD: - i1 = aml_evalint(sc, childOf(node, 0), env); - iresult = aml_dec2bcd(i1); - aml_setnodeinteger(sc, childOf(node, 1), iresult, env); - break; - case AMLOP_FROMBCD: - i1 = aml_evalint(sc, childOf(node, 0), env); - iresult = aml_bcd2dec(i1); - aml_setnodeinteger(sc, childOf(node, 1), iresult, env); - break; - case AMLOP_TODECSTRING: - tmpstr = acpi_os_allocmem(AML_INTSTRLEN+1); - if (tmpstr != NULL) { - aml_eval_object(sc, childOf(node, 0), &lhs, env); - if (lhs.type == AML_OBJTYPE_INTEGER) - snprintf(tmpstr, AML_INTSTRLEN, "%d", lhs.v_integer); - } - break; - case AMLOP_TOHEXSTRING: - tmpstr = acpi_os_allocmem(AML_INTSTRLEN+1); - if (tmpstr != NULL) { - aml_eval_object(sc, childOf(node, 0), &lhs, env); - if (lhs.type == AML_OBJTYPE_INTEGER) - snprintf(tmpstr, AML_INTSTRLEN, "%x", lhs.v_integer); - } - break; - - case AMLOP_MID: - aml_eval_object(sc, childOf(node, 0), &tmp, env); - aml_eval_object(sc, childOf(node, 1), &lhs, env); - aml_eval_object(sc, childOf(node, 2), &rhs, env); - if (tmp.type != AML_OBJTYPE_STRING) - return (-1); - - tmpstr = acpi_os_allocmem(rhs.v_integer+1); - if (tmpstr != NULL) { - strncpy(tmpstr, tmp.v_string + lhs.v_integer, rhs.v_integer); - } - break; - - case AMLOP_STALL: - i1 = aml_evalint(sc, childOf(node, 0), env); - dnprintf(50, "aml_stall: %d\n", i1); - break; - case AMLOP_SLEEP: - i1 = aml_evalint(sc, childOf(node, 0), env); - dnprintf(50, "aml_sleep: %d\n", i1); - break; - case AMLOP_OBJECTTYPE: - aml_eval_object(sc, childOf(node, 0), &lhs, env); - aml_setinteger(result, lhs.type); - break; - - case AMLOP_NAMECHAR: /* Inline method call */ - aml_eval_name(sc, NULL, node->name, result, env); - break; - - case AMLOP_METHOD: - dnprintf(50, "eval-method : %s argcount:%d\n", - node->name, AML_METHOD_ARGCOUNT(node->flag)); - - lhs.type = AML_OBJTYPE_METHOD; - lhs.length = AML_METHOD_ARGCOUNT(node->flag); - if (lhs.length > 0) { - lhs.v_method.args = acpi_os_allocmem(lhs.length * sizeof(struct aml_value)); - memset(lhs.v_method.args, 0, lhs.length * sizeof(struct aml_value)); - } - lhs.v_method.locals = acpi_os_allocmem(8 * sizeof(struct aml_value)); - - for (i1=0; i1<lhs.length; i1++) { - dnprintf(50, " evalmeth: %s:%d\n", node->name, i1); - aml_eval_object(sc, childOf(node, i1), &lhs.v_method.args[i1], env); - aml_showvalue(&lhs.v_method.args[i1]); - } - while (childOf(node, i1)) { - aml_eval_object(sc, childOf(node, i1++), result, &lhs); - } - break; - - case AMLOP_CONCAT: - aml_eval_object(sc, childOf(node, 0), &lhs, env); - aml_eval_object(sc, childOf(node, 1), &rhs, env); - break; - - case AMLOP_NOP: - break; - - case AMLOP_SIZEOF: - aml_eval_object(sc, childOf(node, 0), &lhs, env); - px = aml_getnodevalue(sc, childOf(node, 0), env); - aml_showvalue(px); - for(;;); - break; - - case AMLOP_MATCH: - aml_eval_object(sc, childOf(node, 0), &pkg, env); - i1 = aml_evalint(sc, childOf(node, 1), env); - aml_eval_object(sc, childOf(node, 2), &lhs, env); - i2 = aml_evalint(sc, childOf(node, 3), env); - aml_eval_object(sc, childOf(node, 4), &lhs, env); - idx = aml_evalint(sc, childOf(node, 5), env); - if (pkg.type == AML_OBJTYPE_PACKAGE) { - iresult = -1; - while (idx < pkg.length) { - if (aml_match(sc, i1, &pkg.v_package[idx], &lhs) || - aml_match(sc, i2, &pkg.v_package[idx], &rhs)) { - iresult = idx; - break; + case AMLOP_TOBCD: + i1 = aml_evalint(sc, childOf(node, 0), env); + iresult = aml_dec2bcd(i1); + aml_setnodeinteger(sc, childOf(node, 1), iresult, env); + break; + case AMLOP_FROMBCD: + i1 = aml_evalint(sc, childOf(node, 0), env); + iresult = aml_bcd2dec(i1); + aml_setnodeinteger(sc, childOf(node, 1), iresult, env); + break; + case AMLOP_TODECSTRING: + tmpstr = acpi_os_allocmem(AML_INTSTRLEN+1); + if (tmpstr != NULL) { + aml_eval_object(sc, childOf(node, 0), &lhs, env); + if (lhs.type == AML_OBJTYPE_INTEGER) + snprintf(tmpstr, AML_INTSTRLEN, "%d", lhs.v_integer); + } + break; + case AMLOP_TOHEXSTRING: + tmpstr = acpi_os_allocmem(AML_INTSTRLEN+1); + if (tmpstr != NULL) { + aml_eval_object(sc, childOf(node, 0), &lhs, env); + if (lhs.type == AML_OBJTYPE_INTEGER) + snprintf(tmpstr, AML_INTSTRLEN, "%x", lhs.v_integer); + } + break; + + case AMLOP_MID: + aml_eval_object(sc, childOf(node, 0), &tmp, env); + aml_eval_object(sc, childOf(node, 1), &lhs, env); + aml_eval_object(sc, childOf(node, 2), &rhs, env); + if (tmp.type != AML_OBJTYPE_STRING) + return (-1); + + tmpstr = acpi_os_allocmem(rhs.v_integer+1); + if (tmpstr != NULL) { + strncpy(tmpstr, tmp.v_string + lhs.v_integer, rhs.v_integer); + } + break; + + case AMLOP_STALL: + i1 = aml_evalint(sc, childOf(node, 0), env); + dnprintf(50, "aml_stall: %d\n", i1); + break; + case AMLOP_SLEEP: + i1 = aml_evalint(sc, childOf(node, 0), env); + dnprintf(50, "aml_sleep: %d\n", i1); + break; + case AMLOP_OBJECTTYPE: + aml_eval_object(sc, childOf(node, 0), &lhs, env); + aml_setinteger(result, lhs.type); + break; + + case AMLOP_NAMECHAR: /* Inline method call */ + aml_eval_name(sc, NULL, node->name, result, env); + break; + + case AMLOP_METHOD: + dnprintf(50, "eval-method : %s argcount:%d\n", + node->name, AML_METHOD_ARGCOUNT(node->flag)); + + lhs.type = AML_OBJTYPE_METHOD; + lhs.length = AML_METHOD_ARGCOUNT(node->flag); + if (lhs.length > 0) { + lhs.v_method.args = acpi_os_allocmem(lhs.length * sizeof(struct aml_value)); + memset(lhs.v_method.args, 0, lhs.length * sizeof(struct aml_value)); + } + lhs.v_method.locals = acpi_os_allocmem(8 * sizeof(struct aml_value)); + + for (i1=0; i1<lhs.length; i1++) { + dnprintf(50, " evalmeth: %s:%d\n", node->name, i1); + aml_eval_object(sc, childOf(node, i1), &lhs.v_method.args[i1], env); + aml_showvalue(&lhs.v_method.args[i1]); + } + while (childOf(node, i1)) { + aml_eval_object(sc, childOf(node, i1++), result, &lhs); + } + break; + + case AMLOP_CONCAT: + aml_eval_object(sc, childOf(node, 0), &lhs, env); + aml_eval_object(sc, childOf(node, 1), &rhs, env); + break; + + case AMLOP_NOP: + break; + + case AMLOP_SIZEOF: + aml_eval_object(sc, childOf(node, 0), &lhs, env); + px = aml_getnodevalue(sc, childOf(node, 0), env); + aml_showvalue(px); + for(;;); + break; + + case AMLOP_MATCH: + aml_eval_object(sc, childOf(node, 0), &pkg, env); + i1 = aml_evalint(sc, childOf(node, 1), env); + aml_eval_object(sc, childOf(node, 2), &lhs, env); + i2 = aml_evalint(sc, childOf(node, 3), env); + aml_eval_object(sc, childOf(node, 4), &lhs, env); + idx = aml_evalint(sc, childOf(node, 5), env); + if (pkg.type == AML_OBJTYPE_PACKAGE) { + iresult = -1; + while (idx < pkg.length) { + if (aml_match(sc, i1, &pkg.v_package[idx], &lhs) || + aml_match(sc, i2, &pkg.v_package[idx], &rhs)) { + iresult = idx; + break; + } + idx++; + } + aml_setinteger(result, iresult); + } + break; + + default: + printf("Unknown eval: %.4x %s\n", node->opcode, node->mnem); + break; } - idx++; - } - aml_setinteger(result, iresult); - } - break; - - default: - printf("Unknown eval: %.4x %s\n", node->opcode, node->mnem); - break; - } #endif - return (0); + return (0); } int aml_parseargs(struct acpi_context *ctx, struct aml_node *node, const char *arg) { - struct aml_node *pnode; - - while (*arg) { - pnode = node; - switch (*arg) { - case AML_ARG_FLAG: - node->flag = aml_parseint(ctx, 1); - if (node->opcode == AMLOP_METHOD) { - dnprintf(50, " method %s %.2x argcount:%d serialized:%d synclevel:%d\n", - node->name, node->flag, - AML_METHOD_ARGCOUNT(node->flag), - AML_METHOD_SERIALIZED(node->flag), - AML_METHOD_SYNCLEVEL(node->flag)); - } - else { - dnprintf(50, " field %s %.2x access:%d lock:%d update:%d\n", - node->name, node->flag, - AML_FIELD_ACCESS(node->flag), - AML_FIELD_LOCK(node->flag), - AML_FIELD_UPDATE(node->flag)); - } - break; - case AML_ARG_IMPBYTE: - /* Implied byte: same as opcode */ - node->value = aml_allocint((char)node->opcode); - dnprintf(50, " ibyte: %x\n", (int8_t)node->opcode); - break; - case AML_ARG_BYTE: - if (node->opcode != AMLOP_BYTEPREFIX) { - pnode = aml_create_node(ctx, node, AMLOP_BYTEPREFIX); - } - pnode->value = aml_allocint(aml_parseint(ctx, 1)); - dnprintf(50, " byte: %x\n", pnode->value->v_integer); - break; - case AML_ARG_WORD: - if (node->opcode != AMLOP_WORDPREFIX) { - pnode = aml_create_node(ctx, node, AMLOP_WORDPREFIX); - } - pnode->value = aml_allocint(aml_parseint(ctx, 2)); - dnprintf(50, " word: %x\n", pnode->value->v_integer); - break; - case AML_ARG_DWORD: - if (node->opcode != AMLOP_DWORDPREFIX) { - pnode = aml_create_node(ctx, node, AMLOP_DWORDPREFIX); - } - pnode->value = aml_allocint(aml_parseint(ctx, 4)); - dnprintf(50, " dword: %x\n", pnode->value->v_integer); - break; - case AML_ARG_QWORD: - if (node->opcode == AMLOP_QWORDPREFIX) { - pnode = aml_create_node(ctx, node, AMLOP_QWORDPREFIX); - } - pnode->value = aml_allocint(aml_parseint(ctx, 8)); - dnprintf(50, " qword: %x\n", pnode->value->v_integer); - break; - case AML_ARG_FIELDLIST: - dnprintf(50, " fieldlist\n"); - aml_parsefieldlist(ctx, node); - break; - case AML_ARG_BYTELIST: - dnprintf(50, " bytelist\n"); - node->start = ctx->pos; - ctx->pos = node->end; - break; - case AML_ARG_STRING: - node->value = aml_allocstr(aml_parsestr(ctx)); - dnprintf(50, " string: %s\n", node->value->v_string); - break; - case AML_ARG_NAMESTRING: - node->name = aml_parsename(ctx, "name"); - break; - case AML_ARG_NAMEREF: - pnode = aml_create_node(ctx, node, AMLOP_NAMECHAR); - pnode->name = aml_parsename(ctx, "nameref"); - break; - case AML_ARG_OBJLEN: - dnprintf(50, " pkglen\n"); - node->end = ctx->pos; - node->end += aml_parselength(ctx); - break; - case AML_ARG_METHOD: - dnprintf(50, " method\n"); - node->start = ctx->pos; - ctx->pos = node->end; - break; - case AML_ARG_INTEGER: - case AML_ARG_TERMOBJ: - /* Recursively parse children */ - aml_parse_object(ctx, node); - break; - case AML_ARG_TERMOBJLIST: - /* Recursively parse children */ - aml_parse_objlist(ctx, node); - break; - - default: - printf("Unknown arg: %c\n", *arg); - break; - } - - arg++; - } - - return (0); + struct aml_node *pnode; + + while (*arg) { + pnode = node; + switch (*arg) { + case AML_ARG_FLAG: + node->flag = aml_parseint(ctx, 1); + if (node->opcode == AMLOP_METHOD) { + dnprintf(50, " method %s %.2x argcount:%d serialized:%d synclevel:%d\n", + node->name, node->flag, + AML_METHOD_ARGCOUNT(node->flag), + AML_METHOD_SERIALIZED(node->flag), + AML_METHOD_SYNCLEVEL(node->flag)); + } + else { + dnprintf(50, " field %s %.2x access:%d lock:%d update:%d\n", + node->name, node->flag, + AML_FIELD_ACCESS(node->flag), + AML_FIELD_LOCK(node->flag), + AML_FIELD_UPDATE(node->flag)); + } + break; + case AML_ARG_IMPBYTE: + /* Implied byte: same as opcode */ + node->value = aml_allocint((char)node->opcode); + dnprintf(50, " ibyte: %x\n", (int8_t)node->opcode); + break; + case AML_ARG_BYTE: + if (node->opcode != AMLOP_BYTEPREFIX) { + pnode = aml_create_node(ctx, node, AMLOP_BYTEPREFIX); + } + pnode->value = aml_allocint(aml_parseint(ctx, 1)); + dnprintf(50, " byte: %x\n", pnode->value->v_integer); + break; + case AML_ARG_WORD: + if (node->opcode != AMLOP_WORDPREFIX) { + pnode = aml_create_node(ctx, node, AMLOP_WORDPREFIX); + } + pnode->value = aml_allocint(aml_parseint(ctx, 2)); + dnprintf(50, " word: %x\n", pnode->value->v_integer); + break; + case AML_ARG_DWORD: + if (node->opcode != AMLOP_DWORDPREFIX) { + pnode = aml_create_node(ctx, node, AMLOP_DWORDPREFIX); + } + pnode->value = aml_allocint(aml_parseint(ctx, 4)); + dnprintf(50, " dword: %x\n", pnode->value->v_integer); + break; + case AML_ARG_QWORD: + if (node->opcode == AMLOP_QWORDPREFIX) { + pnode = aml_create_node(ctx, node, AMLOP_QWORDPREFIX); + } + pnode->value = aml_allocint(aml_parseint(ctx, 8)); + dnprintf(50, " qword: %x\n", pnode->value->v_integer); + break; + case AML_ARG_FIELDLIST: + dnprintf(50, " fieldlist\n"); + aml_parse_fieldlist(ctx, node); + break; + case AML_ARG_BYTELIST: + dnprintf(50, " bytelist\n"); + node->start = ctx->pos; + ctx->pos = node->end; + break; + case AML_ARG_STRING: + node->value = aml_allocstr(aml_parsestr(ctx)); + dnprintf(50, " string: %s\n", node->value->v_string); + break; + case AML_ARG_NAMESTRING: + node->name = aml_parsename(ctx, "name"); + break; + case AML_ARG_NAMEREF: + pnode = aml_create_node(ctx, node, AMLOP_NAMECHAR); + pnode->name = aml_parsename(ctx, "nameref"); + break; + case AML_ARG_OBJLEN: + dnprintf(50, " pkglen\n"); + node->end = ctx->pos; + node->end += aml_parselength(ctx); + break; + case AML_ARG_METHOD: + dnprintf(50, " method\n"); + node->start = ctx->pos; + ctx->pos = node->end; + break; + case AML_ARG_INTEGER: + case AML_ARG_TERMOBJ: + /* Recursively parse children */ + aml_parse_object(ctx, node); + break; + case AML_ARG_TERMOBJLIST: + /* Recursively parse children */ + aml_parse_objlist(ctx, node); + break; + + default: + printf("Unknown arg: %c\n", *arg); + break; + } + + arg++; + } + + return (0); } void aml_addchildnode(struct aml_node *parent, struct aml_node *child) { - struct aml_node *psib; + struct aml_node *psib; + + child->parent = parent; + child->sibling = NULL; + for (psib = parent->child; psib; psib = psib->sibling) { + if (psib->sibling == NULL) { + psib->sibling = child; + return; + } + } + parent->child = child; +} + +int +aml_tstbit(const u_int8_t *pb, int bit) +{ + pb += aml_bytepos(bit); + return (*pb & (1L << aml_bitpos(bit))); +} + +void +aml_setbit(u_int8_t *pb, int bit, int val) +{ + pb += aml_bytepos(bit); + if (val) { + *pb |= (1L << aml_bitpos(bit)); + } + else { + *pb &= ~(1L << aml_bitpos(bit)); + } +} + + +/* aml_bufcpy copies/shifts buffer data, special case for aligned transfers + * dstPos/srcPos are bit positions within destination/source buffers + */ +void +aml_bufcpy(u_int8_t *pDst, int dstPos, const u_int8_t *pSrc, int srcPos, + int len) +{ + int idx; + + if (aml_bytealigned(dstPos|srcPos|len)) { + /* Aligned transfer: use memcpy */ + memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos), aml_bytelen(len)); + } + else { + /* Misaligned transfer: perform bitwise copy */ + for (idx=0; idx<len; idx++) { + aml_setbit(pDst, idx+dstPos, aml_tstbit(pSrc, idx+srcPos)); + } + } +} + +/* Copy to/from a buffer object */ +struct aml_value * +aml_bufferio(struct acpi_context *ctx, struct aml_value *pfield, struct aml_value *rhs) +{ + struct aml_value *pbuf, *rv; + + pbuf = _aml_evalnode(ctx, pfield->v_field.ref); + if (pbuf->type != AML_OBJTYPE_BUFFERFIELD) { + dnprintf(50, "Invalid bufferio!\n"); + return NULL; + } + if (rhs == NULL) { + /* Return buffer object */ + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, pfield->length, NULL, "bufferio"); + if (rv != NULL) { + aml_bufcpy(rv->v_buffer, 0, pbuf->v_buffer, + pfield->v_field.bitpos, + pfield->v_field.bitlen); + aml_showvalue(rv); + aml_freevalue(pbuf); + } + return rv; + } + + switch (rhs->type) { + case AML_OBJTYPE_INTEGER: + aml_bufcpy(pbuf->v_buffer, pfield->v_field.bitpos, (u_int8_t *)&rhs->v_integer, 0, pfield->v_field.bitlen); + break; + case AML_OBJTYPE_BUFFER: + aml_bufcpy(pbuf->v_buffer, pfield->v_field.bitpos, rhs->v_buffer, 0, pfield->v_field.bitlen); + break; + default: + dnprintf(50, "invalid type to bufferio\n"); + } + return NULL; +} + +/* Copy to/from a field object */ +struct aml_value * +aml_fieldio(struct acpi_context *ctx, struct aml_value *pfield, struct aml_value *rhs) +{ + struct aml_value *pbuf, *rv; - child->parent = parent; - child->sibling = NULL; - for (psib = parent->child; psib; psib = psib->sibling) { - if (psib->sibling == NULL) { - psib->sibling = child; - return; - } - } - parent->child = child; + pbuf = _aml_evalnode(ctx, pfield->v_field.ref); + if (pbuf->type != AML_OBJTYPE_OPREGION) { + dnprintf(50, "Invalid fieldio!\n"); + return NULL; + } + if (rhs == NULL) { + /* Return buffer object */ + rv = aml_allocvalue(AML_OBJTYPE_BUFFER, pfield->length, NULL, "bufferio"); + if (rv != NULL) { + aml_showvalue(rv); + } + return rv; + } + return pbuf; } void aml_showvalue(struct aml_value *value) { - int idx; - - if (value == NULL) - return; - switch (value->type) { - case AML_OBJTYPE_INTEGER: - dnprintf(50, "integer: %x\n", value->v_integer); - break; - case AML_OBJTYPE_STRING: - dnprintf(50, "string: %s\n", value->v_string); - break; - case AML_OBJTYPE_BUFFER: - dnprintf(50, "buffer: %d {\n", value->length); - for (idx=0; idx<value->length; idx++) { - dnprintf(50, "%s0x%.2x", (idx ? "," : ""), value->v_buffer[idx]); - } - dnprintf(50, "}\n"); - 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_DEBUGOBJ: - dnprintf(50, "debug"); - break; - case AML_OBJTYPE_DEVICE: + int idx; + + if (value == NULL) + return; + switch (value->type) { + case AML_OBJTYPE_INTEGER: + dnprintf(50, "integer: %x\n", value->v_integer); + break; + case AML_OBJTYPE_STRING: + dnprintf(50, "string: %s\n", value->v_string); + break; + case AML_OBJTYPE_BUFFER: + dnprintf(50, "buffer: %d {\n", value->length); + for (idx=0; idx<value->length; idx++) { + dnprintf(50, "%s0x%.2x", (idx ? "," : ""), value->v_buffer[idx]); + } + dnprintf(50, "}\n"); + 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_DEBUGOBJ: + dnprintf(50, "debug"); + break; + case AML_OBJTYPE_DEVICE: #if 0 - xxx - dnprintf(50, "device: %s", val->v_device->name); + xxx + dnprintf(50, "device: %s", val->v_device->name); #endif - break; - case AML_OBJTYPE_PROCESSOR: - dnprintf(50, "cpu: %x,%x,%x\n", - value->v_processor.proc_id, - value->v_processor.proc_addr, - value->v_processor.proc_len); - break; - case AML_OBJTYPE_FIELDUNIT: - dnprintf(50, "field: %.4x %x,%x\n", - value->v_field.ftype, - value->v_field.bitpos, - value->v_field.bitlen); - break; - case AML_OBJTYPE_BUFFERFIELD: - dnprintf(50, "bufferfield: %.4x %x,%x\n", - value->v_field.ftype, - value->v_field.bitpos, - value->v_field.bitlen); - break; - case AML_OBJTYPE_OPREGION: - dnprintf(50, "opregion: %s,0x%x,0x%x\n", - opregion(value->v_opregion.iospace), - value->v_opregion.iobase, - value->v_opregion.iolen); - break; - default: - printf("unknown: %d\n", value->type); - break; - } + break; + case AML_OBJTYPE_PROCESSOR: + dnprintf(50, "cpu: %x,%x,%x\n", + value->v_processor.proc_id, + value->v_processor.proc_addr, + value->v_processor.proc_len); + break; + case AML_OBJTYPE_FIELDUNIT: + dnprintf(50, "field: %.4x %x,%x\n", + value->v_field.ftype, + value->v_field.bitpos, + value->v_field.bitlen); + break; + case AML_OBJTYPE_BUFFERFIELD: + dnprintf(50, "bufferfield: %.4x %x,%x\n", + value->v_field.ftype, + value->v_field.bitpos, + value->v_field.bitlen); + break; + case AML_OBJTYPE_OPREGION: + dnprintf(50, "opregion: %s,0x%x,0x%x\n", + opregion(value->v_opregion.iospace), + value->v_opregion.iobase, + value->v_opregion.iolen); + break; + default: + printf("unknown: %d\n", value->type); + break; + } } void aml_shownode(struct aml_node *node) { - dnprintf(50, " opcode:%.4x mnem:%s %s %.2x ", - node->opcode, node->mnem ? node->mnem : "", - node->name ? node->name : "", - node->flag); - switch(node->opcode) { - case AMLOP_METHOD: - dnprintf(50, "argcount:%d serialized:%d synclevel:%d", - AML_METHOD_ARGCOUNT(node->flag), - AML_METHOD_SERIALIZED(node->flag), - AML_METHOD_SYNCLEVEL(node->flag)); - break; - case AMLOP_FIELD: - case AMLOP_BANKFIELD: - case AMLOP_INDEXFIELD: - dnprintf(50, "access:%d lock:%d update:%d\n", - AML_FIELD_ACCESS(node->flag), - AML_FIELD_LOCK(node->flag), - AML_FIELD_UPDATE(node->flag)); - break; + dnprintf(50, " opcode:%.4x mnem:%s %s %.2x ", + node->opcode, node->mnem ? node->mnem : "", + node->name ? node->name : "", + node->flag); + switch(node->opcode) { + case AMLOP_METHOD: + dnprintf(50, "argcount:%d serialized:%d synclevel:%d", + AML_METHOD_ARGCOUNT(node->flag), + AML_METHOD_SERIALIZED(node->flag), + AML_METHOD_SYNCLEVEL(node->flag)); + break; + case AMLOP_FIELD: + case AMLOP_BANKFIELD: + case AMLOP_INDEXFIELD: + dnprintf(50, "access:%d lock:%d update:%d\n", + AML_FIELD_ACCESS(node->flag), + AML_FIELD_LOCK(node->flag), + AML_FIELD_UPDATE(node->flag)); + break; - case AMLOP_BYTEPREFIX: - dnprintf(50, "byte: %.2x", node->value->v_integer); - break; - case AMLOP_WORDPREFIX: - dnprintf(50, "word: %.4x", node->value->v_integer); - break; - case AMLOP_DWORDPREFIX: - dnprintf(50, "dword: %.8x", node->value->v_integer); - break; - case AMLOP_STRINGPREFIX: - dnprintf(50, "string: %s", node->value->v_string); - break; - } - dnprintf(50, "\n"); + case AMLOP_BYTEPREFIX: + dnprintf(50, "byte: %.2x", node->value->v_integer); + break; + case AMLOP_WORDPREFIX: + dnprintf(50, "word: %.4x", node->value->v_integer); + break; + case AMLOP_DWORDPREFIX: + dnprintf(50, "dword: %.8x", node->value->v_integer); + break; + case AMLOP_STRINGPREFIX: + dnprintf(50, "string: %s", node->value->v_string); + break; + } + dnprintf(50, "\n"); } struct aml_node * aml_parse_object(struct acpi_context *ctx, struct aml_node *parent) { - struct aml_optable *optab = aml_table; - struct aml_node *node; - - /* Get AML Opcode; if it is an embedded name, extract name */ - node = aml_create_node(ctx, parent, -1); - while (optab->opcode != 0xFFFF) { - if (optab->opcode == node->opcode) { - node->mnem = optab->mnem; - aml_parseargs(ctx, node, optab->args); - return node; - } - optab++; - } - printf("Invalid AML Opcode : @ %.4x %.4x\n", ctx->pos - ctx->start, node->opcode); - acpi_os_freemem(node); + struct aml_optable *optab = aml_table; + struct aml_node *node; + + /* Get AML Opcode; if it is an embedded name, extract name */ + node = aml_create_node(ctx, parent, -1); + while (optab->opcode != 0xFFFF) { + if (optab->opcode == node->opcode) { + node->mnem = optab->mnem; + aml_parseargs(ctx, node, optab->args); + return node; + } + optab++; + } + printf("Invalid AML Opcode : @ %.4x %.4x\n", ctx->pos - ctx->start, node->opcode); + acpi_os_freemem(node); - return NULL; + return NULL; } void aml_walktree(struct aml_node *node, int depth) { - int idx; - - while(node) { - dnprintf(50, " %d ", depth); - for(idx=0; idx<depth; idx++) { - dnprintf(50, ".."); - } - aml_shownode(node); - aml_walktree(node->child, depth+1); - node = node->sibling; - } + int idx; + + while(node) { + dnprintf(50, " %d ", depth); + for(idx=0; idx<depth; idx++) { + dnprintf(50, ".."); + } + aml_shownode(node); + aml_walktree(node->child, depth+1); + node = node->sibling; + } } void aml_walkroot() { - aml_walktree(aml_root.child, 0); + aml_walktree(aml_root.child, 0); } int @@ -1835,19 +2259,19 @@ aml_find_node(struct aml_node *node, const char *name, void (*cbproc)(struct aml_node *, void *arg), void *arg) { - const char *nn; - - while (node) { - if ((nn = node->name) != NULL) { - if (*nn == AMLOP_ROOTCHAR) nn++; - while (*nn == AMLOP_PARENTPREFIX) nn++; - if (!strcmp(name, nn)) - cbproc(node, arg); - } - aml_find_node(node->child, name, cbproc, arg); - node = node->sibling; - } - return (0); + const char *nn; + + while (node) { + if ((nn = node->name) != NULL) { + if (*nn == AMLOP_ROOTCHAR) nn++; + while (*nn == AMLOP_PARENTPREFIX) nn++; + if (!strcmp(name, nn)) + cbproc(node, arg); + } + aml_find_node(node->child, name, cbproc, arg); + node = node->sibling; + } + return (0); } const char hext[] = "0123456789ABCDEF"; @@ -1855,18 +2279,18 @@ const char hext[] = "0123456789ABCDEF"; const char * aml_eisaid(u_int32_t pid) { - static char id[8]; - - id[0] = '@' + ((pid >> 2) & 0x1F); - id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7); - id[2] = '@' + ((pid >> 8) & 0x1F); - id[3] = hext[(pid >> 20) & 0xF]; - id[4] = hext[(pid >> 16) & 0xF]; - id[5] = hext[(pid >> 28) & 0xF]; - id[6] = hext[(pid >> 24) & 0xF]; - id[7] = 0; - - return id; + static char id[8]; + + id[0] = '@' + ((pid >> 2) & 0x1F); + id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7); + id[2] = '@' + ((pid >> 8) & 0x1F); + id[3] = hext[(pid >> 20) & 0xF]; + id[4] = hext[(pid >> 16) & 0xF]; + id[5] = hext[(pid >> 28) & 0xF]; + id[6] = hext[(pid >> 24) & 0xF]; + id[7] = 0; + + return id; } void ex5(struct aml_node *, void *); @@ -1874,46 +2298,46 @@ void ex5(struct aml_node *, void *); void ex5(struct aml_node *node, void *arg) { - struct acpi_softc *sc = arg; - struct aml_value res, env; + struct acpi_softc *sc = arg; + struct aml_value res, env; - memset(&res, 0, sizeof(res)); - memset(&env, 0, sizeof(env)); + memset(&res, 0, sizeof(res)); + memset(&env, 0, sizeof(env)); - dnprintf(50, "Value is: %s\n", node->name); - aml_eval_object(sc, node->child, &res, &env); - aml_showvalue(&res); + dnprintf(50, "Value is: %s\n", node->name); + aml_eval_object(sc, node->child, &res, &env); + aml_showvalue(&res); } int aml_parse_objlist(struct acpi_context *ctx, struct aml_node *parent) { - while (ctx->pos < parent->end) { - aml_parse_object(ctx, parent); - } - if (ctx->pos != parent->end) { - dnprintf(50, "parseobjlist: invalid end!\n"); - ctx->pos = parent->end; - return (1); - } - return (0); + while (ctx->pos < parent->end) { + aml_parse_object(ctx, parent); + } + if (ctx->pos != parent->end) { + dnprintf(50, "parseobjlist: invalid end!\n"); + ctx->pos = parent->end; + return (1); + } + return (0); } int acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length) { - struct acpi_context ctx; + struct acpi_context ctx; - memset(&ctx, 0, sizeof(ctx)); - ctx.pos = start; - ctx.start = start; - ctx.end = ctx.start + length; + memset(&ctx, 0, sizeof(ctx)); + ctx.pos = start; + ctx.start = start; + ctx.end = ctx.start + length; - aml_root.start = start; - aml_root.end = start + length; + aml_root.start = start; + aml_root.end = start + length; - aml_parse_objlist(&ctx, &aml_root); - dnprintf(50, " : parsed %d AML bytes\n", length); + aml_parse_objlist(&ctx, &aml_root); + dnprintf(50, " : parsed %d AML bytes\n", length); - return (0); + return (0); } |