summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2010-07-08 20:56:32 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2010-07-08 20:56:32 +0000
commitdd962e3f38e19806f683e5169e01253927248af4 (patch)
tree4c6b8d37f0da22f500938a26a6f8b52d304b3be4 /sys/dev/acpi
parent933022a0b195fe12232960cf6cc3e54fe63f7354 (diff)
Add mapping for ACPI device to PCI bdf (match autoconf tree)
Simplify resource parsing function to use buffer argument Convert namespace linked lists to use queue macros ok marco@, deraadt@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpi.c194
-rw-r--r--sys/dev/acpi/acpidebug.c9
-rw-r--r--sys/dev/acpi/acpiprt.c29
-rw-r--r--sys/dev/acpi/amltypes.h25
-rw-r--r--sys/dev/acpi/dsdt.c251
-rw-r--r--sys/dev/acpi/dsdt.h4
6 files changed, 299 insertions, 213 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 7b141c24292..3ca034f7f08 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.172 2010/07/06 20:15:31 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.173 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -42,6 +42,10 @@
#include <dev/acpi/dsdt.h>
#include <dev/wscons/wsdisplayvar.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/ppbreg.h>
+
#include <dev/pci/pciidereg.h>
#include <dev/pci/pciidevar.h>
@@ -67,6 +71,8 @@ int acpi_saved_spl;
void acpi_isr_thread(void *);
void acpi_create_thread(void *);
+void acpi_pci_match(struct device *, struct pci_attach_args *);
+
int acpi_match(struct device *, void *, void *);
void acpi_attach(struct device *, struct device *, void *);
int acpi_submatch(struct device *, void *, void *);
@@ -95,12 +101,15 @@ int acpi_foundide(struct aml_node *node, void *arg);
int acpiide_notify(struct aml_node *, int, void *);
int _acpi_matchhids(const char *, const char *[]);
+int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[],
+ const char *driver);
+
+struct acpi_q *acpi_maptable(struct acpi_softc *, paddr_t, const char *,
+ const char *, const char *, int);
void wdcattach(struct channel_softc *);
int wdcdetach(struct channel_softc *, int);
-struct acpi_q *acpi_maptable(struct acpi_softc *, paddr_t, const char *, const char *, const char *, int);
-
struct idechnl
{
struct acpi_softc *sc;
@@ -490,6 +499,157 @@ acpi_match(struct device *parent, void *match, void *aux)
return (1);
}
+TAILQ_HEAD(, acpi_pci) acpi_pcidevs =
+ TAILQ_HEAD_INITIALIZER(acpi_pcidevs);
+
+int acpi_getpci(struct aml_node *node, void *arg);
+int acpi_getminbus(union acpi_resource *crs, void *arg);
+
+int
+acpi_getminbus(union acpi_resource *crs, void *arg)
+{
+ int *bbn = arg;
+ int typ = AML_CRSTYPE(crs);
+
+ /* Check for embedded bus number */
+ if (typ == LR_WORD && crs->lr_word.type == 2)
+ *bbn = crs->lr_word._min;
+ return 0;
+}
+
+int
+_acpi_matchhids(const char *hid, const char *hids[])
+{
+ int i;
+
+ for (i = 0; hids[i]; i++)
+ if (!strcmp(hid, hids[i]))
+ return (1);
+ return (0);
+}
+
+int
+acpi_matchhids(struct acpi_attach_args *aa, const char *hids[],
+ const char *driver)
+{
+
+ if (aa->aaa_dev == NULL || aa->aaa_node == NULL)
+ return (0);
+ if (_acpi_matchhids(aa->aaa_dev, hids)) {
+ dnprintf(5, "driver %s matches %s\n", driver, hids[i]);
+ return (1);
+ }
+ return (0);
+}
+
+/* Map ACPI device node to PCI */
+int
+acpi_getpci(struct aml_node *node, void *arg)
+{
+ const char *pcihid[] = { ACPI_DEV_PCIB, ACPI_DEV_PCIEB, "HWP0002", 0 };
+ struct acpi_pci *pci, *ppci;
+ struct aml_value res;
+ struct acpi_softc *sc = arg;
+ pci_chipset_tag_t pc = NULL;
+ pcitag_t tag;
+ uint64_t val;
+ uint32_t reg;
+
+ if (!node->value || node->value->type != AML_OBJTYPE_DEVICE)
+ return 0;
+ if (!aml_evalhid(node, &res)) {
+ /* Check if this is a PCI Root node */
+ if (_acpi_matchhids(res.v_string, pcihid)) {
+ aml_freevalue(&res);
+
+ pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO);
+
+ pci->bus = -1;
+ if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val))
+ pci->seg = val;
+ if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) {
+ aml_parse_resource(&res, acpi_getminbus,
+ &pci->bus);
+ printf("%s post-crs: %d\n", aml_nodename(node),
+ pci->bus);
+ }
+ if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) {
+ printf("%s post-bbn: %d, %lld\n", aml_nodename(node),
+ pci->bus, val);
+ if (pci->bus == -1)
+ pci->bus = val;
+ }
+ pci->sub = pci->bus;
+ node->pci = pci;
+ dnprintf(10, "found PCI root: %s %d\n",
+ aml_nodename(node), pci->bus);
+ }
+ aml_freevalue(&res);
+ return 0;
+ }
+
+ /* If parent is not PCI, or device does not have _ADR, return */
+ if (!node->parent || (ppci = node->parent->pci) == NULL)
+ return 0;
+ if (aml_evalinteger(sc, node, "_ADR", 0, NULL, &val))
+ return 0;
+
+ pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO);
+ pci->bus = ppci->sub;
+ pci->dev = ACPI_ADR_PCIDEV(val);
+ pci->fun = ACPI_ADR_PCIFUN(val);
+ pci->node = node;
+ pci->sub = -1;
+
+ dnprintf(10, "%.2x:%.2x.%x -> %s\n",
+ pci->bus, pci->dev, pci->fun,
+ aml_nodename(node));
+
+ /* Check if PCI device exists */
+ tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun);
+ reg = pci_conf_read(pc, tag, PCI_ID_REG);
+ if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) {
+ free(pci, M_DEVBUF);
+ return (1);
+ }
+ node->pci = pci;
+
+ TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next);
+
+ /* Check if this is a PCI bridge */
+ reg = pci_conf_read(pc, tag, PCI_CLASS_REG);
+ if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE &&
+ PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI) {
+ reg = pci_conf_read(pc, tag, PPB_REG_BUSINFO);
+ pci->sub = PPB_BUSINFO_SECONDARY(reg);
+
+ dnprintf(10, "found PCI bridge: %s %d\n",
+ aml_nodename(node), pci->sub);
+
+ /* Continue scanning */
+ return (0);
+ }
+
+ /* Device does not have children, stop scanning */
+ return (1);
+}
+
+void
+acpi_pci_match(struct device *dev, struct pci_attach_args *pa)
+{
+ struct acpi_pci *pdev;
+
+ TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
+ if (pdev->bus == pa->pa_bus &&
+ pdev->dev == pa->pa_device &&
+ pdev->fun == pa->pa_function) {
+ dnprintf(10,"%s at acpi0 %s\n",
+ dev->dv_xname, aml_nodename(pdev->node));
+ pdev->device = dev;
+ }
+ }
+}
+
void
acpi_attach(struct device *parent, struct device *self, void *aux)
{
@@ -707,6 +867,9 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
/* initialize runtime environment */
aml_find_node(&aml_root, "_INI", acpi_inidev, sc);
+ /* Get PCI mapping */
+ aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc);
+
/* attach pci interrupt routing tables */
aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc);
@@ -2316,31 +2479,6 @@ acpi_foundec(struct aml_node *node, void *arg)
}
int
-_acpi_matchhids(const char *hid, const char *hids[])
-{
- int i;
-
- for (i = 0; hids[i]; i++)
- if (!strcmp(hid, hids[i]))
- return (1);
- return (0);
-}
-
-int
-acpi_matchhids(struct acpi_attach_args *aa, const char *hids[],
- const char *driver)
-{
-
- if (aa->aaa_dev == NULL || aa->aaa_node == NULL)
- return (0);
- if (_acpi_matchhids(aa->aaa_dev, hids)) {
- dnprintf(5, "driver %s matches %s\n", driver, hids[i]);
- return (1);
- }
- return (0);
-}
-
-int
acpi_foundhid(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
diff --git a/sys/dev/acpi/acpidebug.c b/sys/dev/acpi/acpidebug.c
index 1e979170afb..b5cf136af7c 100644
--- a/sys/dev/acpi/acpidebug.c
+++ b/sys/dev/acpi/acpidebug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.25 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.26 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
*
@@ -238,9 +238,8 @@ db_aml_walktree(struct aml_node *node)
{
while (node) {
db_aml_showvalue(node->value);
- db_aml_walktree(node->child);
-
- node = node->sibling;
+ db_aml_walktree(SIMPLEQ_FIRST(&node->son));
+ node = SIMPLEQ_NEXT(node, sib);
}
}
@@ -334,7 +333,7 @@ db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif)
void
db_acpi_tree(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
- db_aml_walktree(aml_root.child);
+ db_aml_walktree(&aml_root);
}
void
diff --git a/sys/dev/acpi/acpiprt.c b/sys/dev/acpi/acpiprt.c
index c677299e983..24cfe86b72e 100644
--- a/sys/dev/acpi/acpiprt.c
+++ b/sys/dev/acpi/acpiprt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiprt.c,v 1.38 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: acpiprt.c,v 1.39 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org>
*
@@ -101,14 +101,22 @@ acpiprt_attach(struct device *parent, struct device *self, void *aux)
struct acpiprt_softc *sc = (struct acpiprt_softc *)self;
struct acpi_attach_args *aa = aux;
struct aml_value res;
- int i;
+ int i, nbus;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node;
sc->sc_bus = acpiprt_getpcibus(sc, sc->sc_devnode);
-
+ nbus = (sc->sc_devnode->parent && sc->sc_devnode->parent->pci) ?
+ sc->sc_devnode->parent->pci->sub : -1;
printf(": bus %d (%s)", sc->sc_bus, sc->sc_devnode->parent->name);
+ if (nbus != sc->sc_bus) {
+ printf("%s: bus mismatch, new:%d old:%d\n",
+ aml_nodename(sc->sc_devnode),
+ nbus, sc->sc_bus);
+ panic("aiiiee..");
+ }
+
if (aml_evalnode(sc->sc_acpi, sc->sc_devnode, 0, NULL, &res)) {
printf(": no PCI interrupt routing table\n");
return;
@@ -279,18 +287,13 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v)
aml_freevalue(&res);
return;
}
- aml_parse_resource(res.length, res.v_buffer,
- acpiprt_getirq, &irq);
+ aml_parse_resource(&res, acpiprt_getirq, &irq);
aml_freevalue(&res);
/* Pick a new IRQ if necessary. */
if ((irq == 0 || irq == 2 || irq == 13) &&
!aml_evalname(sc->sc_acpi, node, "_PRS", 0, NULL, &res)){
- if (res.type == AML_OBJTYPE_BUFFER &&
- res.length >= 5) {
- aml_parse_resource(res.length, res.v_buffer,
- acpiprt_chooseirq, &irq);
- }
+ aml_parse_resource(&res, acpiprt_chooseirq, &irq);
aml_freevalue(&res);
}
@@ -396,9 +399,7 @@ acpiprt_getpcibus(struct acpiprt_softc *sc, struct aml_node *node)
*/
if (aml_evalname(sc->sc_acpi, parent, "_CRS.", 0, NULL, &res) == 0) {
rv = -1;
- if (res.type == AML_OBJTYPE_BUFFER)
- aml_parse_resource(res.length, res.v_buffer,
- acpiprt_getminbus, &rv);
+ aml_parse_resource(&res, acpiprt_getminbus, &rv);
aml_freevalue(&res);
if (rv != -1)
return rv;
@@ -484,7 +485,7 @@ acpiprt_route_interrupt(int bus, int dev, int pin)
aml_freevalue(&res);
return;
}
- aml_parse_resource(res.length, res.v_buffer, acpiprt_getirq, &irq);
+ aml_parse_resource(&res, acpiprt_getirq, &irq);
/* Only re-route interrupts when necessary. */
if ((sta & STA_ENABLED) && irq == newirq) {
diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h
index 38ed5a5ce63..d8f5523aa27 100644
--- a/sys/dev/acpi/amltypes.h
+++ b/sys/dev/acpi/amltypes.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amltypes.h,v 1.36 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: amltypes.h,v 1.37 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -347,21 +347,32 @@ struct aml_value {
#define aml_pkglen(v) ((v)->length)
#define aml_pkgval(v,i) (&(v)->v_package[(i)])
+struct acpi_pci {
+ TAILQ_ENTRY(acpi_pci) next;
+
+ struct aml_node *node;
+ struct device *device;
+
+ int sub;
+ int seg;
+ int bus;
+ int dev;
+ int fun;
+};
+
struct aml_node {
struct aml_node *parent;
- struct aml_node *child;
- struct aml_node *sibling;
+
+ SIMPLEQ_HEAD(,aml_node) son;
+ SIMPLEQ_ENTRY(aml_node) sib;
char name[5];
u_int16_t opcode;
u_int8_t *start;
u_int8_t *end;
- // const char *name;
- // const char *mnem;
struct aml_value *value;
-
- int depth;
+ struct acpi_pci *pci;
};
#define aml_bitmask(n) (1L << ((n) & 0x7))
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 8e0076aabff..b4d0fb272fb 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.164 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: dsdt.c,v 1.165 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -96,12 +96,6 @@ void _acpi_os_free(void *, const char *, int);
void acpi_sleep(int);
void acpi_stall(int);
-uint8_t *aml_xparsename(uint8_t *pos, struct aml_node *node,
- void (*fn)(struct aml_node *, int, uint8_t *, void *), void *arg);
-void ns_xcreate(struct aml_node *node, int n, uint8_t *pos, void *arg);
-void ns_xdis(struct aml_node *node, int n, uint8_t *pos, void *arg);
-void ns_xsearch(struct aml_node *node, int n, uint8_t *pos, void *arg);
-
struct aml_value *aml_callosi(struct aml_scope *, struct aml_value *);
const char *aml_getname(const char *);
@@ -606,16 +600,16 @@ void aml_delchildren(struct aml_node *);
struct aml_node *
__aml_search(struct aml_node *root, uint8_t *nameseg, int create)
{
- struct aml_node **sp, *node;
+ struct aml_node *node;
/* XXX: Replace with SLIST/SIMPLEQ routines */
if (root == NULL)
return NULL;
//rw_enter_read(&aml_nslock);
- for (sp = &root->child; *sp; sp = &(*sp)->sibling) {
- if (!strncmp((*sp)->name, nameseg, AML_NAMESEG_LEN)) {
+ SIMPLEQ_FOREACH(node, &root->son, sib) {
+ if (!strncmp(node->name, nameseg, AML_NAMESEG_LEN)) {
//rw_exit_read(&aml_nslock);
- return *sp;
+ return node;
}
}
//rw_exit_read(&aml_nslock);
@@ -625,13 +619,14 @@ __aml_search(struct aml_node *root, uint8_t *nameseg, int create)
node->value = aml_allocvalue(0,0,NULL);
node->value->node = node;
node->parent = root;
- node->sibling = NULL;
+
+ SIMPLEQ_INIT(&node->son);
+ SIMPLEQ_INSERT_TAIL(&root->son, node, sib);
//rw_enter_write(&aml_nslock);
- *sp = node;
//rw_exit_write(&aml_nslock);
}
- return *sp;
+ return node;
}
/* Get absolute pathname of AML node */
@@ -694,8 +689,8 @@ aml_delchildren(struct aml_node *node)
if (node == NULL)
return;
- while ((onode = node->child) != NULL) {
- node->child = onode->sibling;
+ while ((onode = SIMPLEQ_FIRST(&node->son)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&node->son, sib);
aml_delchildren(onode);
@@ -1233,8 +1228,9 @@ aml_walknodes(struct aml_node *node, int mode,
if (node == NULL)
return;
if (mode == AML_WALK_PRE)
- nodecb(node, arg);
- for (child = node->child; child; child = child->sibling)
+ if (nodecb(node, arg))
+ return;
+ SIMPLEQ_FOREACH(child, &node->son, sib)
aml_walknodes(child, mode, nodecb, arg);
if (mode == AML_WALK_POST)
nodecb(node, arg);
@@ -1256,8 +1252,8 @@ aml_find_node(struct aml_node *node, const char *name,
}
/* Only recurse if cbproc() wants us to */
if (!st)
- aml_find_node(node->child, name, cbproc, arg);
- node = node->sibling;
+ aml_find_node(SIMPLEQ_FIRST(&node->son), name, cbproc, arg);
+ node = SIMPLEQ_NEXT(node, sib);
}
return st;
}
@@ -1265,7 +1261,7 @@ aml_find_node(struct aml_node *node, const char *name,
/*
* @@@: Parser functions
*/
-uint8_t *aml_parsename(struct aml_scope *);
+uint8_t *aml_parsename(struct aml_node *, uint8_t *, struct aml_value **, int);
uint8_t *aml_parseend(struct aml_scope *scope);
int aml_parselength(struct aml_scope *);
int aml_parseopcode(struct aml_scope *);
@@ -1299,27 +1295,67 @@ aml_parseopcode(struct aml_scope *scope)
/* Decode embedded AML Namestring */
uint8_t *
-aml_parsename(struct aml_scope *scope)
+aml_parsename(struct aml_node *inode, uint8_t *pos, struct aml_value **rval, int create)
{
- uint8_t *name = scope->pos;
-
- while (*scope->pos == AMLOP_ROOTCHAR || *scope->pos == AMLOP_PARENTPREFIX)
- scope->pos++;
+ struct aml_node *relnode, *node = inode;
+ uint8_t *start = pos;
+ int i;
- switch (*scope->pos) {
+ if (*pos == AMLOP_ROOTCHAR) {
+ pos++;
+ node = &aml_root;
+ }
+ while (*pos == AMLOP_PARENTPREFIX) {
+ pos++;
+ if ((node = node->parent) == NULL)
+ node = &aml_root;
+ }
+ switch (*pos) {
case 0x00:
+ pos++;
break;
case AMLOP_MULTINAMEPREFIX:
- scope->pos += 2+AML_NAMESEG_LEN*scope->pos[1];
+ for (i=0; i<pos[1]; i++)
+ node = __aml_search(node, pos+2+i*AML_NAMESEG_LEN,
+ create);
+ pos += 2+i*AML_NAMESEG_LEN;
break;
case AMLOP_DUALNAMEPREFIX:
- scope->pos += 1+AML_NAMESEG_LEN*2;
+ node = __aml_search(node, pos+1, create);
+ node = __aml_search(node, pos+1+AML_NAMESEG_LEN, create);
+ pos += 1+2*AML_NAMESEG_LEN;
break;
default:
- scope->pos += AML_NAMESEG_LEN;
+ /* If Relative Search (pos == start), recursively go up root */
+ relnode = node;
+ do {
+ node = __aml_search(relnode, pos, create);
+ relnode = relnode->parent;
+ } while (!node && pos == start && relnode);
+ pos += AML_NAMESEG_LEN;
break;
}
- return name;
+ if (node) {
+ *rval = node->value;
+
+ /* Dereference ALIAS here */
+ if ((*rval)->type == AML_OBJTYPE_OBJREF &&
+ (*rval)->v_objref.type == AMLOP_ALIAS) {
+ dnprintf(10, "deref alias: %s\n", aml_nodename(node));
+ *rval = (*rval)->v_objref.ref;
+ }
+ aml_xaddref(*rval, 0);
+
+ dnprintf(10, "parsename: %s %x\n", aml_nodename(node),
+ (*rval)->type);
+ } else {
+ *rval = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, start);
+
+ dnprintf(10, "%s:%s not found\n", aml_nodename(inode),
+ aml_getname(start));
+ }
+
+ return pos;
}
/* Decode AML Length field
@@ -1498,19 +1534,20 @@ aml_create_defaultobjects()
osstring[15] = 'w';
osstring[18] = 'N';
+ SIMPLEQ_INIT(&aml_root.son);
strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
aml_root.value = aml_allocvalue(0, 0, NULL);
aml_root.value->node = &aml_root;
for (def = aml_defobj; def->name; def++) {
/* Allocate object value + add to namespace */
- aml_xparsename((uint8_t *)def->name, &aml_root,
- ns_xcreate, &tmp);
+ aml_parsename(&aml_root, (uint8_t *)def->name, &tmp, 1);
_aml_setvalue(tmp, def->type, def->ival, def->bval);
if (def->gval) {
/* Set root object pointer */
*def->gval = tmp;
}
+ aml_xdelref(&tmp, 0);
}
}
@@ -1591,17 +1628,19 @@ aml_mapresource(union acpi_resource *crs)
}
int
-aml_parse_resource(int length, uint8_t *buffer,
+aml_parse_resource(struct aml_value *res,
int (*crs_enum)(union acpi_resource *, void *), void *arg)
{
int off, rlen;
union acpi_resource *crs;
- for (off = 0; off < length; off += rlen) {
- crs = (union acpi_resource *)(buffer+off);
+ if (res->type != AML_OBJTYPE_BUFFER || res->length < 5)
+ return (-1);
+ for (off = 0; off < res->length; off += rlen) {
+ crs = (union acpi_resource *)(res->v_buffer+off);
rlen = AML_CRSLEN(crs);
- if (crs->hdr.typecode == 0x79 || rlen <= 3)
+ if (crs->hdr.typecode == 0x79 || !rlen)
break;
crs = aml_mapresource(crs);
@@ -1973,92 +2012,6 @@ aml_xmatch(struct aml_value *pkg, int index,
}
/*
- * Namespace functions
- */
-
-/* Search for name in namespace */
-void
-ns_xsearch(struct aml_node *node, int n, uint8_t *pos, void *arg)
-{
- struct aml_value **rv = arg;
- struct aml_node *rnode;
-
- /* If name search is relative, check up parent nodes */
- for (rnode=node; n == 1 && rnode; rnode=rnode->parent) {
- if (__aml_search(rnode, pos, 0) != NULL)
- break;
- }
- while (n--) {
- rnode = __aml_search(rnode, pos, 0);
- pos += 4;
- }
- if (rnode != NULL) {
- *rv = rnode->value;
- return;
- }
- *rv = NULL;
-}
-
-/* Create name in namespace */
-void
-ns_xcreate(struct aml_node *node, int n, uint8_t *pos, void *arg)
-{
- struct aml_value **rv = arg;
-
- while (n--) {
- node = __aml_search(node, pos, 1);
- pos += 4;
- }
- *rv = node->value;
-}
-
-void
-ns_xdis(struct aml_node *node, int n, uint8_t *pos, void *arg)
-{
- printf(aml_nodename(node));
- while (n--) {
- printf("%s%c%c%c%c", n ? "." : "",
- pos[0], pos[1], pos[2], pos[3]);
- pos+=4;
- }
-}
-
-uint8_t *
-aml_xparsename(uint8_t *pos, struct aml_node *node,
- void (*fn)(struct aml_node *, int, uint8_t *, void *), void *arg)
-{
- uint8_t *rpos = pos;
- struct aml_value **rv = arg;
-
- if (*pos == AMLOP_ROOTCHAR) {
- node = &aml_root;
- pos++;
- }
- while (*pos == AMLOP_PARENTPREFIX) {
- node = node ? node->parent : &aml_root;
- pos++;
- }
- if (*pos == 0) {
- fn(node, 0, pos, arg);
- pos++;
- } else if (*pos == AMLOP_MULTINAMEPREFIX) {
- fn(node, pos[1], pos+2, arg);
- pos += 2 + 4 * pos[1];
- } else if (*pos == AMLOP_DUALNAMEPREFIX) {
- fn(node, 2, pos+1, arg);
- pos += 9;
- } else if (*pos == '_' || (*pos >= 'A' && *pos <= 'Z')) {
- fn(node, 1, pos, arg);
- pos += 4;
- } else {
- printf("Invalid name!!!\n");
- }
- if (rv && *rv == NULL)
- *rv = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, rpos);
- return pos;
-}
-
-/*
* Conversion routines
*/
int64_t
@@ -2237,8 +2190,8 @@ aml_xconcatres(struct aml_value *a1, struct aml_value *a2)
aml_die("concatres: not buffers\n");
/* Walk a1, a2, get length minus end tags, concatenate buffers, add end tag */
- aml_parse_resource(a1->length, a1->v_buffer, aml_ccrlen, &l1);
- aml_parse_resource(a2->length, a2->v_buffer, aml_ccrlen, &l2);
+ aml_parse_resource(a1, aml_ccrlen, &l1);
+ aml_parse_resource(a2, aml_ccrlen, &l2);
/* Concatenate buffers, add end tag */
c = aml_allocvalue(AML_OBJTYPE_BUFFER, l1+l2+l3, NULL);
@@ -2510,11 +2463,12 @@ aml_xparsefieldlist(struct aml_scope *mscope, int opcode, int flags,
blen = 0;
break;
default: // 4-byte name, length
- mscope->pos = aml_xparsename(mscope->pos, mscope->node,
- ns_xcreate, &rv);
+ mscope->pos = aml_parsename(mscope->node, mscope->pos,
+ &rv, 1);
blen = aml_parselength(mscope);
aml_xcreatefield(rv, opcode, data, bpos, blen, index,
indexval, flags);
+ aml_xdelref(&rv, 0);
break;
}
bpos += blen;
@@ -2711,8 +2665,7 @@ aml_disasm(struct aml_scope *scope, int lvl,
ch = NULL;
switch (opcode) {
case AMLOP_NAMECHAR:
- scope->pos = aml_xparsename(scope->pos, scope->node,
- ns_xsearch, &rv);
+ scope->pos = aml_parsename(scope->node, scope->pos, &rv, 0);
if (rv->type == AML_OBJTYPE_NAMEREF) {
ch = "@@@";
aml_xdelref(&rv, "disasm");
@@ -2728,6 +2681,7 @@ aml_disasm(struct aml_scope *scope, int lvl,
}
strlcat(mch, ")", sizeof(mch));
}
+ aml_xdelref(&rv, "");
ch = mch;
break;
@@ -2963,8 +2917,10 @@ aml_disasm(struct aml_scope *scope, int lvl,
break;
case 'R':
/* Search name */
- scope->pos = aml_xparsename(scope->pos, scope->node,
- ns_xdis, &rv);
+ printf("%s", aml_getname(scope->pos));
+ scope->pos = aml_parsename(scope->node, scope->pos,
+ &rv, 0);
+ aml_xdelref(&rv, 0);
break;
case 'z':
case 'n':
@@ -2988,11 +2944,12 @@ aml_disasm(struct aml_scope *scope, int lvl,
} else if (*ms->pos == 0x01) {
ms->pos+=3;
} else {
- ms->pos = aml_xparsename(ms->pos,
- ms->node, ns_xcreate, &rv);
+ ms->pos = aml_parsename(ms->node,
+ ms->pos, &rv, 1);
aml_parselength(ms);
dbprintf(arg," %s\n",
aml_nodename(rv->node));
+ aml_xdelref(&rv, 0);
}
}
aml_xpopscope(ms);
@@ -3216,16 +3173,6 @@ aml_xeval(struct aml_scope *scope, struct aml_value *my_ret, int ret_type,
struct aml_value *
aml_xparsesimple(struct aml_scope *scope, char ch, struct aml_value *rv)
{
- if (ch == AML_ARG_CREATENAME) {
- scope->pos = aml_xparsename(scope->pos, scope->node,
- ns_xcreate, &rv);
- return rv;
- }
- else if (ch == AML_ARG_SEARCHNAME) {
- scope->pos = aml_xparsename(scope->pos, scope->node,
- ns_xsearch, &rv);
- return rv;
- }
if (rv == NULL)
rv = aml_allocvalue(0,0,NULL);
switch (ch) {
@@ -3429,17 +3376,12 @@ aml_xparse(struct aml_scope *scope, int ret_type, const char *stype)
(char)opcode, NULL);
break;
case AML_ARG_CREATENAME:
- rv = aml_xparsesimple(scope, *ch, NULL);
- if (rv->type != 0 && opcode != AMLOP_SCOPE)
- dnprintf(10, "%s value already exists %s\n",
- aml_nodename(rv->node),
- htab->mnem);
- aml_xaddref(rv, "Create Name");
+ scope->pos = aml_parsename(scope->node, scope->pos,
+ &rv, 1);
break;
case AML_ARG_SEARCHNAME:
- rv = aml_xparsesimple(scope, *ch, NULL);
- if (rv->type != AML_OBJTYPE_NAMEREF)
- aml_xaddref(rv, "Search Name");
+ scope->pos = aml_parsename(scope->node, scope->pos,
+ &rv, 0);
break;
case AML_ARG_BYTE:
case AML_ARG_WORD:
@@ -3803,12 +3745,7 @@ aml_xparse(struct aml_scope *scope, int ret_type, const char *stype)
/* Name: Nt */
rv = opargs[0];
aml_freevalue(rv);
- if (!strcmp(rv->node->name, "_HID") && opargs[1]->type == AML_OBJTYPE_INTEGER) {
- /* Shortcut for _HID: autoconvert to string */
- _aml_setvalue(rv, AML_OBJTYPE_STRING, -1, aml_eisaid(opargs[1]->v_integer));
- } else {
aml_copyvalue(rv, opargs[1]);
- }
break;
case AMLOP_ALIAS:
/* Alias: nN */
diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h
index 89bff04d762..0992193daf7 100644
--- a/sys/dev/acpi/dsdt.h
+++ b/sys/dev/acpi/dsdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.48 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: dsdt.h,v 1.49 2010/07/08 20:56:31 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -213,7 +213,7 @@ union acpi_resource {
3+(x)->hdr.length : 1+((x)->hdr.typecode & 0x7))
int aml_print_resource(union acpi_resource *, void *);
-int aml_parse_resource(int, uint8_t *,
+int aml_parse_resource(struct aml_value *,
int (*)(union acpi_resource *, void *), void *);
#define ACPI_E_NOERROR 0x00