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