summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c4
-rw-r--r--sys/arch/i386/pci/pci_machdep.c4
-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
8 files changed, 303 insertions, 217 deletions
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index 5c36eb3d91e..f4d4d603692 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.34 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.35 2010/07/08 20:56:31 jordan Exp $ */
/* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
/*-
@@ -428,6 +428,6 @@ void
pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
{
#if NACPI > 0
- //acpi_pci_match(dev, pa);
+ acpi_pci_match(dev, pa);
#endif
}
diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c
index f75a68e06c7..d4a0336a104 100644
--- a/sys/arch/i386/pci/pci_machdep.c
+++ b/sys/arch/i386/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.52 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.53 2010/07/08 20:56:31 jordan Exp $ */
/* $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */
/*-
@@ -667,6 +667,6 @@ void
pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
{
#if NACPI > 0
- //acpi_pci_match(dev, pa);
+ acpi_pci_match(dev, pa);
#endif
}
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