summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/acpi/amltypes.h16
-rw-r--r--sys/dev/acpi/dsdt.c1153
-rw-r--r--sys/dev/acpi/dsdt.h10
3 files changed, 744 insertions, 435 deletions
diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h
index 098a649f9d8..1a50e6eba1a 100644
--- a/sys/dev/acpi/amltypes.h
+++ b/sys/dev/acpi/amltypes.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amltypes.h,v 1.7 2005/12/13 07:23:34 marco Exp $ */
+/* $OpenBSD: amltypes.h,v 1.8 2005/12/28 03:04:56 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -172,7 +172,9 @@ enum aml_objecttype {
AML_OBJTYPE_THERMZONE,
AML_OBJTYPE_BUFFERFIELD,
AML_OBJTYPE_DDBHANDLE,
- AML_OBJTYPE_DEBUGOBJ
+ AML_OBJTYPE_DEBUGOBJ,
+
+ AML_OBJTYPE_NAMEREF = 0x100
};
/* AML Opcode Arguments */
@@ -186,9 +188,8 @@ enum aml_objecttype {
#define AML_ARG_STRING 's'
#define AML_ARG_BYTELIST 'B'
#define AML_ARG_REVISION 'R'
-#define AML_ARG_RESULT 'r'
-#define AML_ARG_SUPERNAME 'S'
+#define AML_ARG_METHOD 'M'
#define AML_ARG_NAMESTRING 'N'
#define AML_ARG_NAMEREF 'n'
#define AML_ARG_FIELDLIST 'F'
@@ -196,8 +197,6 @@ enum aml_objecttype {
#define AML_ARG_TERMOBJLIST 'T'
#define AML_ARG_TERMOBJ 't'
-#define AML_ARG_DATAOBJLIST 'O'
-#define AML_ARG_DATAOBJ 'o'
#define AML_METHOD_ARGCOUNT(v) (((v) >> 0) & 0x7)
#define AML_METHOD_SERIALIZED(v) (((v) >> 3) & 0x1)
@@ -232,7 +231,6 @@ struct aml_value
struct aml_value *vpackage;
struct acpi_gas vopregion;
struct {
- int argcount;
struct aml_value *args;
struct aml_value *locals;
struct aml_value *result;
@@ -264,6 +262,10 @@ struct aml_value
#define v_powerrsrc _.vpowerrsrc
#define v_thrmzone _.vthrmzone
+#define aml_intval(v) ((v)->v_integer)
+#define aml_strval(v) ((v)->v_string)
+#define aml_bufval(v) ((v)->v_buffer)
+
struct aml_node
{
struct aml_node *parent;
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index a7341a7deed..446a904eacd 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.11 2005/12/16 00:08:53 jordan Exp $ */
+/* $OpenBSD: dsdt.c,v 1.12 2005/12/28 03:04:56 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -43,46 +43,103 @@ struct aml_stream
u_int8_t *pos;
};
+struct acpi_stack
+{
+ 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;
+};
+
int aml_isnamedop(u_int16_t);
-u_int8_t *aml_decodelength(u_int8_t *, int *);
-u_int8_t *aml_decodename(u_int8_t *, const char **, const char *);
-u_int8_t *aml_getopcode(u_int8_t *, u_int16_t *);
-u_int8_t *aml_parseargs(struct acpi_softc *, struct aml_node *, u_int8_t *, const char *);
-u_int8_t *aml_parse_object(struct acpi_softc *, struct aml_node *, u_int8_t *);
+void aml_parsefieldlist(struct acpi_softc *sc, struct aml_node *parent);
+int aml_parselength(struct acpi_softc *sc);
+const char *aml_parsename(struct acpi_softc *sc, const char *);
+u_int16_t aml_getopcode(struct acpi_softc *sc);
+int aml_parseargs(struct acpi_softc *, struct aml_node *, const char *);
+struct aml_node *aml_parse_object(struct acpi_softc *, struct aml_node *);
+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_int32_t val);
int aml_msb(u_int32_t val);
-void aml_addchildnode(struct aml_node *, struct aml_node *);
-void aml_walktree(struct aml_node *, int);
+
void aml_walkroot(void);
+void aml_addchildnode(struct aml_node *, struct aml_node *);
+struct aml_node *aml_create_node(struct acpi_softc *, struct aml_node *, int opcode);
+struct aml_node *aml_find_name(struct acpi_softc *, struct aml_node *, const char *);
int64_t aml_evalmath(u_int16_t, int64_t, int64_t);
int aml_testlogical(u_int16_t, long, long);
int aml_strcmp(u_int16_t opcode, const char *lhs, const char *rhs);
-void aml_setinteger(struct aml_value *, int, int64_t);
+int aml_evalint(struct acpi_softc *, struct aml_node *, struct aml_value *);
+int aml_eval_object(struct acpi_softc *, struct aml_node *, struct aml_value *, struct aml_value *);
+void aml_copyvalue(struct aml_value *, const struct aml_value *);
+void aml_setinteger(struct aml_value *, int64_t);
void aml_setstring(struct aml_value *, const char *);
void aml_setbuffer(struct aml_value *, int, u_int8_t *);
-void aml_setfield(struct aml_value *, int, int, struct aml_node *);
+void aml_setfield(struct aml_value *, int, int, struct aml_node *, struct aml_node *);
void aml_setopregion(struct aml_value *, int, int, u_int64_t);
void aml_setpackage(struct aml_value *, struct aml_node *);
void aml_setprocessor(struct aml_value *, u_int8_t, u_int32_t, u_int8_t);
-void aml_setnodevalue(struct acpi_softc *, struct aml_node *, const struct aml_value *);
-void aml_setnodeinteger(struct acpi_softc *, struct aml_node *, int64_t);
+struct aml_value *aml_getnodevalue(struct acpi_softc *, struct aml_node *, struct aml_value *);
+void aml_setnodevalue(struct acpi_softc *, struct aml_node *, const struct aml_value *, struct aml_value *);
+void aml_setnodeinteger(struct acpi_softc *, struct aml_node *, int64_t, struct aml_value *);
int aml_match(struct acpi_softc *, int, const struct aml_value *, const struct aml_value *);
int aml_cmpobj(struct acpi_softc *, const struct aml_value *, const struct aml_value *);
+const char *aml_parsestr(struct acpi_softc *);
+u_int64_t aml_parseint(struct acpi_softc *, int);
+
+struct aml_node aml_root;
+
+const char *
+aml_parsestr(struct acpi_softc *sc)
+{
+ const char *str = sc->amlpc.pos;
+
+ sc->amlpc.pos += strlen(str)+1;
+ return str;
+}
+
+/* Read value from AML bytestream */
+uint64_t
+aml_parseint(struct acpi_softc *sc, int size)
+{
+ u_int8_t *pc = sc->amlpc.pos;
+
+ sc->amlpc.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);
+}
+
void
-aml_setinteger(struct aml_value *val, int size, int64_t value)
+aml_setinteger(struct aml_value *val, int64_t value)
{
val->type = AML_OBJTYPE_INTEGER;
val->v_integer = value;
- val->length = size;
+ val->length = 0;
}
void
@@ -102,8 +159,9 @@ aml_setbuffer(struct aml_value *val, int size, u_int8_t *ptr)
}
void
-aml_setfield(struct aml_value *val, int bitpos, int bitlen, struct aml_node *ref)
+aml_setfield(struct aml_value *val, int bitpos, int bitlen, struct aml_node *ref, struct aml_node *node)
{
+ printf("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;
@@ -134,6 +192,7 @@ 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)
{
+ printf("setopregion: %.2x %.4x %.8x\n", addrtype, size, addr);
val->type = AML_OBJTYPE_OPREGION;
val->v_opregion.address_space_id = addrtype;
val->v_opregion.register_bit_width = 0;
@@ -149,87 +208,115 @@ aml_setopregion(struct aml_value *val, int addrtype, int size, u_int64_t addr)
* 0x80 = length is lower 4 bits + 2 bytes
* 0xC0 = length is lower 4 bits + 3 bytes
*/
-u_int8_t *
-aml_decodelength(u_int8_t *pos, int *length)
+int
+aml_parselength(struct acpi_softc *sc)
{
u_int8_t lcode;
+ int ival;
- lcode = *(pos++);
-
- *length = (lcode & 0xF);
- switch(lcode >> 6) {
- case 0x01:
- *length += (pos[0] << 4L);
- return pos+1;
- case 0x02:
- *length += (pos[0] << 4L) + (pos[1] << 12L);
- return pos+2;
- case 0x03:
- *length += (pos[0] << 4L) + (pos[1] << 12L) + (pos[2] << 20L);
- return pos+3;
- default:
- *length = (lcode & 0x3F);
- return pos;
+ lcode = aml_parseint(sc, 1);
+ if (lcode <= 0x3F) {
+ return lcode;
+ }
+
+ ival = lcode & 0xF;
+ if (lcode >= 0x40) ival |= aml_parseint(sc, 1) << 4;
+ if (lcode >= 0x80) ival |= aml_parseint(sc, 1) << 12;
+ if (lcode >= 0xC0) ival |= aml_parseint(sc, 1) << 20;
+
+ return ival;
+}
+
+void
+aml_parsefieldlist(struct acpi_softc *sc, struct aml_node *node)
+{
+ u_int8_t type, attr;
+ int len, start;
+ struct aml_node *pf;
+
+ start = 0;
+ printf("-- parsefield\n");
+ while (sc->amlpc.pos < node->end) {
+ switch (aml_parseint(sc, 1)) {
+ case 0x00: /* reserved */
+ len = aml_parselength(sc);
+ start += len;
+ break;
+ case 0x01: /* access field */
+ type = aml_parseint(sc, 1);
+ attr = aml_parseint(sc, 1);
+ printf(" type=%.2x attr=%.2x\n", type, attr);
+ break;
+ default: /* named field */
+ --sc->amlpc.pos;
+ pf = aml_create_node(sc, node, AMLOP_CREATEFIELD);
+ pf->name = aml_parsename(sc, "field");
+ len = aml_parselength(sc);
+
+ aml_setfield(&pf->value, start, len, node, pf);
+ start += len;
+ }
}
}
/* Decode AML Namestring from stream */
-u_int8_t *
-aml_decodename(u_int8_t *pos, const char **ref, const char *lbl)
+const char *
+aml_parsename(struct acpi_softc *sc, const char *lbl)
{
- int count, pfxlen, idx;
- char *name;
+ int count, pfxlen;
+ char *name, *pn;
u_int8_t *base;
- base = pos;
- if (*pos == AMLOP_ROOTCHAR) {
- pos++;
+ pfxlen = 0;
+ if (sc->amlpc.pos[pfxlen] == AMLOP_ROOTCHAR) {
+ pfxlen++;
}
- while (*pos == AMLOP_PARENTPREFIX) {
- pos++;
+ while (sc->amlpc.pos[pfxlen] == AMLOP_PARENTPREFIX) {
+ pfxlen++;
}
- pfxlen = pos - base;
- count = 1;
- if (*pos == AMLOP_MULTINAMEPREFIX) {
- count = *(++pos);
- pos++;
- }
- else if (*pos == AMLOP_DUALNAMEPREFIX) {
- count = 2;
- pos++;
- }
- else if (*pos == 0) {
+ switch (sc->amlpc.pos[pfxlen]) {
+ case 0x00:
count = 0;
- pos++;
+ base = sc->amlpc.pos + pfxlen + 1;
+ break;
+ case AMLOP_MULTINAMEPREFIX:
+ count = sc->amlpc.pos[pfxlen+1];
+ base = sc->amlpc.pos + pfxlen + 2;
+ break;
+ case AMLOP_DUALNAMEPREFIX:
+ count = 2;
+ base = sc->amlpc.pos + pfxlen + 1;
+ break;
+ default:
+ count = 1;
+ base = sc->amlpc.pos + pfxlen;
+ break;
}
name = malloc(pfxlen + count * 5, M_DEVBUF, M_WAITOK);
- if (name == NULL)
- return pos;
+ pn = name;
- if (pfxlen > 0) {
- memcpy(name, base, pfxlen);
- }
+ while (pfxlen--)
+ *(pn++) = *(sc->amlpc.pos++);
+
/* Copy name segments in chunks of 4 bytes */
- base = name+pfxlen;
- for(idx=0; idx<count; idx++) {
- if (idx) *(base++) = '.';
- memcpy(base, pos, 4);
- pos += 4;
+ while (count--) {
+ memcpy(pn, base, 4);
+ if (count) {
+ *(pn + 4) = '.';
+ pn++;
+ }
+ pn += 4;
base += 4;
}
- *base = 0;
+ *pn = 0;
dnprintf(50, " acpi_name (%s): %s\n", lbl, name);
- if (ref != NULL) {
- *ref = name;
- }
- else {
- free(name, M_DEVBUF);
- }
- return pos;
+ sc->amlpc.pos = base;
+
+ return name;
}
/* Is this opcode an encoded name? */
@@ -395,30 +482,30 @@ aml_testlogical(u_int16_t opcode, long lhs, long rhs)
* Some opcodes are multibyte
* Strings can also be embedded within the stream
*/
-u_int8_t *
-aml_getopcode(u_int8_t *pos, u_int16_t *opcode)
+u_int16_t
+aml_getopcode(struct acpi_softc *sc)
{
u_int16_t twocode;
+ u_int16_t opcode;
/* Check for encoded name */
- if (aml_isnamedop(*pos)) {
- *opcode = AMLOP_NAMECHAR;
- return pos;
+ if (aml_isnamedop(*sc->amlpc.pos)) {
+ return AMLOP_NAMECHAR;
}
- *opcode = *(pos++);
- twocode = (*opcode << 8L) + *pos;
+ opcode = aml_parseint(sc, 1);
+ twocode = (opcode << 8L) + *sc->amlpc.pos;
/* Check multi-byte opcodes */
if (twocode == AMLOP_LNOTEQUAL ||
twocode == AMLOP_LLESSEQUAL ||
twocode == AMLOP_LGREATEREQUAL ||
- *opcode == AMLOP_EXTPREFIX) {
- pos++;
- *opcode = twocode;
+ opcode == AMLOP_EXTPREFIX) {
+ sc->amlpc.pos++;
+ return twocode;
}
- return pos;
+ return opcode;
}
struct aml_optable aml_table[] = {
@@ -458,29 +545,29 @@ struct aml_optable aml_table[] = {
{ AMLOP_WHILE, "While", "piT", },
{ AMLOP_BREAK, "Break", "", },
{ AMLOP_CONTINUE, "Continue", "", },
- { AMLOP_RETURN, "Return", "o", },
+ { AMLOP_RETURN, "Return", "t", },
{ AMLOP_FATAL, "Fatal", "bdi", },
{ AMLOP_NOP, "Nop", "", },
{ AMLOP_BREAKPOINT, "BreakPoint", "", },
/* Arithmetic operations */
- { AMLOP_INCREMENT, "Increment", "S", },
- { AMLOP_DECREMENT, "Decrement", "S", },
- { AMLOP_ADD, "Add", "iir", },
- { AMLOP_SUBTRACT, "Subtract", "iir", },
- { AMLOP_MULTIPLY, "Multiply", "iir", },
- { AMLOP_DIVIDE, "Divide", "iirr", },
- { AMLOP_SHL, "ShiftLeft", "iir", },
- { AMLOP_SHR, "ShiftRight", "iir", },
- { AMLOP_AND, "And", "iir", },
- { AMLOP_NAND, "Nand", "iir", },
- { AMLOP_OR, "Or", "iir", },
- { AMLOP_NOR, "Nor", "iir", },
- { AMLOP_XOR, "Xor", "iir", },
- { AMLOP_NOT, "Not", "ir", },
- { AMLOP_MOD, "Mod", "iir", },
- { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "ir", },
- { AMLOP_FINDSETRIGHTBIT, "FindSetRightBit", "ir", },
+ { 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", },
@@ -495,20 +582,20 @@ struct aml_optable aml_table[] = {
/* Named objects */
{ AMLOP_EVENT, "Event", "N", },
- { AMLOP_NAME, "Name", "No", },
+ { AMLOP_NAME, "Name", "Nt", },
{ AMLOP_MUTEX, "Mutex", "Nb", },
- { AMLOP_ALIAS, "Alias", "Nn", },
+ { AMLOP_ALIAS, "Alias", "Nt", },
{ AMLOP_DATAREGION, "DataRegion", "Nttt" },
- { AMLOP_OPREGION, "OpRegion", "Nfii" },
+ { AMLOP_OPREGION, "OpRegion", "Nbii" },
{ AMLOP_SCOPE, "Scope", "pNT" },
- { AMLOP_DEVICE, "Device", "pNO" },
- { AMLOP_POWERRSRC, "Power Resource", "pNbwO" },
+ { AMLOP_DEVICE, "Device", "pNT" },
+ { AMLOP_POWERRSRC, "Power Resource", "pNbwT" },
{ AMLOP_THERMALZONE, "ThermalZone", "pNT" },
- { AMLOP_METHOD, "Method", "pNfT", },
- { AMLOP_PROCESSOR, "Processor", "pNbdbO", },
+ { AMLOP_METHOD, "Method", "pNfM", },
+ { AMLOP_PROCESSOR, "Processor", "pNbdbT", },
{ AMLOP_FIELD, "Field", "pNfF" },
- { AMLOP_INDEXFIELD, "IndexField", "pNnfF" },
- { AMLOP_BANKFIELD, "BankField", "pNnifF" },
+ { AMLOP_INDEXFIELD, "IndexField", "pNtfF" },
+ { AMLOP_BANKFIELD, "BankField", "pNtifF" },
/* Field operations */
{ AMLOP_CREATEFIELD, "CreateField", "tiiN", },
@@ -519,53 +606,49 @@ struct aml_optable aml_table[] = {
{ AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", },
/* Conversion operations */
- { AMLOP_TOINTEGER, "ToInteger", "tr", },
- { AMLOP_TOBUFFER, "ToBuffer", "tr", },
- { AMLOP_TODECSTRING, "ToDecString", "ir", },
- { AMLOP_TOHEXSTRING, "ToHexString", "ir", },
+ { AMLOP_TOINTEGER, "ToInteger", "tt", },
+ { AMLOP_TOBUFFER, "ToBuffer", "tt", },
+ { AMLOP_TODECSTRING, "ToDecString", "it", },
+ { AMLOP_TOHEXSTRING, "ToHexString", "it", },
{ AMLOP_TOSTRING, "ToString", "t", },
- { AMLOP_FROMBCD, "FromBCD", "ir", },
- { AMLOP_TOBCD, "ToBCD", "ir", },
- { AMLOP_MID, "Mid", "tiir", },
+ { AMLOP_FROMBCD, "FromBCD", "it", },
+ { AMLOP_TOBCD, "ToBCD", "it", },
+ { AMLOP_MID, "Mid", "tiit", },
/* Mutex/Signal operations */
- { AMLOP_ACQUIRE, "Acquire", "Sw", },
- { AMLOP_RELEASE, "Release", "S", },
- { AMLOP_SIGNAL, "Signal", "S", },
- { AMLOP_WAIT, "Wait", "Si", },
- { AMLOP_RESET, "Reset", "S", },
+ { AMLOP_ACQUIRE, "Acquire", "tw", },
+ { AMLOP_RELEASE, "Release", "t", },
+ { AMLOP_SIGNAL, "Signal", "t", },
+ { AMLOP_WAIT, "Wait", "ti", },
+ { AMLOP_RESET, "Reset", "t", },
- { AMLOP_INDEX, "Index", "ttr", },
+ { AMLOP_INDEX, "Index", "ttt", },
{ AMLOP_PACKAGE, "Package", "pbT", },
{ AMLOP_VARPACKAGE, "VarPackage", "piT", },
{ AMLOP_DEREFOF, "DerefOf", "t", },
- { AMLOP_REFOF, "RefOf", "S", },
- { AMLOP_CONDREFOF, "CondRef", "SS", },
+ { AMLOP_REFOF, "RefOf", "t", },
+ { AMLOP_CONDREFOF, "CondRef", "tt", },
{ AMLOP_LOADTABLE, "LoadTable", "tttttt" },
{ AMLOP_STALL, "Stall", "i", },
{ AMLOP_SLEEP, "Sleep", "i", },
- { AMLOP_LOAD, "Load", "NS" },
- { AMLOP_UNLOAD, "Unload", "S" },
- { AMLOP_STORE, "Store", "oS", },
- { AMLOP_CONCAT, "Concat", "ttr" },
- { AMLOP_CONCATRES, "ConcatRes", "ttr" },
- { AMLOP_NOTIFY, "Notify", "Si" },
- { AMLOP_SIZEOF, "Sizeof", "S", },
+ { AMLOP_LOAD, "Load", "tt" },
+ { 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", "S", },
- { AMLOP_COPYOBJECT, "CopyObject", "tS" },
+ { AMLOP_OBJECTTYPE, "ObjectType", "t", },
+ { AMLOP_COPYOBJECT, "CopyObject", "tt" },
{ 0xFFFF }
};
-int aml_evalnode(struct acpi_softc *, struct aml_node *, struct aml_value *,
- struct aml_value *);
-void aml_copyvalue(struct aml_value *, const struct aml_value *);
-
/* Copy an AML value object */
void aml_copyvalue(struct aml_value *dst, const struct aml_value *src)
{
- dst->type = src->type;
+ dst->type = src->type;
dst->length = src->length;
switch (dst->type) {
@@ -578,6 +661,9 @@ void aml_copyvalue(struct aml_value *dst, const struct aml_value *src)
case AML_OBJTYPE_BUFFER:
dst->v_buffer = src->v_buffer;
break;
+ case AML_OBJTYPE_PACKAGE:
+ dst->v_package = src->v_package;
+ break;
}
}
@@ -597,75 +683,144 @@ childOf(struct aml_node *parent, int child)
#define AML_NUM_LOCALS 8
#define AML_INTSTRLEN 16
-struct aml_value aml_debug;
+struct aml_value aml_debugobj;
-void
-aml_setnodevalue(struct acpi_softc *sc, struct aml_node *node, const struct aml_value *val)
+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:
- aml_copyvalue(&aml_debug, val);
- break;
+ 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_REVISION:
case AMLOP_BYTEPREFIX:
case AMLOP_WORDPREFIX:
case AMLOP_DWORDPREFIX:
case AMLOP_QWORDPREFIX:
- printf("read-only\n");
- break;
+ case AMLOP_STRINGPREFIX:
+ return &node->value;
default:
- aml_copyvalue(&node->value, val);
+ printf("aml_getnodevalue: no type: %.4x\n", node->opcode);
break;
}
+ return NULL;
}
void
-aml_setnodeinteger(struct acpi_softc *sc, struct aml_node *node, int64_t value)
+aml_setnodevalue(struct acpi_softc *sc, struct aml_node *node, const struct aml_value *val,
+ struct aml_value *env)
{
- struct aml_value ival;
+ struct aml_value *dest = NULL;
+ struct aml_value lhs;
+ int id;
- aml_setinteger(&ival, 0, value);
- aml_setnodevalue(sc, node, &ival);
-}
+ if (node == NULL) {
+ printf("aml_setnodevalue: null\n");
+ return;
+ }
+ printf("--- setnodevalue:\n");
+ aml_shownode(node);
+ aml_showvalue((struct aml_value *)val);
+ switch (node->opcode) {
+ case AMLOP_DEBUG:
+ dest = &aml_debugobj;
+ break;
-#if 0
-int
-aml_callmethod(struct acpi_softc *sc, struct aml_node *parent, const char *method,
- int nargs, struct aml_value *args, struct aml_value *result)
-{
- struct aml_node *pnode;
- struct aml_value env;
+ 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;
- pnode = aml_findnode(sc, parent, method);
- if (pnode == NULL || pnode->type != AML_METHOD)
- return (-1);
+ 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;
- if (nargs != AML_METHOD_ARGCOUNT(pnode->flag))
- return (-1);
+ case AMLOP_NAMECHAR:
+ return aml_setnodevalue(sc, aml_find_name(sc, NULL, node->name), val, env);
- env.type = AML_OBJTYPE_METHOD;
- env.v_method.argcount = nargs;
- env.v_method.args = args;
- env.v_method.locals = malloc(sizeof(struct aml_value) * AML_NUM_LOCALS,
- M_DEVBUF, M_WAITOK);
- aml_evalnode(sc, pnode, result, &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;
-int
-aml_readfield(struct acpi_softc *sc, const struct aml_value *field, struct aml_value *dest)
-{
+ 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) {
+ printf("aml_setnodeval: %.4x\n", node->opcode);
+ aml_copyvalue(dest, val);
+ }
}
-int
-aml_writefield(struct acpi_softc *sc, const struct aml_value *field, const struct aml_value *src)
+void
+aml_setnodeinteger(struct acpi_softc *sc, struct aml_node *node, int64_t value,
+ struct aml_value *env)
{
+ struct aml_value ival;
+
+ aml_setinteger(&ival, value);
+ aml_setnodevalue(sc, node, &ival, env);
}
-#endif
int aml_cmpobj(struct acpi_softc *sc, const struct aml_value *lhs,
const struct aml_value *rhs)
@@ -713,19 +868,96 @@ aml_match(struct acpi_softc *sc, int mtype, const struct aml_value *lhs,
return (0);
}
+struct aml_node *
+aml_create_node(struct acpi_softc *sc, struct aml_node *parent, int opcode)
+{
+ struct aml_node *node;
+
+ node = malloc(sizeof(struct aml_node), M_DEVBUF, M_WAITOK);
+ memset(node, 0, sizeof(struct aml_node));
+
+ node->start = sc->amlpc.pos;
+ node->opcode = (opcode == -1) ? aml_getopcode(sc) : opcode;
+ aml_addchildnode(parent, node);
+
+ return node;
+}
+
+int
+aml_evalint(struct acpi_softc *sc, struct aml_node *node, struct aml_value *env)
+{
+ struct aml_value ival;
+
+ aml_eval_object(sc, node, &ival, env);
+ if (ival.type == AML_OBJTYPE_INTEGER)
+ return ival.v_integer;
+
+ 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;
+}
+
+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);
+
+ if (root != NULL) {
+ printf("found eval object : %s, %.4x\n", root->name, root->opcode);
+ return aml_eval_object(sc, root, result, env);
+ }
+ return (0);
+}
+
int
-aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *result,
+aml_eval_object(struct acpi_softc *sc, struct aml_node *node, struct aml_value *result,
struct aml_value *env)
{
- struct aml_value lhs, rhs, tmp, pkg, op1, op2;
+ struct aml_value lhs, rhs, tmp, pkg;
+ struct aml_value *px;
int64_t iresult, id, idx;
- struct aml_node *cflow;
+ struct aml_node *cflow = NULL;
+ int i1, i2, i3;
char *tmpstr;
if (node == NULL)
return (-1);
- cflow = NULL;
+ printf("--- Evaluating object:\n");
+ aml_shownode(node);
+
switch (node->opcode) {
case AMLOP_ZERO:
case AMLOP_ONE:
@@ -736,30 +968,43 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_QWORDPREFIX:
case AMLOP_STRINGPREFIX:
case AMLOP_REVISION:
- case AMLOP_BUFFER:
aml_copyvalue(result, &node->value);
break;
+ case AMLOP_BUFFER:
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ printf("@@@@@@@@@@@@@@ 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_DEBUG:
- aml_copyvalue(result, &aml_debug);
+ aml_copyvalue(result, &aml_debugobj);
break;
+ case AMLOP_NAME:
+ case AMLOP_ALIAS:
+ return aml_eval_object(sc, childOf(node, 0), result, env);
+
case AMLOP_PROCESSOR:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
- aml_evalnode(sc, childOf(node, 2), &tmp, env);
- aml_setprocessor(result, lhs.v_integer, rhs.v_integer, tmp.v_integer);
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
- aml_setopregion(result, node->flag, rhs.v_integer, lhs.v_integer);
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- if (lhs.v_integer) {
+ i1 = aml_evalint(sc, childOf(node,0), env);
+ if (i1 != 0) {
/* Test true, select 'If' block */
cflow = childOf(node, 1);
}
@@ -769,7 +1014,7 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
}
while (cflow) {
/* Execute all instructions in scope block */
- aml_evalnode(sc, cflow, result, env);
+ aml_eval_object(sc, cflow, result, env);
cflow = cflow->sibling;
}
break;
@@ -779,8 +1024,8 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
if (cflow == NULL) {
/* Perform While test */
cflow = childOf(node, 1);
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- if (lhs.v_integer == 0)
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ if (i1 == 0)
break;
}
else if (cflow->opcode == AMLOP_BREAK)
@@ -790,14 +1035,14 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
cflow = NULL;
else {
/* Execute all instructions in scope block */
- aml_evalnode(sc, cflow, result, env);
+ aml_eval_object(sc, cflow, result, env);
cflow = cflow->sibling;
}
}
break;
case AMLOP_RETURN:
- aml_evalnode(sc, childOf(node, 0), result, env);
+ aml_eval_object(sc, childOf(node, 0), result, env);
break;
case AMLOP_ARG0:
@@ -808,9 +1053,8 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_ARG5:
case AMLOP_ARG6:
id = node->opcode - AMLOP_ARG0;
- if (id < env->v_method.argcount) {
- aml_copyvalue(result, &env->v_method.args[id]);
- }
+ if (id < env->length)
+ aml_copyvalue(result, &node->value.v_method.locals[id]);
break;
case AMLOP_LOCAL0:
@@ -827,41 +1071,43 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_PACKAGE:
case AMLOP_VARPACKAGE:
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ printf("package = %d\n", i1);
+ result->type = AML_OBJTYPE_PACKAGE;
+ result->length = i1;
+
+ result->v_package = malloc(i1 * sizeof(struct aml_value), M_DEVBUF, M_WAITOK);
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- /* ASSERT: lhs.type == AML_OBJTYPE_INTEGER */
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_evalmath(node->opcode, lhs.v_integer, 0);
- aml_setnodeinteger(sc, childOf(node, 0), iresult);
- }
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- /* ASSERT: lhs.type == AML_OBJTYPE_INTEGER */
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_evalmath(node->opcode, lhs.v_integer, 0);
- aml_setnodeinteger(sc, childOf(node, 1), iresult);
- }
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER && rhs.type == AML_OBJTYPE_INTEGER) {
- /* Set remainder */
- iresult = aml_evalmath(AMLOP_MOD, lhs.v_integer, rhs.v_integer);
- aml_setnodeinteger(sc, childOf(node, 2), iresult);
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ i2 = aml_evalint(sc, childOf(node, 1), env);
- /* Set quotient */
- iresult = aml_evalmath(node->opcode, lhs.v_integer, rhs.v_integer);
- aml_setnodeinteger(sc, childOf(node, 3), iresult);
- }
+ /* 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:
@@ -875,30 +1121,25 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_NOR:
case AMLOP_XOR:
case AMLOP_MOD:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER && rhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_evalmath(node->opcode, lhs.v_integer, rhs.v_integer);
- aml_setnodeinteger(sc, childOf(node, 2), iresult);
- }
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_testlogical(node->opcode, lhs.v_integer, 0);
- aml_setinteger(result, 0, iresult);
- }
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(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);
- aml_setinteger(result, 0, iresult);
- }
+ 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:
@@ -907,73 +1148,63 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_LGREATEREQUAL:
case AMLOP_LGREATER:
case AMLOP_LLESS:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
+ 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, 0, iresult);
+ aml_setinteger(result, iresult);
break;
case AMLOP_CREATEFIELD:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- aml_evalnode(sc, childOf(node, 2), &rhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer, rhs.v_integer, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer, 1, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer * 8, 8, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer * 8, 16, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer * 8, 32, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- aml_setfield(result, lhs.v_integer * 8, 64, childOf(node, 0));
- }
+ 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:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_dec2bcd(lhs.v_integer);
- aml_setnodeinteger(sc, childOf(node, 1), iresult);
- }
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ iresult = aml_dec2bcd(i1);
+ aml_setnodeinteger(sc, childOf(node, 1), iresult, env);
break;
case AMLOP_FROMBCD:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- if (lhs.type == AML_OBJTYPE_INTEGER) {
- iresult = aml_bcd2dec(lhs.v_integer);
- aml_setnodeinteger(sc, childOf(node, 1), iresult);
- }
+ 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 = malloc(AML_INTSTRLEN+1, M_DEVBUF, M_WAITOK);
if (tmpstr != NULL) {
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
+ aml_eval_object(sc, childOf(node, 0), &lhs, env);
if (lhs.type == AML_OBJTYPE_INTEGER)
snprintf(tmpstr, AML_INTSTRLEN, "%d", lhs.v_integer);
}
@@ -981,16 +1212,16 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
case AMLOP_TOHEXSTRING:
tmpstr = malloc(AML_INTSTRLEN+1, M_DEVBUF, M_WAITOK);
if (tmpstr != NULL) {
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
+ 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_evalnode(sc, childOf(node, 0), &tmp, env);
- aml_evalnode(sc, childOf(node, 1), &lhs, env);
- aml_evalnode(sc, childOf(node, 2), &rhs, env);
+ 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);
@@ -1001,72 +1232,77 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
break;
case AMLOP_STALL:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- dnprintf(50, "aml_stall: %d\n", lhs.v_integer);
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ dnprintf(50, "aml_stall: %d\n", i1);
break;
case AMLOP_SLEEP:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- dnprintf(50, "aml_sleep: %d\n", lhs.v_integer);
+ i1 = aml_evalint(sc, childOf(node, 0), env);
+ dnprintf(50, "aml_sleep: %d\n", i1);
break;
case AMLOP_OBJECTTYPE:
- aml_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_setinteger(result, 1, lhs.type);
+ aml_eval_object(sc, childOf(node, 0), &lhs, env);
+ aml_setinteger(result, lhs.type);
break;
case AMLOP_NAMECHAR: /* Inline method call */
- cflow = node->sibling;
-
- /* node = aml_findnode(sc, node->mnem); */
- if (node->opcode == AMLOP_METHOD) {
- /* Arguments are following in the stream */
- lhs.v_method.argcount = AML_METHOD_ARGCOUNT(node->flag);
- lhs.v_method.args = malloc(sizeof(struct aml_value) * lhs.v_method.argcount,
- M_DEVBUF, M_WAITOK);
- lhs.v_method.locals = malloc(sizeof(struct aml_value) * AML_NUM_LOCALS,
- M_DEVBUF, M_WAITOK);
- for (id=0; id<lhs.v_method.argcount; id++) {
- aml_evalnode(sc, cflow, &lhs.v_method.args[id], env);
- cflow = cflow->sibling;
- }
-
- /* Evaluate method itself */
- aml_evalnode(sc, node, result, &lhs);
- free(lhs.v_method.args, M_DEVBUF);
- free(lhs.v_method.locals, M_DEVBUF);
- }
+ aml_eval_name(sc, NULL, node->name, result, env);
break;
case AMLOP_METHOD:
- for (cflow=childOf(node, 0); cflow; cflow=cflow->sibling) {
- aml_evalnode(sc, cflow, result, env);
+ printf("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 = malloc(lhs.length * sizeof(struct aml_value), M_DEVBUF, M_WAITOK);
+ memset(lhs.v_method.args, 0, lhs.length * sizeof(struct aml_value));
+ }
+ lhs.v_method.locals = malloc(8 * sizeof(struct aml_value), M_DEVBUF, M_WAITOK);
+
+ for (i1=0; i1<lhs.length; i1++) {
+ printf(" 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_evalnode(sc, childOf(node, 0), &lhs, env);
- aml_evalnode(sc, childOf(node, 1), &rhs, env);
+ 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_evalnode(sc, childOf(node, 0), &pkg, env);
- aml_evalnode(sc, childOf(node, 1), &op1, env);
- aml_evalnode(sc, childOf(node, 2), &lhs, env);
- aml_evalnode(sc, childOf(node, 3), &op2, env);
- aml_evalnode(sc, childOf(node, 4), &lhs, env);
- aml_evalnode(sc, childOf(node, 5), &tmp, env);
+ 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;
- for (idx=tmp.v_integer; idx < pkg.length; idx++) {
- if (aml_match(sc, op1.v_integer, &pkg.v_package[idx], &lhs) ||
- aml_match(sc, op2.v_integer, &pkg.v_package[idx], &rhs)) {
+ 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, 0, iresult);
+ aml_setinteger(result, iresult);
}
break;
@@ -1077,18 +1313,17 @@ aml_evalnode(struct acpi_softc *sc, struct aml_node *node, struct aml_value *res
return (0);
}
-u_int8_t *
-aml_parseargs(struct acpi_softc *sc, struct aml_node *node, u_int8_t *pos,
- const char *arg)
+int
+aml_parseargs(struct acpi_softc *sc, struct aml_node *node, const char *arg)
{
- int len;
- u_int8_t *nxtpos;
+ struct aml_node *pnode;
+ //struct aml_value *i1, *i2;
- nxtpos = pos;
while (*arg) {
+ pnode = node;
switch (*arg) {
case AML_ARG_FLAG:
- node->flag = *(u_int8_t *)pos;
+ node->flag = aml_parseint(sc, 1);
if (node->opcode == AMLOP_METHOD) {
dnprintf(50, " method %s %.2x argcount:%d serialized:%d synclevel:%d\n",
node->name, node->flag,
@@ -1103,89 +1338,87 @@ aml_parseargs(struct acpi_softc *sc, struct aml_node *node, u_int8_t *pos,
AML_FIELD_LOCK(node->flag),
AML_FIELD_UPDATE(node->flag));
}
- nxtpos = pos+1;
break;
case AML_ARG_IMPBYTE:
/* Implied byte: same as opcode */
+ aml_setinteger(&node->value, (int8_t)node->opcode);
dnprintf(50, " ibyte: %x\n", (int8_t)node->opcode);
- aml_setinteger(&node->value, 1, (int8_t)node->opcode);
break;
case AML_ARG_BYTE:
- dnprintf(50, " byte: %x\n", *(u_int8_t *)pos);
- if (node->opcode == AMLOP_BYTEPREFIX) {
- aml_setinteger(&node->value, 1, *(int8_t *)pos);
+ if (node->opcode != AMLOP_BYTEPREFIX) {
+ pnode = aml_create_node(sc, node, AMLOP_BYTEPREFIX);
}
- nxtpos = pos+1;
+ aml_setinteger(&pnode->value, (int8_t)aml_parseint(sc, 1));
+ dnprintf(50, " byte: %x\n", pnode->value.v_integer);
break;
case AML_ARG_WORD:
- dnprintf(50, " word: %x\n", *(u_int16_t *)pos);
- if (node->opcode == AMLOP_WORDPREFIX) {
- aml_setinteger(&node->value, 2, (int16_t)letoh16(*(u_int16_t *)pos));
+ if (node->opcode != AMLOP_WORDPREFIX) {
+ pnode = aml_create_node(sc, node, AMLOP_WORDPREFIX);
}
- nxtpos = pos+2;
+ aml_setinteger(&pnode->value, (int16_t)aml_parseint(sc, 2));
+ dnprintf(50, " word: %x\n", pnode->value.v_integer);
break;
case AML_ARG_DWORD:
- dnprintf(50, " dword: %x\n", *(u_int32_t *)pos);
- if (node->opcode == AMLOP_DWORDPREFIX) {
- aml_setinteger(&node->value, 4, (int32_t)letoh32(*(u_int32_t *)pos));
+ if (node->opcode != AMLOP_DWORDPREFIX) {
+ pnode = aml_create_node(sc, node, AMLOP_DWORDPREFIX);
}
- nxtpos = pos+4;
+ aml_setinteger(&pnode->value, (int32_t)aml_parseint(sc, 4));
+ dnprintf(50, " dword: %x\n", pnode->value.v_integer);
break;
case AML_ARG_QWORD:
- dnprintf(50, " qword: %x\n", *(u_int32_t *)pos);
if (node->opcode == AMLOP_QWORDPREFIX) {
- aml_setinteger(&node->value, 8, (int64_t)letoh64(*(u_int64_t *)pos));
+ pnode = aml_create_node(sc, node, AMLOP_QWORDPREFIX);
}
- nxtpos = pos+8;
+ aml_setinteger(&pnode->value, aml_parseint(sc, 8));
+ dnprintf(50, " qword: %x\n", pnode->value.v_integer);
break;
case AML_ARG_FIELDLIST:
dnprintf(50, " fieldlist\n");
- nxtpos = node->end;
+ aml_parsefieldlist(sc, node);
break;
case AML_ARG_BYTELIST:
dnprintf(50, " bytelist\n");
- aml_setbuffer(&node->value, node->end - pos, pos);
- nxtpos = node->end;
+ aml_setbuffer(&node->value, node->end - sc->amlpc.pos, sc->amlpc.pos);
+ sc->amlpc.pos = node->end;
break;
case AML_ARG_STRING:
- dnprintf(50, " string: %s\n", pos);
- len = strlen((const char *)pos);
- aml_setstring(&node->value, (const char *)pos);
- nxtpos = pos + len + 1;
+ aml_setstring(&node->value, aml_parsestr(sc));
+ dnprintf(50, " string: %s\n", node->value.v_string);
break;
case AML_ARG_NAMESTRING:
- nxtpos = aml_decodename(pos, &node->name, "name");
+ node->name = aml_parsename(sc, "name");
break;
case AML_ARG_NAMEREF:
- nxtpos = aml_decodename(pos, NULL, "ref");
+ pnode = aml_create_node(sc, node, AMLOP_NAMECHAR);
+ pnode->name = aml_parsename(sc, "nameref");
break;
case AML_ARG_OBJLEN:
- nxtpos = aml_decodelength(pos, &len);
- node->end = pos + len;
+ node->end = sc->amlpc.pos;
+ node->end += aml_parselength(sc);
break;
case AML_ARG_INTEGER:
- case AML_ARG_DATAOBJ:
case AML_ARG_TERMOBJ:
- case AML_ARG_RESULT:
- case AML_ARG_SUPERNAME:
- nxtpos = aml_parse_object(sc, node, pos);
+ /* Recursively parse children */
+ aml_parse_object(sc, node);
break;
case AML_ARG_TERMOBJLIST:
- case AML_ARG_DATAOBJLIST:
- while (nxtpos && nxtpos < node->end) {
- nxtpos = aml_parse_object(sc, node, nxtpos);
+ case AML_ARG_METHOD:
+ /* Recursively parse children */
+ while (sc->amlpc.pos < node->end) {
+ aml_parse_object(sc, node);
}
+ sc->amlpc.pos = node->end;
break;
+
default:
printf("Unknown arg: %c\n", *arg);
break;
}
- pos = nxtpos;
arg++;
}
- return pos;
+ return (0);
}
void
@@ -1204,36 +1437,108 @@ aml_addchildnode(struct aml_node *parent, struct aml_node *child)
parent->child = child;
}
-u_int8_t *
-aml_parse_object(struct acpi_softc *sc, struct aml_node *parent, u_int8_t *pos)
+void
+aml_showvalue(struct aml_value *value)
{
- struct aml_optable *optab = aml_table;
- u_int8_t *nxtpos;
- struct aml_node *node;
+ int idx;
- node = malloc(sizeof(struct aml_node), M_DEVBUF, M_WAITOK);
- if (node == NULL)
- return pos;
- memset(node, 0, sizeof(struct aml_node));
+ switch (value->type) {
+ case AML_OBJTYPE_INTEGER:
+ printf("integer: %x\n", value->v_integer);
+ break;
+ case AML_OBJTYPE_STRING:
+ printf("string: %s\n", value->v_string);
+ break;
+ case AML_OBJTYPE_BUFFER:
+ printf("buffer: %d {\n", value->length);
+ for (idx=0; idx<value->length; idx++) {
+ printf("%s0x%.2x", (idx ? "," : ""), value->v_buffer[idx]);
+ }
+ printf("}\n");
+ break;
+ case AML_OBJTYPE_PACKAGE:
+ printf("package: %d {\n", value->length);
+ for (idx=0; idx<value->length; idx++)
+ aml_showvalue(&value->v_package[idx]);
+ printf("}\n");
+ break;
+ default:
+ printf("unknown: %d\n", value->type);
+ break;
+ }
+}
+
+void
+aml_shownode(struct aml_node *node)
+{
+ printf(" opcode:%.4x mnem:%s %s %.2x ",
+ node->opcode, node->mnem ? node->mnem : "",
+ node->name ? node->name : "",
+ node->flag);
+ switch(node->opcode) {
+ case AMLOP_METHOD:
+ printf("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:
+ printf("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:
+ printf("byte: %.2x", node->value.v_integer);
+ break;
+ case AMLOP_WORDPREFIX:
+ printf("word: %.4x", node->value.v_integer);
+ break;
+ case AMLOP_DWORDPREFIX:
+ printf("dword: %.8x", node->value.v_integer);
+ break;
+ case AMLOP_STRINGPREFIX:
+ printf("string: %s", node->value.v_string);
+ break;
+ }
+ printf("\n");
+}
+
+struct aml_node *
+aml_parse_object(struct acpi_softc *sc, struct aml_node *parent)
+{
+ struct aml_optable *optab = aml_table;
+ struct aml_node *node, *pr;
+ int idx;
/* Get AML Opcode; if it is an embedded name, extract name */
- node->start = pos;
- nxtpos = aml_getopcode(pos, &node->opcode);
+ node = aml_create_node(sc, parent, -1);
if (node->opcode == AMLOP_NAMECHAR) {
- aml_addchildnode(parent, node);
- dnprintf(50, "opcode: xxxx <name>\n");
- return aml_decodename(pos, &node->mnem, "embed");
+ node->name = aml_parsename(sc, "embed");
+ node->mnem = "embed";
+
+ pr = aml_find_name(sc, NULL, node->name);
+ if (pr != NULL && pr->opcode == AMLOP_METHOD) {
+ /* Parse method arguments as siblings */
+ for (idx=0; idx<AML_METHOD_ARGCOUNT(pr->flag); idx++) {
+ //printf(" parsing method %s:%d\n", pr->name, idx);
+ aml_parse_object(sc, node);
+ }
+ }
+ return (node);
}
while (optab->opcode != 0xFFFF) {
if (optab->opcode == node->opcode) {
- dnprintf(50, "opcode: %.4x = %s\n", node->opcode, optab->mnem);
- aml_addchildnode(parent, node);
node->mnem = optab->mnem;
- return aml_parseargs(sc, node, nxtpos, optab->args);
+ aml_parseargs(sc, node, optab->args);
+ return node;
}
optab++;
}
- printf("Invalid AML Opcode : %.4x\n", node->opcode);
+ printf("Invalid AML Opcode : @ %.4x %.4x\n", sc->amlpc.pos - sc->amlpc.start, node->opcode);
free(node, M_DEVBUF);
return NULL;
@@ -1249,46 +1554,12 @@ aml_walktree(struct aml_node *node, int depth)
for(idx=0; idx<depth; idx++) {
printf("..");
}
- printf(" opcode:%.4x mnem:%s %s ",
- node->opcode, node->mnem, node->name ? node->name : "");
- switch(node->opcode) {
- case AMLOP_METHOD:
- printf(" 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:
- printf("byte: %.2x", node->value.v_integer);
- break;
- case AMLOP_WORDPREFIX:
- printf("word: %.4x", node->value.v_integer);
- break;
- case AMLOP_DWORDPREFIX:
- printf("dword: %.8x", node->value.v_integer);
- break;
- case AMLOP_STRINGPREFIX:
- printf("string: %s", node->value.v_string);
- break;
- }
- printf("\n");
+ aml_shownode(node);
aml_walktree(node->child, depth+1);
-
node = node->sibling;
}
}
-struct aml_node aml_root;
-
void
aml_walkroot()
{
@@ -1300,9 +1571,15 @@ 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 (node->name && !strcmp(name, node->name))
- cbproc(node, arg);
+ 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;
}
@@ -1328,13 +1605,35 @@ aml_eisaid(u_int32_t pid)
return id;
}
+void ex5(struct aml_node *, void *);
+
+void
+ex5(struct aml_node *node, void *arg)
+{
+ struct acpi_softc *sc = arg;
+ struct aml_value res, env;
+
+ memset(&res, 0, sizeof(res));
+ memset(&env, 0, sizeof(env));
+
+ printf("Value is: %s\n", node->name);
+ aml_eval_object(sc, node->child, &res, &env);
+ aml_showvalue(&res);
+}
+
int
acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length)
{
- u_int8_t *pos, *nxtpos;
+ struct aml_value rv, env;
+
+ sc->amlpc.pos = start;
+ sc->amlpc.start = start;
+ sc->amlpc.end = start+length;
- for (pos = start; pos && pos < start+length; pos=nxtpos) {
- nxtpos = aml_parse_object(sc, &aml_root, pos);
+ memset(&rv, 0, sizeof(rv));
+ memset(&env, 0, sizeof(env));
+ while (sc->amlpc.pos < sc->amlpc.end) {
+ aml_parse_object(sc, &aml_root);
}
printf(" : parsed %d AML bytes\n", length);
diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h
index 28f521835c8..df96ddaeeb3 100644
--- a/sys/dev/acpi/dsdt.h
+++ b/sys/dev/acpi/dsdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.2 2005/12/16 00:08:53 jordan Exp $ */
+/* $OpenBSD: dsdt.h,v 1.3 2005/12/28 03:04:56 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -23,4 +23,12 @@ int aml_find_node(struct aml_node *, const char *,
void (*)(struct aml_node *, void *), void *);
int acpi_parse_aml(struct acpi_softc *, u_int8_t *, u_int32_t);
+int aml_eval_object(struct acpi_softc *, struct aml_node *,
+ struct aml_value *, struct aml_value *);
+int aml_eval_name(struct acpi_softc *, struct aml_node *, const char *,
+ struct aml_value *, struct aml_value *);
+void aml_showvalue(struct aml_value *);
+
+void aml_walktree(struct aml_node *, int);
+
#endif /* __DEV_ACPI_DSDT_H__ */