ACPI PCI mapping revert diff

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Jordan Hargrave
Date: Thursday, July 1, 2010 - 1:37 am

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 <tholo@sigmasoft.com>
   * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -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 <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
  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 <kettenis@openbsd.org>
   *
@@ -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 <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))
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 <jordan@openbsd.org>
   *
@@ -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 <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
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
ACPI PCI mapping revert diff, Jordan Hargrave, (Thu Jul 1, 1:37 am)
Re: ACPI PCI mapping revert diff, Stuart Henderson, (Thu Jul 1, 5:27 am)
Re: ACPI PCI mapping revert diff, jordan hargrave, (Thu Jul 1, 8:27 am)
Re: ACPI PCI mapping revert diff, Stuart Henderson, (Thu Jul 1, 9:09 am)