diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2010-07-08 20:56:32 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2010-07-08 20:56:32 +0000 |
commit | dd962e3f38e19806f683e5169e01253927248af4 (patch) | |
tree | 4c6b8d37f0da22f500938a26a6f8b52d304b3be4 /sys/dev/acpi | |
parent | 933022a0b195fe12232960cf6cc3e54fe63f7354 (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.c | 194 | ||||
-rw-r--r-- | sys/dev/acpi/acpidebug.c | 9 | ||||
-rw-r--r-- | sys/dev/acpi/acpiprt.c | 29 | ||||
-rw-r--r-- | sys/dev/acpi/amltypes.h | 25 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 251 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.h | 4 |
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 |