summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2006-10-12 16:38:22 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2006-10-12 16:38:22 +0000
commit6da6d7f85be2b5a66f1fabf7819fcf4571af7818 (patch)
treeb02a1468c2198cc0b02a60af99e7764246a7c66f /sys
parentceb8e7fc2476b3fef728bffeacd7694ec28ce742 (diff)
Massive ACPI changes
Fixed ACPI leaks new ACPI API ok marco@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpi.c82
-rw-r--r--sys/dev/acpi/acpiac.c17
-rw-r--r--sys/dev/acpi/acpibat.c77
-rw-r--r--sys/dev/acpi/acpibtn.c11
-rw-r--r--sys/dev/acpi/acpicpu.c39
-rw-r--r--sys/dev/acpi/acpidebug.c35
-rw-r--r--sys/dev/acpi/acpidev.h10
-rw-r--r--sys/dev/acpi/acpiec.c30
-rw-r--r--sys/dev/acpi/acpitz.c22
-rw-r--r--sys/dev/acpi/amltypes.h16
-rw-r--r--sys/dev/acpi/dsdt.c4612
-rw-r--r--sys/dev/acpi/dsdt.h34
12 files changed, 2448 insertions, 2537 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 2558eaf9fd3..0ced1644dda 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.55 2006/06/30 23:09:41 gwk Exp $ */
+/* $OpenBSD: acpi.c,v 1.56 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -129,7 +129,7 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
bus_addr_t ioaddr;
int reg, idx, ival, sval;
- dnprintf(30, "gasio: %.2x 0x%.8llx %s\n",
+ dnprintf(50, "gasio: %.2x 0x%.8llx %s\n",
iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
pb = (u_int8_t *)buffer;
@@ -528,9 +528,8 @@ void
acpi_inidev(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
- struct aml_value res;
- aml_eval_object(sc, node, &res, 0, NULL);
+ aml_evalnode(sc, node, 0, NULL, NULL);
}
void
@@ -579,18 +578,19 @@ acpi_foundhid(struct aml_node *node, void *arg)
struct acpi_softc *sc = (struct acpi_softc *)arg;
struct device *self = (struct device *)arg;
const char *dev;
- struct aml_value res;
+ struct aml_value res;
struct acpi_attach_args aaa;
dnprintf(10, "found hid device: %s ", node->parent->name);
- aml_eval_object(sc, node, &res, 0, NULL);
+ if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
+ return;
switch (res.type) {
case AML_OBJTYPE_STRING:
- dev = aml_strval(&res);
+ dev = res.v_string;
break;
case AML_OBJTYPE_INTEGER:
- dev = aml_eisaid(aml_val2int(NULL, &res));
+ dev = aml_eisaid(aml_val2int(&res));
break;
default:
dev = "unknown";
@@ -615,6 +615,7 @@ acpi_foundhid(struct aml_node *node, void *arg)
if (aaa.aaa_name)
config_found(self, &aaa, acpi_print);
+ aml_freevalue(&res);
}
@@ -624,18 +625,19 @@ acpi_foundec(struct aml_node *node, void *arg)
struct acpi_softc *sc = (struct acpi_softc *)arg;
struct device *self = (struct device *)arg;
const char *dev;
- struct aml_value res;
- struct acpi_attach_args aaa;
+ struct aml_value res;
+ struct acpi_attach_args aaa;
dnprintf(10, "found hid device: %s ", node->parent->name);
- aml_eval_object(sc, node, &res, 0, NULL);
+ if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
+ return;
switch (res.type) {
case AML_OBJTYPE_STRING:
- dev = aml_strval(&res);
+ dev = res.v_string;
break;
case AML_OBJTYPE_INTEGER:
- dev = aml_eisaid(aml_val2int(NULL, &res));
+ dev = aml_eisaid(aml_val2int(&res));
break;
default:
dev = "unknown";
@@ -654,6 +656,8 @@ acpi_foundec(struct aml_node *node, void *arg)
if (aaa.aaa_name)
config_found(self, &aaa, acpi_print);
+
+ aml_freevalue(&res);
}
int
@@ -740,6 +744,9 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
acpi_enabled=1;
+ /* Create Default AML objects */
+ aml_create_defaultobjects();
+
/*
* Load the DSDT from the FADT pointer -- use the
* extended (64-bit) pointer if it exists
@@ -767,6 +774,8 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
}
}
+ /* Walk AML Tree */
+ //aml_walkroot();
/* Find available sleeping states */
acpi_init_states(sc);
@@ -1142,13 +1151,12 @@ int
acpi_gpe_level(struct acpi_softc *sc, int gpe, void *arg)
{
struct aml_node *node = arg;
- struct aml_value res;
uint8_t mask;
dnprintf(10, "handling Level-sensitive GPE %.2x\n", gpe);
mask = (1L << (gpe & 7));
- if (node != NULL)
- aml_eval_object(sc, node, &res, 0, NULL);
+
+ aml_evalnode(sc, node, 0, NULL, NULL);
acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, mask);
@@ -1160,13 +1168,12 @@ acpi_gpe_edge(struct acpi_softc *sc, int gpe, void *arg)
{
struct aml_node *node = arg;
- struct aml_value res;
uint8_t mask;
dnprintf(10, "handling Edge-sensitive GPE %.2x\n", gpe);
mask = (1L << (gpe & 7));
- if (node != NULL)
- aml_eval_object(sc, node, &res, 0, NULL);
+
+ aml_evalnode(sc, node, 0, NULL, NULL);
acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, mask);
@@ -1205,7 +1212,7 @@ acpi_init_gpes(struct acpi_softc *sc)
gpe = aml_searchname(&aml_root, name);
if (gpe != NULL)
acpi_set_gpehandler(sc, idx, acpi_gpe_level, gpe,
- "level");
+ "level");
if (gpe == NULL) {
/* Search Edge-sensitive GPES */
sc->sc_gpes[ngpe].gpe_type = GPE_EDGE;
@@ -1213,7 +1220,7 @@ acpi_init_gpes(struct acpi_softc *sc)
gpe = aml_searchname(&aml_root, name);
if (gpe != NULL)
acpi_set_gpehandler(sc, idx, acpi_gpe_edge, gpe,
- "edge");
+ "edge");
}
if (gpe != NULL) {
sc->sc_gpes[ngpe].gpe_number = idx;
@@ -1238,23 +1245,20 @@ acpi_enable_gpe(struct acpi_softc *sc, u_int32_t gpemask)
void
acpi_init_states(struct acpi_softc *sc)
{
- struct acpi_context *ctx;
- struct aml_value res, env;
+ struct aml_value res;
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;
sc->sc_sleeptype[i].slp_typb = -1;
- 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_val2int(ctx,
- res.v_package[0]);
- sc->sc_sleeptype[i].slp_typb = aml_val2int(ctx,
- res.v_package[1]);
+ if (aml_evalname(sc, aml_root.child, name, 0, NULL, &res) == 0) {
+ if (res.type == AML_OBJTYPE_PACKAGE) {
+ sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]);
+ sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]);
+ }
+ aml_freevalue(&res);
}
}
}
@@ -1273,7 +1277,7 @@ void
acpi_enter_sleep_state(struct acpi_softc *sc, int state)
{
#ifdef ACPI_ENABLE
- struct aml_value res, env;
+ struct aml_value env;
u_int16_t rega, regb;
int retries;
@@ -1290,7 +1294,7 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
env.v_integer = state;
/* _TTS(state) */
if (sc->sc_tts) {
- if (aml_eval_object(sc, sc->sc_tts, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _TTS failed.\n",
DEVNAME(sc));
return;
@@ -1309,7 +1313,7 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
}
/* _PTS(state) */
if (sc->sc_pts) {
- if (aml_eval_object(sc, sc->sc_pts, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _PTS failed.\n",
DEVNAME(sc));
return;
@@ -1318,7 +1322,7 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
sc->sc_state = state;
/* _GTS(state) */
if (sc->sc_gts) {
- if (aml_eval_object(sc, sc->sc_gts, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_gts, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _GTS failed.\n",
DEVNAME(sc));
return;
@@ -1362,13 +1366,13 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
void
acpi_resume(struct acpi_softc *sc)
{
- struct aml_value res, env;
+ struct aml_value env;
env.type = AML_OBJTYPE_INTEGER;
env.v_integer = sc->sc_state;
if (sc->sc_bfs) {
- if (aml_eval_object(sc, sc->sc_pts, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _BFS failed.\n",
DEVNAME(sc));
}
@@ -1376,7 +1380,7 @@ acpi_resume(struct acpi_softc *sc)
dopowerhooks(PWR_RESUME);
inittodr(0);
if (sc->sc_wak) {
- if (aml_eval_object(sc, sc->sc_wak, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _WAK failed.\n",
DEVNAME(sc));
}
@@ -1384,7 +1388,7 @@ acpi_resume(struct acpi_softc *sc)
sc->sc_state = ACPI_STATE_S0;
if (sc->sc_tts) {
env.v_integer = sc->sc_state;
- if (aml_eval_object(sc, sc->sc_wak, &res, 1, &env)) {
+ if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _TTS failed.\n",
DEVNAME(sc));
}
diff --git a/sys/dev/acpi/acpiac.c b/sys/dev/acpi/acpiac.c
index a875f9035fc..9b0142ce699 100644
--- a/sys/dev/acpi/acpiac.c
+++ b/sys/dev/acpi/acpiac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiac.c,v 1.7 2006/02/22 19:29:24 jordan Exp $ */
+/* $OpenBSD: acpiac.c,v 1.8 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -122,25 +122,20 @@ acpiac_refresh(void *arg)
int
acpiac_getsta(struct acpiac_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_STA", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, NULL) != 0) {
dnprintf(10, "%s: no _STA\n",
DEVNAME(sc));
}
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_PSR", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSR", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _PSR\n",
DEVNAME(sc));
return (1);
}
-
- sc->sc_ac_stat = aml_val2int(NULL, &res);
+ sc->sc_ac_stat = aml_val2int(&res);
+ aml_freevalue(&res);
return (0);
}
diff --git a/sys/dev/acpi/acpibat.c b/sys/dev/acpi/acpibat.c
index 5d2db6b5fc8..c9a3c74670f 100644
--- a/sys/dev/acpi/acpibat.c
+++ b/sys/dev/acpi/acpibat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpibat.c,v 1.24 2006/09/19 18:01:36 mk Exp $ */
+/* $OpenBSD: acpibat.c,v 1.25 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -86,23 +86,18 @@ acpibat_attach(struct device *parent, struct device *self, void *aux)
{
struct acpibat_softc *sc = (struct acpibat_softc *)self;
struct acpi_attach_args *aa = aux;
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node->child;
rw_init(&sc->sc_lock, "acpibat");
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
/* XXX this trick seems to only work during boot */
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_STA", &res, &env))
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &res) != 0)
dnprintf(10, "%s: no _STA\n",
DEVNAME(sc));
-
+
if (!(res.v_integer & STA_BATTERY)) {
sc->sc_bat_present = 0;
printf(": %s: not present\n", sc->sc_devnode->parent->name);
@@ -126,6 +121,7 @@ acpibat_attach(struct device *parent, struct device *self, void *aux)
acpibat_monitor(sc);
}
+ aml_freevalue(&res);
aml_register_notify(sc->sc_devnode->parent, aa->aaa_dev,
acpibat_notify, sc);
@@ -250,17 +246,12 @@ acpibat_refresh(void *arg)
int
acpibat_getbif(struct acpibat_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
int rv = 1;
rw_enter_write(&sc->sc_lock);
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_STA", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _STA\n",
DEVNAME(sc));
goto out;
@@ -270,12 +261,14 @@ acpibat_getbif(struct acpibat_softc *sc)
/*
if (!(res.v_integer & STA_BATTERY)) {
sc->sc_bat_present = 0;
+ aml_freevalue(&res);
return (1);
} else
sc->sc_bat_present = 1;
*/
+ aml_freevalue(&res);
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_BIF", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BIF", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _BIF\n",
DEVNAME(sc));
printf("bif fails\n");
@@ -289,19 +282,24 @@ acpibat_getbif(struct acpibat_softc *sc)
}
memset(&sc->sc_bif, 0, sizeof sc->sc_bif);
- sc->sc_bif.bif_power_unit = aml_val2int(ctx, res.v_package[0]);
- sc->sc_bif.bif_capacity = aml_val2int(ctx, res.v_package[1]);
- sc->sc_bif.bif_last_capacity = aml_val2int(ctx, res.v_package[2]);
- sc->sc_bif.bif_technology = aml_val2int(ctx, res.v_package[3]);
- sc->sc_bif.bif_voltage = aml_val2int(ctx, res.v_package[4]);
- sc->sc_bif.bif_warning = aml_val2int(ctx, res.v_package[5]);
- sc->sc_bif.bif_low = aml_val2int(ctx, res.v_package[6]);
- sc->sc_bif.bif_cap_granu1 = aml_val2int(ctx, res.v_package[7]);
- sc->sc_bif.bif_cap_granu2 = aml_val2int(ctx, res.v_package[8]);
- sc->sc_bif.bif_model = aml_strval(res.v_package[9]);
- sc->sc_bif.bif_serial = aml_strval(res.v_package[10]);
- sc->sc_bif.bif_type = aml_strval(res.v_package[11]);
- sc->sc_bif.bif_oem = aml_strval(res.v_package[12]);
+ sc->sc_bif.bif_power_unit = aml_val2int(res.v_package[0]);
+ sc->sc_bif.bif_capacity = aml_val2int(res.v_package[1]);
+ sc->sc_bif.bif_last_capacity = aml_val2int(res.v_package[2]);
+ sc->sc_bif.bif_technology = aml_val2int(res.v_package[3]);
+ sc->sc_bif.bif_voltage = aml_val2int(res.v_package[4]);
+ sc->sc_bif.bif_warning = aml_val2int(res.v_package[5]);
+ sc->sc_bif.bif_low = aml_val2int(res.v_package[6]);
+ sc->sc_bif.bif_cap_granu1 = aml_val2int(res.v_package[7]);
+ sc->sc_bif.bif_cap_granu2 = aml_val2int(res.v_package[8]);
+
+ strlcpy(sc->sc_bif.bif_model, aml_strval(res.v_package[9]),
+ sizeof(sc->sc_bif.bif_model));
+ strlcpy(sc->sc_bif.bif_serial, aml_strval(res.v_package[10]),
+ sizeof(sc->sc_bif.bif_serial));
+ strlcpy(sc->sc_bif.bif_type, aml_strval(res.v_package[11]),
+ sizeof(sc->sc_bif.bif_type));
+ strlcpy(sc->sc_bif.bif_oem, aml_strval(res.v_package[12]),
+ sizeof(sc->sc_bif.bif_oem));
dnprintf(60, "power_unit: %u capacity: %u last_cap: %u tech: %u "
"volt: %u warn: %u low: %u gran1: %u gran2: %d model: %s "
@@ -321,6 +319,7 @@ acpibat_getbif(struct acpibat_softc *sc)
sc->sc_bif.bif_oem);
out:
+ aml_freevalue(&res);
rw_exit_write(&sc->sc_lock);
return (rv);
}
@@ -328,17 +327,12 @@ out:
int
acpibat_getbst(struct acpibat_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
int rv = 0;
rw_enter_write(&sc->sc_lock);
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_BST", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BST", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _BST\n",
DEVNAME(sc));
printf("_bst fails\n");
@@ -353,10 +347,11 @@ acpibat_getbst(struct acpibat_softc *sc)
goto out;
}
- sc->sc_bst.bst_state = aml_val2int(ctx, res.v_package[0]);
- sc->sc_bst.bst_rate = aml_val2int(ctx, res.v_package[1]);
- sc->sc_bst.bst_capacity = aml_val2int(ctx, res.v_package[2]);
- sc->sc_bst.bst_voltage = aml_val2int(ctx, res.v_package[3]);
+ sc->sc_bst.bst_state = aml_val2int(res.v_package[0]);
+ sc->sc_bst.bst_rate = aml_val2int(res.v_package[1]);
+ sc->sc_bst.bst_capacity = aml_val2int(res.v_package[2]);
+ sc->sc_bst.bst_voltage = aml_val2int(res.v_package[3]);
+ aml_freevalue(&res);
dnprintf(60, "state: %u rate: %u cap: %u volt: %u ",
sc->sc_bst.bst_state,
diff --git a/sys/dev/acpi/acpibtn.c b/sys/dev/acpi/acpibtn.c
index 46ef1f9670f..9b1573f4302 100644
--- a/sys/dev/acpi/acpibtn.c
+++ b/sys/dev/acpi/acpibtn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpibtn.c,v 1.10 2006/05/31 10:01:56 canacar Exp $ */
+/* $OpenBSD: acpibtn.c,v 1.11 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -102,14 +102,7 @@ acpibtn_attach(struct device *parent, struct device *self, void *aux)
int
acpibtn_getsta(struct acpibtn_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
-
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_STA", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, NULL) != 0) {
dnprintf(20, "%s: no _STA\n", DEVNAME(sc));
/* XXX not all buttons have _STA so FALLTROUGH */
}
diff --git a/sys/dev/acpi/acpicpu.c b/sys/dev/acpi/acpicpu.c
index a4b027d710b..5bb492448f0 100644
--- a/sys/dev/acpi/acpicpu.c
+++ b/sys/dev/acpi/acpicpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpicpu.c,v 1.9 2006/03/09 05:16:27 jordan Exp $ */
+/* $OpenBSD: acpicpu.c,v 1.10 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -124,22 +124,18 @@ acpicpu_attach(struct device *parent, struct device *self, void *aux)
int
acpicpu_getpct(struct acpicpu_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_PPC", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PPC", 0, NULL, &res) != 0) {
dnprintf(20, "%s: no _PPC\n", DEVNAME(sc));
printf("%s: no _PPC\n", DEVNAME(sc));
return (1);
}
- dnprintf(10, "_PPC: %d\n", aml_val2int(NULL, &res));
+ dnprintf(10, "_PPC: %d\n", aml_val2int(&res));
+ aml_freevalue(&res);
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_PCT", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PCT", 0, NULL, &res) != 0) {
dnprintf(20, "%s: no _PCT\n", DEVNAME(sc));
printf("%s: no _PCT\n", DEVNAME(sc));
return (1);
@@ -155,6 +151,7 @@ acpicpu_getpct(struct acpicpu_softc *sc)
sizeof sc->sc_pct.pct_ctrl);
memcpy(&sc->sc_pct.pct_status, res.v_package[1]->v_buffer,
sizeof sc->sc_pct.pct_status);
+ aml_freevalue(&res);
dnprintf(10, "_PCT(ctrl) : %02x %04x %02x %02x %02x %02x %016x\n",
sc->sc_pct.pct_ctrl.grd_descriptor,
@@ -209,15 +206,10 @@ acpicpu_getpct(struct acpicpu_softc *sc)
int
acpicpu_getpss(struct acpicpu_softc *sc)
{
- struct aml_value res, env;
- struct acpi_context *ctx;
+ struct aml_value res;
int i;
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- ctx = NULL;
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_PSS", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSS", 0, NULL, &res) != 0) {
dnprintf(20, "%s: no _PSS\n", DEVNAME(sc));
return (1);
}
@@ -231,19 +223,20 @@ acpicpu_getpss(struct acpicpu_softc *sc)
memset(sc->sc_pss, 0, res.length * sizeof *sc->sc_pss);
for (i = 0; i < res.length; i++) {
- sc->sc_pss[i].pss_core_freq = aml_val2int(ctx,
+ sc->sc_pss[i].pss_core_freq = aml_val2int(
res.v_package[i]->v_package[0]);
- sc->sc_pss[i].pss_power = aml_val2int(ctx,
+ sc->sc_pss[i].pss_power = aml_val2int(
res.v_package[i]->v_package[1]);
- sc->sc_pss[i].pss_trans_latency = aml_val2int(ctx,
+ sc->sc_pss[i].pss_trans_latency = aml_val2int(
res.v_package[i]->v_package[2]);
- sc->sc_pss[i].pss_bus_latency = aml_val2int(ctx,
+ sc->sc_pss[i].pss_bus_latency = aml_val2int(
res.v_package[i]->v_package[3]);
- sc->sc_pss[i].pss_ctrl = aml_val2int(ctx,
+ sc->sc_pss[i].pss_ctrl = aml_val2int(
res.v_package[i]->v_package[4]);
- sc->sc_pss[i].pss_status = aml_val2int(ctx,
+ sc->sc_pss[i].pss_status = aml_val2int(
res.v_package[i]->v_package[5]);
}
+ aml_freevalue(&res);
sc->sc_pss_len = res.length;
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c
index 60c5717425b..63e123b32ed 100644
--- a/sys/dev/acpi/acpidebug.c
+++ b/sys/dev/acpi/acpidebug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.8 2006/03/21 21:11:10 jordan Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.9 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -128,10 +128,7 @@ db_aml_showvalue(struct aml_value *value)
return;
if (value->node)
- db_printf("node:%.8x ", value->node);
-
- if (value->name)
- db_printf("name:%s ", value->name);
+ db_printf("node:%.8x name:%s ", value->node, value->node->name);
switch (value->type) {
case AML_OBJTYPE_OBJREF:
@@ -140,13 +137,12 @@ db_aml_showvalue(struct aml_value *value)
db_printf("}\n");
break;
case AML_OBJTYPE_NAMEREF:
- db_printf("nameref: %s %.8x\n", value->name,
- value->v_objref.ref);
+ db_printf("nameref: %s\n", value->v_nameref);
break;
- case AML_OBJTYPE_STATICINT:
+ case AML_OBJTYPE_INTEGER+AML_STATIC:
case AML_OBJTYPE_INTEGER:
db_printf("integer: %llx %s\n", value->v_integer,
- (value->type == AML_OBJTYPE_STATICINT) ? "(static)" : "");
+ (value->type & AML_STATIC) ? "(static)" : "");
break;
case AML_OBJTYPE_STRING:
db_printf("string: %s\n", value->v_string);
@@ -188,7 +184,7 @@ db_aml_showvalue(struct aml_value *value)
case AML_OBJTYPE_FIELDUNIT:
db_printf("%s: access=%x,lock=%x,update=%x pos=%.4x "
"len=%.4x\n",
- aml_opname(value->v_field.type),
+ aml_mnem(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),
@@ -200,7 +196,7 @@ db_aml_showvalue(struct aml_value *value)
break;
case AML_OBJTYPE_BUFFERFIELD:
db_printf("%s: pos=%.4x len=%.4x ",
- aml_opname(value->v_field.type),
+ aml_mnem(value->v_field.type),
value->v_field.bitpos,
value->v_field.bitlen);
@@ -243,7 +239,7 @@ db_aml_objtype(struct aml_value *val)
return "nil";
switch (val->type) {
- case AML_OBJTYPE_STATICINT:
+ case AML_OBJTYPE_INTEGER+AML_STATIC:
return "staticint";
case AML_OBJTYPE_INTEGER:
return "integer";
@@ -279,7 +275,7 @@ db_aml_objtype(struct aml_value *val)
return "refof";
case AML_OBJTYPE_FIELDUNIT:
case AML_OBJTYPE_BUFFERFIELD:
- return aml_opname(val->v_field.type);
+ return aml_mnem(val->v_field.type);
};
return ("");
@@ -463,14 +459,14 @@ void
db_aml_shownode(struct aml_node *node)
{
db_printf(" opcode:%.4x mnem:%s %s ",
- node->opcode, node->mnem, node->name ? node->name : "");
+ node->opcode, aml_mnem(node->opcode), node->name ? node->name : "");
switch(node->opcode) {
case AMLOP_METHOD:
break;
case AMLOP_NAMECHAR:
- db_printf("%s", node->value->name);
+ db_printf("%s", node->name);
break;
case AMLOP_FIELD:
@@ -591,3 +587,12 @@ db_acpi_tree(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
db_aml_walktree(aml_root.child);
}
+u_int8_t *aml_eparselen(struct acpi_context *ctx)
+{
+ return 0;
+}
+struct acpi_context *acpi_alloccontext(struct acpi_softc *s,
+ struct aml_node *n, int c, struct aml_value *v)
+{
+ return NULL;
+}
diff --git a/sys/dev/acpi/acpidev.h b/sys/dev/acpi/acpidev.h
index b34e8fbc032..76fd98f90ed 100644
--- a/sys/dev/acpi/acpidev.h
+++ b/sys/dev/acpi/acpidev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidev.h,v 1.8 2006/03/04 05:36:42 marco Exp $ */
+/* $OpenBSD: acpidev.h,v 1.9 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
@@ -57,10 +57,10 @@ struct acpibat_bif {
u_int32_t bif_low;
u_int32_t bif_cap_granu1;
u_int32_t bif_cap_granu2;
- const char *bif_model;
- const char *bif_serial;
- const char *bif_type;
- const char *bif_oem;
+ char bif_model[20];
+ char bif_serial[20];
+ char bif_type[20];
+ char bif_oem[20];
};
/*
diff --git a/sys/dev/acpi/acpiec.c b/sys/dev/acpi/acpiec.c
index c87f4ad1aaa..47af083c6aa 100644
--- a/sys/dev/acpi/acpiec.c
+++ b/sys/dev/acpi/acpiec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiec.c,v 1.3 2006/06/30 04:16:15 jordan Exp $ */
+/* $OpenBSD: acpiec.c,v 1.4 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2006 Can Erkin Acar <canacar@openbsd.org>
*
@@ -379,7 +379,6 @@ acpiec_gpehandler(struct acpi_softc *acpi_sc, int gpe, void *arg)
void
acpiec_handle_events(struct acpiec_softc *sc)
{
- struct aml_value res;
int idx;
if (sc->sc_pending == 0)
@@ -392,8 +391,7 @@ acpiec_handle_events(struct acpiec_softc *sc)
sc->sc_events[idx].event == NULL)
continue;
dnprintf(10, "%s: handling event 0x%02x\n", DEVNAME(sc), idx);
- aml_eval_object(sc->sc_acpi, sc->sc_events[idx].event,
- &res, 0, NULL);
+ aml_evalnode(sc->sc_acpi, sc->sc_events[idx].event, 0, NULL, NULL);
sc->sc_events[idx].active = 0;
}
}
@@ -442,23 +440,21 @@ acpiec_getregister(const u_int8_t *buf, int size, int *type, bus_size_t *addr)
int
acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
{
- struct aml_value res, env;
+ struct aml_value res;
bus_size_t ec_sc, ec_data;
int type1, type2;
char *buf;
int size, ret;
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_GPE", &res, &env)) {
+ if (!aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &res)) {
dnprintf(10, "%s: no _GPE\n", DEVNAME(sc));
return (1);
}
- sc->sc_gpe = aml_val2int(NULL, &res);
+ sc->sc_gpe = aml_val2int(&res);
+ aml_freevalue(&res);
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_CRS", &res, &env)) {
+ if (!aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
dnprintf(10, "%s: no _CRS\n", DEVNAME(sc));
return (1);
}
@@ -468,6 +464,7 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
if (res.type != AML_OBJTYPE_BUFFER) {
dnprintf(10, "%s: unknown _CRS type %d\n",
DEVNAME(sc), res.type);
+ aml_freevalue(&res);
return (1);
}
@@ -478,6 +475,7 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
if (ret <= 0) {
dnprintf(10, "%s: failed to read DATA from _CRS\n",
DEVNAME(sc));
+ aml_freevalue(&res);
return (1);
}
@@ -488,6 +486,7 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
if (ret <= 0) {
dnprintf(10, "%s: failed to read S/C from _CRS\n",
DEVNAME(sc));
+ aml_freevalue(&res);
return (1);
}
@@ -496,8 +495,10 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
if (size != 2 || *buf != RES_TYPE_ENDTAG) {
dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc));
+ aml_freevalue(&res);
return (1);
}
+ aml_freevalue(&res);
/* XXX: todo - validate _CRS checksum? */
@@ -531,7 +532,7 @@ 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 *res, arg[2];
struct aml_node *root;
memset(&res, 0, sizeof(res));
@@ -544,14 +545,13 @@ acpiec_reg(struct acpiec_softc *sc)
arg[1].type = AML_OBJTYPE_INTEGER;
arg[1].v_integer = 1;
- root = aml_find_name(sc->sc_acpi, sc->sc_devnode, "_REG");
-
+ root = aml_searchname(sc->sc_devnode, "_REG");
if (root == NULL) {
dnprintf(10, "%s: no _REG method\n", DEVNAME(sc));
return (1);
}
- if (aml_eval_object(sc->sc_acpi, root, &res, 2, arg)) {
+ if (aml_evalnode(sc->sc_acpi, root, 2, arg, NULL) != 0) {
dnprintf(10, "%s: evaluating method _REG failed.\n", DEVNAME(sc));
return (1);
}
diff --git a/sys/dev/acpi/acpitz.c b/sys/dev/acpi/acpitz.c
index dd255b16881..95ed954ad80 100644
--- a/sys/dev/acpi/acpitz.c
+++ b/sys/dev/acpi/acpitz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpitz.c,v 1.2 2006/07/30 05:30:45 gwk Exp $ */
+/* $OpenBSD: acpitz.c,v 1.3 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2006 Can Erkin Acar <canacar@openbsd.org>
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
@@ -163,22 +163,20 @@ acpitz_refresh(void *arg)
int
acpitz_gettmp(struct acpitz_softc *sc)
{
- struct aml_value res, env;
+ struct aml_value res;
int rv = 1;
rw_enter_write(&sc->sc_lock);
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_TMP", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_TMP", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _TMP\n", DEVNAME(sc));
goto out;
}
- sc->sc_tmp = aml_val2int(NULL, &res);
+ sc->sc_tmp = aml_val2int(&res);
rv = 0;
out:
+ aml_freevalue(&res);
rw_exit_write(&sc->sc_lock);
return (rv);
}
@@ -186,22 +184,20 @@ acpitz_gettmp(struct acpitz_softc *sc)
int
acpitz_getcrt(struct acpitz_softc *sc)
{
- struct aml_value res, env;
+ struct aml_value res;
int rv = 1;
rw_enter_write(&sc->sc_lock);
- memset(&res, 0, sizeof(res));
- memset(&env, 0, sizeof(env));
-
- if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_CRT", &res, &env)) {
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRT", 0, NULL, &res) != 0) {
dnprintf(10, "%s: no _CRT\n", DEVNAME(sc));
goto out;
}
- sc->sc_crt = aml_val2int(NULL, &res);
+ sc->sc_crt = aml_val2int(&res);
rv = 0;
out:
+ aml_freevalue(&res);
rw_exit_write(&sc->sc_lock);
return (rv);
}
diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h
index 1b936048c66..b7732525dbf 100644
--- a/sys/dev/acpi/amltypes.h
+++ b/sys/dev/acpi/amltypes.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amltypes.h,v 1.15 2006/03/07 23:13:28 marco Exp $ */
+/* $OpenBSD: amltypes.h,v 1.16 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -156,6 +156,8 @@
#define AML_MATCH_GE 4
#define AML_MATCH_GT 5
+#define AML_STATIC 0x8000
+
/* Defined types for ObjectType() */
enum aml_objecttype {
AML_OBJTYPE_UNINITIALIZED = 0,
@@ -178,7 +180,6 @@ enum aml_objecttype {
AML_OBJTYPE_NAMEREF = 0x100,
AML_OBJTYPE_OBJREF,
- AML_OBJTYPE_STATICINT,
};
/* AML Opcode Arguments */
@@ -241,7 +242,6 @@ struct aml_value
int type;
int length;
int refcnt;
- const char *name;
struct aml_node *node;
union {
int64_t vinteger;
@@ -283,6 +283,7 @@ struct aml_value
} _;
};
+#define v_nameref _.vbuffer
#define v_objref _.vobjref
#define v_integer _.vinteger
#define v_string _.vstring
@@ -308,15 +309,16 @@ struct aml_node
struct aml_node *child;
struct aml_node *sibling;
- u_int16_t opcode;
+ char name[5];
+ u_int16_t opcode;
u_int8_t *start;
u_int8_t *end;
- const char *name;
- const char *mnem;
+ // const char *name;
+ // const char *mnem;
struct aml_value *value;
- int depth;
+ int depth;
};
#define AML_FALSE (0)
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 91bb4c876af..44ee8483755 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.47 2006/06/14 16:30:07 canacar Exp $ */
+/* $openbsd: dsdt.c,v 1.47 2006/06/14 16:30:07 canacar Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -32,6 +32,15 @@
#include <dev/acpi/amltypes.h>
#include <dev/acpi/dsdt.h>
+/* XXX: endian macros */
+#define aml_letohost16(x) x
+#define aml_letohost32(x) x
+#define aml_letohost64(x) x
+
+#define opsize(opcode) (((opcode) & 0xFF00) ? 2 : 1)
+
+#define AML_CHECKSTACK()
+
#define AML_FIELD_RESERVED 0x00
#define AML_FIELD_ATTRIB 0x01
@@ -55,248 +64,248 @@
#define aml_ipaddr(n) ((n)-aml_root.start)
-#ifdef ACPI_DEBUG
-const char *opregion(int);
+struct aml_scope;
-const char *
-opregion(int id)
-{
- switch(id) {
- case 0:
- return "SystemMemory";
- case 1:
- return "SystemIO";
- case 2:
- return "PCIConfig";
- case 3:
- return "Embedded";
- case 4:
- return "SMBus";
- case 5:
- return "CMOS";
- case 6:
- return "PCIBAR";
- }
- return "";
-}
-#endif
+/* New jordan code */
+int aml_cmpvalue(struct aml_value *, struct aml_value *, int);
+void aml_copyvalue(struct aml_value *, struct aml_value *);
-const char *aml_parse_string(struct acpi_context *);
-int _aml_freevalue(struct aml_value *);
-int aml_isnamedop(u_int16_t);
-int aml_logicalcmp(u_int16_t, int64_t, int64_t);
-int aml_lsb(u_int64_t);
-int aml_match(int64_t, int, int64_t);
+void aml_setvalue(struct aml_scope *, struct aml_value *, struct aml_value *, int64_t);
+void aml_freevalue(struct aml_value *);
+struct aml_value *aml_allocvalue(int, int64_t, const void *);
+struct aml_value *_aml_setvalue(struct aml_value *, int, int64_t, const void *);
+
+u_int64_t aml_convradix(u_int64_t, int, int);
+int64_t aml_evalexpr(int64_t, int64_t, int);
+int aml_lsb(u_int64_t);
int aml_msb(u_int64_t);
-int aml_parse_length(struct acpi_context *);
-int aml_strcmp(u_int16_t, const char *, const char *);
-int aml_tstbit(const u_int8_t *, int);
-int64_t aml_evalmath(u_int16_t, int64_t, int64_t);
-int64_t aml_str2int(const char *, int, int);
-int64_t aml_val2int(struct acpi_context *, struct aml_value *);
-struct aml_opcode *aml_getopcode(struct acpi_context *);
-struct aml_node *_aml_searchname(struct aml_node *, const char *);
-struct aml_node *aml_createname(struct aml_node *, const char *);
-struct aml_node *aml_doname(struct aml_node *, const char *, int);
-struct aml_value *aml_doconcat(struct acpi_context *);
-struct aml_value *aml_parse_bufferfield(struct acpi_context *, int, int, int);
-struct aml_value *aml_parse_fieldunit(struct acpi_context *, int);
-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_dowhile(struct acpi_context *);
-struct aml_value *aml_domid(struct acpi_context *);
-struct aml_value *aml_ederef(struct acpi_context *, struct aml_value *);
-struct aml_value *aml_eparselist(struct acpi_context *, u_int8_t *, int);
-struct aml_value *aml_eparseval(struct acpi_context *, int);
-struct aml_value *aml_evalnode(struct acpi_softc *, struct aml_node *,
- int, struct aml_value **);
-struct aml_value *aml_evalname(struct acpi_softc *, struct aml_node *, const char *,
- int, struct aml_value **);
-struct aml_value *aml_evalmethod(struct acpi_context *, struct aml_value *);
-u_int64_t aml_bcd2dec(u_int64_t);
-u_int64_t aml_dec2bcd(u_int64_t);
-u_int64_t aml_parse_int(struct acpi_context *, int);
-void *acpi_os_allocmem(size_t);
-void acpi_os_freemem(void *);
-void aml_addchildnode(struct aml_node *, struct aml_node *);
-void aml_bufcpy(u_int8_t *, int, const u_int8_t *, int, int);
-void aml_dump(int, u_int8_t *);
-void aml_resizevalue(struct aml_value *, int);
-void aml_setbit(u_int8_t *, int, int);
-void aml_shownode(struct aml_node *);
-
-struct aml_node *aml_addvname(struct acpi_context *, const char *, int,
- struct aml_value *);
-int aml_bufcmp(const u_int8_t *, int, const u_int8_t *,
- int);
-struct aml_node *aml_create_node(struct aml_node *, int, const char *,
- u_int8_t *);
-struct aml_node *aml_find_name(struct acpi_softc *, struct aml_node *,
- const char *);
-struct aml_value *aml_domethod(struct acpi_context *, struct aml_value *,
- int, struct aml_value **);
-struct aml_value *aml_efield(struct acpi_context *, struct aml_value *,
- struct aml_value *);
-struct aml_value *aml_eparsenode(struct acpi_context *,
- struct aml_node *);
-struct aml_value *aml_eparsescope(struct acpi_context *, const char *,
- u_int8_t *, struct aml_opcode *,
- struct aml_value *);
-struct aml_value *aml_esetnodevalue(struct acpi_context *,
- struct aml_value *, struct aml_value *, int64_t);
-struct aml_value *aml_getnodevalue(struct acpi_context *,
- struct aml_node *);
-struct aml_value *aml_val2buf(struct acpi_context *, struct aml_value *,
- int);
-uint64_t aml_get_pciaddr(struct acpi_context *,
- struct aml_node *);
-void aml_delchildren(struct acpi_context *,
- struct aml_node *);
+void aml_dump(int, u_int8_t *);
+int aml_tstbit(const u_int8_t *, int);
+void aml_setbit(u_int8_t *, int, int);
+
+void aml_bufcpy(void *, int, const void *, int, int);
+
+void aml_delref(struct aml_value **);
+void aml_addref(struct aml_value *);
+int aml_pc(uint8_t *);
+struct aml_value *aml_parseop(struct aml_scope *, struct aml_value *);
+struct aml_value *aml_parsetarget(struct aml_scope *, struct aml_value *, struct aml_value **);
+struct aml_value *aml_parseterm(struct aml_scope *, struct aml_value *);
+
+struct aml_value *aml_evaltarget(struct aml_scope *scope, struct aml_value *res);
+int aml_evalterm(struct aml_scope *scope, struct aml_value *raw, struct aml_value *dst);
+
+
+void aml_gasio(struct acpi_softc *, int, uint64_t, uint64_t,
+ int, int, int, void *, int);
+
+
+struct aml_opcode *aml_findopcode(int);
+
+void *_acpi_os_malloc(size_t, const char *, int);
+void _acpi_os_free(void *, const char *, int);
+
+struct aml_value *aml_evalmethod(struct aml_node *, int, struct aml_value *, struct aml_value *);
+
+/*
+ * @@@: Global variables
+ */
+int aml_intlen=64;
struct aml_node aml_root;
-struct aml_value aml_os;
-struct aml_value *aml_global_lock;
+struct aml_value *aml_global_lock;
+struct acpi_softc *dsdt_softc;
+
+/* Perfect hash function for valid AML bytecodes */
+#define HASH_OFF 6904
+#define HASH_SIZE 179
+#define HASH_KEY(k) (((k) ^ HASH_OFF) % HASH_SIZE)
+
+#define HASH_MAGIC(v) (0xC0DE0000L + (v))
+#define HTE(v,f...) [ HASH_KEY(v) ] { HASH_MAGIC(v), f }
struct aml_opcode aml_table[] = {
/* Simple types */
- { AMLOP_ZERO, "Zero", "!" },
- { AMLOP_ONE, "One", "!" },
- { AMLOP_ONES, "Ones", "!" },
- { AMLOP_BYTEPREFIX, ".Byte", "b" },
- { AMLOP_WORDPREFIX, ".Word", "w" },
- { AMLOP_DWORDPREFIX, ".DWord", "d" },
- { AMLOP_QWORDPREFIX, ".QWord", "q" },
- { AMLOP_REVISION, "Revision", "" },
- { AMLOP_STRINGPREFIX, ".String", "a" },
- { AMLOP_DEBUG, "DebugOp", "", },
- { AMLOP_BUFFER, "Buffer", "piB" },
- { AMLOP_PACKAGE, "Package", "pbT" },
- { AMLOP_VARPACKAGE, "VarPackage", "piT" },
+ HTE(AMLOP_ZERO, "Zero", "c" ),
+ HTE(AMLOP_ONE, "One", "c" ),
+ HTE(AMLOP_ONES, "Ones", "c" ),
+ HTE(AMLOP_REVISION, "Revision", "R" ),
+ HTE(AMLOP_BYTEPREFIX, ".Byte", "b" ),
+ HTE(AMLOP_WORDPREFIX, ".Word", "w" ),
+ HTE(AMLOP_DWORDPREFIX, ".DWord", "d" ),
+ HTE(AMLOP_QWORDPREFIX, ".QWord", "q" ),
+ HTE(AMLOP_STRINGPREFIX, ".String", "a" ),
+ HTE(AMLOP_DEBUG, "DebugOp", "D", ),
+ HTE(AMLOP_BUFFER, "Buffer", "piB" ),
+ HTE(AMLOP_PACKAGE, "Package", "pbT" ),
+ HTE(AMLOP_VARPACKAGE, "VarPackage", "piT" ),
/* Simple objects */
- { AMLOP_LOCAL0, "Local0", "", },
- { AMLOP_LOCAL1, "Local1", "", },
- { AMLOP_LOCAL2, "Local2", "", },
- { AMLOP_LOCAL3, "Local3", "", },
- { AMLOP_LOCAL4, "Local4", "", },
- { AMLOP_LOCAL5, "Local5", "", },
- { AMLOP_LOCAL6, "Local6", "", },
- { AMLOP_LOCAL7, "Local7", "", },
- { AMLOP_ARG0, "Arg0", "", },
- { AMLOP_ARG1, "Arg1", "", },
- { AMLOP_ARG2, "Arg2", "", },
- { AMLOP_ARG3, "Arg3", "", },
- { AMLOP_ARG4, "Arg4", "", },
- { AMLOP_ARG5, "Arg5", "", },
- { AMLOP_ARG6, "Arg6", "", },
+ HTE(AMLOP_LOCAL0, "Local0", "L", ),
+ HTE(AMLOP_LOCAL1, "Local1", "L", ),
+ HTE(AMLOP_LOCAL2, "Local2", "L", ),
+ HTE(AMLOP_LOCAL3, "Local3", "L", ),
+ HTE(AMLOP_LOCAL4, "Local4", "L", ),
+ HTE(AMLOP_LOCAL5, "Local5", "L", ),
+ HTE(AMLOP_LOCAL6, "Local6", "L", ),
+ HTE(AMLOP_LOCAL7, "Local7", "L", ),
+ HTE(AMLOP_ARG0, "Arg0", "A", ),
+ HTE(AMLOP_ARG1, "Arg1", "A", ),
+ HTE(AMLOP_ARG2, "Arg2", "A", ),
+ HTE(AMLOP_ARG3, "Arg3", "A", ),
+ HTE(AMLOP_ARG4, "Arg4", "A", ),
+ HTE(AMLOP_ARG5, "Arg5", "A", ),
+ HTE(AMLOP_ARG6, "Arg6", "A", ),
/* Control flow */
- { AMLOP_IF, "If", "piT", },
- { AMLOP_ELSE, "Else", "pT", },
- { AMLOP_WHILE, "While", "piT", },
- { AMLOP_BREAK, "Break", "", },
- { AMLOP_CONTINUE, "Continue", "", },
- { AMLOP_RETURN, "Return", "t", },
- { AMLOP_FATAL, "Fatal", "bdi", },
- { AMLOP_NOP, "Nop", "", },
- { AMLOP_BREAKPOINT, "BreakPoint", "", },
+ HTE(AMLOP_IF, "If", "pI", ),
+ HTE(AMLOP_ELSE, "Else", "pT", ),
+ HTE(AMLOP_WHILE, "While", "piT", ),
+ HTE(AMLOP_BREAK, "Break", "", ),
+ HTE(AMLOP_CONTINUE, "Continue", "", ),
+ HTE(AMLOP_RETURN, "Return", "t", ),
+ HTE(AMLOP_FATAL, "Fatal", "bdi", ),
+ HTE(AMLOP_NOP, "Nop", "", ),
+ HTE(AMLOP_BREAKPOINT, "BreakPoint", "", ),
/* Arithmetic operations */
- { AMLOP_INCREMENT, "Increment", "t", },
- { AMLOP_DECREMENT, "Decrement", "t", },
- { AMLOP_ADD, "Add", "iit", },
- { AMLOP_SUBTRACT, "Subtract", "iit", },
- { AMLOP_MULTIPLY, "Multiply", "iit", },
- { AMLOP_DIVIDE, "Divide", "iitt", },
- { AMLOP_SHL, "ShiftLeft", "iit", },
- { AMLOP_SHR, "ShiftRight", "iit", },
- { AMLOP_AND, "And", "iit", },
- { AMLOP_NAND, "Nand", "iit", },
- { AMLOP_OR, "Or", "iit", },
- { AMLOP_NOR, "Nor", "iit", },
- { AMLOP_XOR, "Xor", "iit", },
- { AMLOP_NOT, "Not", "it", },
- { AMLOP_MOD, "Mod", "iit", },
- { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "it", },
- { AMLOP_FINDSETRIGHTBIT, "FindSetRightBit", "it", },
+ HTE(AMLOP_INCREMENT, "Increment", "t", ),
+ HTE(AMLOP_DECREMENT, "Decrement", "t", ),
+ HTE(AMLOP_ADD, "Add", "iir", ),
+ HTE(AMLOP_SUBTRACT, "Subtract", "iir", ),
+ HTE(AMLOP_MULTIPLY, "Multiply", "iir", ),
+ HTE(AMLOP_DIVIDE, "Divide", "iirr", ),
+ HTE(AMLOP_SHL, "ShiftLeft", "iir", ),
+ HTE(AMLOP_SHR, "ShiftRight", "iir", ),
+ HTE(AMLOP_AND, "And", "iir", ),
+ HTE(AMLOP_NAND, "Nand", "iir", ),
+ HTE(AMLOP_OR, "Or", "iir", ),
+ HTE(AMLOP_NOR, "Nor", "iir", ),
+ HTE(AMLOP_XOR, "Xor", "iir", ),
+ HTE(AMLOP_NOT, "Not", "ir", ),
+ HTE(AMLOP_MOD, "Mod", "iir", ),
+ HTE(AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "ir", ),
+ HTE(AMLOP_FINDSETRIGHTBIT,"FindSetRightBit", "ir", ),
/* Logical test operations */
- { AMLOP_LAND, "LAnd", "ii", },
- { AMLOP_LOR, "LOr", "ii", },
- { AMLOP_LNOT, "LNot", "i", },
- { AMLOP_LNOTEQUAL, "LNotEqual", "tt", },
- { AMLOP_LLESSEQUAL, "LLessEqual", "tt", },
- { AMLOP_LGREATEREQUAL, "LGreaterEqual", "tt", },
- { AMLOP_LEQUAL, "LEqual", "tt", },
- { AMLOP_LGREATER, "LGreater", "tt", },
- { AMLOP_LLESS, "LLess", "tt", },
+ HTE(AMLOP_LAND, "LAnd", "ii", ),
+ HTE(AMLOP_LOR, "LOr", "ii", ),
+ HTE(AMLOP_LNOT, "LNot", "i", ),
+ HTE(AMLOP_LNOTEQUAL, "LNotEqual", "tt", ),
+ HTE(AMLOP_LLESSEQUAL, "LLessEqual", "tt", ),
+ HTE(AMLOP_LGREATEREQUAL, "LGreaterEqual", "tt", ),
+ HTE(AMLOP_LEQUAL, "LEqual", "tt", ),
+ HTE(AMLOP_LGREATER, "LGreater", "tt", ),
+ HTE(AMLOP_LLESS, "LLess", "tt", ),
/* Named objects */
- { AMLOP_NAMECHAR, ".NameRef", "n" },
- { AMLOP_ALIAS, "Alias", "nN", },
- { AMLOP_NAME, "Name", "Nt", },
- { AMLOP_EVENT, "Event", "N", },
- { AMLOP_MUTEX, "Mutex", "Nb", },
- { AMLOP_DATAREGION, "DataRegion", "Nttt" },
- { AMLOP_OPREGION, "OpRegion", "Nbii" },
- { AMLOP_SCOPE, "Scope", "pNT" },
- { AMLOP_DEVICE, "Device", "pNT" },
- { AMLOP_POWERRSRC, "Power Resource", "pNbwT" },
- { AMLOP_THERMALZONE, "ThermalZone", "pNT" },
- { AMLOP_PROCESSOR, "Processor", "pNbdbT", },
- { AMLOP_METHOD, "Method", "pNfM", },
+ HTE(AMLOP_NAMECHAR, ".NameRef", "n" ),
+ HTE(AMLOP_ALIAS, "Alias", "nN", ),
+ HTE(AMLOP_NAME, "Name", "Nt", ),
+ HTE(AMLOP_EVENT, "Event", "N", ),
+ HTE(AMLOP_MUTEX, "Mutex", "Nb", ),
+ HTE(AMLOP_DATAREGION, "DataRegion", "Nttt" ),
+ HTE(AMLOP_OPREGION, "OpRegion", "Nbii" ),
+ HTE(AMLOP_SCOPE, "Scope", "pNT" ),
+ HTE(AMLOP_DEVICE, "Device", "pNT" ),
+ HTE(AMLOP_POWERRSRC, "Power Resource", "pNbwT" ),
+ HTE(AMLOP_THERMALZONE, "ThermalZone", "pNT" ),
+ HTE(AMLOP_PROCESSOR, "Processor", "pNbdbT", ),
+ HTE(AMLOP_METHOD, "Method", "pNfM", ),
/* Field operations */
- { AMLOP_FIELD, "Field", "pnfF" },
- { AMLOP_INDEXFIELD, "IndexField", "pntfF" },
- { AMLOP_BANKFIELD, "BankField", "pnnifF" },
- { AMLOP_CREATEFIELD, "CreateField", "tiiN", },
- { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN", },
- { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN", },
- { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN", },
- { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN", },
- { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", },
+ HTE(AMLOP_FIELD, "Field", "pnfF" ),
+ HTE(AMLOP_INDEXFIELD, "IndexField", "pntfF" ),
+ HTE(AMLOP_BANKFIELD, "BankField", "pnnifF" ),
+ HTE(AMLOP_CREATEFIELD, "CreateField", "tiiN", ),
+ HTE(AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN", ),
+ HTE(AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN", ),
+ HTE(AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN", ),
+ HTE(AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN", ),
+ HTE(AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", ),
/* Conversion operations */
- { AMLOP_TOINTEGER, "ToInteger", "tt", },
- { AMLOP_TOBUFFER, "ToBuffer", "tt", },
- { AMLOP_TODECSTRING, "ToDecString", "it", },
- { AMLOP_TOHEXSTRING, "ToHexString", "it", },
- { AMLOP_TOSTRING, "ToString", "t", },
- { AMLOP_FROMBCD, "FromBCD", "it", },
- { AMLOP_TOBCD, "ToBCD", "it", },
- { AMLOP_MID, "Mid", "tiit", },
+ HTE(AMLOP_TOINTEGER, "ToInteger", "tr", ),
+ HTE(AMLOP_TOBUFFER, "ToBuffer", "tr", ),
+ HTE(AMLOP_TODECSTRING, "ToDecString", "ir", ),
+ HTE(AMLOP_TOHEXSTRING, "ToHexString", "ir", ),
+ HTE(AMLOP_TOSTRING, "ToString", "t", ),
+ HTE(AMLOP_FROMBCD, "FromBCD", "ir", ),
+ HTE(AMLOP_TOBCD, "ToBCD", "ir", ),
+ HTE(AMLOP_MID, "Mid", "tiir", ),
/* Mutex/Signal operations */
- { AMLOP_ACQUIRE, "Acquire", "tw", },
- { AMLOP_RELEASE, "Release", "t", },
- { AMLOP_SIGNAL, "Signal", "t", },
- { AMLOP_WAIT, "Wait", "ti", },
- { AMLOP_RESET, "Reset", "t", },
+ HTE(AMLOP_ACQUIRE, "Acquire", "tw", ),
+ HTE(AMLOP_RELEASE, "Release", "t", ),
+ HTE(AMLOP_SIGNAL, "Signal", "t", ),
+ HTE(AMLOP_WAIT, "Wait", "ti", ),
+ HTE(AMLOP_RESET, "Reset", "t", ),
- { AMLOP_INDEX, "Index", "tit", },
- { AMLOP_DEREFOF, "DerefOf", "t", },
- { AMLOP_REFOF, "RefOf", "t", },
- { AMLOP_CONDREFOF, "CondRef", "tt", },
-
- { AMLOP_LOADTABLE, "LoadTable", "tttttt" },
- { AMLOP_STALL, "Stall", "i", },
- { AMLOP_SLEEP, "Sleep", "i", },
- { AMLOP_LOAD, "Load", "nt" },
- { AMLOP_UNLOAD, "Unload", "t" },
- { AMLOP_STORE, "Store", "tt", },
- { AMLOP_CONCAT, "Concat", "ttt" },
- { AMLOP_CONCATRES, "ConcatRes", "ttt" },
- { AMLOP_NOTIFY, "Notify", "ti" },
- { AMLOP_SIZEOF, "Sizeof", "t", },
- { AMLOP_MATCH, "Match", "tbibii", },
- { AMLOP_OBJECTTYPE, "ObjectType", "t", },
- { AMLOP_COPYOBJECT, "CopyObject", "tt" },
- { 0xFFFF }
+ HTE(AMLOP_INDEX, "Index", "tir", ),
+ HTE(AMLOP_DEREFOF, "DerefOf", "t", ),
+ HTE(AMLOP_REFOF, "RefOf", "t", ),
+ HTE(AMLOP_CONDREFOF, "CondRef", "nr", ),
+
+ HTE(AMLOP_LOADTABLE, "LoadTable", "tttttt" ),
+ HTE(AMLOP_STALL, "Stall", "i", ),
+ HTE(AMLOP_SLEEP, "Sleep", "i", ),
+ HTE(AMLOP_LOAD, "Load", "nt" ),
+ HTE(AMLOP_UNLOAD, "Unload", "t" ),
+ HTE(AMLOP_STORE, "Store", "tr", ),
+ HTE(AMLOP_CONCAT, "Concat", "ttr" ),
+ HTE(AMLOP_CONCATRES, "ConcatRes", "ttt" ),
+ HTE(AMLOP_NOTIFY, "Notify", "ti" ),
+ HTE(AMLOP_SIZEOF, "Sizeof", "t", ),
+ HTE(AMLOP_MATCH, "Match", "tbibii", ),
+ HTE(AMLOP_OBJECTTYPE, "ObjectType", "t" ),
+ HTE(AMLOP_COPYOBJECT, "CopyObject", "tr" ),
};
+void _aml_die(const char *fn, int line, const char *fmt, ...);
+
+int aml_pc(uint8_t *src)
+{
+ return src - aml_root.start;
+}
+
+void _aml_die(const char *fn, int line, const char *fmt, ...)
+{
+ va_list ap;
+ char tmpbuf[256];
+
+ va_start(ap, fmt);
+ snprintf(tmpbuf,sizeof(tmpbuf),"aml_die %s:%d ", fn, line);
+ vprintf(fmt, ap);
+ printf("\n");
+ va_end(ap);
+
+ /* XXX: don't panic */
+ panic(tmpbuf);
+}
+#define aml_die(x...) _aml_die(__FUNCTION__,__LINE__,x)
+
+struct aml_opcode *
+aml_findopcode(int opcode)
+{
+ struct aml_opcode *tab;
+
+ tab = &aml_table[HASH_KEY(opcode)];
+ if (tab->opcode == HASH_MAGIC(opcode))
+ return tab;
+ return NULL;
+}
+
+const char *
+aml_mnem(int opcode)
+{
+ struct aml_opcode *tab;
+
+ if ((tab = aml_findopcode(opcode)) != NULL)
+ return tab->mnem;
+ return ("xxx");
+}
+
struct aml_notify_data
{
struct aml_node *node;
@@ -309,26 +318,56 @@ struct aml_notify_data
SLIST_HEAD(aml_notify_head, aml_notify_data);
struct aml_notify_head aml_notify_list =
- SLIST_HEAD_INITIALIZER(&aml_notify_list);
+SLIST_HEAD_INITIALIZER(&aml_notify_list);
+
+/*
+ * @@@: Memory management functions
+ */
+
+#define acpi_os_malloc(sz) _acpi_os_malloc(sz, __FUNCTION__, __LINE__)
+#define acpi_os_free(ptr) _acpi_os_free(ptr, __FUNCTION__, __LINE__)
+long acpi_nalloc;
+
+struct acpi_memblock
+{
+ size_t size;
+};
+
void *
-acpi_os_allocmem(size_t size)
+_acpi_os_malloc(size_t size, const char *fn, int line)
{
- void *ptr;
-
- ptr = malloc(size, M_DEVBUF, M_WAITOK);
- if (ptr)
- memset(ptr, 0, size);
+ struct acpi_memblock *sptr;
- return (ptr);
+ sptr = malloc(size+sizeof(*sptr), M_DEVBUF, M_WAITOK);
+ dnprintf(99,"alloc: %x %s:%d\n", sptr, fn, line);
+ if (sptr) {
+ acpi_nalloc += size;
+ sptr->size = size;
+ memset(&sptr[1], 0, size);
+ return &sptr[1];
+ }
+ return NULL;
}
void
-acpi_os_freemem(void *ptr)
+_acpi_os_free(void *ptr, const char *fn, int line)
{
- /* free(ptr, M_DEVBUF); */
+ struct acpi_memblock *sptr;
+
+ if (ptr != NULL) {
+ sptr = &(((struct acpi_memblock *)ptr)[-1]);
+ acpi_nalloc -= sptr->size;
+
+ dnprintf(99,"free: %x %s:%d\n", sptr, fn, line);
+ free(sptr, M_DEVBUF);
+ }
}
+/*
+ * @@@: Misc utility functions
+ */
+
void
aml_dump(int len, u_int8_t *buf)
{
@@ -361,16 +400,31 @@ 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
+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);
+}
+#endif
+
+/*
+ * @@@: Notify functions
+ */
+
void
aml_register_notify(struct aml_node *node, const char *pnpid,
- int (*proc)(struct aml_node *, int, void *), void *arg)
+ int (*proc)(struct aml_node *, int, void *), void *arg)
{
struct aml_notify_data *pdata;
dnprintf(10, "aml_register_notify: %s %s %x\n",
node->name, pnpid ? pnpid : "", proc);
- pdata = acpi_os_allocmem(sizeof(struct aml_notify_data));
+ pdata = acpi_os_malloc(sizeof(struct aml_notify_data));
pdata->node = node;
pdata->cbarg = arg;
pdata->cbproc = proc;
@@ -407,575 +461,931 @@ aml_notify_dev(const char *pnpid, int notify_value)
pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
}
-void
-aml_addchildnode(struct aml_node *parent, struct aml_node *child)
-{
- struct aml_node **tmp;
+/*
+ * @@@: Namespace functions
+ */
- for (tmp = &parent->child; *tmp; tmp = &((*tmp)->sibling))
- ;
+struct aml_node *__aml_search(struct aml_node *, uint8_t *);
+void aml_delchildren(struct aml_node *);
+const char *aml_getname(const char *);
+const char *aml_nodename(struct aml_node *);
- child->sibling = NULL;
- child->parent = parent;
- *tmp = child;
-}
+/* Search for a name in children nodes */
struct aml_node *
-aml_create_node(struct aml_node *parent, int opcode, const char *mnem,
- u_int8_t *start)
+__aml_search(struct aml_node *root, uint8_t *nameseg)
{
- struct aml_node *node;
-
- node = (struct aml_node *)acpi_os_allocmem(sizeof(struct aml_node));
- if (node == NULL)
+ if (root == NULL)
return NULL;
+ for (root=root->child; root; root=root->sibling) {
+ if (!memcmp(root->name, nameseg, AML_NAMESEG_LEN))
+ return root;
+ }
+ return NULL;
+}
- node->opcode = opcode;
- node->mnem = mnem;
- node->depth = parent->depth+1;
- node->start = start;
- node->end = parent->end;
- node->child = NULL;
-
- aml_addchildnode(parent, node);
+/* Get absolute pathname of AML node */
+const char *
+aml_nodename(struct aml_node *node)
+{
+ static char namebuf[128];
- return (node);
+ namebuf[0] = 0;
+ if (node) {
+ aml_nodename(node->parent);
+ if (node->parent != &aml_root)
+ strlcat(namebuf, ".", sizeof(namebuf));
+ strlcat(namebuf, node->name, sizeof(namebuf));
+ }
+ return namebuf+1;
}
-/* Allocate dynamic AML value
- * type : Type of object to allocate (AML_OBJTYPE_XXXX)
- * ival : Integer value (action depends on type)
- * bval : Buffer value (action depends on type)
- */
-struct aml_value *
-aml_allocvalue(int type, int64_t ival, void *bval)
+const char *
+aml_getname(const char *name)
{
- struct aml_value *rv;
- struct aml_value **pv;
- int64_t idx;
-
- rv = (struct aml_value *)acpi_os_allocmem(sizeof(struct aml_value));
- rv->type = type;
+ static char namebuf[128], *p;
+ int count;
- switch (type) {
- case AML_OBJTYPE_UNINITIALIZED:
+ p = namebuf;
+ while (*name == AMLOP_ROOTCHAR || *name == AMLOP_PARENTPREFIX) {
+ *(p++) = *(name++);
+ }
+ switch (*name) {
+ case 0x00:
+ count = 0;
break;
- case AML_OBJTYPE_NAMEREF:
- rv->name = bval;
- rv->v_objref.index = -1;
+ case AMLOP_MULTINAMEPREFIX:
+ count = name[1];
+ name += 2;
break;
- case AML_OBJTYPE_OBJREF:
- rv->v_objref.index = ival;
- rv->v_objref.ref = (struct aml_value *)bval;
+ case AMLOP_DUALNAMEPREFIX:
+ count = 2;
+ name += 1;
break;
- case AML_OBJTYPE_STATICINT:
- case AML_OBJTYPE_INTEGER:
- rv->v_integer = ival;
+ default:
+ count = 1;
+ }
+ while (count--) {
+ memcpy(p, name, 4);
+ p[4] = '.';
+ p += 5;
+ name += 4;
+ if (*name == '.') name++;
+ }
+ *(--p) = 0;
+ return namebuf;
+}
+
+/* Create name/value pair in namespace */
+struct aml_node *
+aml_createname(struct aml_node *root, const void *vname, struct aml_value *value)
+{
+ struct aml_node *node, **pp;
+ uint8_t *name = (uint8_t *)vname;
+ int count;
+
+ if (*name == AMLOP_ROOTCHAR) {
+ root = &aml_root;
+ name++;
+ }
+ while (*name == AMLOP_PARENTPREFIX && root) {
+ root = root->parent;
+ name++;
+ }
+ switch (*name) {
+ case 0x00:
+ return root;
+ case AMLOP_MULTINAMEPREFIX:
+ count = name[1];
+ name += 2;
break;
- case AML_OBJTYPE_STRING:
- /* Allocate string: if pointer valid, copy data */
- if (ival < 0)
- ival = strlen((const char *)bval);
- rv->length = ival;
- if (ival) {
- rv->v_string = acpi_os_allocmem(ival + 1);
- if (bval)
- strncpy(rv->v_string, bval, ival);
- }
+ case AMLOP_DUALNAMEPREFIX:
+ count = 2;
+ name += 1;
break;
- case AML_OBJTYPE_BUFFER:
- /* Allocate buffer: if pointer valid, copy data */
- rv->length = ival;
- if (ival) {
- rv->v_buffer = acpi_os_allocmem(ival);
- if (bval)
- memcpy(rv->v_buffer, bval, ival);
- }
+ default:
+ count = 1;
break;
- case AML_OBJTYPE_PACKAGE:
- /* Allocate package pointers */
- rv->length = ival;
- rv->v_package = (struct aml_value **)acpi_os_allocmem(
- rv->length * sizeof(struct aml_value *));
- if (bval != NULL) {
- pv = (struct aml_value **)bval;
- dnprintf(40, "alloc package.. %lld\n", ival);
- for (idx = 0; idx < ival; idx++)
- rv->v_package[idx] = aml_copyvalue(pv[idx]);
+ }
+ node = NULL;
+ while (count-- && root) {
+ /* Create new name if it does not exist */
+ if ((node = __aml_search(root, name)) == NULL) {
+ node = acpi_os_malloc(sizeof(struct aml_node));
+
+ memcpy((void *)node->name, name, AML_NAMESEG_LEN);
+ for (pp = &root->child; *pp; pp=&(*pp)->sibling)
+ ;
+ node->parent = root;
+ node->sibling = NULL;
+ *pp = node;
}
+ root = node;
+ name += AML_NAMESEG_LEN;
+ }
+ /* If node created, set value pointer */
+ if (node && value) {
+ node->value = value;
+ value->node = node;
+ }
+ return node;
+}
+
+/* Search namespace for a named node */
+struct aml_node *
+aml_searchname(struct aml_node *root, const void *vname)
+{
+ struct aml_node *node;
+ uint8_t *name = (uint8_t *)vname;
+ int count;
+
+ if (*name == AMLOP_ROOTCHAR) {
+ root = &aml_root;
+ name++;
+ }
+ while (*name == AMLOP_PARENTPREFIX && root) {
+ root = root->parent;
+ name++;
+ }
+ if (strlen(name) < AML_NAMESEG_LEN) {
+ aml_die("bad name");
+ }
+ switch (*name) {
+ case 0x00:
+ return root;
+ case AMLOP_MULTINAMEPREFIX:
+ count = name[1];
+ name += 2;
break;
- case AML_OBJTYPE_METHOD:
- rv->v_method.flags = ival;
- break;
- case AML_OBJTYPE_MUTEX:
- rv->v_integer = ival;
- break;
- case AML_OBJTYPE_OPREGION:
- case AML_OBJTYPE_DEVICE:
- case AML_OBJTYPE_EVENT:
- case AML_OBJTYPE_POWERRSRC:
- case AML_OBJTYPE_PROCESSOR:
- case AML_OBJTYPE_THERMZONE:
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
+ case AMLOP_DUALNAMEPREFIX:
+ count = 2;
+ name += 1;
break;
default:
- dnprintf(40, "Unknown aml_allocvalue: %.2x\n", type);
+ if (name[4] == '.') {
+ /* Called from user code */
+ while (*name && (root = __aml_search(root, name)) != NULL) {
+ name += AML_NAMESEG_LEN+1;
+ }
+ return root;
+ }
+ /* Special case.. search relative for name */
+ while (root && (node = __aml_search(root, name)) == NULL) {
+ root = root->parent;
+ }
+ return node;
}
-
- return (rv);
+ /* Search absolute for name*/
+ while (count-- && (root = __aml_search(root, name)) != NULL) {
+ name += AML_NAMESEG_LEN;
+ }
+ return root;
}
-struct aml_value *
-aml_allocint(u_int64_t ival)
+/* Free all children nodes/values */
+void
+aml_delchildren(struct aml_node *node)
{
- return aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL);
+ struct aml_node *onode;
+
+ if (node == NULL)
+ return;
+ while ((onode = node->child) != NULL) {
+ node->child = onode->sibling;
+
+ aml_delchildren(onode);
+
+ /* Decrease reference count */
+ aml_delref(&onode->value);
+
+ /* Delete node */
+ acpi_os_free(onode);
+ }
}
+/*
+ * @@@: Value functions
+ */
+struct aml_vallist
+{
+ struct aml_value *obj;
+ int nobj;
+ struct aml_vallist *next;
+};
+
+struct aml_scope
+{
+ struct acpi_softc *sc;
+ uint8_t *pos;
+ uint8_t *end;
+ struct aml_node *node;
+ struct aml_vallist *tmpvals;
+ struct aml_scope *parent;
+ struct aml_value *locals;
+ struct aml_value *args;
+ int nargs;
+};
+
+struct aml_value *aml_alloctmp(struct aml_scope *, int);
+struct aml_scope *aml_pushscope(struct aml_scope *, uint8_t *, uint8_t *, struct aml_node *);
+struct aml_scope *aml_popscope(struct aml_scope *);
+int aml_parsenode(struct aml_node *, uint8_t *, uint8_t **, struct aml_value *);
+
+#define LHS 0
+#define RHS 1
+#define DST 2
+#define DST2 3
+
+/* Allocate temporary storage in this scope */
struct aml_value *
-aml_allocstr(const char *str)
+aml_alloctmp(struct aml_scope *scope, int narg)
{
- return aml_allocvalue(AML_OBJTYPE_STRING, -1, (void *)str);
+ struct aml_vallist *tmp;
+
+ /* Allocate array of temp values */
+ tmp = (struct aml_vallist *)acpi_os_malloc(sizeof(struct aml_vallist) +
+ narg * sizeof(struct aml_value));
+
+ tmp->obj = (struct aml_value *)&tmp[1];
+ tmp->nobj = narg;
+
+ /* Link into scope */
+ tmp->next = scope->tmpvals;
+ scope->tmpvals = tmp;
+
+ /* Return array of values */
+ return tmp->obj;
}
-int
-_aml_freevalue(struct aml_value *v)
+/* Allocate+push parser scope */
+struct aml_scope *
+aml_pushscope(struct aml_scope *parent, uint8_t *start, uint8_t *end,
+ struct aml_node *node)
{
- int idx;
+ struct aml_scope *scope;
- /* Don't free static values */
- if (v == NULL)
- return (-1);
+ scope = acpi_os_malloc(sizeof(struct aml_scope));
+ scope->pos = start;
+ scope->end = end;
+ scope->node = node;
+ scope->parent = parent;
+ scope->sc = dsdt_softc;
- if (v->node || v->refcnt)
- return (-1);
+ return scope;
+}
- dnprintf(50, "freeing value : %4x %s\n", v->type,
- v->node ? "attached" : "freeable");
+struct aml_scope *
+aml_popscope(struct aml_scope *scope)
+{
+ struct aml_scope *nscope;
+ struct aml_vallist *ol;
+ int idx;
- /* XXX */
- return (-1);
+ if (scope == NULL)
+ return NULL;
+ nscope = scope->parent;
- switch (v->type) {
- case AML_OBJTYPE_STRING:
- if (v->v_string) {
- acpi_os_freemem((void *)v->v_string);
- v->v_string = NULL;
- }
- break;
- case AML_OBJTYPE_BUFFER:
- if (v->v_buffer) {
- acpi_os_freemem(v->v_buffer);
- v->v_buffer = NULL;
+ /* Free temporary values */
+ while ((ol = scope->tmpvals) != NULL) {
+ scope->tmpvals = ol->next;
+ for (idx=0; idx<ol->nobj; idx++) {
+ aml_freevalue(&ol->obj[idx]);
}
- break;
- case AML_OBJTYPE_PACKAGE:
- for (idx = 0; idx < v->length; idx++)
- aml_freevalue(&v->v_package[idx]);
- acpi_os_freemem(v->v_package);
- v->v_package = NULL;
- break;
- case AML_OBJTYPE_METHOD:
- acpi_os_freemem(v->v_method.start);
- break;
+ acpi_os_free(ol);
}
- v->length = 0;
- v->type = 0;
+ acpi_os_free(scope);
- return (0);
+ return nscope;
}
+int
+aml_parsenode(struct aml_node *node, uint8_t *start, uint8_t **end,
+ struct aml_value *res)
+{
+ struct aml_scope *scope;
+
+ /* Don't parse zero-length scope */
+ if (start == *end) {
+ return 0;
+ }
+ scope = aml_pushscope(NULL, start, *end, node);
+ if (res == NULL) {
+ res = aml_alloctmp(scope, 1);
+ }
+ while (scope != NULL) {
+ while (scope->pos < scope->end)
+ aml_parseop(scope, res);
+ scope = aml_popscope(scope);
+ }
+ return 0;
+}
+
+/*
+ * Field I/O code
+ */
+void aml_setbufint(struct aml_value *, int, int, struct aml_value *);
+void aml_getbufint(struct aml_value *, int, int, struct aml_value *);
+void aml_fieldio(struct aml_scope *, struct aml_value *, struct aml_value *, int);
+
+/* Copy from a bufferfield to an integer/buffer */
void
-aml_freevalue(struct aml_value **pv)
+aml_setbufint(struct aml_value *dst, int bitpos, int bitlen,
+ struct aml_value *src)
{
- if (_aml_freevalue(*pv) == 0) {
- acpi_os_freemem(*pv);
- *pv = NULL;
+ if (src->type != AML_OBJTYPE_BUFFER) {
+ aml_die("wrong setbufint type\n");
+ }
+ if (bitlen < aml_intlen) {
+ /* XXX: Endian issues?? */
+ /* Return integer type */
+ _aml_setvalue(dst, AML_OBJTYPE_INTEGER, 0, NULL);
+ aml_bufcpy(&dst->v_integer, 0, src->v_buffer, bitpos, bitlen);
+ }
+ else {
+ /* Return buffer type */
+ _aml_setvalue(dst, AML_OBJTYPE_BUFFER, (bitlen+7)>>3, NULL);
+ aml_bufcpy(dst->v_buffer, 0, src->v_buffer, bitpos, bitlen);
}
}
+/* Copy from a string/integer/buffer to a bufferfield */
void
-aml_showvalue(struct aml_value *value)
+aml_getbufint(struct aml_value *src, int bitpos, int bitlen,
+ struct aml_value *dst)
{
- int idx;
+ 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);
+ break;
+ case AML_OBJTYPE_BUFFER:
+ aml_bufcpy(dst->v_buffer, bitpos, src->v_buffer, 0, bitlen);
+ break;
+ case AML_OBJTYPE_STRING:
+ aml_bufcpy(dst->v_buffer, bitpos, src->v_string, 0, bitlen);
+ break;
+ }
+}
- if (value == NULL)
- return;
+/*
+ * Buffer/Region: read/write to bitfields
+ */
+void
+aml_fieldio(struct aml_scope *scope, struct aml_value *field,
+ struct aml_value *res, int mode)
+{
+ struct aml_value opr, *pop;
+ int bpos, blen, aligned, mask;
- if (value->node)
- dnprintf(50, "node:%.8x ", value->node);
+ 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_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_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) {
+ aml_die("Not an opregion!\n");
+ }
- if (value->name)
- dnprintf(50, "name:%s ", value->name);
+ /* Get field access size */
+ switch (AML_FIELD_ACCESS(field->v_field.flags)) {
+ case AML_FIELD_ANYACC:
+ case AML_FIELD_BYTEACC:
+ mask = 7;
+ break;
+ case AML_FIELD_WORDACC:
+ mask = 15;
+ break;
+ case AML_FIELD_DWORDACC:
+ mask = 31;
+ break;
+ case AML_FIELD_QWORDACC:
+ mask = 63;
+ break;
+ }
- 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");
+ /* Get aligned bitpos/bitlength */
+ bpos = field->v_field.bitpos & ~mask;
+ blen = ((field->v_field.bitpos & mask) +
+ field->v_field.bitlen + mask) & ~mask;
+ aligned = (bpos == field->v_field.bitpos &&
+ blen == field->v_field.bitlen);
+ mask++;
+
+ /* Verify that I/O is in range */
+#if 0
+ 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,
+ pop->v_opregion.iobase,
+ pop->v_opregion.iolen,
+ bpos+blen);
+ }
+#endif
+
+ _aml_setvalue(&opr, AML_OBJTYPE_BUFFER, blen>>3, NULL);
+ if (mode == ACPI_IOREAD) {
+ /* Read from GAS space */
+ aml_gasio(scope->sc, pop->v_opregion.iospace,
+ pop->v_opregion.iobase,
+ pop->v_opregion.iolen,
+ bpos, blen, mask+1,
+ opr.v_buffer,
+ ACPI_IOREAD);
+ aml_setbufint(res, field->v_field.bitpos & mask,
+ field->v_field.bitlen, &opr);
+ }
+ else {
+ switch (AML_FIELD_UPDATE(field->v_field.flags)) {
+ case AML_FIELD_WRITEASONES:
+ if (!aligned) {
+ dnprintf(50,"fpr:WriteOnes\n");
+ memset(opr.v_buffer, 0xff, opr.length);
+ }
+ break;
+ case AML_FIELD_PRESERVE:
+ if (!aligned) {
+ /* Non-aligned I/O: need to read current value */
+ dnprintf(50,"fpr:Preserve\n");
+ aml_gasio(scope->sc, pop->v_opregion.iospace,
+ pop->v_opregion.iobase,
+ pop->v_opregion.iolen,
+ bpos, blen, mask+1,
+ opr.v_buffer,
+ ACPI_IOREAD);
+ }
+ break;
+ }
+ /* Copy Bits into destination buffer */
+ aml_getbufint(res, field->v_field.bitpos & mask,
+ field->v_field.bitlen,
+ &opr);
+ aml_gasio(scope->sc, pop->v_opregion.iospace,
+ pop->v_opregion.iobase,
+ pop->v_opregion.iolen,
+ bpos, blen, mask+1,
+ opr.v_buffer,
+ ACPI_IOWRITE);
+ }
+ aml_freevalue(&opr);
break;
- case AML_OBJTYPE_NAMEREF:
- dnprintf(50, "nameref: %s %.8x\n", value->name,
- value->v_objref.ref);
+ 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) {
+ aml_setbufint(res, bpos, blen, pop);
+ }
+ else {
+ aml_getbufint(res, bpos, blen, pop);
+ }
break;
- case AML_OBJTYPE_STATICINT:
+ }
+}
+
+/*
+ * @@@: Value set/compare/alloc/free routines
+ */
+int64_t aml_str2int(const char *, int);
+struct aml_value *aml_dereftarget(struct aml_scope *, struct aml_value *);
+struct aml_value *aml_derefterm(struct aml_scope *, struct aml_value *, int);
+
+void
+aml_showvalue(struct aml_value *val)
+{
+ int idx;
+
+ if (val == NULL)
+ return;
+
+ if (val->node) {
+ dnprintf(0," [%s]", aml_nodename(val->node));
+ }
+ dnprintf(0," %p cnt:%.2x", val, val->refcnt);
+ switch (val->type) {
case AML_OBJTYPE_INTEGER:
- dnprintf(50, "integer: %llx %s\n", value->v_integer,
- (value->type == AML_OBJTYPE_STATICINT) ? "(static)" : "");
+ dnprintf(0," integer: %llx\n", val->v_integer);
break;
case AML_OBJTYPE_STRING:
- dnprintf(50, "string: %s\n", value->v_string);
+ dnprintf(0," string: %s\n", val->v_string);
+ break;
+ case AML_OBJTYPE_METHOD:
+ dnprintf(0," method: %.2x\n", val->v_method.flags);
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");
+ dnprintf(0," package: %.2x\n", val->length);
+ for (idx=0; idx<val->length; idx++) {
+ aml_showvalue(val->v_package[idx]);
+ }
break;
case AML_OBJTYPE_BUFFER:
- dnprintf(50, "buffer: %d ", value->length);
- aml_dump(value->length, value->v_buffer);
+ dnprintf(0," buffer: %.2x {", val->length);
+ for (idx=0; idx<val->length; idx++) {
+ dnprintf(0,"%s%.2x", idx ? ", " : "", val->v_buffer[idx]);
+ }
+ dnprintf(0,"}\n");
break;
- case AML_OBJTYPE_DEBUGOBJ:
- dnprintf(50, "debug");
+ case AML_OBJTYPE_FIELDUNIT:
+ case AML_OBJTYPE_BUFFERFIELD:
+ dnprintf(0," field: bitpos=%.4x bitlen=%.4x ref1:%x ref2:%x [%s]\n",
+ val->v_field.bitpos, val->v_field.bitlen,
+ val->v_field.ref1, val->v_field.ref2,
+ aml_mnem(val->v_field.type));
+ aml_showvalue(val->v_field.ref1);
+ aml_showvalue(val->v_field.ref2);
break;
case AML_OBJTYPE_MUTEX:
- dnprintf(50, "mutex : %llx\n", value->v_integer);
- break;
- case AML_OBJTYPE_DEVICE:
- dnprintf(50, "device\n");
+ dnprintf(0," mutex: %llx\n", val->v_integer);
break;
case AML_OBJTYPE_EVENT:
- dnprintf(50, "event\n");
+ dnprintf(0," event:\n");
break;
- case AML_OBJTYPE_PROCESSOR:
- dnprintf(50, "cpu: %x,%x,%x\n",
- value->v_processor.proc_id,
- value->v_processor.proc_addr,
- value->v_processor.proc_len);
+ case AML_OBJTYPE_OPREGION:
+ dnprintf(0," opregion: %.2x,%.8llx,%x\n",
+ val->v_opregion.iospace,
+ val->v_opregion.iobase,
+ val->v_opregion.iolen);
break;
- case AML_OBJTYPE_METHOD:
- dnprintf(50, "method: args=%d, serialized=%d, synclevel=%d\n",
- AML_METHOD_ARGCOUNT(value->v_method.flags),
- AML_METHOD_SERIALIZED(value->v_method.flags),
- AML_METHOD_SYNCLEVEL(value->v_method.flags));
+ case AML_OBJTYPE_NAMEREF:
+ dnprintf(0," nameref: %s\n", aml_getname(val->v_nameref));
break;
- case AML_OBJTYPE_FIELDUNIT:
- 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.bitpos,
- value->v_field.bitlen);
-
- aml_showvalue(value->v_field.ref1);
- aml_showvalue(value->v_field.ref2);
+ case AML_OBJTYPE_DEVICE:
+ dnprintf(0," device:\n");
break;
- case AML_OBJTYPE_BUFFERFIELD:
- dnprintf(50, "%s: pos=%.4x len=%.4x ",
- aml_opname(value->v_field.type),
- value->v_field.bitpos,
- value->v_field.bitlen);
-
- if (value->v_field.ref1)
- aml_dump(aml_bytelen(value->v_field.bitlen),
- value->v_field.ref1->v_buffer +
- aml_bytepos(value->v_field.bitpos));
-
- aml_showvalue(value->v_field.ref1);
+ case AML_OBJTYPE_PROCESSOR:
+ dnprintf(0," cpu: %.2x,%.4x,%.2x\n",
+ val->v_processor.proc_id, val->v_processor.proc_addr,
+ val->v_processor.proc_len);
break;
- case AML_OBJTYPE_OPREGION:
- dnprintf(50, "opregion: %s,0x%llx,0x%x\n",
- opregion(value->v_opregion.iospace),
- value->v_opregion.iobase,
- value->v_opregion.iolen);
+ case AML_OBJTYPE_THERMZONE:
+ dnprintf(0," thermzone:\n");
break;
- default:
- dnprintf(50, "unknown: %d\n", value->type);
+ case AML_OBJTYPE_POWERRSRC:
+ dnprintf(0," pwrrsrc: %.2x,%.2x\n",
+ val->v_powerrsrc.pwr_level,
+ val->v_powerrsrc.pwr_order);
+ break;
+ case AML_OBJTYPE_OBJREF:
+ dnprintf(0," objref: %p index:%x\n", val->v_objref.ref, val->v_objref.index);
+ aml_showvalue(val->v_objref.ref);
break;
+ default:
+ dnprintf(0," !!type: %x\n", val->type);
}
}
-int
-aml_comparevalue(struct acpi_context *ctx, int opcode, struct aml_value *lhs,
- struct aml_value *rhs)
+/* Returns dereferenced target value */
+struct aml_value *
+aml_dereftarget(struct aml_scope *scope, struct aml_value *ref)
{
- struct aml_value *tmp;
- int rc;
+ struct aml_node *node;
+ int index;
- if (lhs->type == AML_OBJTYPE_INTEGER)
- return aml_logicalcmp(opcode, lhs->v_integer,
- aml_val2int(ctx, rhs));
+ for(;;) {
+ switch (ref->type) {
+ case AML_OBJTYPE_NAMEREF:
+ node = aml_searchname(scope->node, ref->v_nameref);
+ if (node && node->value)
+ ref = node->value;
+ break;
+ case AML_OBJTYPE_OBJREF:
+ index = ref->v_objref.index;
+ ref = aml_dereftarget(scope, ref->v_objref.ref);
+ if (index != -1) {
+ switch (ref->type) {
+ case AML_OBJTYPE_PACKAGE:
+ ref = ref->v_package[index];
+ break;
+ default:
+ aml_die("Index");
+ break;
+ }
+ }
+ break;
+ default:
+ return ref;
+ }
+ }
+}
+/* Perform DeRef on terminal
+ * Returns expected type if required
+ */
+struct aml_value *
+aml_derefterm(struct aml_scope *scope, struct aml_value *ref, int expect)
+{
+ struct aml_value *tmp;
- if (rhs->type == AML_OBJTYPE_INTEGER)
- return aml_logicalcmp(opcode,
- aml_val2int(ctx, lhs), rhs->v_integer);
+ ref = aml_dereftarget(scope, ref);
+ switch (ref->type) {
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ /* Read I/O field into temporary storage */
+ tmp = aml_alloctmp(scope, 1);
+ aml_fieldio(scope, ref, tmp, ACPI_IOREAD);
+ return tmp;
+ }
+ if (expect != ref->type) {
+ dnprintf(50,"convert in derefterm\n");
+ }
+ return ref;
+}
- if (lhs->type == AML_OBJTYPE_BUFFER) {
- tmp = aml_val2buf(ctx, rhs, 0);
- rc = aml_bufcmp(lhs->v_buffer, lhs->length,
- tmp->v_buffer, tmp->length);
+int64_t
+aml_str2int(const char *str, int radix)
+{
+ /* XXX: fixme */
+ return 0;
+}
- return (opcode == AMLOP_LNOTEQUAL) ?
- (rc != AMLOP_LEQUAL) : (rc == opcode);
- }
- /* XXX: fix this.. non integer comparisons */
- dnprintf(40,"comparevalue: %.2x %.2x\n", lhs->type, rhs->type);
+int64_t
+aml_val2int(struct aml_value *rval)
+{
+ int64_t ival = 0;
- return (0);
+ if (rval == NULL) {
+ dnprintf(50,"null val2int\n");
+ return (0);
+ }
+ switch (rval->type & ~AML_STATIC) {
+ case AML_OBJTYPE_INTEGER:
+ ival = rval->v_integer;
+ break;
+ case AML_OBJTYPE_BUFFER:
+ aml_bufcpy(&ival, 0, rval->v_buffer, 0,
+ min(aml_intlen*8, rval->length*8));
+ break;
+ case AML_OBJTYPE_STRING:
+ ival = (strncmp(rval->v_string, "0x", 2) == 0) ?
+ aml_str2int(rval->v_string+2, 16) :
+ aml_str2int(rval->v_string, 10);
+ break;
+ }
+ return (ival);
}
struct aml_value *
-aml_copyvalue(const struct aml_value *rhs)
+_aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
{
- struct aml_value *rv;
+ memset(&lhs->_, 0x0, sizeof(lhs->_));
- switch (rhs->type) {
- case AML_OBJTYPE_STATICINT:
+ lhs->type = type;
+ switch (lhs->type & ~AML_STATIC) {
case AML_OBJTYPE_INTEGER:
- return aml_allocvalue(rhs->type, rhs->v_integer, NULL);
- case AML_OBJTYPE_STRING:
- return aml_allocvalue(rhs->type, rhs->length, rhs->v_string);
+ lhs->v_integer = ival;
+ break;
+ case AML_OBJTYPE_METHOD:
+ lhs->v_integer = ival;
+ break;
+ case AML_OBJTYPE_NAMEREF:
+ lhs->v_nameref = (uint8_t *)bval;
+ break;
+ case AML_OBJTYPE_OBJREF:
+ lhs->v_objref.index = ival;
+ lhs->v_objref.ref = (struct aml_value *)bval;
+ break;
case AML_OBJTYPE_BUFFER:
- return aml_allocvalue(rhs->type, rhs->length, rhs->v_buffer);
+ lhs->length = ival;
+ lhs->v_buffer = (uint8_t *)acpi_os_malloc(ival);
+ if (bval)
+ memcpy(lhs->v_buffer, bval, ival);
+ break;
+ case AML_OBJTYPE_STRING:
+ if (ival == -1)
+ ival = strlen((const char *)bval);
+ lhs->length = ival;
+ lhs->v_string = (char *)acpi_os_malloc(ival+1);
+ if (bval)
+ strncpy(lhs->v_string, (const char *)bval, ival);
+ break;
case AML_OBJTYPE_PACKAGE:
- return aml_allocvalue(rhs->type, rhs->length, rhs->v_package);
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
- rv = aml_allocvalue(rhs->type, 0, NULL);
- if (rv != NULL) {
- rv->name = rhs->name;
- rv->length = rhs->length;
- rv->v_field = rhs->v_field;
+ lhs->length = ival;
+ lhs->v_package = (struct aml_value **)acpi_os_malloc(ival * sizeof(struct aml_value *));
+ for (ival=0; ival<lhs->length; ival++) {
+ lhs->v_package[ival] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
}
- return (rv);
-
- default:
- dnprintf(40,"copy unknown : %x\n", rhs->type);
- rv = aml_allocvalue(rhs->type, 0, NULL);
- *rv = *rhs;
break;
}
- return (rv);
+ return lhs;
}
-/* Resize buffer/string/package if out-of-bounds access */
void
-aml_resizevalue(struct aml_value *pv, int newlen)
+aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
{
- struct aml_value **newpkg;
- u_int8_t *newbuf;
- int i1;
+ int idx;
- ++newlen;
- dnprintf(40, "supersizeme\n");
- switch (pv->type) {
+ lhs->type = rhs->type & ~AML_STATIC;
+ switch (lhs->type) {
+ case AML_OBJTYPE_UNINITIALIZED:
+ break;
+ case AML_OBJTYPE_INTEGER:
+ case AML_OBJTYPE_MUTEX:
+ lhs->v_integer = rhs->v_integer;
+ break;
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;
+ _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer);
+ break;
+ case AML_OBJTYPE_STRING:
+ _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string);
+ break;
+ case AML_OBJTYPE_OPREGION:
+ lhs->v_opregion = rhs->v_opregion;
+ break;
+ case AML_OBJTYPE_NAMEREF:
+ lhs->v_nameref = rhs->v_nameref;
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;
-
+ _aml_setvalue(lhs, rhs->type, rhs->length, NULL);
+ 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);
+ break;
+ default:
+ aml_die("copyvalue: %x", rhs->type);
break;
}
}
-/* * AML Parsing routines */
-const char *
-aml_parse_string(struct acpi_context *ctx)
+/* Guts of the code: Assign one value to another */
+void
+aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
+ struct aml_value *rhs, int64_t ival)
{
- const char *str = ctx->pos;
+ struct aml_value tmpint;
+ struct aml_value *olhs;
- ctx->pos += strlen(str) + 1;
+ /* Use integer as result */
+ if (rhs == NULL) {
+ memset(&tmpint, 0, sizeof(tmpint));
+ rhs = _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, ival, NULL);
+ }
- return (str);
-}
+ olhs = lhs;
+ lhs = aml_dereftarget(scope, lhs);
-/* Read value from AML bytestream */
-u_int64_t
-aml_parse_int(struct acpi_context *ctx, int size)
-{
- u_int8_t *pc = ctx->pos;
-
- switch (size) {
- case AML_BYTE:
- ctx->pos += 1;
- return *(u_int8_t *)pc;
- case AML_WORD:
- ctx->pos += 2;
- return *(u_int16_t *)pc;
- case AML_DWORD:
- ctx->pos += 4;
- return *(u_int32_t *)pc;
- case AML_QWORD:
- ctx->pos += 8;
- return *(u_int64_t *)pc;
+ switch (lhs->type) {
+ case AML_OBJTYPE_UNINITIALIZED:
+ aml_copyvalue(lhs, rhs);
+ break;
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ aml_fieldio(scope, lhs, rhs, ACPI_IOWRITE);
+ break;
+ case AML_OBJTYPE_DEBUGOBJ:
+ case AML_OBJTYPE_INTEGER+AML_STATIC:
+ break;
+ case AML_OBJTYPE_INTEGER:
+ lhs->v_integer = aml_val2int(rhs);
+ break;
+ case AML_OBJTYPE_BUFFER:
+ 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) {
+ _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, sizeof(rhs->v_integer),
+ &rhs->v_integer);
+ }
+ 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) {
+ 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) {
+ _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length, rhs->v_buffer);
+ }
+ 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");
+ }
+ break;
+ default:
+ /* XXX: */
+ dnprintf(0,"setvalue.unknown: %x", lhs->type);
+ break;
}
-
- return (0);
}
-/* Decode AML Package length
- * Upper two bits of first byte denote length
- * 0x00 = length is in lower 6 bits
- * 0x40 = length is lower 4 bits + 1 byte
- * 0x80 = length is lower 4 bits + 2 bytes
- * 0xC0 = length is lower 4 bits + 3 bytes
+/* Allocate dynamic AML value
+ * type : Type of object to allocate (AML_OBJTYPE_XXXX)
+ * ival : Integer value (action depends on type)
+ * bval : Buffer value (action depends on type)
*/
-int
-aml_parse_length(struct acpi_context *ctx)
+struct aml_value *
+aml_allocvalue(int type, int64_t ival, const void *bval)
{
- u_int8_t lcode;
- int ival;
-
- lcode = aml_parse_int(ctx, AML_BYTE);
- if (lcode <= 0x3f)
- return (lcode);
-
- ival = lcode & 0xf;
- 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;
+ struct aml_value *rv;
- return (ival);
+ rv = (struct aml_value *)acpi_os_malloc(sizeof(struct aml_value));
+ if (rv != NULL) {
+ aml_addref(rv);
+ return _aml_setvalue(rv, type, ival, bval);
+ }
+ return NULL;
}
-/* Decode AML Namestring from stream */
-const char *
-aml_parse_name(struct acpi_context *ctx)
+void
+aml_freevalue(struct aml_value *val)
{
- int count, pfxlen;
- char *name, *pn;
- u_int8_t *base;
-
- pfxlen = 0;
- if (ctx->pos[pfxlen] == AMLOP_ROOTCHAR)
- pfxlen++;
-
- while (ctx->pos[pfxlen] == AMLOP_PARENTPREFIX)
- pfxlen++;
-
- switch (ctx->pos[pfxlen]) {
- case 0x00:
- count = 0;
- base = ctx->pos + pfxlen + 1;
+ int idx;
+
+ if (val == NULL)
+ return;
+ switch (val->type) {
+ case AML_OBJTYPE_STRING:
+ acpi_os_free(val->v_string);
break;
- case AMLOP_MULTINAMEPREFIX:
- count = ctx->pos[pfxlen + 1];
- base = ctx->pos + pfxlen + 2;
+ case AML_OBJTYPE_BUFFER:
+ acpi_os_free(val->v_buffer);
break;
- case AMLOP_DUALNAMEPREFIX:
- count = 2;
- base = ctx->pos + pfxlen + 1;
+ case AML_OBJTYPE_PACKAGE:
+ for (idx=0; idx<val->length; idx++) {
+ aml_freevalue(val->v_package[idx]);
+ acpi_os_free(val->v_package[idx]);
+ }
+ acpi_os_free(val->v_package);
break;
- default:
- count = 1;
- base = ctx->pos + pfxlen;
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ aml_delref(&val->v_field.ref1);
+ aml_delref(&val->v_field.ref2);
break;
}
-
- name = acpi_os_allocmem(pfxlen + count * 5);
- pn = name;
-
- while (pfxlen--)
- *(pn++) = *(ctx->pos++);
-
- /* Copy name segments in chunks of 4 bytes */
- while (count--) {
- memcpy(pn, base, 4);
- if (count) {
- *(pn + 4) = '.';
- pn++;
- }
- pn += 4;
- base += 4;
- }
- *pn = 0;
-
- ctx->pos = base;
-
- return (name);
+ val->type = 0;
+ memset(&val->_, 0, sizeof(val->_));
}
-/* Is this opcode an encoded name? */
-int
-aml_isnamedop(u_int16_t opcode)
+/* Increase reference count */
+void
+aml_addref(struct aml_value *val)
{
- switch (opcode) {
- case AMLOP_ROOTCHAR:
- case AMLOP_PARENTPREFIX:
- case AMLOP_MULTINAMEPREFIX:
- case AMLOP_DUALNAMEPREFIX:
- case AMLOP_NAMECHAR:
- case 'A'...'Z':
- return (1);
- }
-
- return (0);
+ if (val)
+ val->refcnt++;
}
-/* * Math eval routines */
-u_int64_t
-aml_bcd2dec(u_int64_t val)
+/* Decrease reference count + delete value */
+void
+aml_delref(struct aml_value **val)
{
- u_int64_t rval;
- int n, pos;
-
- pos = 1;
- for (rval = 0; val; val >>= 4) {
- n = (val & 0xf);
- if (n > 9)
- return (0);
-
- rval += (n * pos);
- pos *= 10;
+ if (val && *val && --(*val)->refcnt == 0) {
+ aml_freevalue(*val);
+ acpi_os_free(*val);
+ *val = NULL;
}
-
- return (rval);
}
-u_int64_t
-aml_dec2bcd(u_int64_t val)
-{
- u_int64_t rval;
- int n, pos;
+/*
+ * @@@: Math eval routines
+ */
- pos = 0;
- for (rval = 0; val; val /= 10) {
- n = (val % 10);
+/* Convert number from one radix to another
+ * Used in BCD conversion routines */
+u_int64_t
+aml_convradix(u_int64_t val, int iradix, int oradix)
+{
+ u_int64_t rv = 0, pwr;
- rval += (n << pos);
- pos += 4;
+ rv = 0;
+ pwr = 1;
+ while (val) {
+ rv += (val % iradix) * pwr;
+ val /= iradix;
+ pwr *= oradix;
}
-
- return (rval);
+ return rv;
}
-
/* Calculate LSB */
int
aml_lsb(u_int64_t val)
@@ -1008,11 +1418,12 @@ aml_msb(u_int64_t val)
/* Evaluate Math operands */
int64_t
-aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs)
+aml_evalexpr(int64_t lhs, int64_t rhs, int opcode)
{
- dnprintf(50, "evalmath: %s %lld %lld\n", aml_opname(opcode), lhs, rhs);
+ dnprintf(50, "evalexpr: %s %lld %lld\n", aml_mnem(opcode), lhs, rhs);
switch (opcode) {
+ /* Math operations */
case AMLOP_INCREMENT:
case AMLOP_ADD:
return (lhs + rhs);
@@ -1039,31 +1450,22 @@ aml_evalmath(u_int16_t opcode, int64_t lhs, int64_t rhs)
return ~(lhs | rhs);
case AMLOP_XOR:
return (lhs ^ rhs);
+ case AMLOP_NOT:
+ return ~(lhs);
+
+ /* Conversion/misc */
case AMLOP_FINDSETLEFTBIT:
return aml_msb(lhs);
case AMLOP_FINDSETRIGHTBIT:
return aml_lsb(lhs);
- case AMLOP_NOT:
- return ~(lhs);
case AMLOP_TOINTEGER:
return (lhs);
case AMLOP_FROMBCD:
- return aml_bcd2dec(lhs);
+ return aml_convradix(lhs, 16, 10);
case AMLOP_TOBCD:
- return aml_dec2bcd(lhs);
- }
-
- return (0);
-}
+ return aml_convradix(lhs, 10, 16);
-/* Evaluate logical test operands */
-int
-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) {
+ /* Logical/Comparison */
case AMLOP_LAND:
return (lhs && rhs);
case AMLOP_LOR:
@@ -1087,1339 +1489,1271 @@ aml_logicalcmp(u_int16_t opcode, int64_t lhs, int64_t rhs)
return (0);
}
-const char *
-aml_opname(int opcode)
+int
+aml_cmpvalue(struct aml_value *lhs, struct aml_value *rhs, int opcode)
{
- struct aml_opcode *ptab = aml_table;
+ int rc;
- while (ptab->opcode != 0xffff) {
- if (ptab->opcode == opcode)
- return ptab->mnem;
- ptab++;
+ rc = 0;
+ if (lhs->type == rhs->type) {
+ switch (lhs->type) {
+ case AML_OBJTYPE_INTEGER:
+ rc = (lhs->v_integer - rhs->v_integer);
+ break;
+ case AML_OBJTYPE_STRING:
+ rc = strncmp(lhs->v_string, rhs->v_string, min(lhs->length, rhs->length));
+ if (rc == 0)
+ rc = lhs->length - rhs->length;
+ break;
+ case AML_OBJTYPE_BUFFER:
+ rc = memcmp(lhs->v_buffer, rhs->v_buffer, min(lhs->length, rhs->length));
+ if (rc == 0)
+ rc = lhs->length - rhs->length;
+ break;
+ }
+ }
+ else if (lhs->type == AML_OBJTYPE_INTEGER) {
+ rc = lhs->v_integer - aml_val2int(rhs);
+ }
+ else if (rhs->type == AML_OBJTYPE_INTEGER) {
+ rc = aml_val2int(lhs) - rhs->v_integer;
}
- return ("");
-}
-
-/* Extract opcode from AML bytestream
- *
- * Some opcodes are multibyte
- * Name strings can also be embedded within the stream
- */
-struct aml_opcode
-*aml_getopcode(struct acpi_context *ctx)
-{
- struct aml_opcode *ptab;
- u_int16_t twocode, opcode;
-
- /* Check if this is a name object */
- if (aml_isnamedop(*ctx->pos))
- opcode = AMLOP_NAMECHAR;
else {
- opcode = aml_parse_int(ctx, AML_BYTE);
- twocode = (opcode << 8L) + *ctx->pos;
-
- /* Check multi-byte opcodes */
- if (twocode == AMLOP_LNOTEQUAL ||
- twocode == AMLOP_LLESSEQUAL ||
- twocode == AMLOP_LGREATEREQUAL ||
- opcode == AMLOP_EXTPREFIX) {
- opcode = twocode;
- ctx->pos++;
- }
+ aml_die("mismatched compare\n");
}
-
- for (ptab = aml_table; ptab->opcode != 0xffff; ptab++)
- if (ptab->opcode == opcode)
- return (ptab);
-
- dnprintf(40, "aml_getopcode: Unknown opcode %.4x\n", opcode);
-
- return (NULL);
+ return aml_evalexpr(rc, 0, opcode);
}
-/* Test AML_MATCH operation */
-int
-aml_match(int64_t lhs, int mtype, int64_t rhs)
+/*
+ * aml_bufcpy copies/shifts buffer data, special case for aligned transfers
+ * dstPos/srcPos are bit positions within destination/source buffers
+ */
+void
+aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos,
+ int len)
{
- switch (mtype) {
- case AML_MATCH_TR:
- return (1);
- case AML_MATCH_EQ:
- return (lhs == rhs);
- case AML_MATCH_LT:
- return (lhs < rhs);
- case AML_MATCH_LE:
- return (lhs <= rhs);
- case AML_MATCH_GE:
- return (lhs >= rhs);
- case AML_MATCH_GT:
- return (lhs > rhs);
+ const u_int8_t *pSrc = pvSrc;
+ u_int8_t *pDst = pvDst;
+ int idx;
+
+ if (aml_bytealigned(dstPos|srcPos|len)) {
+ /* Aligned transfer: use memcpy */
+ memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos), aml_bytelen(len));
+ return;
}
- return (0);
+ /* Misaligned transfer: perform bitwise copy (slow) */
+ for (idx = 0; idx < len; idx++)
+ aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
}
-struct aml_node *
-aml_find_name(struct acpi_softc *sc, struct aml_node *root, const char *name)
+/*
+ * Evaluate an AML method
+ *
+ * Returns a copy of the result in res (must be freed by user)
+ */
+struct aml_value *
+aml_evalmethod(struct aml_node *node,
+ int argc, struct aml_value *argv,
+ struct aml_value *res)
{
- struct aml_node *ret;
- const char *sname;
+ struct aml_scope *scope;
- if (*name == AMLOP_ROOTCHAR) {
- root = &aml_root;
- name++;
- }
+ scope = aml_pushscope(NULL, node->value->v_method.start,
+ node->value->v_method.end, node);
+ scope->args = argv;
+ scope->nargs = argc;
+ scope->locals = aml_alloctmp(scope, AML_MAX_LOCAL);
- while (*name == AMLOP_PARENTPREFIX) {
- if (root)
- root = root->parent;
- name++;
- }
+ if (res == NULL)
+ res = aml_alloctmp(scope, 1);
+#ifdef ACPI_DEBUG
+ dnprintf(10,"calling [%s] (%d args)\n",
+ aml_nodename(node),
+ scope->nargs);
+ while (scope->pos < scope->end)
+ aml_parseterm(scope, res);
+ printf("[%s] returns: ", aml_nodename(node));
+ aml_showvalue(res);
+#else
+ while (scope->pos < scope->end)
+ aml_parseterm(scope, res);
+#endif
+ /* Free any temporary children nodes */
+ aml_delchildren(node);
+ aml_popscope(scope);
- if (root == NULL)
- root = &aml_root;
+ return NULL;
+}
- for (ret = NULL; root && !ret; root = root->sibling) {
- if ((sname = root->name) != NULL) {
- if (*sname == AMLOP_ROOTCHAR)
- sname++;
+/*
+ * @@@: External API
+ *
+ * evaluate an AML node
+ * Returns a copy of the value in res (must be freed by user)
+ */
+int
+aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
+ int argc, struct aml_value *argv,
+ struct aml_value *res)
+{
+ static int lastck;
- while (*sname == AMLOP_PARENTPREFIX)
- sname++;
+ if (res)
+ memset(res, 0, sizeof(struct aml_value));
+ if (node == NULL || node->value == NULL)
+ return (ACPI_E_BADVALUE);
- if (!strcmp(name, sname))
- return (root);
+ switch (node->value->type) {
+ case AML_OBJTYPE_METHOD:
+ aml_evalmethod(node, argc, argv, res);
+ if (acpi_nalloc > lastck) {
+ /* Check if our memory usage has increased */
+ dnprintf(0,"Leaked: [%s] %d\n",
+ aml_nodename(node), acpi_nalloc);
+ lastck = acpi_nalloc;
}
- if (root->child)
- ret = aml_find_name(sc, root->child, name);
+ break;
+ case AML_OBJTYPE_INTEGER:
+ case AML_OBJTYPE_STRING:
+ case AML_OBJTYPE_BUFFER:
+ case AML_OBJTYPE_PACKAGE:
+ case AML_OBJTYPE_EVENT:
+ case AML_OBJTYPE_DEVICE:
+ case AML_OBJTYPE_MUTEX:
+ case AML_OBJTYPE_OPREGION:
+ case AML_OBJTYPE_POWERRSRC:
+ case AML_OBJTYPE_PROCESSOR:
+ case AML_OBJTYPE_THERMZONE:
+ case AML_OBJTYPE_DEBUGOBJ:
+ if (res)
+ aml_copyvalue(res, node->value);
+ break;
+ default:
+ break;
}
-
- return (ret);
+ return (0);
}
+/*
+ * evaluate an AML name
+ * Returns a copy of the value in res (must be freed by user)
+ */
int
-aml_eval_name(struct acpi_softc *sc, struct aml_node *root, const char *name,
- struct aml_value *result, struct aml_value *env)
+aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
+ int argc, struct aml_value *argv,
+ struct aml_value *res)
{
- root = aml_find_name(sc, root, name);
-
- if (root != NULL) {
- dnprintf(50, "found eval object : %s, %.4x\n",
- root->name, root->opcode);
-
- return aml_eval_object(sc, root, result, 0, env);
- }
-
- return (1);
+ return aml_evalnode(sc, aml_searchname(parent, name), argc, argv, res);
}
-int64_t
-aml_str2int(const char *str, int len, int radix)
-{
- int64_t rval, cb;
-
- rval = 0;
- while (*str && len--) {
- cb = *(str++);
- rval *= radix;
- if (cb >= 'A' && cb <= 'F' && radix == 16)
- rval += (cb - 'A');
- else if (cb >= 'a' && cb <= 'f' && radix == 16)
- rval += (cb - 'a');
- else if (cb >= '0' && cb <= '9')
- rval += (cb - '0');
- else
- break;
+void
+aml_walktree(struct aml_node *node)
+{
+ while(node) {
+ aml_showvalue(node->value);
+ aml_walktree(node->child);
+ node = node->sibling;
}
-
- return rval;
}
-
-/*
- * aml_bufcpy copies/shifts buffer data, special case for aligned transfers
- * dstPos/srcPos are bit positions within destination/source buffers
- */
void
-aml_bufcpy(u_int8_t *pDst, int dstPos, const u_int8_t *pSrc, int srcPos,
- int len)
+aml_walkroot(void)
{
- int idx;
-
- if (aml_bytealigned(dstPos|srcPos|len)) {
- /* Aligned transfer: use memcpy */
- memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos), aml_bytelen(len));
- return;
- }
-
- /* Misaligned transfer: perform bitwise copy */
- for (idx = 0; idx < len; idx++)
- aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
+ aml_walktree(aml_root.child);
}
-/* Compare two buffers; return comparison type */
int
-aml_bufcmp(const u_int8_t *abuf, int alen, const u_int8_t *bbuf, int blen)
+aml_find_node(struct aml_node *node, const char *name,
+ void (*cbproc)(struct aml_node *, void *arg),
+ void *arg)
{
- int rc;
+ const char *nn;
- while (alen && blen) {
- rc = *(abuf++) - *(bbuf++);
- if (rc != 0)
- return (rc < 0) ? AMLOP_LLESS : AMLOP_LGREATER;
- alen--;
- blen--;
+ while (node) {
+ if ((nn = node->name) != NULL) {
+ if (*nn == AMLOP_ROOTCHAR) nn++;
+ while (*nn == AMLOP_PARENTPREFIX) nn++;
+ if (!strcmp(name, nn))
+ cbproc(node, arg);
+ }
+ aml_find_node(node->child, name, cbproc, arg);
+ node = node->sibling;
}
- return (alen ? AMLOP_LGREATEREQUAL :
- (blen ? AMLOP_LLESSEQUAL : AMLOP_LEQUAL));
+ return (0);
}
/*
- * Search list of objects for a name match
- * Special case for fields: search children only
+ * @@@: Parser functions
*/
-struct aml_node *
-_aml_searchname(struct aml_node *list, const char *name)
+uint8_t *aml_parsename(struct aml_scope *);
+uint8_t *aml_parseend(struct aml_scope *scope);
+int aml_parselength(struct aml_scope *);
+int aml_parseopcode(struct aml_scope *);
+
+/* Get AML Opcode */
+int
+aml_parseopcode(struct aml_scope *scope)
{
- struct aml_node *child;
+ int opcode = (scope->pos[0]);
+ int twocode = (scope->pos[0]<<8) + scope->pos[1];
- if (list == NULL)
- return (NULL);
+ /* Check if this is an embedded name */
+ switch (opcode) {
+ case AMLOP_ROOTCHAR:
+ case AMLOP_PARENTPREFIX:
+ case AMLOP_MULTINAMEPREFIX:
+ case AMLOP_DUALNAMEPREFIX:
+ case AMLOP_NAMECHAR:
+ case 'A' ... 'Z':
+ return AMLOP_NAMECHAR;
+ }
+ if (twocode == AMLOP_LNOTEQUAL ||
+ twocode == AMLOP_LLESSEQUAL ||
+ twocode == AMLOP_LGREATEREQUAL ||
+ opcode == AMLOP_EXTPREFIX)
+ {
+ scope->pos += 2;
+ return twocode;
+ }
+ scope->pos += 1;
+ return opcode;
+}
- while (list) {
- if (list->opcode == AMLOP_FIELD ||
- list->opcode == AMLOP_BANKFIELD ||
- list->opcode == AMLOP_INDEXFIELD)
- if ((child = _aml_searchname(list->child, name)) !=
- NULL)
- return child;
+/* Decode embedded AML Namestring */
+uint8_t *
+aml_parsename(struct aml_scope *scope)
+{
+ uint8_t *name = scope->pos;
- if (list->name && !strncmp(list->name, name, AML_NAMESEG_LEN))
- return (list);
+ while (*scope->pos == AMLOP_ROOTCHAR || *scope->pos == AMLOP_PARENTPREFIX)
+ scope->pos++;
- list = list->sibling;
+ switch (*scope->pos) {
+ case 0x00:
+ break;
+ case AMLOP_MULTINAMEPREFIX:
+ scope->pos += 2+AML_NAMESEG_LEN*scope->pos[1];
+ break;
+ case AMLOP_DUALNAMEPREFIX:
+ scope->pos += 1+AML_NAMESEG_LEN*2;
+ break;
+ default:
+ scope->pos += AML_NAMESEG_LEN;
+ break;
}
-
- return (NULL);
+ return name;
}
-/* Create name references in tree, even if not initialized */
-struct aml_node *
-aml_doname(struct aml_node *root, const char *name, int create)
+/* Decode AML Length field */
+int
+aml_parselength(struct aml_scope *scope)
{
- struct aml_node *tmp;
-
- if (*name == AMLOP_ROOTCHAR) {
- name++;
- root = &aml_root;
- }
+ int len = (*scope->pos & 0xF);
- while (*name == AMLOP_PARENTPREFIX) {
- name++;
- if ((root = root->parent) == NULL)
- return (NULL);
+ switch (*scope->pos >> 6) {
+ case 0x00:
+ len = scope->pos[0] & 0x3F;
+ scope->pos += 1;
+ break;
+ case 0x01:
+ len += (scope->pos[1]<<4L);
+ scope->pos += 2;
+ break;
+ case 0x02:
+ len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L);
+ scope->pos += 3;
+ break;
+ case 0x03:
+ len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L) + (scope->pos[3]<<20L);
+ scope->pos += 4;
+ break;
}
+ return len;
+}
- if (root == NULL)
- root = &aml_root;
+/* Get address of end of scope; based on current address */
+uint8_t *
+aml_parseend(struct aml_scope *scope)
+{
+ uint8_t *pos = scope->pos;
+ int len;
- if (*name && name[AML_NAMESEG_LEN] == '\0' && !create) {
- do {
- tmp = _aml_searchname(root->child, name);
- root = root->parent;
- } while (tmp == NULL && root != NULL);
- return tmp;
+ len = aml_parselength(scope);
+ if (pos+len > scope->end) {
+ dnprintf(0,"Bad scope... runover pos:%.4x new end:%.4x scope end:%.4x\n",
+ aml_pc(pos), aml_pc(pos+len), aml_pc(scope->end));
+ pos = scope->end;
}
+ return pos+len;
+}
- for (tmp = root; tmp && *name; name += AML_NAMESEG_LEN) {
- if (*name == '.')
- name++;
+/*
+ * @@@: Opcode utility functions
+ */
+int aml_match(int, int64_t, struct aml_value *);
+void aml_getpciaddr(struct aml_scope *, struct aml_value *);
+void aml_fixref(struct aml_value **);
+int64_t aml_parseint(struct aml_scope *, int);
- tmp = _aml_searchname(root->child, name);
+int
+aml_match(int op, int64_t mv1, struct aml_value *mv2)
+{
+ struct aml_value tmpint;
- /* Create name if queried */
- if (tmp == NULL && create) {
- tmp = aml_create_node(root, -1, "DUMMY", root->start);
- if (tmp != NULL) {
- tmp->name = acpi_os_allocmem(
- AML_NAMESEG_LEN + 1);
- if (tmp->name)
- memcpy((char *)tmp->name, name,
- AML_NAMESEG_LEN);
- }
- }
- root = tmp;
+ memset(&tmpint, 0, sizeof(tmpint));
+ _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, mv1, NULL);
+ switch (op) {
+ case AML_MATCH_EQ:
+ return aml_cmpvalue(&tmpint, mv2, AMLOP_LEQUAL);
+ case AML_MATCH_LT:
+ return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESS);
+ case AML_MATCH_LE:
+ return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESSEQUAL);
+ case AML_MATCH_GE:
+ return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATEREQUAL);
+ case AML_MATCH_GT:
+ return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATER);
}
+ return (1);
+}
- return (tmp);
+void
+aml_getpciaddr(struct aml_scope *scope, struct aml_value *res)
+{
+ struct aml_node *node;
+ struct aml_value *tmpres;
+
+ /* PCI */
+ tmpres = aml_alloctmp(scope, 1);
+ node = aml_searchname(scope->node, "_ADR");
+ if (node != NULL) {
+ aml_evalterm(scope, node->value, tmpres);
+ res->v_opregion.iobase += (aml_val2int(tmpres) << 16L);
+ }
+ node = aml_searchname(scope->node, "_BBN");
+ if (node != NULL) {
+ aml_evalterm(scope, node->value, tmpres);
+ res->v_opregion.iobase += (aml_val2int(tmpres) << 48L);
+ }
}
-struct aml_node *
-aml_createname(struct aml_node *root, const char *name)
+/* Fixup references for BufferFields/FieldUnits */
+void
+aml_fixref(struct aml_value **res)
{
- return aml_doname(root, name, 1);
+ struct aml_value *oldres;
+
+ while (*res &&
+ (*res)->type == AML_OBJTYPE_OBJREF &&
+ (*res)->v_objref.index == -1)
+ {
+ oldres = (*res)->v_objref.ref;
+ aml_delref(res);
+ aml_addref(oldres);
+ *res = oldres;
+ }
}
-struct aml_node *
-aml_searchname(struct aml_node *root, const char *name)
+int64_t
+aml_parseint(struct aml_scope *scope, int opcode)
{
- return aml_doname(root, name, 0);
+ uint8_t *np = scope->pos;
+ struct aml_value *tmpval;
+ int64_t rval;
+
+ if (opcode == AML_ANYINT)
+ opcode = aml_parseopcode(scope);
+ switch (opcode) {
+ case AMLOP_ZERO:
+ rval = 0;
+ break;
+ case AMLOP_ONE:
+ rval = 1;
+ break;
+ case AMLOP_ONES:
+ rval = -1;
+ break;
+ case AMLOP_REVISION:
+ rval = 0x101;
+ break;
+ case AMLOP_BYTEPREFIX:
+ rval = *(uint8_t *)scope->pos;
+ scope->pos += 1;
+ break;
+ case AMLOP_WORDPREFIX:
+ rval = aml_letohost16(*(uint16_t *)scope->pos);
+ scope->pos += 2;
+ break;
+ case AMLOP_DWORDPREFIX:
+ rval = aml_letohost32(*(uint32_t *)scope->pos);
+ scope->pos += 4;
+ break;
+ case AMLOP_QWORDPREFIX:
+ rval = aml_letohost64(*(uint64_t *)scope->pos);
+ scope->pos += 8;
+ break;
+ default:
+ scope->pos = np;
+ tmpval = aml_alloctmp(scope, 1);
+ aml_parseterm(scope, tmpval);
+ return aml_val2int(tmpval);
+ }
+ dnprintf(60,"%.4x: [%s] %s\n",
+ aml_pc(scope->pos-opsize(opcode)),
+ aml_nodename(scope->node),
+ aml_mnem(opcode));
+
+ return rval;
}
struct aml_value *
-aml_ederef(struct acpi_context *ctx, struct aml_value *val)
+aml_evaltarget(struct aml_scope *scope, struct aml_value *res)
{
- struct aml_node *pn;
- struct aml_value *ref;
- int64_t i1;
+ return res;
+}
- if (val == NULL)
- return NULL;
+int
+aml_evalterm(struct aml_scope *scope, struct aml_value *raw,
+ struct aml_value *dst)
+{
+ int index, argc;
+ struct aml_node *deref;
+ struct aml_value *tmparg = NULL;
- switch (val->type) {
+ loop:
+ switch (raw->type) {
case AML_OBJTYPE_NAMEREF:
- if (val->v_objref.ref == NULL)
- if ((pn = aml_searchname(ctx->scope, val->name)) !=
- NULL)
- val->v_objref.ref = pn->value;
-
- if (val->v_objref.ref != NULL)
- return aml_ederef(ctx, val->v_objref.ref);
-
- return (NULL);
+ deref = aml_searchname(scope->node, raw->v_nameref);
+ if (deref && deref->value) {
+ raw = deref->value;
+ goto loop;
+ }
+ aml_setvalue(scope, dst, raw, 0);
+ break;
case AML_OBJTYPE_OBJREF:
- i1 = val->v_objref.index;
- ref = aml_ederef(ctx, val->v_objref.ref);
- if (ref == NULL)
- return (NULL);
-
- if (i1 == -1)
- return aml_ederef(ctx, ref);
-
- if (i1 > ref->length)
- aml_resizevalue(ref, i1);
+ while (raw->type == AML_OBJTYPE_OBJREF && raw->v_objref.index == -1) {
+ raw = raw->v_objref.ref;
+ }
+ if (raw->type != AML_OBJTYPE_OBJREF)
+ goto loop;
- switch (ref->type) {
+ index = raw->v_objref.index;
+ raw = raw->v_objref.ref;
+ switch (raw->type) {
case AML_OBJTYPE_PACKAGE:
- if (ref->v_package[i1] == NULL) {
- /* Lazy allocate package */
- dnprintf(40, "LazyPkg: %lld/%d\n", i1,
- ref->length);
- ref->v_package[i1] = aml_allocvalue(
- AML_OBJTYPE_UNINITIALIZED, 0, NULL);
+ if (index >= raw->length) {
+ aml_setvalue(scope, dst, NULL, 0);
}
- return (ref->v_package[i1]);
+ else {
+ aml_setvalue(scope, dst, raw->v_package[index], 0);
+ }
+ goto loop;
+ break;
case AML_OBJTYPE_BUFFER:
- return aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 8,
- ref->v_buffer+i1);
+ aml_setvalue(scope, dst, NULL, raw->v_buffer[index]);
+ break;
+ case AML_OBJTYPE_STRING:
+ aml_setvalue(scope, dst, NULL, raw->v_string[index]);
+ break;
default:
- dnprintf(50,"Unknown refof\n");
+ aml_die("evalterm");
+ break;
}
+ break;
+ case AML_OBJTYPE_METHOD:
+ /* Read arguments from current scope */
+ argc = AML_METHOD_ARGCOUNT(raw->v_method.flags);
+ tmparg = aml_alloctmp(scope, argc);
+ for (index=0; index<argc; index++) {
+ aml_parseop(scope, &tmparg[index]);
+ aml_addref(&tmparg[index]);
+ }
+ aml_evalmethod(raw->node, argc, tmparg, dst);
+ break;
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ aml_fieldio(scope, raw, dst, ACPI_IOREAD);
+ break;
+ default:
+ aml_freevalue(dst);
+ aml_setvalue(scope, dst, raw, 0);
break;
}
-
- return (val);
+ return (0);
}
-uint64_t
-aml_get_pciaddr(struct acpi_context *ctx, struct aml_node *node)
-{
- struct aml_node *pn;
- uint8_t bus, dev, fn;
- uint64_t ioaddr;
- if ((pn = aml_searchname(node, "_ADR")) == NULL)
- return (0xffff);
+/*
+ * @@@: Opcode functions
+ */
+struct aml_value *aml_parsenamed(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsenamedscope(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsemath(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsecompare(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parseif(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsewhile(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsebufpkg(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsemethod(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsesimple(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsefieldunit(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsebufferfield(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsemisc3(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsemuxaction(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsemisc2(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsematch(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parseref(struct aml_scope *, int, struct aml_value *);
+struct aml_value *aml_parsestring(struct aml_scope *, int, struct aml_value *);
+
+/* Parse named objects */
+struct aml_value *
+aml_parsenamed(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ uint8_t *name;
- /* _ADR holds <dev>:<fn> */
- ioaddr = aml_val2int(ctx, pn->value);
- fn = ioaddr & 0xffff;
- dev = ioaddr >> 16;
- bus = 0;
+ AML_CHECKSTACK();
+ name = aml_parsename(scope);
- if ((pn = aml_searchname(node, "_BBN")) != NULL) /* _BBN holds <bus> */
- bus = aml_val2int(ctx, pn->value);
+ res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
+ switch (opcode) {
+ case AMLOP_NAME:
+ aml_parseop(scope, res);
+ break;
+ case AMLOP_ALIAS:
+ _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, name);
+ name = aml_parsename(scope);
+ break;
+ case AMLOP_EVENT:
+ _aml_setvalue(res, AML_OBJTYPE_EVENT, 0, NULL);
+ break;
+ case AMLOP_MUTEX:
+ _aml_setvalue(res, AML_OBJTYPE_MUTEX, 0, NULL);
+ res->v_integer = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ break;
+ case AMLOP_OPREGION:
+ _aml_setvalue(res, AML_OBJTYPE_OPREGION, 0, NULL);
+ res->v_opregion.iospace = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_opregion.iobase = aml_parseint(scope, AML_ANYINT);
+ res->v_opregion.iolen = aml_parseint(scope, AML_ANYINT);
+ if (res->v_opregion.iospace == GAS_PCI_CFG_SPACE)
+ aml_getpciaddr(scope, res);
+ break;
+ }
+ aml_createname(scope->node, name, res);
- return ACPI_PCI_ADDR(bus, dev, fn, 0);
+ return res;
}
+/* Parse Named objects with scope */
struct aml_value *
-aml_efield(struct acpi_context *ctx, struct aml_value *e_fld,
- struct aml_value *rhs)
-{
- struct aml_value *e_rgn;
- struct aml_value *rv;
- struct aml_value tmp;
- uint8_t *pb;
- uint64_t ioaddr;
- int blen;
-
- dnprintf(80, "efield %s: ", rhs ? "set" : "get");
- aml_showvalue(e_fld);
- aml_showvalue(rhs);
-
- 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 (!aml_bytealigned(e_fld->v_field.bitpos)) {
- dnprintf(40, "aml_efield: INDEXFIELD not "
- "byte-aligned..\n");
- }
- 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);
-
- case AMLOP_BANKFIELD:
- /* Set bank value */
- tmp.v_integer = e_fld->v_field.ref3;
- aml_efield(ctx, e_fld->v_field.ref2, &tmp);
- return aml_efield(ctx, e_fld->v_field.ref2, rhs);
-
- case AMLOP_FIELD:
- /* e_rgn should be OPREGION */
- e_rgn = aml_ederef(ctx, e_fld->v_field.ref1);
- if (e_rgn == NULL)
- return NULL;
- if (e_rgn->type != AML_OBJTYPE_OPREGION) {
- dnprintf(40, "aml_efield: Wrong FIELD type!\n");
- return (NULL);
- }
-
- ioaddr = e_rgn->v_opregion.iobase +
- aml_bytepos(e_fld->v_field.bitpos);
-
- blen = aml_bytelen(e_fld->v_field.bitlen);
- pb = acpi_os_allocmem(blen+8); /* padded space */
- if (rhs == 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, ioaddr,
- AML_FIELD_ACCESS(e_fld->v_field.flags),
- blen, pb);
-
- 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,
- aml_bitpos(e_fld->v_field.bitpos),
- e_fld->v_field.bitlen);
+aml_parsenamedscope(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ uint8_t *end, *name;
+ struct aml_node *node;
- acpi_os_freemem(pb);
- }
- return (rv);
- }
-
- /* Write field */
- if (AML_FIELD_LOCK(e_fld->v_field.flags)) {
- acpi_mutex_acquire(ctx, aml_global_lock, -1);
- }
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
+ name = aml_parsename(scope);
- 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(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, ioaddr,
- AML_FIELD_ACCESS(e_fld->v_field.flags),
- blen, pb);
-#if 0
- aml_showvalue(rv);
-#endif
-#endif
- break;
- case AML_FIELD_WRITEASONES:
- memset(pb, 0xff, blen + 8);
- break;
- case AML_FIELD_WRITEASZEROES:
- memset(pb, 0x00, blen + 8);
- break;
- }
-
- rv = aml_val2buf(ctx, rhs, blen);
+ switch (opcode) {
+ case AMLOP_DEVICE:
+ res = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, NULL);
+ break;
+ case AMLOP_SCOPE:
+ res = NULL;
+ break;
+ case AMLOP_PROCESSOR:
+ res = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, NULL);
+ res->v_processor.proc_id = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_processor.proc_addr = aml_parseint(scope, AMLOP_DWORDPREFIX);
+ res->v_processor.proc_len = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ break;
+ case AMLOP_POWERRSRC:
+ res = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, NULL);
+ res->v_powerrsrc.pwr_level = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_powerrsrc.pwr_order = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ break;
+ case AMLOP_THERMALZONE:
+ res = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, NULL);
+ break;
+ }
+ node = aml_createname(scope->node, name, res);
+ aml_parsenode(node, scope->pos, &end, NULL);
+ scope->pos = end;
- aml_bufcpy(pb, aml_bitpos(e_fld->v_field.bitpos),
- rv->v_buffer, 0, e_fld->v_field.bitlen);
+ return res;
+}
- if (rv != rhs)
- aml_freevalue(&rv);
+/* Parse math opcodes */
+struct aml_value *
+aml_parsemath(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ struct aml_value *tmparg;
+ int64_t i1, i2, i3;
- 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),
- blen, pb);
+ AML_CHECKSTACK();
+ tmparg = aml_alloctmp(scope, 4);
- if (AML_FIELD_LOCK(e_fld->v_field.flags)) {
- acpi_mutex_release(ctx, aml_global_lock);
- }
+ switch (opcode) {
+ case AMLOP_LNOT:
+ i2 = 0;
+ i1 = aml_parseint(scope, AML_ANYINT);
+ break;
+ case AMLOP_LAND:
+ case AMLOP_LOR:
+ i1 = aml_parseint(scope, AML_ANYINT);
+ i2 = aml_parseint(scope, AML_ANYINT);
+ break;
+ case AMLOP_NOT:
+ case AMLOP_TOBCD:
+ case AMLOP_FROMBCD:
+ case AMLOP_TOINTEGER:
+ case AMLOP_FINDSETLEFTBIT:
+ case AMLOP_FINDSETRIGHTBIT:
+ i2 = 0;
+ i1 = aml_parseint(scope, AML_ANYINT);
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+ break;
+ case AMLOP_INCREMENT:
+ case AMLOP_DECREMENT:
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+ aml_evalterm(scope, &tmparg[DST], &tmparg[LHS]);
+ i1 = aml_val2int(&tmparg[LHS]);
+ i2 = 1;
+ break;
+ case AMLOP_DIVIDE:
+ i1 = aml_parseint(scope, AML_ANYINT);
+ i2 = aml_parseint(scope, AML_ANYINT);
+ aml_parsetarget(scope, &tmparg[DST2], NULL); // remainder
+ aml_parsetarget(scope, &tmparg[DST], NULL); // quotient
- acpi_os_freemem(pb);
+ aml_setvalue(scope, &tmparg[DST2], NULL, (i1 % i2));
break;
default:
- /* This is a buffer field */
- e_rgn = aml_ederef(ctx, e_fld->v_field.ref1);
- if (e_rgn == NULL)
- return (NULL);
-
- if (e_rgn->type != AML_OBJTYPE_BUFFER) {
- 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, 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);
- return (rv);
- }
-
- /* Write buffer */
- rv = aml_val2buf(ctx, rhs, blen);
- aml_bufcpy(e_rgn->v_buffer, e_fld->v_field.bitpos,
- rv->v_buffer, 0,
- e_fld->v_field.bitlen);
-
- if (rv != rhs)
- aml_freevalue(&rv);
+ i1 = aml_parseint(scope, AML_ANYINT);
+ i2 = aml_parseint(scope, AML_ANYINT);
+ aml_parsetarget(scope, &tmparg[DST], NULL);
break;
}
+ i3 = aml_evalexpr(i1, i2, opcode);
+ aml_setvalue(scope, res, NULL, i3);
+ aml_setvalue(scope, &tmparg[DST], NULL, i3);
- return (NULL);
+ return (res);
}
+/* Parse logical comparison opcodes */
struct aml_value *
-aml_val2buf(struct acpi_context *ctx, struct aml_value *oval, int mlen)
+aml_parsecompare(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_value *pb, *val;
-
- if (val == NULL)
- return (NULL);
-
- val = aml_ederef(ctx, oval);
- if (val == NULL)
- return (NULL);
- switch (val->type) {
- case AML_OBJTYPE_BUFFER:
- if (mlen < val->length)
- mlen = val->length;
+ struct aml_value *tmparg;
+ int rc;
- pb = aml_allocvalue(AML_OBJTYPE_BUFFER, mlen, NULL);
- if (val->v_buffer && val->length)
- memcpy(pb->v_buffer, val->v_buffer, val->length);
+ AML_CHECKSTACK();
+ tmparg = aml_alloctmp(scope, 2);
+ aml_parseterm(scope, &tmparg[LHS]);
+ aml_parseterm(scope, &tmparg[RHS]);
- return (pb);
+ /* Compare both values */
+ rc = aml_cmpvalue(&tmparg[LHS], &tmparg[RHS], opcode);
+ aml_setvalue(scope, res, NULL, rc);
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
- return aml_efield(ctx, val, NULL);
+ return res;
+}
- case AML_OBJTYPE_STATICINT:
- case AML_OBJTYPE_INTEGER:
- return aml_allocvalue(AML_OBJTYPE_BUFFER, 8, &val->v_integer);
+/* Parse IF/ELSE opcodes */
+struct aml_value *
+aml_parseif(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ int64_t test;
+ uint8_t *end;
+
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
+ test = aml_parseint(scope, AML_ANYINT);
+
+ dnprintf(40, "@ iftest: %llx\n", test);
+ while (test && scope->pos && scope->pos < end) {
+ /* Parse if scope */
+ aml_parseterm(scope, res);
+ }
+ if (*end == AMLOP_ELSE) {
+ scope->pos = ++end;
+ end = aml_parseend(scope);
+ while (!test && scope->pos && scope->pos < end) {
+ /* Parse ELSE scope */
+ aml_parseterm(scope, res);
+ }
+ }
+ if (scope->pos < end)
+ scope->pos = end;
+ return res;
+}
- case AML_OBJTYPE_STRING:
- return aml_allocvalue(AML_OBJTYPE_BUFFER, val->length,
- val->v_string);
+struct aml_value *
+aml_parsewhile(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ uint8_t *end, *start;
+ int test, cnt;
+
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
+ start = scope->pos;
+ cnt = 0;
+ do {
+ test = 1;
+ if (scope->pos == start || scope->pos == end) {
+ scope->pos = start;
+ test = aml_parseint(scope, AML_ANYINT);
+ dnprintf(40, "@whiletest = %d %x\n", test, cnt++);
+ }
+ else if (*scope->pos == AMLOP_BREAK) {
+ scope->pos++;
+ test = 0;
+ }
+ else if (*scope->pos == AMLOP_CONTINUE) {
+ scope->pos = start;
+ }
+ else {
+ aml_parseterm(scope, res);
+ }
+ } while (test && scope->pos <= end && cnt < 0x199);
+ /* XXX: shouldn't need breakout counter */
- default:
- dnprintf(40, "Unknown val2buf : %d\n", val->type);
- return (NULL);
- }
+ dnprintf(40,"Set While end : %x\n", cnt);
+ if (scope->pos < end)
+ scope->pos = end;
+ return res;
}
-int64_t
-aml_val2int(struct acpi_context *ctx, struct aml_value *val)
+/* Parse Buffer/Package opcodes */
+struct aml_value *
+aml_parsebufpkg(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_value *pb;
- int64_t rval;
+ uint8_t *end;
+ int len;
- pb = NULL;
- if (val == NULL) {
- dnprintf(40, "null val2int\n");
- return 0;
- }
- rval = 0;
- switch (val->type) {
- case AML_OBJTYPE_BUFFER:
- 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);
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
+ len = aml_parseint(scope, (opcode == AMLOP_PACKAGE) ?
+ AMLOP_BYTEPREFIX : AML_ANYINT);
- case AML_OBJTYPE_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);
+ switch (opcode) {
+ case AMLOP_BUFFER:
+ _aml_setvalue(res, AML_OBJTYPE_BUFFER, len, NULL);
+ if (scope->pos < end) {
+ memcpy(res->v_buffer, scope->pos, end-scope->pos);
+ }
+ if (len != end-scope->pos) {
+ dnprintf(99,"buffer: %.4x %.4x\n", len, end-scope->pos);
}
- return (rval);
-
- case AML_OBJTYPE_NAMEREF:
- case AML_OBJTYPE_OBJREF:
- if (ctx == NULL)
- return (0);
- pb = aml_ederef(ctx, val);
- break;
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
- if (ctx == NULL)
- return (0);
- pb = aml_efield(ctx, val, NULL);
- break;
- case AML_OBJTYPE_METHOD:
- if (ctx == NULL)
- return 0;
- pb = aml_domethod(ctx, val, -1, NULL);
break;
- default:
- dnprintf(40, "Unknown val2int: %x\n", val->type);
+ case AMLOP_PACKAGE:
+ case AMLOP_VARPACKAGE:
+ _aml_setvalue(res, AML_OBJTYPE_PACKAGE, len, NULL);
+ for (len=0; len < res->length && scope->pos < end; len++) {
+ aml_parseop(scope, res->v_package[len]);
+ }
+ if (scope->pos != end) {
+ dnprintf(99,"Package not equiv!! %.4x %.4x %d of %d\n",
+ aml_pc(scope->pos), aml_pc(end), len, res->length);
+ }
break;
}
-
- if (pb != NULL)
- return aml_val2int(ctx, pb);
-
- return (0);
+ scope->pos = end;
+ return res;
}
-struct aml_node *
-aml_addvname(struct acpi_context *ctx, const char *name, int opcode,
- struct aml_value *val)
+struct aml_value *
+aml_parsemethod(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_node *pn;
+ uint8_t *end, *name;
- pn = aml_createname(ctx->scope, name);
- pn->opcode = opcode;
- pn->mnem = aml_opname(opcode);
- if (val != NULL) {
- if (val->type == AML_OBJTYPE_STATICINT)
- val = aml_allocvalue(AML_OBJTYPE_INTEGER, val->v_integer, NULL);
- val->name = name;
- val->node = pn;
- }
- if (pn->value) {
- dnprintf(40, "addvname: error, already set!\n");
- aml_freevalue(&pn->value);
- }
- pn->value = val;
-#if 0
- aml_showvalue(val);
- dnprintf(40, "\n");
-#endif
- return pn;
-}
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
+ name = aml_parsename(scope);
-/* Parse package length & return pointer to end of package */
-u_int8_t *
-aml_eparselen(struct acpi_context *ctx)
-{
- u_int8_t *pos = ctx->pos;
+ res = aml_allocvalue(AML_OBJTYPE_METHOD, 0, NULL);
+ res->v_method.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_method.start = scope->pos;
+ res->v_method.end = end;
+ aml_createname(scope->node, name, res);
- return pos + aml_parse_length(ctx);
+ scope->pos = end;
+
+ return res;
}
-/* Parse integer value */
-int64_t
-aml_eparseint(struct acpi_context *ctx, int type)
+/* Parse simple type opcodes */
+struct aml_value *
+aml_parsesimple(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_value *rv;
- int64_t rval;
+ struct aml_node *node;
- 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;
+ AML_CHECKSTACK();
+ switch (opcode) {
+ case AMLOP_ZERO:
+ _aml_setvalue(res, AML_OBJTYPE_INTEGER+AML_STATIC,
+ aml_parseint(scope, opcode),
+ NULL);
+ break;
+ case AMLOP_ONE:
+ case AMLOP_ONES:
+ case AMLOP_BYTEPREFIX:
+ case AMLOP_WORDPREFIX:
+ case AMLOP_DWORDPREFIX:
+ case AMLOP_QWORDPREFIX:
+ case AMLOP_REVISION:
+ _aml_setvalue(res, AML_OBJTYPE_INTEGER,
+ aml_parseint(scope, opcode),
+ NULL);
+ break;
+ case AMLOP_DEBUG:
+ _aml_setvalue(res, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
+ break;
+ case AMLOP_STRINGPREFIX:
+ _aml_setvalue(res, AML_OBJTYPE_STRING, -1, scope->pos);
+ scope->pos += res->length+1;
+ break;
+ case AMLOP_NAMECHAR:
+ _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, NULL);
+ res->v_nameref = aml_parsename(scope);
+ node = aml_searchname(scope->node, res->v_nameref);
+ if (node && node->value) {
+ _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, node->value);
}
- }
- if (type != AML_ANYINT) {
- /* Type may have changed here parse byte directly */
- rval = aml_parse_int(ctx, type);
- }
- return rval;
+ break;
+ }
+ return res;
}
-/* Create field unit
- * AMLOP_FIELD
- * AMLOP_INDEXFIELD
- * AMLOP_BANKFIELD
- */
-
+/* Parse field unit opcodes */
struct aml_value *
-aml_parse_fieldunit(struct acpi_context *ctx, int opcode)
+aml_parsefieldunit(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- u_int8_t *end;
- int attr, access;
- struct aml_value *rv, tmp;
+ uint8_t *end, *name;
+ struct aml_value *fld;
- /* Create field template */
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = AML_OBJTYPE_FIELDUNIT;
- tmp.v_field.type = opcode;
+ AML_CHECKSTACK();
+ end = aml_parseend(scope);
- end = aml_eparselen(ctx);
switch (opcode) {
case AMLOP_FIELD:
- tmp.v_field.ref1 = aml_eparseval(ctx, 1);
+ aml_parsetarget(scope, NULL, &res->v_field.ref1);
break;
case AMLOP_INDEXFIELD:
- tmp.v_field.ref1 = aml_eparseval(ctx, 0);
- tmp.v_field.ref2 = aml_eparseval(ctx, 0);
+ aml_parsetarget(scope, NULL, &res->v_field.ref1);
+ aml_parsetarget(scope, NULL, &res->v_field.ref2);
break;
case AMLOP_BANKFIELD:
- 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);
+ aml_parsetarget(scope, NULL, &res->v_field.ref1);
+ aml_parsetarget(scope, NULL, &res->v_field.ref2);
+ res->v_field.ref3 = aml_parseint(scope, AML_ANYINT);
break;
}
- tmp.v_field.flags = aml_parse_int(ctx, AML_BYTE);
+ res->v_field.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_field.type = opcode;
- while (ctx->pos < end) {
- switch (*ctx->pos) {
- case AML_FIELD_RESERVED:
- ctx->pos++;
- tmp.v_field.bitlen = aml_parse_length(ctx);
- break;
- case AML_FIELD_ATTRIB:
- ctx->pos++;
- access = aml_parse_int(ctx, AML_BYTE);
- attr = aml_parse_int(ctx, AML_BYTE);
+ aml_fixref(&res->v_field.ref1);
+ aml_fixref(&res->v_field.ref2);
- tmp.v_field.flags &= ~AML_FIELD_ACCESSMASK;
- tmp.v_field.flags |= (access & AML_FIELD_ACCESSMASK);
+ while (scope->pos < end) {
+ switch (*scope->pos) {
+ case 0x00: // reserved
+ scope->pos++;
+ res->v_field.bitlen = aml_parselength(scope);
break;
- default:
- tmp.name = aml_parse_name(ctx);
- tmp.v_field.bitlen = aml_parse_length(ctx);
- rv = aml_copyvalue(&tmp);
- aml_addvname(ctx, tmp.name, opcode, rv);
+ case 0x01: // attrib
+ scope->pos++;
+ /* XXX: do something with this */
+ aml_parseint(scope, AMLOP_BYTEPREFIX);
+ aml_parseint(scope, AMLOP_BYTEPREFIX);
+ res->v_field.bitlen = 0;
break;
- }
- tmp.v_field.bitpos += tmp.v_field.bitlen;
- }
- return NULL;
-}
+ default:
+ name = aml_parsename(scope);
+ res->v_field.bitlen = aml_parselength(scope);
-/* Create buffer field object
- * AMLOP_CREATEFIELD
- * AMLOP_CREATEBITFIELD
- * AMLOP_CREATEBYTEFIELD
- * AMLOP_CREATEWORDFIELD
- * AMLOP_CREATEDWORDFIELD
- * AMLOP_CREATEQWORDFIELD
- */
-struct aml_value *
-aml_parse_bufferfield(struct acpi_context *ctx, int size, int bitlen, int opcode)
-{
- struct aml_value *rv;
+ /* Allocate new fieldunit */
+ fld = aml_allocvalue(AML_OBJTYPE_FIELDUNIT, 0, 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, 1);
- rv->v_field.bitpos = aml_eparseint(ctx, AML_ANYINT) * size;
- rv->v_field.bitlen = (opcode == AMLOP_CREATEFIELD) ?
- aml_eparseint(ctx, AML_ANYINT) : bitlen;
+ /* Increase reference count on field */
+ fld->v_field = res->v_field;
+ aml_addref(fld->v_field.ref1);
+ aml_addref(fld->v_field.ref2);
- aml_addvname(ctx, aml_parse_name(ctx), opcode, rv);
+ aml_createname(scope->node, name, fld);
+ break;
+ }
+ res->v_field.bitpos += res->v_field.bitlen;
}
- return rv;
+ /* Delete redundant reference */
+ aml_delref(&res->v_field.ref1);
+ aml_delref(&res->v_field.ref2);
+ return res;
}
-/* Set node value */
+/* Parse CreateXXXField opcodes */
struct aml_value *
-aml_esetnodevalue(struct acpi_context *ctx, struct aml_value *lhs,
- struct aml_value *rhs, int64_t rval)
+aml_parsebufferfield(struct aml_scope *scope, int opcode,
+ struct aml_value *res)
{
- struct aml_value *tmp;
+ uint8_t *name;
- if (rhs == NULL) {
- rhs = aml_allocint(rval);
- }
+ AML_CHECKSTACK();
+ res = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL);
+ res->v_field.type = opcode;
+ aml_parsetarget(scope, NULL, &res->v_field.ref1);
+ res->v_field.bitpos = aml_parseint(scope, AML_ANYINT);
- dnprintf(50, "------------ SET NODE VALUE -------------\n");
- dnprintf(50, "new : ");
- aml_showvalue(rhs);
- dnprintf(50, "current: ");
- aml_showvalue(lhs);
+ aml_fixref(&res->v_field.ref1);
- tmp = aml_ederef(ctx, lhs);
- if (tmp == NULL)
- return (NULL);
- switch (tmp->type) {
- case AML_OBJTYPE_UNINITIALIZED:
- /* Object is not initialized */
- *tmp = *rhs;
+ switch (opcode) {
+ case AMLOP_CREATEFIELD:
+ res->v_field.bitlen = aml_parseint(scope, AML_ANYINT);
break;
- case AML_OBJTYPE_DEBUGOBJ:
- dnprintf(1, "debug object: ");
- aml_showvalue(rhs);
+ case AMLOP_CREATEBITFIELD:
+ res->v_field.bitlen = 1;
break;
- case AML_OBJTYPE_FIELDUNIT:
- case AML_OBJTYPE_BUFFERFIELD:
- aml_efield(ctx, tmp, rhs);
+ case AMLOP_CREATEBYTEFIELD:
+ res->v_field.bitlen = 8;
+ res->v_field.bitpos *= 8;
break;
- case AML_OBJTYPE_STATICINT:
- /* Read-only */
+ case AMLOP_CREATEWORDFIELD:
+ res->v_field.bitlen = 16;
+ res->v_field.bitpos *= 8;
+ break;
+ case AMLOP_CREATEDWORDFIELD:
+ res->v_field.bitlen = 32;
+ res->v_field.bitpos *= 8;
+ break;
+ case AMLOP_CREATEQWORDFIELD:
+ res->v_field.bitlen = 64;
+ res->v_field.bitpos *= 8;
break;
- default:
- /* Object is already initialized, free old value */
- _aml_freevalue(tmp);
- *tmp = *rhs;
- }
- aml_showvalue(tmp);
- if (tmp != lhs) {
- aml_freevalue(&tmp);
}
- dnprintf(50, "--------- post set ----------\n");
- return rhs;
+ name = aml_parsename(scope);
+ aml_createname(scope->node, name, res);
+
+ return res;
}
-/* Parse scoped object
- * AMLOP_SCOPE
- * AMLOP_DEVICE
- * AMLOP_POWERRSRC
- * AMLOP_PROCESSOR
- * AMLOP_THERMALZONE
- */
+/* Parse Mutex/Event action */
struct aml_value *
-aml_eparsescope(struct acpi_context *ctx, const char *name, u_int8_t *end,
- struct aml_opcode *opc,
- struct aml_value *val)
+aml_parsemuxaction(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_node *oldscope;
- struct aml_value *rv;
+ struct aml_value *tmparg;
+ int64_t i1;
- oldscope = ctx->scope;
- ctx->scope = aml_addvname(ctx, name, opc->opcode, val);
+ AML_CHECKSTACK();
- rv = aml_eparselist(ctx, end, 0);
+ tmparg = aml_alloctmp(scope, 1);
+ aml_parsetarget(scope, tmparg, NULL);
+ switch (opcode) {
+ case AMLOP_ACQUIRE:
+ /* Assert: tmparg is AML_OBJTYPE_MUTEX */
+ i1 = aml_parseint(scope, AMLOP_WORDPREFIX);
- ctx->scope = oldscope;
- return rv;
-}
+ /* Return true if timed out */
+ aml_setvalue(scope, res, NULL, 0);
+ break;
+ case AMLOP_RELEASE:
+ break;
-/* Parse list of objects */
-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, deref);
+ case AMLOP_WAIT:
+ /* Assert: tmparg is AML_OBJTYPE_EVENT */
+ i1 = aml_parseint(scope, AML_ANYINT);
+
+ /* Return true if timed out */
+ aml_setvalue(scope, res, NULL, 0);
+ break;
+ case AMLOP_SIGNAL:
+ break;
+ case AMLOP_RESET:
+ break;
}
- return rv;
+
+ return res;
}
-/* Parse AMLOP_CONCAT */
+/* Parse Miscellaneous opcodes */
struct aml_value *
-aml_doconcat(struct acpi_context *ctx)
+aml_parsemisc2(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_value *lhs, *rhs, *set, *tmp;
+ struct aml_value *tmparg, *dev;
+ int i1, i2, i3;
- 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);
- if (tmp != NULL) {
- strlcpy(tmp->v_string, lhs->v_string, lhs->length);
- strlcat(tmp->v_string, rhs->v_string, rhs->length);
- return aml_esetnodevalue(ctx, set, tmp, 0);
+ switch (opcode) {
+ case AMLOP_NOTIFY:
+ /* Assert: tmparg is nameref or objref */
+ tmparg = aml_alloctmp(scope, 1);
+ aml_parseop(scope, tmparg);
+ dev = aml_dereftarget(scope, tmparg);
+
+ i1 = aml_parseint(scope, AML_ANYINT);
+ if (dev && dev->node) {
+ dnprintf(0,"Notify: [%s] %.2x\n",
+ aml_nodename(dev->node), i1);
+ aml_notify(dev->node, i1);
}
break;
- case AML_OBJTYPE_BUFFER:
- tmp = aml_allocvalue(AML_OBJTYPE_BUFFER,
- 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);
- }
+ case AMLOP_SLEEP:
+ i1 = aml_parseint(scope, AML_ANYINT);
+ dnprintf(10,"SLEEP: %x\n", i1);
break;
- default:
- dnprintf(50, "aml_doconcat: wrong type %.4x\n", lhs->type);
+ case AMLOP_STALL:
+ i1 = aml_parseint(scope, AML_ANYINT);
+ dnprintf(10,"STALL: %x\n", i1);
+ break;
+ case AMLOP_FATAL:
+ i1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ i2 = aml_parseint(scope, AMLOP_DWORDPREFIX);
+ i3 = aml_parseint(scope, AML_ANYINT);
+ aml_die("FATAL: %x %x %x\n", i1, i2, i3);
break;
}
- return NULL;
+ return res;
}
-/* Parse AMLOP_IF/AMLOP_ELSE block */
+/* Parse Miscellaneous opcodes */
struct aml_value *
-aml_doif(struct acpi_context *ctx)
+aml_parsemisc3(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- struct aml_value *rv;
- u_int8_t *end;
- int64_t i1;
-
- rv = NULL;
- end = aml_eparselen(ctx);
- i1 = aml_eparseint(ctx, AML_ANYINT);
- dnprintf(40, "evalif: %lld\n", i1);
-
- if (i1 != 0) {
- /* Parse IF block */
- rv = aml_eparselist(ctx, end, 1);
- }
- if (ctx->pos != NULL && *end == AMLOP_ELSE) {
- /* Parse ELSE block */
- ctx->pos = ++end;
- end = aml_eparselen(ctx);
- if (i1 == 0) {
- rv = aml_eparselist(ctx, end, 1);
- }
+ struct aml_value *tmparg;
+
+ AML_CHECKSTACK();
+ tmparg = aml_alloctmp(scope, 1);
+ aml_parseterm(scope, tmparg);
+ switch (opcode) {
+ case AMLOP_SIZEOF:
+ aml_setvalue(scope, res, NULL, tmparg->length);
+ break;
+ case AMLOP_OBJECTTYPE:
+ aml_setvalue(scope, res, NULL, tmparg->type);
+ break;
}
- if (ctx->pos != NULL) {
- ctx->pos = end;
+
+ return res;
+}
+
+/* Parse AMLOP_MATCH */
+struct aml_value *
+aml_parsematch(struct aml_scope *scope, int opcode, struct aml_value *res)
+{
+ struct aml_value *pkg;
+ int op1, op2, idx, mv1, mv2;
+
+ AML_CHECKSTACK();
+ pkg = aml_parseterm(scope, NULL);
+ op1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ mv1 = aml_parseint(scope, AML_ANYINT);
+ op2 = aml_parseint(scope, AMLOP_BYTEPREFIX);
+ mv2 = aml_parseint(scope, AML_ANYINT);
+ idx = aml_parseint(scope, AML_ANYINT);
+
+ aml_setvalue(scope, res, NULL, -1);
+ while (idx < pkg->length) {
+ if (aml_match(op1, mv1, pkg->v_package[idx]) ||
+ aml_match(op2, mv2, pkg->v_package[idx]))
+ {
+ aml_setvalue(scope, res, NULL, idx);
+ break;
+ }
+ idx++;
}
- return rv;
+ aml_delref(&pkg);
+ return res;
}
-/* Parse AMLOP_WHILE/AMLOP_BREAK/AMLOP_CONTINUE block */
+/* Parse referenced objects */
struct aml_value *
-aml_dowhile(struct acpi_context *ctx)
+aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- u_int8_t *start, *end;
- struct aml_value *rv;
- int64_t i1;
+ struct aml_value *tmparg;
- end = aml_eparselen(ctx);
- start = ctx->pos;
+ AML_CHECKSTACK();
- rv = NULL;
- for(;;) {
- if (ctx->pos == end) {
- ctx->pos = start;
+ tmparg = aml_alloctmp(scope, 4);
+ switch (opcode) {
+ case AMLOP_INDEX:
+ aml_parsetarget(scope, res, NULL);
+ opcode = aml_parseint(scope, AML_ANYINT);
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+
+ if (res->type == AML_OBJTYPE_OBJREF && res->v_objref.index == -1)
+ {
+ dnprintf(10,"fixup index\n");
+ res->v_objref.index = opcode;
+ aml_setvalue(scope, &tmparg[DST], res, 0);
}
- /* Perform test condition */
- if (ctx->pos == start) {
- i1 = aml_eparseint(ctx, AML_ANYINT);
- dnprintf(40, "whiletest: %lld\n", i1);
- if (i1 == 0) {
- break;
+ break;
+ case AMLOP_DEREFOF:
+ aml_parseop(scope, res);
+ break;
+ case AMLOP_RETURN:
+ aml_parseterm(scope, &tmparg[DST]);
+ aml_setvalue(scope, res, &tmparg[DST], 0);
+ while (scope) {
+ scope->pos = scope->end;
+ scope = scope->parent;
+ }
+ 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]);
}
- if (ctx->pos == NULL || *ctx->pos == AMLOP_BREAK) {
- dnprintf(40, "break\n");
- break;
+ 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]);
}
- else if (*ctx->pos == AMLOP_CONTINUE) {
- dnprintf(40, "continue\n");
- ctx->pos = start;
+ break;
+ case AMLOP_LOAD:
+ aml_parseop(scope, &tmparg[LHS]);
+ aml_parseop(scope, &tmparg[RHS]);
+ break;
+ case AMLOP_STORE:
+ aml_parseterm(scope, res);
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+ aml_setvalue(scope, &tmparg[DST], res, 0);
+ break;
+ case AMLOP_REFOF:
+ _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
+ aml_parsetarget(scope, NULL, &res->v_objref.ref);
+ break;
+ case AMLOP_CONDREFOF:
+ /* Returns true if object exists */
+ aml_parseterm(scope, &tmparg[LHS]);
+ aml_parsetarget(scope, &tmparg[DST], NULL);
+ if (tmparg[LHS].type != AML_OBJTYPE_NAMEREF) {
+ /* Object exists */
+ aml_setvalue(scope, &tmparg[DST], &tmparg[LHS], 0);
+ aml_setvalue(scope, res, NULL, 1);
}
else {
- aml_freevalue(&rv);
- rv = aml_eparseval(ctx, 1);
+ /* Object doesn't exist */
+ aml_setvalue(scope, res, NULL, 0);
}
+ break;
}
- if (ctx->pos != NULL) {
- ctx->pos = end;
- }
- return rv;
+
+ return res;
}
-/* Call AML Method */
struct aml_value *
-aml_domethod(struct acpi_context *ctx, struct aml_value *val,
- int argc, struct aml_value **argv)
+aml_parsestring(struct aml_scope *scope, int opcode, struct aml_value *res)
{
- int64_t i1, i2;
- struct aml_value **newarg, **oldarg;
- struct aml_value **newloc, **oldloc;
- struct aml_node *oldscope;
- struct aml_value *rv;
- u_int8_t *oldpos;
-
- if (val->type != AML_OBJTYPE_METHOD) {
- dnprintf(40, "aml_domethod: Invalid type\n");
- }
+ struct aml_value *tmpval;
+ int i1, i2;
- i2 = AML_METHOD_ARGCOUNT(val->v_method.flags);
- 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, 0);
+ AML_CHECKSTACK();
+ tmpval = aml_alloctmp(scope, 4);
+ switch (opcode) {
+ case AMLOP_MID:
+ aml_parseterm(scope, &tmpval[0]);
+ i1 = aml_parseint(scope, AML_ANYINT); // start
+ i2 = aml_parseint(scope, AML_ANYINT); // length
+ aml_parsetarget(scope, &tmpval[1], NULL);
+ if (i1 > tmpval[0].length)
+ i1 = tmpval[0].length;
+ if (i1+i2 > tmpval[0].length)
+ i2 = tmpval[0].length-i1;
+ _aml_setvalue(res, AML_OBJTYPE_STRING, i2, tmpval[0].v_string+i1);
+ break;
+ case AMLOP_TODECSTRING:
+ case AMLOP_TOHEXSTRING:
+ i1 = aml_parseint(scope, AML_ANYINT);
+ _aml_setvalue(res, AML_OBJTYPE_STRING, 10, NULL);
+ snprintf(res->v_string, res->length, ((opcode == AMLOP_TODECSTRING) ?
+ "%d" : "%x"), i1);
+ break;
+ default:
+ aml_die("to_string");
+ break;
}
- /* 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;
- 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]);
- }
- for (i1=0; i1<i2; i1++) {
- aml_freevalue(&newarg[i1]);
- }
- return rv;
-
+ return res;
}
-/* 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;
+aml_parseterm(struct aml_scope *scope, struct aml_value *res)
+{
+ struct aml_value *tmpres;
+
+ /* If no value specified, allocate dynamic */
+ if (res == NULL)
+ res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
+ tmpres = aml_alloctmp(scope, 1);
+ aml_parseop(scope, tmpres);
+ aml_evalterm(scope, tmpres, res);
+ return res;
}
-/* Handle AMLOP_MID */
struct aml_value *
-aml_domid(struct acpi_context *ctx)
+aml_parsetarget(struct aml_scope *scope, struct aml_value *res, struct aml_value **opt)
{
- struct aml_value *rhs, *lhs, *rv;
- int64_t i1, i2;
+ struct aml_value *dummy;
- 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;
- }
- }
- aml_freevalue(&lhs);
- aml_freevalue(&rhs);
- return rv;
+ /* If no value specified, allocate dynamic */
+ if (res == NULL)
+ res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
+ aml_parseop(scope, res);
+ dummy = aml_evaltarget(scope, res);
+ if (opt != NULL)
+ *opt = dummy;
+ return res;
}
-/* 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, 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);
- if (lhs->type == AML_OBJTYPE_PACKAGE) {
- for (; idx < lhs->length; 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;
- }
- }
- }
- aml_freevalue(&lhs);
- return rv;
-}
+aml_parseop(struct aml_scope *scope, struct aml_value *res)
+{
+ int opcode;
+ struct aml_value *rval;
+ opcode = aml_parseopcode(scope);
+ dnprintf(60,"%.4x: [%s] %s\n",
+ aml_pc(scope->pos-opsize(opcode)),
+ aml_nodename(scope->node),
+ aml_mnem(opcode));
+ aml_freevalue(res);
-/* Parse AMLOP_XXXX
- *
- * This is the guts of the evaluator
- */
-struct aml_value *
-aml_eparseval(struct acpi_context *ctx, int deref)
-{
- struct aml_opcode *opc;
- struct aml_node *node;
- struct aml_value *lhs, *rhs, *tmp, *rv;
- u_int8_t *end, *start;
- const char *name;
- int64_t i1, i2;
-
- rhs = NULL;
- lhs = NULL;
- tmp = NULL;
- rv = NULL;
-
- /* Allocate a new instruction, get opcode, etc */
- start = ctx->pos;
- opc = aml_getopcode(ctx);
-
- dnprintf(40, "### %2d %.4x %s\n",
- ctx->depth, opc->opcode, opc->mnem);
-
- ctx->depth++;
- end = NULL;
- switch (opc->opcode) {
- case AMLOP_NAMECHAR:
- name = aml_parse_name(ctx);
- rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, (char *)name);
- if ((rhs = aml_ederef(ctx, rv)) != NULL) {
- if (rhs->type == AML_OBJTYPE_METHOD) {
- lhs = rhs;
- rv = aml_domethod(ctx, rhs, -1, NULL);
- }
- else {
- rv = rhs;
- rhs = NULL;
- }
- }
- break;
- case AMLOP_NOP:
- break;
+ switch (opcode) {
case AMLOP_ZERO:
- rv = aml_allocvalue(AML_OBJTYPE_STATICINT, 0, NULL);
- break;
case AMLOP_ONE:
- rv = aml_allocvalue(AML_OBJTYPE_STATICINT, 1, NULL);
- break;
case AMLOP_ONES:
- rv = aml_allocvalue(AML_OBJTYPE_STATICINT, -1, NULL);
- break;
case AMLOP_REVISION:
- rv = aml_allocvalue(AML_OBJTYPE_STATICINT, AML_REVISION, NULL);
- break;
case AMLOP_BYTEPREFIX:
- rv = aml_allocint(aml_eparseint(ctx, AML_BYTE));
- break;
case AMLOP_WORDPREFIX:
- rv = aml_allocint(aml_eparseint(ctx, AML_WORD));
- break;
case AMLOP_DWORDPREFIX:
- rv = aml_allocint(aml_eparseint(ctx, AML_DWORD));
- break;
case AMLOP_QWORDPREFIX:
- rv = aml_allocint(aml_eparseint(ctx, AML_QWORD));
- break;
case AMLOP_STRINGPREFIX:
- rv = aml_allocstr(aml_parse_string(ctx));
- break;
- case AMLOP_FIELD:
- case AMLOP_INDEXFIELD:
- case AMLOP_BANKFIELD:
- rv = aml_parse_fieldunit(ctx, opc->opcode);
- break;
- case AMLOP_CREATEFIELD:
- rv = aml_parse_bufferfield(ctx, 1, -1, opc->opcode);
- break;
- case AMLOP_CREATEBITFIELD:
- rv = aml_parse_bufferfield(ctx, 1, 1, opc->opcode);
- break;
- case AMLOP_CREATEBYTEFIELD:
- rv = aml_parse_bufferfield(ctx, 8, 8, opc->opcode);
- break;
- case AMLOP_CREATEWORDFIELD:
- rv = aml_parse_bufferfield(ctx, 8, 16, opc->opcode);
- break;
- case AMLOP_CREATEDWORDFIELD:
- rv = aml_parse_bufferfield(ctx, 8, 32, opc->opcode);
- break;
- case AMLOP_CREATEQWORDFIELD:
- rv = aml_parse_bufferfield(ctx, 8, 64, opc->opcode);
- break;
case AMLOP_DEBUG:
- rv = aml_allocvalue(AML_OBJTYPE_DEBUGOBJ, 0, NULL);
- break;
- case AMLOP_BUFFER:
- end = aml_eparselen(ctx);
- i2 = aml_eparseint(ctx, AML_ANYINT); // requested length
- i1 = end - ctx->pos; // supplied length
- dnprintf(40, "buffer: %lld of %lld\n", i1, i2);
- if (i2 < i1)
- i2 = i1;
- rv = aml_allocvalue(AML_OBJTYPE_BUFFER, i2, NULL);
- if (i1 > 0)
- memcpy(rv->v_buffer, ctx->pos, i1);
- break;
- case AMLOP_PACKAGE:
- case AMLOP_VARPACKAGE:
- end = aml_eparselen(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);
- for (i1=0; i1 < i2 && ctx->pos < end; i1++)
- rv->v_package[i1] = aml_eparseval(ctx, 0);
- dnprintf(40, "package: %lld of %lld parsed\n", i1, i2);
- break;
- case AMLOP_LOCAL0:
- case AMLOP_LOCAL1:
- case AMLOP_LOCAL2:
- case AMLOP_LOCAL3:
- case AMLOP_LOCAL4:
- case AMLOP_LOCAL5:
- case AMLOP_LOCAL6:
- case AMLOP_LOCAL7:
- i1 = opc->opcode - AMLOP_LOCAL0;
- if (ctx->locals[i1] == NULL) {
- /* Lazy allocate LocalX */
- dnprintf(40, "LazyLocal%lld\n", i1);
- ctx->locals[i1] = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
- }
- rv = ctx->locals[i1];
- break;
- case AMLOP_ARG0:
- case AMLOP_ARG1:
- case AMLOP_ARG2:
- case AMLOP_ARG3:
- case AMLOP_ARG4:
- case AMLOP_ARG5:
- case AMLOP_ARG6:
- i1 = opc->opcode - AMLOP_ARG0;
- if (ctx->args[i1] == NULL) {
- /* Lazy allocate ArgX - shouldn't happen? */
- 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, 1);
- i1 = aml_val2int(ctx, lhs);
- rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(opc->opcode, i1, 1));
+ case AMLOP_NAMECHAR:
+ case AMLOP_NOP:
+ rval = aml_parsesimple(scope, opcode, res);
break;
+ case AMLOP_LNOT:
+ case AMLOP_LAND:
+ case AMLOP_LOR:
+ case AMLOP_NOT:
+ case AMLOP_TOBCD:
+ case AMLOP_FROMBCD:
+ case AMLOP_TOINTEGER:
case AMLOP_FINDSETLEFTBIT:
case AMLOP_FINDSETRIGHTBIT:
- case AMLOP_TOINTEGER:
- case AMLOP_FROMBCD:
- case AMLOP_TOBCD:
- case AMLOP_NOT:
- 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_INCREMENT:
+ case AMLOP_DECREMENT:
case AMLOP_DIVIDE:
- i1 = aml_eparseint(ctx, AML_ANYINT);
- i2 = aml_eparseint(ctx, AML_ANYINT);
-
- /* Set remainder */
- tmp = aml_eparseval(ctx, 1);
- rhs = aml_esetnodevalue(ctx, tmp, NULL, aml_evalmath(AMLOP_MOD, i1, i2));
-
- /* Set quotient */
- lhs = aml_eparseval(ctx, 1);
- rv = aml_esetnodevalue(ctx, lhs, NULL, aml_evalmath(AMLOP_DIVIDE, i1, i2));
- break;
- case AMLOP_ADD:
+ case AMLOP_ADD:
case AMLOP_SUBTRACT:
case AMLOP_MULTIPLY:
case AMLOP_SHL:
@@ -2427,23 +2761,13 @@ aml_eparseval(struct acpi_context *ctx, int deref)
case AMLOP_AND:
case AMLOP_NAND:
case AMLOP_OR:
- case AMLOP_XOR:
case AMLOP_NOR:
+ case AMLOP_XOR:
case AMLOP_MOD:
- 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, AML_ANYINT);
- i2 = aml_eparseint(ctx, AML_ANYINT);
- rv = aml_allocint(aml_logicalcmp(opc->opcode, i1, i2));
+ rval = aml_parsemath(scope, opcode, res);
break;
- case AMLOP_LNOT:
- i1 = aml_eparseint(ctx, AML_ANYINT);
- rv = aml_allocint(aml_logicalcmp(opc->opcode, i1, 0));
+ case AMLOP_MATCH:
+ rval = aml_parsematch(scope, opcode, res);
break;
case AMLOP_LLESS:
case AMLOP_LLESSEQUAL:
@@ -2451,553 +2775,88 @@ aml_eparseval(struct acpi_context *ctx, int deref)
case AMLOP_LNOTEQUAL:
case AMLOP_LGREATEREQUAL:
case AMLOP_LGREATER:
- 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, 1);
- i1 = aml_eparseint(ctx, AML_ANYINT); // maximum length
- lhs = aml_eparseval(ctx, 1);
-
- tmp = aml_val2buf(ctx, rhs, 0);
- if (i1 > tmp->length)
- i1 = tmp->length;
- for(i2=0; i2<i1; i1++) {
- if (tmp->v_buffer[i2] == 0)
- break;
- }
- rv = aml_allocvalue(AML_OBJTYPE_STRING, i2, tmp->v_buffer);
- aml_esetnodevalue(ctx, lhs, rv, 0);
- break;
- case AMLOP_TOBUFFER:
- 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:
- case AMLOP_TOHEXSTRING:
- 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, AML_ANYINT);
- dnprintf(40, "stall %lld usecs\n", i1);
- acpi_delay(ctx->sc, i1);
- break;
- case AMLOP_SLEEP:
- i1 = aml_eparseint(ctx, AML_ANYINT);
- dnprintf(40, "sleep %lld msecs\n", i1);
- acpi_delay(ctx->sc, i1 * 1000);
+ rval = aml_parsecompare(scope, opcode, res);
break;
+ case AMLOP_NAME:
+ case AMLOP_ALIAS:
+ case AMLOP_EVENT:
case AMLOP_MUTEX:
- name = aml_parse_name(ctx);
- i1 = aml_eparseint(ctx, AML_BYTE);
- rv = aml_allocvalue(AML_OBJTYPE_MUTEX, i1, NULL);
- aml_addvname(ctx, name, opc->opcode, rv);
+ case AMLOP_OPREGION:
+ rval = aml_parsenamed(scope, opcode, res);
break;
- case AMLOP_ACQUIRE:
- i2 = 0;
- lhs = aml_eparseval(ctx, 1);
- i1 = aml_eparseint(ctx, AML_WORD); // timeout (0xffff = infinite)
- acpi_mutex_acquire(ctx, &lhs->v_mutex, i1);
-
- /* Returns true for timeout */
- rv = aml_allocint(i2);
+ case AMLOP_DEVICE:
+ case AMLOP_SCOPE:
+ case AMLOP_PROCESSOR:
+ case AMLOP_POWERRSRC:
+ case AMLOP_THERMALZONE:
+ rval = aml_parsenamedscope(scope, opcode, res);
break;
+ case AMLOP_ACQUIRE:
case AMLOP_RELEASE:
- 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, NULL);
- aml_addvname(ctx, name, opc->opcode, rv);
- break;
- case AMLOP_SIGNAL:
- lhs = aml_eparseval(ctx, 1);
- dnprintf(40, "signal: %s\n", lhs->v_string);
- break;
case AMLOP_WAIT:
- lhs = aml_eparseval(ctx, 1);
- i1 = aml_eparseint(ctx, AML_ANYINT);
- dnprintf(40, "wait: %s %llx\n", lhs->v_string, i1);
- break;
+ case AMLOP_SIGNAL:
case AMLOP_RESET:
- lhs = aml_eparseval(ctx, 1);
- dnprintf(40, "reset: %s\n", lhs->v_string);
+ rval = aml_parsemuxaction(scope, opcode, res);
break;
+ case AMLOP_SLEEP:
+ case AMLOP_STALL:
+ case AMLOP_FATAL:
case AMLOP_NOTIFY:
- lhs = aml_eparseval(ctx, 1);
- i1 = aml_eparseint(ctx, AML_ANYINT);
- /* XXX: Fix me when we deref properly */
- if ((node = lhs->node) == NULL)
- node = aml_searchname(ctx->scope, lhs->name);
- dnprintf(10, "NOTIFY: %llx %s\n", i1, lhs->name);
- aml_notify(node, i1);
+ rval = aml_parsemisc2(scope, opcode, res);
break;
- case AMLOP_LOAD:
- case AMLOP_STORE:
- rhs = aml_eparseval(ctx, 1);
- lhs = aml_eparseval(ctx, 0);
- rv = aml_esetnodevalue(ctx, lhs, rhs, 0);
-
+ case AMLOP_SIZEOF:
+ case AMLOP_OBJECTTYPE:
+ rval = aml_parsemisc3(scope, opcode, res);
break;
- case AMLOP_COPYOBJECT:
- rhs = aml_eparseval(ctx, 1);
- lhs = aml_eparseval(ctx, 1);
- rv = aml_copyvalue(rhs);
- aml_esetnodevalue(ctx, lhs, rv, 0);
+ case AMLOP_CREATEFIELD:
+ case AMLOP_CREATEBITFIELD:
+ case AMLOP_CREATEBYTEFIELD:
+ case AMLOP_CREATEWORDFIELD:
+ case AMLOP_CREATEDWORDFIELD:
+ case AMLOP_CREATEQWORDFIELD:
+ rval = aml_parsebufferfield(scope, opcode, res);
break;
- case AMLOP_OPREGION:
- name = aml_parse_name(ctx);
- 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);
-
- /* Special case: get PCI address */
- if (rv->v_opregion.iospace == GAS_PCI_CFG_SPACE) {
- i1 = aml_get_pciaddr(ctx, ctx->scope);
- if (i1 == 0xFFFF)
- dnprintf(50, "aml_pciregion: no _ADR for %s!\n",
- name);
- else {
- rv->v_opregion.iobase += i1;
- dnprintf(50, "aml_pciregion: %llx\n", rv->v_opregion.iobase);
- }
- }
- aml_addvname(ctx, name, opc->opcode, rv);
- }
+ case AMLOP_FIELD:
+ case AMLOP_INDEXFIELD:
+ case AMLOP_BANKFIELD:
+ rval = aml_parsefieldunit(scope, opcode, res);
break;
- case AMLOP_ALIAS:
- 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);
+ case AMLOP_BUFFER:
+ case AMLOP_PACKAGE:
+ case AMLOP_VARPACKAGE:
+ rval = aml_parsebufpkg(scope, opcode, res);
break;
- case AMLOP_NAME:
- name = aml_parse_name(ctx);
- rv = aml_eparseval(ctx, 0);
- aml_addvname(ctx, name, opc->opcode, rv);
+ case AMLOP_IF:
+ rval = aml_parseif(scope, opcode, res);
break;
- case AMLOP_RETURN:
- rv = aml_eparseval(ctx, 1);
- dnprintf(40, "RETURNING: ");
- aml_showvalue(rv);
- ctx->pos = NULL;
+ case AMLOP_WHILE:
+ rval = aml_parsewhile(scope, opcode, res);
break;
case AMLOP_MID:
- rv = aml_domid(ctx);
- break;
- case AMLOP_CONCAT:
- rv = aml_doconcat(ctx);
- break;
-
- case AMLOP_SCOPE:
- end = aml_eparselen(ctx);
- name = aml_parse_name(ctx);
-
- /* Save old scope, create new scope */
- rv = aml_eparsescope(ctx, name, end, opc, NULL);
- break;
- case AMLOP_DEVICE:
- end = aml_eparselen(ctx);
- name = aml_parse_name(ctx);
-
- /* Save old scope, create new scope */
- 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, 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, 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, NULL);
- lhs = aml_eparsescope(ctx, name, end, opc, rv);
- break;
- case AMLOP_OBJECTTYPE:
- lhs = aml_eparseval(ctx, 1);
- i1 = (lhs->type == AML_OBJTYPE_STATICINT) ?
- AML_OBJTYPE_INTEGER : lhs->type;
- rv = aml_allocint(i1);
- break;
- case AMLOP_SIZEOF:
- 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_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);
- rv->v_method.end = rv->v_method.start + rv->length;
-
- memcpy(rv->v_method.start, ctx->pos, rv->length);
- aml_addvname(ctx, name, opc->opcode, rv);
- }
- break;
- case AMLOP_CONDREFOF:
- 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);
- aml_esetnodevalue(ctx, lhs, tmp, 0);
- rv->v_integer = 1;
- }
- dnprintf(40,"condrefof: %lld\n", rv->v_integer);
- break;
- case AMLOP_REFOF:
- 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);
- }
+ case AMLOP_TOSTRING:
+ case AMLOP_TODECSTRING:
+ case AMLOP_TOHEXSTRING:
+ rval = aml_parsestring(scope, opcode, res);
break;
case AMLOP_INDEX:
- 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_REFOF:
case AMLOP_DEREFOF:
- rv = aml_eparseval(ctx, 1);
- break;
- case AMLOP_LOADTABLE:
- rv = aml_doloadtable(ctx);
- break;
- case AMLOP_MATCH:
- rv = aml_domatch(ctx);
- break;
- case AMLOP_WHILE:
- rv = aml_dowhile(ctx);
- break;
- case AMLOP_IF:
- rv = aml_doif(ctx);
- break;
-
- default:
- 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;
-
- --ctx->depth;
- return rv;
-}
-
-/* Remove all children nodes */
-void
-aml_delchildren(struct acpi_context *ctx, struct aml_node *node)
-{
- struct aml_node *pn;
-
- if (node == NULL)
- 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);
- }
-}
-
-/* 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_node *oldscope;
- struct aml_value *rv;
-
- if (node->value == NULL)
- return NULL;
- switch (node->value->type) {
- case AML_OBJTYPE_NAMEREF:
- case AML_OBJTYPE_INTEGER:
- case AML_OBJTYPE_STRING:
- case AML_OBJTYPE_BUFFER:
- case AML_OBJTYPE_PACKAGE:
- return node->value;
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
- return aml_efield(ctx, node->value, NULL);
- case AML_OBJTYPE_METHOD:
- /* Setup method call */
- oldscope = ctx->scope;
- ctx->scope = node->parent;
-
- dnprintf(40, "Call function: %s\n", node->name);
-
- ctx->pos = node->value->v_method.start;
- rv = aml_eparselist(ctx, node->value->v_method.end, 1);
-
- /* Delete dynamic names */
- aml_delchildren(ctx, node);
-
- ctx->scope = oldscope;
- return rv;
- default:
- 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)
-{
- struct acpi_context *ctx;
- struct aml_value *rv;
-
- ret->type = 0;
- ctx = acpi_alloccontext(sc, node, argc, argv);
- rv = aml_eparsenode(ctx, node);
- dnprintf(40, "###### RETURNING #####\n");
- aml_showvalue(rv);
- if (rv != NULL)
- *ret = *rv;
-
- /* XXX: must free rv */
- acpi_freecontext(ctx);
-
- return 0;
-}
-
-struct aml_value *
-aml_evalmethod(struct acpi_context *ctx, struct aml_value *method)
-{
- struct aml_value **argv, *rv;
- int64_t idx, size, argc;
-
- /* Decode method arguments from bytestream */
- size = sizeof(struct aml_value *) * AML_MAX_ARG;
- argv = (struct aml_value **)acpi_os_allocmem(size);
-
- argc = AML_METHOD_ARGCOUNT(method->v_method.flags);
- for (idx = 0; idx < argc; idx++)
- argv[idx] = aml_eparseval(ctx, 0);
-
- /* Evaluate method */
- rv = aml_evalnode(ctx->sc, method->node, argc, argv);
-
- /* Free arguments */
- for(idx = 0; idx < AML_MAX_ARG; idx++)
- aml_freevalue(&argv[idx]);
-
- acpi_os_freemem(argv);
-
- return (rv);
-}
-
-struct aml_value *
-aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
- int argc, struct aml_value **argv)
-{
- struct acpi_context *ctx;
- struct aml_value *rv, **tmparg;
-
- /* This shouldn't happen... */
- if (node->value == NULL)
- return NULL;
-
- /* Simple objects: return node value */
- dnprintf(10, "--- eval: (%s)\n", node->name);
- switch (node->value->type) {
- case AML_OBJTYPE_NAMEREF:
- case AML_OBJTYPE_INTEGER:
- case AML_OBJTYPE_STATICINT:
- case AML_OBJTYPE_STRING:
- case AML_OBJTYPE_BUFFER:
- case AML_OBJTYPE_PACKAGE:
- return node->value;
- }
-
- /* Method or field context required */
- if ((ctx = acpi_alloccontext(sc, node, 0, NULL)) == NULL)
- return NULL;
-
- /* XXX: ugh, fix this, set method argument pointer */
- tmparg = ctx->args;
- if (argv != NULL)
- ctx->args = argv;
-
- rv = NULL;
- switch (node->value->type) {
- case AML_OBJTYPE_BUFFERFIELD:
- case AML_OBJTYPE_FIELDUNIT:
- rv = aml_efield(ctx, node->value, NULL);
- break;
- case AML_OBJTYPE_METHOD:
- ctx->pos = node->value->v_method.start;
- rv = aml_eparselist(ctx, node->value->v_method.end, 0);
- break;
- default:
- dnprintf(1, "aml_evalnode: Unknown type (%d) for %s\n",
- node->value->type,
- node->name);
+ case AMLOP_CONDREFOF:
+ case AMLOP_STORE:
+ case AMLOP_RETURN:
+ case AMLOP_LOAD:
+ case AMLOP_ARG0 ... AMLOP_ARG6:
+ case AMLOP_LOCAL0 ... AMLOP_LOCAL7:
+ rval = aml_parseref(scope, opcode, res);
break;
- }
- ctx->args = tmparg;
- aml_delchildren(ctx, node);
- acpi_freecontext(ctx);
-
- return rv;
-}
-
-struct aml_value *
-aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
- int argc, struct aml_value **argv)
-{
- struct aml_node *node;
-
- if ((node = aml_searchname(parent, name)) != NULL)
- return aml_evalnode(sc, node, argc, argv);
-
- return NULL;
-}
-
-void
-aml_shownode(struct aml_node *node)
-{
- dnprintf(50, " opcode:%.4x mnem:%s %s ",
- node->opcode, node->mnem, node->name ? node->name : "");
- switch(node->opcode) {
case AMLOP_METHOD:
+ rval = aml_parsemethod(scope, opcode, res);
break;
-
- case AMLOP_NAMECHAR:
- dnprintf(50, "%s", node->value->name);
- break;
-
- case AMLOP_FIELD:
- case AMLOP_BANKFIELD:
- case AMLOP_INDEXFIELD:
- break;
-
- case AMLOP_BYTEPREFIX:
- dnprintf(50, "byte: %.2x", node->value->v_integer);
- break;
- case AMLOP_WORDPREFIX:
- dnprintf(50, "word: %.4x", node->value->v_integer);
- break;
- case AMLOP_DWORDPREFIX:
- dnprintf(50, "dword: %.8x", node->value->v_integer);
- break;
- case AMLOP_STRINGPREFIX:
- dnprintf(50, "string: %s", node->value->v_string);
+ default:
+ aml_die("Unknown opcode: %.4x", opcode);
break;
}
- dnprintf(50, "\n");
-}
-
-void
-aml_walktree(struct aml_node *node)
-{
- int idx;
-
- while(node) {
- dnprintf(50, " %d ", node->depth);
- for(idx=0; idx<node->depth; idx++)
- dnprintf(50, "..");
- aml_shownode(node);
- aml_walktree(node->child);
- node = node->sibling;
- }
-}
-
-void
-aml_walkroot(void)
-{
- aml_walktree(aml_root.child);
-}
-
-int
-aml_find_node(struct aml_node *node, const char *name,
- void (*cbproc)(struct aml_node *, void *arg),
- void *arg)
-{
- const char *nn;
-
- while (node) {
- if ((nn = node->name) != NULL) {
- if (*nn == AMLOP_ROOTCHAR) nn++;
- while (*nn == AMLOP_PARENTPREFIX) nn++;
- if (!strcmp(name, nn))
- cbproc(node, arg);
- }
- aml_find_node(node->child, name, cbproc, arg);
- node = node->sibling;
- }
- return (0);
+ return rval;
}
const char hext[] = "0123456789ABCDEF";
@@ -3019,70 +2878,127 @@ aml_eisaid(u_int32_t pid)
return id;
}
-struct acpi_context *acpi_alloccontext(struct acpi_softc *sc,
- struct aml_node *node,
- int argc,
- struct aml_value *argv)
+/*
+ * @@@: Fixup DSDT code
+ */
+struct aml_fixup
+{
+ int offset;
+ u_int8_t oldv;
+ u_int8_t newv;
+};
+
+struct aml_blacklist
{
- struct acpi_context *ctx;
- int idx;
+ const char *oem;
+ const char *oemtbl;
+ u_int8_t cksum;
+ struct aml_fixup *fixtab;
+};
- if ((ctx = acpi_os_allocmem(sizeof(struct acpi_context))) != NULL) {
- ctx->sc = sc;
- ctx->depth = 0;
- ctx->start = node->start;
- ctx->pos = node->start;
- ctx->scope = node;
- ctx->locals = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *) * 8);
- ctx->args = (struct aml_value **)acpi_os_allocmem(sizeof(struct aml_value *) * 8);
- for (idx=0; idx<argc; idx++) {
- ctx->args[idx] = aml_copyvalue(&argv[idx]);
+struct aml_fixup __ibm300gl[] = {
+ { 0x19, 0x3a, 0x3b },
+ { -1 }
+};
+
+struct aml_blacklist amlfix_list[] = {
+ { "IBM ", "CDTPWSNH", 0x41, __ibm300gl },
+ { NULL },
+};
+
+void
+aml_fixup_dsdt(u_int8_t *acpi_hdr, u_int8_t *base, int len)
+{
+ struct acpi_table_header *hdr = (struct acpi_table_header *)acpi_hdr;
+ struct aml_blacklist *fixlist;
+ struct aml_fixup *fixtab;
+
+ for (fixlist=amlfix_list; fixlist->oem; fixlist++) {
+ if (!memcmp(fixlist->oem, hdr->oemid, 6) &&
+ !memcmp(fixlist->oemtbl, hdr->oemtableid, 8) &&
+ fixlist->cksum == hdr->checksum)
+ {
+ /* Found a potential fixup entry */
+ for (fixtab = fixlist->fixtab; fixtab->offset != -1; fixtab++) {
+ if (base[fixtab->offset] == fixtab->oldv)
+ base[fixtab->offset] = fixtab->newv;
+ }
}
}
- return ctx;
}
-void acpi_freecontext(struct acpi_context *ctx)
+/*
+ * @@@: Default Object creation
+ */
+struct aml_defval
{
- int idx;
+ const char *name;
+ int type;
+ int64_t ival;
+ const void *bval;
+ struct aml_value **gval;
+};
+
+struct aml_defval aml_defobj[] = {
+ { "_OS_", AML_OBJTYPE_STRING, -1, "OpenBSD" },
+ { "_REV", AML_OBJTYPE_INTEGER, 2, NULL },
+ { "_GL", AML_OBJTYPE_MUTEX, 1, NULL, &aml_global_lock },
+ { NULL }
+};
- if (ctx) {
- for (idx=0; idx<8; idx++) {
- aml_freevalue(&ctx->args[idx]);
- aml_freevalue(&ctx->locals[idx]);
+void
+aml_create_defaultobjects()
+{
+ struct aml_value *tmp;
+ struct aml_defval *def;
+
+ for (def = aml_defobj; def->name; def++) {
+ /* Allocate object value + add to namespace */
+ tmp = aml_allocvalue(def->type, def->ival, def->bval);
+ aml_createname(&aml_root, def->name, tmp);
+ if (def->gval) {
+ /* Set root object pointer */
+ *def->gval = tmp;
}
- acpi_os_freemem(ctx->args);
- acpi_os_freemem(ctx->locals);
- acpi_os_freemem(ctx);
}
}
int
acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length)
{
- struct acpi_context *ctx;
- struct aml_value *rv;
-
- aml_root.depth = -1;
- aml_root.mnem = "ROOT";
- aml_root.start = start;
- aml_root.end = start + length;
-
- /* Add \_OS_ string */
- aml_os.type = AML_OBJTYPE_STRING;
- aml_os.v_string = "OpenBSD";
- aml_os.length = strlen(aml_os.v_string) + 1;
- ctx = acpi_alloccontext(sc, &aml_root, 0, NULL);
- aml_addvname(ctx, "\\_OS_", AMLOP_NAME, &aml_os);
-
- rv = aml_eparselist(ctx, aml_root.end, 0);
- aml_freevalue(&rv);
+ u_int8_t *end;
- acpi_freecontext(ctx);
+ dsdt_softc = sc;
+ strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
+ if (aml_root.start == NULL) {
+ aml_root.start = start;
+ aml_root.end = start+length;
+ }
+ end = start+length;
+ aml_parsenode(&aml_root, start, &end, NULL);
dnprintf(50, " : parsed %d AML bytes\n", length);
- aml_walktree(&aml_root);
+ return (0);
+}
+/* XXX: kill me */
+int aml_parse_length(struct acpi_context *ctx)
+{
return (0);
}
+int64_t aml_eparseint(struct acpi_context * ctx, int style)
+{
+ return (0);
+}
+struct aml_opcode *aml_getopcode(struct acpi_context *ctx)
+{
+ return NULL;
+}
+void acpi_freecontext(struct acpi_context *ctx)
+{
+}
+const char *aml_parse_name(struct acpi_context *ctx)
+{
+ return "";
+}
diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h
index bb3cf2fb544..36a3c03b40c 100644
--- a/sys/dev/acpi/dsdt.h
+++ b/sys/dev/acpi/dsdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.13 2006/03/09 05:38:12 jordan Exp $ */
+/* $OpenBSD: dsdt.h,v 1.14 2006/10/12 16:38:21 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -31,26 +31,27 @@ struct acpi_context
struct aml_opcode
{
- u_int16_t opcode;
+ u_int32_t opcode;
const char *mnem;
const char *args;
};
const char *aml_eisaid(u_int32_t);
-const char *aml_opname(int);
+const char *aml_mnem(int);
const char *aml_parse_name(struct acpi_context *);
int aml_parse_length(struct acpi_context *);
int64_t aml_eparseint(struct acpi_context *, int);
-int64_t aml_val2int(struct acpi_context *, struct aml_value *);
-struct aml_node *aml_searchname(struct aml_node *, const char *);
+int64_t aml_val2int(struct aml_value *);
+struct aml_node *aml_searchname(struct aml_node *, const void *);
+struct aml_node *aml_createname(struct aml_node *, const void *, struct aml_value *);
+
struct aml_opcode *aml_getopcode(struct acpi_context *);
struct aml_value *aml_allocint(uint64_t);
struct aml_value *aml_allocstr(const char *);
-struct aml_value *aml_allocvalue(int, int64_t, void *);
-struct aml_value *aml_copyvalue(const struct aml_value *);
+struct aml_value *aml_allocvalue(int, int64_t, const void *);
u_int8_t *aml_eparselen(struct acpi_context *);
void acpi_freecontext(struct acpi_context *);
-void aml_freevalue(struct aml_value **);
+void aml_freevalue(struct aml_value *);
void aml_notify(struct aml_node *, int);
void aml_notify_dev(const char *, int);
void aml_showvalue(struct aml_value *);
@@ -61,9 +62,6 @@ int aml_comparevalue(struct acpi_context *, int,
struct aml_value *, struct aml_value *);
int aml_find_node(struct aml_node *, const char *,
void (*)(struct aml_node *, void *), void *);
-int aml_eval_name(struct acpi_softc *, struct aml_node *,
- const char *, struct aml_value *,
- struct aml_value *);
int acpi_parse_aml(struct acpi_softc *, u_int8_t *,
u_int32_t);
int aml_eval_object(struct acpi_softc *, struct aml_node *,
@@ -73,4 +71,18 @@ struct acpi_context *acpi_alloccontext(struct acpi_softc *,
void aml_register_notify(struct aml_node *, const char *,
int (*)(struct aml_node *, int, void *), void *);
+int aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
+ int argc, struct aml_value *argv,
+ struct aml_value *);
+
+int aml_evalname(struct acpi_softc *sc, struct aml_node *parent,
+ const char *, int, struct aml_value *,
+ struct aml_value *);
+
+void aml_fixup_dsdt(u_int8_t *, u_int8_t *, int);
+void aml_create_defaultobjects(void);
+
+#define ACPI_E_NOERROR 0x00
+#define ACPI_E_BADVALUE 0x01
+
#endif /* __DEV_ACPI_DSDT_H__ */