So found the problem; on the R210 the AML code CHANGES the _HID
for the PCI Root Bus depending
on the _OSI OS running.. UGH
I'd had code in dsdt.c for ages that converted the _HID integer value to
its PNP-string equivalent at create time. However with the dynamic _HID
changing code in the AML, the store tried to convert an integer value to a
string, eg. storing integer HID 0x12345 became "12345" instead
of PNP0A03.
I took out the default _HID conversion code in dsdt.c and reverted back to
the original code, this does work on the R210 but would like to test on
other systems as well.
The old acpiprt code worked because it searched for ANY _HID value.. the
new code explicitly looks for PNP0A03 or PNP0A08.
@tech, please test this diff and report any issues with panic
Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.168
diff -u -p -u -p -r1.168 acpi.c
--- acpi.c 1 Jul 2010 06:29:32 -0000 1.168
+++ acpi.c 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.168 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: acpi.c,v 1.167 2010/07/01 01:39:39 jordan Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <[email protected]>
* Copyright (c) 2005 Jordan Hargrave <[email protected]>
@@ -18,6 +18,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/buf.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/fcntl.h>
@@ -41,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>
@@ -66,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 *);
@@ -94,12 +101,15 @@ int acpi_foundide(struct aml_node *node,
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;
@@ -492,6 +502,150 @@ acpi_match(struct device *parent, void *
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);
+
+ if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val))
+ pci->seg = val;
+ if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val))
+ pci->bus = val;
+ else if (!aml_evalname(sc, node, "_CRS", 0, NULL,
&res)) {
+ aml_parse_resource(&res, acpi_getminbus,
+ &pci->bus);
+ }
+ 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)
{
@@ -709,6 +863,9 @@ acpi_attach(struct device *parent, struc
/* 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);
@@ -2105,10 +2262,12 @@ acpi_prepare_sleep_state(struct acpi_sof
acpi_susp_resume_gpewalk(sc, state, 1);
fail:
+
#if NWSDISPLAY > 0
if (error)
wsdisplay_resume();
#endif /* NWSDISPLAY > 0 */
+
return (error);
}
@@ -2289,31 +2448,6 @@ acpi_foundec(struct aml_node *node, void
aml_freevalue(&res);
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);
}
int
Index: acpidebug.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpidebug.c,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 acpidebug.c
--- acpidebug.c 1 Jul 2010 06:29:32 -0000 1.25
+++ acpidebug.c 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidebug.c,v 1.25 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: acpidebug.c,v 1.24 2010/06/27 21:04:22 jordan Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <[email protected]>
*
@@ -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
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
Index: acpiprt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpiprt.c,v
retrieving revision 1.38
diff -u -p -u -p -r1.38 acpiprt.c
--- acpiprt.c 1 Jul 2010 06:29:32 -0000 1.38
+++ acpiprt.c 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiprt.c,v 1.38 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: acpiprt.c,v 1.37 2010/07/01 01:39:39 jordan Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis <[email protected]>
*
@@ -56,7 +56,6 @@ SIMPLEQ_HEAD(, acpiprt_map) acpiprt_map_
int acpiprt_match(struct device *, void *, void *);
void acpiprt_attach(struct device *, struct device *, void *);
int acpiprt_getirq(union acpi_resource *crs, void *arg);
-int acpiprt_getminbus(union acpi_resource *, void *);
int acpiprt_chooseirq(union acpi_resource *, void *);
struct acpiprt_softc {
@@ -279,25 +278,20 @@ acpiprt_prt_add(struct acpiprt_softc *sc
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);
}
if ((p = malloc(sizeof(*p), M_ACPI, M_NOWAIT)) == NULL)
return;
p->bus = sc->sc_bus;
- p->dev = ACPI_PCI_DEV(addr << 16);
+ p->dev = ACPI_ADR_PCIDEV(addr);
p->pin = pin;
p->irq = irq;
p->sc = sc;
@@ -365,85 +359,11 @@ acpiprt_prt_add(struct acpiprt_softc *sc
}
int
-acpiprt_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
acpiprt_getpcibus(struct acpiprt_softc *sc, struct aml_node *node)
{
- struct aml_node *parent = node->parent;
- struct aml_value res;
- pci_chipset_tag_t pc = NULL;
- pcitag_t tag;
- pcireg_t reg;
- int bus, dev, func, rv;
- int64_t ires;
-
- if (parent == NULL)
- return 0;
-
- /*
- * If our parent is a a bridge, it might have an address descriptor
- * that tells us our bus number.
- */
- 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_freevalue(&res);
- if (rv != -1)
- return rv;
- }
-
- /*
- * If our parent is the root of the bus, it should specify the
- * base bus number.
- */
- if (aml_evalinteger(sc->sc_acpi, parent, "_BBN.", 0, NULL, &ires) == 0)
{
- return (ires);
- }
-
- /*
- * If our parent is a PCI-PCI bridge, get our bus number from its
- * PCI config space.
- */
- if (aml_evalinteger(sc->sc_acpi, parent, "_ADR.", 0, NULL, &ires) == 0)
{
- bus = acpiprt_getpcibus(sc, parent);
- dev = ACPI_PCI_DEV(ires << 16);
- func = ACPI_PCI_FN(ires << 16);
-
- /*
- * Some systems return 255 as the device number for
- * devices that are not really there.
- */
- if (dev >= pci_bus_maxdevs(pc, bus))
- return (-1);
-
- tag = pci_make_tag(pc, bus, dev, func);
-
- /* Check whether the device is really there. */
- reg = pci_conf_read(pc, tag, PCI_ID_REG);
- if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID)
- return (-1);
-
- /* Fetch bus number from PCI config space. */
- 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);
- return (PPB_BUSINFO_SECONDARY(reg));
- }
- }
- return (0);
+ /* Check if parent device has PCI mapping */
+ return (node->parent && node->parent->pci) ?
+ node->parent->pci->sub : -1;
}
void
@@ -484,7 +404,7 @@ acpiprt_route_interrupt(int bus, int dev
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) {
Index: amltypes.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 amltypes.h
--- amltypes.h 1 Jul 2010 06:29:32 -0000 1.36
+++ amltypes.h 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: amltypes.h,v 1.36 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: amltypes.h,v 1.35 2010/06/29 22:08:29 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <[email protected]>
*
@@ -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))
Index: dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.164
diff -u -p -u -p -r1.164 dsdt.c
--- dsdt.c 1 Jul 2010 06:29:32 -0000 1.164
+++ dsdt.c 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.164 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: dsdt.c,v 1.163 2010/07/01 01:39:39 jordan Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <[email protected]>
*
@@ -96,12 +96,6 @@ void _acpi_os_free(void *, const char
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, uint
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
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, con
}
/* 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, con
/*
* @@@: 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,14 +1628,16 @@ 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)
@@ -1973,92 +2012,6 @@ aml_xmatch(struct aml_value *pkg, int in
}
/*
- * 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, str
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 *ms
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
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
}
strlcat(mch, ")", sizeof(mch));
}
+ aml_xdelref(&rv, "");
ch = mch;
break;
@@ -2963,8 +2917,10 @@ aml_disasm(struct aml_scope *scope, int
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
} 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, struc
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
(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
/* 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]);
- }
+ aml_copyvalue(rv, opargs[1]);
break;
case AMLOP_ALIAS:
/* Alias: nN */
Index: dsdt.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.h,v
retrieving revision 1.48
diff -u -p -u -p -r1.48 dsdt.h
--- dsdt.h 1 Jul 2010 06:29:32 -0000 1.48
+++ dsdt.h 1 Jul 2010 09:02:54 -0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.48 2010/07/01 06:29:32 jordan Exp $ */
+/* $OpenBSD: dsdt.h,v 1.47 2010/07/01 01:39:39 jordan Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <[email protected]>
*
@@ -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