summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2006-10-15 15:28:33 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2006-10-15 15:28:33 +0000
commitb184ee62f5813867f043c6b03dedb36b0a694e58 (patch)
tree7012be4364e5a77571eb2d8d5b00b2b5793a3e29 /sys/dev/acpi
parent746868310e78c07183a535508747c75998f6b8ae (diff)
Fixed buggy if-else end scope
Fixed multi-level deref/index for thinkpads Some KNF ok marco@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpiec.c14
-rw-r--r--sys/dev/acpi/dsdt.c189
2 files changed, 105 insertions, 98 deletions
diff --git a/sys/dev/acpi/acpiec.c b/sys/dev/acpi/acpiec.c
index bd0274aad05..be45f654f19 100644
--- a/sys/dev/acpi/acpiec.c
+++ b/sys/dev/acpi/acpiec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiec.c,v 1.6 2006/10/14 19:59:51 canacar Exp $ */
+/* $OpenBSD: acpiec.c,v 1.7 2006/10/15 15:28:32 jordan Exp $ */
/*
* Copyright (c) 2006 Can Erkin Acar <canacar@openbsd.org>
*
@@ -329,18 +329,11 @@ acpiec_attach(struct device *parent, struct device *self, void *aux)
acpiec_get_events(sc);
sc->sc_acpi->sc_ec = sc;
- sc->sc_acpi->sc_ec_gpemask = (1L << sc->sc_gpe);
- dnprintf(10, "%s: GPE: %d (%x)\n", DEVNAME(sc),
- sc->sc_gpe, sc->sc_acpi->sc_ec_gpemask);
+ dnprintf(10, "%s: GPE: %d\n", DEVNAME(sc), sc->sc_gpe);
acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler, sc, "acpiec");
-#if 0
- /* Enable EC interrupt */
- acpi_enable_gpe(sc->sc_acpi, sc->sc_acpi->sc_ec_gpemask);
-#endif
-
printf(": %s\n", sc->sc_devnode->parent->name);
}
@@ -531,10 +524,9 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
int
acpiec_reg(struct acpiec_softc *sc)
{
- struct aml_value *res, arg[2];
+ struct aml_value arg[2];
struct aml_node *root;
- memset(&res, 0, sizeof(res));
memset(&arg, 0, sizeof(arg));
#define REG_TYPE_EC 3
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index b03eac25b9d..0fe67ccfc27 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.51 2006/10/15 07:30:01 canacar Exp $ */
+/* $OpenBSD: dsdt.c,v 1.52 2006/10/15 15:28:32 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -400,16 +400,16 @@ aml_setbit(u_int8_t *pb, int bit, int val)
*pb &= ~aml_bitmask(bit);
}
-#if 0
-#define aml_gasio(sc,tt,bb,ll,bp,bl,sz,buf,mode) acpi_gasio(sc,mode,tt,(bb)+((bp)>>3),(sz)>>3,(bl)>>3,buf)
-#else
+/* Read/Write to hardware I/O fields */
void
aml_gasio(struct acpi_softc *sc, int type, uint64_t base, uint64_t length,
int bitpos, int bitlen, int size, void *buf, int mode)
{
- acpi_gasio(sc, mode, type, base+(bitpos>>3), (size>>3), (bitlen>>3), buf);
+ dnprintf(15,"-- aml_gasio: %.2x base:%llx len:%llx bitpos:%.4x bitlen:%.4x sz:%.2x mode=%s\n",
+ type, base, length, bitpos, bitlen, size, mode==ACPI_IOREAD?"read":"write");
+ acpi_gasio(sc, mode, type, base+(bitpos>>3),
+ (size>>3), (bitlen>>3), buf);
}
-#endif
/*
* @@@: Notify functions
@@ -765,13 +765,11 @@ aml_parsenode(struct aml_node *node, uint8_t *start, uint8_t **end,
struct aml_scope *scope;
/* Don't parse zero-length scope */
- if (start == *end) {
+ if (start == *end)
return 0;
- }
scope = aml_pushscope(NULL, start, *end, node);
- if (res == NULL) {
+ if (res == NULL)
res = aml_alloctmp(scope, 1);
- }
while (scope != NULL) {
while (scope->pos < scope->end)
aml_parseop(scope, res);
@@ -792,9 +790,8 @@ void
aml_setbufint(struct aml_value *dst, int bitpos, int bitlen,
struct aml_value *src)
{
- if (src->type != AML_OBJTYPE_BUFFER) {
+ if (src->type != AML_OBJTYPE_BUFFER)
aml_die("wrong setbufint type\n");
- }
if (bitlen < aml_intlen) {
/* XXX: Endian issues?? */
/* Return integer type */
@@ -813,9 +810,8 @@ void
aml_getbufint(struct aml_value *src, int bitpos, int bitlen,
struct aml_value *dst)
{
- if (dst->type != AML_OBJTYPE_BUFFER) {
+ if (dst->type != AML_OBJTYPE_BUFFER)
aml_die("wrong getbufint type\n");
- }
switch (src->type) {
case AML_OBJTYPE_INTEGER:
aml_bufcpy(dst->v_buffer, bitpos, &src->v_integer, 0, bitlen);
@@ -839,24 +835,26 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
struct aml_value opr, *pop;
int bpos, blen, aligned, mask;
+ pop = field->v_field.ref1;
+ bpos = field->v_field.bitpos;
+ blen = field->v_field.bitlen;
+
memset(&opr, 0x0, sizeof(opr));
switch (field->v_field.type) {
case AMLOP_INDEXFIELD:
/* Set Index */
- aml_setvalue(scope, field->v_field.ref1, NULL, field->v_field.bitpos>>3);
+ aml_setvalue(scope, pop, NULL, bpos>>3);
aml_fieldio(scope, field->v_field.ref2, res, mode);
break;
case AMLOP_BANKFIELD:
/* Set Bank */
- aml_setvalue(scope, field->v_field.ref1, NULL, field->v_field.ref3);
+ aml_setvalue(scope, pop, NULL, field->v_field.ref3);
aml_fieldio(scope, field->v_field.ref2, res, mode);
break;
case AMLOP_FIELD:
/* This is an I/O field */
- pop = field->v_field.ref1;
- if (pop->type != AML_OBJTYPE_OPREGION) {
+ if (pop->type != AML_OBJTYPE_OPREGION)
aml_die("Not an opregion!\n");
- }
/* Get field access size */
switch (AML_FIELD_ACCESS(field->v_field.flags)) {
@@ -876,14 +874,15 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
}
/* Get aligned bitpos/bitlength */
- bpos = field->v_field.bitpos & ~mask;
- blen = ((field->v_field.bitpos & mask) +
- field->v_field.bitlen + mask) & ~mask;
+ blen = ((bpos & mask) + blen + mask) & ~mask;
+ bpos = bpos & ~mask;
aligned = (bpos == field->v_field.bitpos &&
blen == field->v_field.bitlen);
/* Verify that I/O is in range */
#if 0
+ /* XXX: some I/O ranges are on dword boundaries, but their length is incorrect
+ * eg. dword access, but length of opregion is 2 bytes. */
if ((bpos+blen) >= (pop->v_opregion.iolen * 8)) {
aml_die("Out of bounds I/O!!! region:%x:%llx:%x %x\n",
pop->v_opregion.iospace,
@@ -899,7 +898,7 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
aml_gasio(scope->sc, pop->v_opregion.iospace,
pop->v_opregion.iobase,
pop->v_opregion.iolen,
- bpos, blen, mask+1,
+ bpos, blen, mask,
opr.v_buffer,
ACPI_IOREAD);
aml_setbufint(res, field->v_field.bitpos & mask,
@@ -920,7 +919,7 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
aml_gasio(scope->sc, pop->v_opregion.iospace,
pop->v_opregion.iobase,
pop->v_opregion.iolen,
- bpos, blen, mask+1,
+ bpos, blen, mask,
opr.v_buffer,
ACPI_IOREAD);
}
@@ -933,7 +932,7 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
aml_gasio(scope->sc, pop->v_opregion.iospace,
pop->v_opregion.iobase,
pop->v_opregion.iolen,
- bpos, blen, mask+1,
+ bpos, blen, mask,
opr.v_buffer,
ACPI_IOWRITE);
}
@@ -941,15 +940,10 @@ aml_fieldio(struct aml_scope *scope, struct aml_value *field,
break;
default:
/* This is a buffer field */
- bpos = field->v_field.bitpos;
- blen = field->v_field.bitlen;
- pop = field->v_field.ref1;
- if (mode == ACPI_IOREAD) {
+ if (mode == ACPI_IOREAD)
aml_setbufint(res, bpos, blen, pop);
- }
- else {
+ else
aml_getbufint(res, bpos, blen, pop);
- }
break;
}
}
@@ -985,15 +979,13 @@ aml_showvalue(struct aml_value *val)
break;
case AML_OBJTYPE_PACKAGE:
dnprintf(0," package: %.2x\n", val->length);
- for (idx=0; idx<val->length; idx++) {
+ for (idx=0; idx<val->length; idx++)
aml_showvalue(val->v_package[idx]);
- }
break;
case AML_OBJTYPE_BUFFER:
dnprintf(0," buffer: %.2x {", val->length);
- for (idx=0; idx<val->length; idx++) {
+ for (idx=0; idx<val->length; idx++)
dnprintf(0,"%s%.2x", idx ? ", " : "", val->v_buffer[idx]);
- }
dnprintf(0,"}\n");
break;
case AML_OBJTYPE_FIELDUNIT:
@@ -1050,6 +1042,7 @@ struct aml_value *
aml_dereftarget(struct aml_scope *scope, struct aml_value *ref)
{
struct aml_node *node;
+ struct aml_value *cbuf;
int index;
for(;;) {
@@ -1063,12 +1056,24 @@ aml_dereftarget(struct aml_scope *scope, struct aml_value *ref)
index = ref->v_objref.index;
ref = aml_dereftarget(scope, ref->v_objref.ref);
if (index != -1) {
+ if (index >= ref->length)
+ aml_die("index.buf out of bounds: %d/%d\n", index, ref->length);
switch (ref->type) {
case AML_OBJTYPE_PACKAGE:
ref = ref->v_package[index];
break;
+ case AML_OBJTYPE_BUFFER:
+ case AML_OBJTYPE_STRING:
+ /* Create a temporary BufferField into the string/buffer */
+ cbuf = aml_alloctmp(scope, 1);
+ _aml_setvalue(cbuf, AML_OBJTYPE_BUFFERFIELD, 0, NULL);
+ cbuf->v_field.type = AMLOP_CREATEBYTEFIELD;
+ cbuf->v_field.bitpos = index * 8;
+ cbuf->v_field.bitlen = 8;
+ cbuf->v_field.ref1 = ref;
+ return cbuf;
default:
- aml_die("Index");
+ aml_die("unknown index type: %d", ref->type);
break;
}
}
@@ -1134,6 +1139,7 @@ aml_val2int(struct aml_value *rval)
return (ival);
}
+/* Sets value into LHS: lhs must already be cleared */
struct aml_value *
_aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
{
@@ -1145,7 +1151,7 @@ _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
lhs->v_integer = ival;
break;
case AML_OBJTYPE_METHOD:
- lhs->v_integer = ival;
+ lhs->v_method.flags = ival;
break;
case AML_OBJTYPE_NAMEREF:
lhs->v_nameref = (uint8_t *)bval;
@@ -1171,21 +1177,21 @@ _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
case AML_OBJTYPE_PACKAGE:
lhs->length = ival;
lhs->v_package = (struct aml_value **)acpi_os_malloc(ival * sizeof(struct aml_value *));
- for (ival=0; ival<lhs->length; ival++) {
+ for (ival=0; ival<lhs->length; ival++)
lhs->v_package[ival] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
- }
break;
}
return lhs;
}
+/* Copy object to another value: lhs must already be cleared */
void
aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
{
int idx;
- lhs->type = rhs->type & ~AML_STATIC;
- switch (lhs->type) {
+ lhs->type = rhs->type;
+ switch (lhs->type & ~AML_STATIC) {
case AML_OBJTYPE_UNINITIALIZED:
break;
case AML_OBJTYPE_INTEGER:
@@ -1206,9 +1212,8 @@ aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
break;
case AML_OBJTYPE_PACKAGE:
_aml_setvalue(lhs, rhs->type, rhs->length, NULL);
- for (idx=0; idx<rhs->length; idx++) {
+ for (idx=0; idx<rhs->length; idx++)
aml_copyvalue(lhs->v_package[idx], rhs->v_package[idx]);
- }
break;
case AML_OBJTYPE_OBJREF:
_aml_setvalue(lhs, rhs->type, rhs->v_objref.index, rhs->v_objref.ref);
@@ -1219,13 +1224,12 @@ aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
}
}
-/* Guts of the code: Assign one value to another */
+/* Guts of the code: Assign one value to another. LHS may contain a previous value */
void
aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
struct aml_value *rhs, int64_t ival)
{
struct aml_value tmpint;
- struct aml_value *olhs;
/* Use integer as result */
if (rhs == NULL) {
@@ -1233,8 +1237,11 @@ aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
rhs = _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, ival, NULL);
}
- olhs = lhs;
lhs = aml_dereftarget(scope, lhs);
+ if (lhs->stack) {
+ /* ACPI: Overwrite writing to LocalX */
+ aml_freevalue(lhs);
+ }
switch (lhs->type) {
case AML_OBJTYPE_UNINITIALIZED:
@@ -1251,40 +1258,32 @@ aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
lhs->v_integer = aml_val2int(rhs);
break;
case AML_OBJTYPE_BUFFER:
- if (lhs->node) {
+ if (lhs->node)
dnprintf(40,"named.buffer\n");
- }
aml_freevalue(lhs);
- if (rhs->type == AML_OBJTYPE_BUFFER) {
- _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer);
- }
- else if (rhs->type == AML_OBJTYPE_INTEGER) {
+ if (rhs->type == AML_OBJTYPE_BUFFER)
+ _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length, rhs->v_buffer);
+ else if (rhs->type == AML_OBJTYPE_INTEGER)
_aml_setvalue(lhs, AML_OBJTYPE_BUFFER, sizeof(rhs->v_integer),
&rhs->v_integer);
- }
- else if (rhs->type == AML_OBJTYPE_STRING) {
+ else if (rhs->type == AML_OBJTYPE_STRING)
_aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length, rhs->v_string);
- }
else {
//aml_showvalue(rhs);
aml_die("setvalue.buf");
- }
+ }
break;
case AML_OBJTYPE_STRING:
- if (lhs->node) {
+ if (lhs->node)
dnprintf(40,"named string\n");
- }
aml_freevalue(lhs);
- if (rhs->type == AML_OBJTYPE_STRING) {
- _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string);
- }
- else if (rhs->type == AML_OBJTYPE_BUFFER) {
+ if (rhs->type == AML_OBJTYPE_STRING)
+ _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length, rhs->v_string);
+ else if (rhs->type == AML_OBJTYPE_BUFFER)
_aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length, rhs->v_buffer);
- }
- else if (rhs->type == AML_OBJTYPE_INTEGER) {
+ else if (rhs->type == AML_OBJTYPE_INTEGER)
_aml_setvalue(lhs, AML_OBJTYPE_STRING, 10, NULL);
snprintf(lhs->v_string, lhs->length, "%lld", rhs->v_integer);
- }
else {
//aml_showvalue(rhs);
aml_die("setvalue.str");
@@ -1557,9 +1556,7 @@ aml_evalmethod(struct aml_node *node,
struct aml_value *res)
{
struct aml_scope *scope;
-#ifdef ACPI_DEBUG
- int idx;
-#endif
+
scope = aml_pushscope(NULL, node->value->v_method.start,
node->value->v_method.end, node);
scope->args = argv;
@@ -1572,9 +1569,9 @@ aml_evalmethod(struct aml_node *node,
dnprintf(10,"calling [%s] (%d args)\n",
aml_nodename(node),
scope->nargs);
- for (idx=0; idx<scope->nargs; idx++) {
- dnprintf(10, " arg%d: ", idx);
- aml_showvalue(&scope->args[idx]);
+ for (argc=0; argc<scope->nargs; argc++) {
+ dnprintf(10, " arg%d: ", argc);
+ aml_showvalue(&scope->args[argc]);
}
while (scope->pos < scope->end)
aml_parseterm(scope, res);
@@ -2189,14 +2186,17 @@ aml_parseif(struct aml_scope *scope, int opcode, struct aml_value *res)
test = aml_parseint(scope, AML_ANYINT);
dnprintf(40, "@ iftest: %llx\n", test);
- while (test && scope->pos && scope->pos < end) {
+ while (test && scope->pos < end) {
/* Parse if scope */
aml_parseterm(scope, res);
}
+ if (scope->pos >= scope->end)
+ return res;
+
if (*end == AMLOP_ELSE) {
scope->pos = ++end;
end = aml_parseend(scope);
- while (!test && scope->pos && scope->pos < end) {
+ while (!test && scope->pos < end) {
/* Parse ELSE scope */
aml_parseterm(scope, res);
}
@@ -2593,6 +2593,15 @@ aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
tmparg = aml_alloctmp(scope, 4);
switch (opcode) {
case AMLOP_INDEX:
+ _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
+ aml_parsetarget(scope, &tmparg[LHS], NULL);
+
+ res->v_objref.index = aml_parseint(scope, AML_ANYINT);
+ res->v_objref.ref = aml_dereftarget(scope, &tmparg[LHS]);
+
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+ aml_setvalue(scope, &tmparg[DST], res, 0);
+#if 0
aml_parsetarget(scope, res, NULL);
opcode = aml_parseint(scope, AML_ANYINT);
aml_parsetarget(scope, &tmparg[DST], NULL);
@@ -2603,6 +2612,7 @@ aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
res->v_objref.index = opcode;
aml_setvalue(scope, &tmparg[DST], res, 0);
}
+#endif
break;
case AMLOP_DEREFOF:
aml_parseop(scope, res);
@@ -2616,22 +2626,27 @@ aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
}
break;
case AMLOP_ARG0 ... AMLOP_ARG6:
- if (scope && scope->args) {
- opcode -= AMLOP_ARG0;
- if (opcode >= scope->nargs) {
- aml_die("arg out of range: %x\n", opcode);
- }
-
- /* Create OBJREF to stack variable */
- _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, &scope->args[opcode]);
- }
+ opcode -= AMLOP_ARG0;
+ if (scope->args == NULL || opcode >= scope->nargs)
+ aml_die("arg %d out of range", opcode);
+
+ /* Create OBJREF to stack variable */
+ _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
+ &scope->args[opcode]);
break;
case AMLOP_LOCAL0 ... AMLOP_LOCAL7:
- if (scope && scope->locals) {
- /* Create OBJREF to stack variable */
- _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
- &scope->locals[opcode - AMLOP_LOCAL0]);
+ opcode -= AMLOP_LOCAL0;
+
+ /* No locals exist.. lazy allocate */
+ if (scope->locals == NULL) {
+ dnprintf(0, "Lazy alloc locals\n");
+ scope->locals = aml_alloctmp(scope, AML_MAX_LOCAL);
}
+
+ /* Create OBJREF to stack variable */
+ _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
+ &scope->locals[opcode]);
+ res->v_objref.ref->stack = opcode+AMLOP_LOCAL0;
break;
case AMLOP_LOAD:
aml_parseop(scope, &tmparg[LHS]);