diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-02-23 19:56:45 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-02-23 19:56:45 +0000 |
commit | 673db3e23df44b85700b1c291bbb9e87d11d4b97 (patch) | |
tree | b4e8265aa5cef5d1955bd0ea30d852dc0cbf0348 | |
parent | f25a9d0f436e7b1263b5ab74a6b5c1ee8b33dfce (diff) |
Pre-parsing PCI address for opregion
ok marco@
-rw-r--r-- | sys/dev/acpi/amltypes.h | 3 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 126 |
2 files changed, 102 insertions, 27 deletions
diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h index 62c55a2b79b..68fb1c29717 100644 --- a/sys/dev/acpi/amltypes.h +++ b/sys/dev/acpi/amltypes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amltypes.h,v 1.13 2006/02/16 21:11:13 jordan Exp $ */ +/* $OpenBSD: amltypes.h,v 1.14 2006/02/23 19:56:44 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -302,7 +302,6 @@ struct aml_node u_int16_t opcode; u_int8_t *start; u_int8_t *end; - u_int8_t flag; const char *name; const char *mnem; diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index 4a6d778965c..3d7e623d7de 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.29 2006/02/22 19:29:24 jordan Exp $ */ +/* $OpenBSD: dsdt.c,v 1.30 2006/02/23 19:56:44 jordan Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -1403,30 +1403,29 @@ struct aml_value *aml_ederef(struct acpi_context *ctx, struct aml_value *val) } uint64_t -aml_get_pciaddr(struct acpi_context *, struct aml_node *, - uint64_t); +aml_get_pciaddr(struct acpi_context *, struct aml_node *); + uint64_t -aml_get_pciaddr(struct acpi_context *ctx, struct aml_node *node, - uint64_t ioaddr) -{ - struct aml_node *val; - uint8_t reg, bus, dev, fn; - - /* ioaddr on input = <reg> */ - bus = dev = fn = 0; - reg = ioaddr; - if ((val = aml_searchname(node, "_ADR")) != NULL) { - /* _ADR holds <dev>:<fn> */ - ioaddr = aml_eparseint(ctx, AML_ANYINT); - fn = ioaddr & 0xFFFF; - dev = ioaddr >> 16; - } - if ((val = aml_searchname(node, "_BBN")) != NULL) { +aml_get_pciaddr(struct acpi_context *ctx, struct aml_node *node) +{ + struct aml_node *pn; + uint8_t bus, dev, fn; + uint64_t ioaddr; + + if ((pn = aml_searchname(node, "_ADR")) == NULL) + return (0xFFFF); + + /* _ADR holds <dev>:<fn> */ + ioaddr = aml_val2int(ctx, pn->value); + fn = ioaddr & 0xFFFF; + dev = ioaddr >> 16; + bus = 0; + + if ((pn = aml_searchname(node, "_BBN")) != NULL) { /* _BBN holds <bus> */ - ioaddr = aml_eparseint(ctx, AML_ANYINT); - bus = ioaddr; + bus = aml_val2int(ctx, pn->value); } - return ACPI_PCI_ADDR(bus, dev, fn, reg); + return ACPI_PCI_ADDR(bus, dev, fn, 0); } struct aml_value * @@ -1470,9 +1469,6 @@ aml_efield(struct acpi_context *ctx, struct aml_value *e_fld, } ioaddr = e_rgn->v_opregion.iobase + aml_bytepos(e_fld->v_field.bitpos); - if (e_rgn->v_opregion.iospace == GAS_PCI_CFG_SPACE) { - ioaddr = aml_get_pciaddr(ctx, ctx->scope, ioaddr); - } blen = aml_bytelen(e_fld->v_field.bitlen); pb = acpi_os_allocmem(blen+8); // padded space @@ -2509,6 +2505,17 @@ aml_eparseval(struct acpi_context *ctx, int deref) rv->v_opregion.iobase = aml_eparseint(ctx, AML_ANYINT); rv->v_opregion.iolen = aml_eparseint(ctx, AML_ANYINT); + /* Special case: get PCI address */ + if (rv->v_opregion.iospace == GAS_PCI_CFG_SPACE) { + i1 = aml_get_pciaddr(ctx, ctx->scope); + if (i1 == 0xFFFF) + dnprintf(50, "aml_pciregion: no _ADR for %s!\n", + name); + else { + rv->v_opregion.iobase += i1; + dnprintf(50, "aml_pciregion: %llx\n", rv->v_opregion.iobase); + } + } aml_addvname(ctx, name, opc->opcode, rv); } break; @@ -2766,6 +2773,75 @@ aml_eval_object(struct acpi_softc *sc, struct aml_node *node, return 0; } +#if 0 +struct aml_value * +aml_evalnode(struct acpi_softc *sc, struct aml_node *node, + int argc, struct aml_value **argv) +{ + struct acpi_context *ctx; + struct aml_value *rv, **tmparg; + + /* This shouldn't happen... */ + if (node->value == NULL) + return NULL; + + /* Simple objects: return node value */ + dnprintf(10, "--- eval: (%s)\n", node->name); + switch (node->value->type) { + case AML_OBJTYPE_NAMEREF: + case AML_OBJTYPE_INTEGER: + case AML_OBJTYPE_STATICINT: + case AML_OBJTYPE_STRING: + case AML_OBJTYPE_BUFFER: + case AML_OBJTYPE_PACKAGE: + return node->value; + } + + /* Method or field context required */ + if ((ctx = acpi_alloccontext(sc, node, 0, NULL)) == NULL) + return NULL; + + /* XXX: ugh, fix this, set method argument pointer */ + tmparg = ctx->args; + if (argv != NULL) + ctx->args = argv; + + rv = NULL; + switch (node->value->type) { + case AML_OBJTYPE_BUFFERFIELD: + case AML_OBJTYPE_FIELDUNIT: + rv = aml_efield(ctx, node->value, NULL); + break; + case AML_OBJTYPE_METHOD: + ctx->pos = node->value->v_method.start; + rv = aml_eparselist(ctx, node->value->v_method.end); + break; + default: + dnprintf(1, "aml_evalnode: Unknown type (%d) for %s\n", + node->value->type, + node->name); + break; + } + ctx->args = tmparg; + aml_delchildren(node->value); + acpi_freecontext(ctx); + + return rv; +} + +struct aml_value * +aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name, + int argc, struct aml_value **argv) +{ + struct aml_value *node; + + if ((node = aml_searchname(parent, name)) != NULL) + return aml_evalnode(sc, node, argc, argv); + + return NULL; +} +#endif + void aml_shownode(struct aml_node *node) { |