Diff below has been in snaps for about a week now without ill effects. It fixes some issues with referencing named ACPI nodes from Packages. These references need to be resolved at runtime rather than when they're parsed such that they pick up the right values for those nodes which can be changed when for example _INI methods run.
The current approach is to replace these reference with a string that names the node in question. The problem with that is that packages can also contain normal strings. Which means that we need special code that depends on the context where the package is used. This diff takes a different approach by retaining a reference when parsing. Code that uses a package will need to resolve this reference but there is no ambiguiety anymore. ok? Index: dev/acpi/acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.392 diff -u -p -r1.392 acpi.c --- dev/acpi/acpi.c 5 Dec 2020 16:14:30 -0000 1.392 +++ dev/acpi/acpi.c 13 Dec 2020 16:16:35 -0000 @@ -2989,21 +2989,24 @@ acpi_getprop(struct aml_node *node, cons /* Check properties. */ for (i = 0; i < dsd.v_package[1]->length; i++) { struct aml_value *res = dsd.v_package[1]->v_package[i]; + struct aml_value *val; int len; if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 || res->v_package[0]->type != AML_OBJTYPE_STRING) continue; - len = res->v_package[1]->length; - switch (res->v_package[1]->type) { + val = res->v_package[1]; + if (val->type == AML_OBJTYPE_OBJREF) + val = val->v_objref.ref; + + len = val->length; + switch (val->type) { case AML_OBJTYPE_BUFFER: - memcpy(buf, res->v_package[1]->v_buffer, - min(len, buflen)); + memcpy(buf, val->v_buffer, min(len, buflen)); return len; case AML_OBJTYPE_STRING: - memcpy(buf, res->v_package[1]->v_string, - min(len, buflen)); + memcpy(buf, val->v_string, min(len, buflen)); return len; } } @@ -3040,14 +3043,22 @@ acpi_getpropint(struct aml_node *node, c /* Check properties. */ for (i = 0; i < dsd.v_package[1]->length; i++) { struct aml_value *res = dsd.v_package[1]->v_package[i]; + struct aml_value *val; if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 || - res->v_package[0]->type != AML_OBJTYPE_STRING || - res->v_package[1]->type != AML_OBJTYPE_INTEGER) + res->v_package[0]->type != AML_OBJTYPE_STRING) + continue; + + val = res->v_package[1]; + if (val->type == AML_OBJTYPE_OBJREF) + val = val->v_objref.ref; + + if (val->type != AML_OBJTYPE_INTEGER) continue; - if (strcmp(res->v_package[0]->v_string, prop) == 0) - return res->v_package[1]->v_integer; + if (strcmp(res->v_package[0]->v_string, prop) == 0 && + val->type == AML_OBJTYPE_INTEGER) + return val->v_integer; } return defval; @@ -3139,7 +3150,7 @@ const char *acpi_isa_hids[] = { void acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node) { - struct aml_value res; + struct aml_value res, *val; struct aml_node *dep; int i; @@ -3150,9 +3161,12 @@ acpi_attach_deps(struct acpi_softc *sc, return; for (i = 0; i < res.length; i++) { - if (res.v_package[i]->type != AML_OBJTYPE_STRING) + val = res.v_package[i]; + if (val->type == AML_OBJTYPE_OBJREF) + val = val->v_objref.ref; + if (val->type != AML_OBJTYPE_DEVICE) continue; - dep = aml_searchrel(node, res.v_package[i]->v_string); + dep = val->node; if (dep == NULL || dep->attached) continue; dep = aml_searchname(dep, "_HID"); Index: dev/acpi/acpiprt.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpiprt.c,v retrieving revision 1.49 diff -u -p -r1.49 acpiprt.c --- dev/acpi/acpiprt.c 11 Apr 2020 11:01:18 -0000 1.49 +++ dev/acpi/acpiprt.c 13 Dec 2020 16:16:35 -0000 @@ -272,14 +272,6 @@ acpiprt_prt_add(struct acpiprt_softc *sc } pp = v->v_package[2]; - if (pp->type == AML_OBJTYPE_STRING) { - node = aml_searchrel(sc->sc_devnode, pp->v_string); - if (node == NULL) { - printf("Invalid device\n"); - return; - } - pp = node->value; - } if (pp->type == AML_OBJTYPE_NAMEREF) { node = aml_searchrel(sc->sc_devnode, pp->v_nameref); if (node == NULL) { Index: dev/acpi/acpipwrres.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpipwrres.c,v retrieving revision 1.8 diff -u -p -r1.8 acpipwrres.c --- dev/acpi/acpipwrres.c 6 Apr 2020 00:01:08 -0000 1.8 +++ dev/acpi/acpipwrres.c 13 Dec 2020 16:16:35 -0000 @@ -291,10 +291,10 @@ acpipwrres_foundcons(struct aml_node *no for (; i < res.length; i++) { ref = res.v_package[i]; - if (ref->type == AML_OBJTYPE_STRING) { + if (ref->type == AML_OBJTYPE_NAMEREF) { struct aml_node *pnode; - pnode = aml_searchrel(&aml_root, ref->v_string); + pnode = aml_searchrel(&aml_root, ref->v_nameref); if (pnode == NULL) { DPRINTF(("%s: device %s not found\n", DEVNAME(sc), ref->v_string)); Index: dev/acpi/acpitz.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpitz.c,v retrieving revision 1.54 diff -u -p -r1.54 acpitz.c --- dev/acpi/acpitz.c 29 Jun 2018 17:39:18 -0000 1.54 +++ dev/acpi/acpitz.c 13 Dec 2020 16:16:35 -0000 @@ -304,9 +304,9 @@ acpitz_setfan(struct acpitz_softc *sc, i } for (y = 0; y < res1.length; y++) { ref = res1.v_package[y]; - if (ref->type == AML_OBJTYPE_STRING) { + if (ref->type == AML_OBJTYPE_NAMEREF) { node = aml_searchrel(sc->sc_devnode, - ref->v_string); + ref->v_nameref); if (node == NULL) { printf("%s: %s[%d.%d] _PR0" " not a valid device\n", Index: dev/acpi/atk0110.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/atk0110.c,v retrieving revision 1.15 diff -u -p -r1.15 atk0110.c --- dev/acpi/atk0110.c 29 Jun 2018 17:39:18 -0000 1.15 +++ dev/acpi/atk0110.c 13 Dec 2020 16:16:35 -0000 @@ -230,12 +230,12 @@ aibs_attach_sif(struct aibs_softc *sc, e } for (i = 0, v++; i < n; i++, v++) { - if(v[0]->type != AML_OBJTYPE_STRING) { - printf("%s: %s: %i: not a string: %i type\n", + if(v[0]->type != AML_OBJTYPE_NAMEREF) { + printf("%s: %s: %i: not a nameref: %i type\n", DEVNAME(sc), name, i, v[0]->type); continue; } - aibs_add_sensor(sc, v[0]->v_string); + aibs_add_sensor(sc, v[0]->v_nameref); } aml_freevalue(&res); Index: dev/acpi/dsdt.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v retrieving revision 1.256 diff -u -p -r1.256 dsdt.c --- dev/acpi/dsdt.c 27 Sep 2020 16:46:15 -0000 1.256 +++ dev/acpi/dsdt.c 13 Dec 2020 16:16:35 -0000 @@ -965,6 +965,7 @@ aml_copyvalue(struct aml_value *lhs, str lhs->v_mutex = rhs->v_mutex; break; case AML_OBJTYPE_POWERRSRC: + lhs->node = rhs->node; lhs->v_powerrsrc = rhs->v_powerrsrc; break; case AML_OBJTYPE_METHOD: @@ -980,6 +981,7 @@ aml_copyvalue(struct aml_value *lhs, str lhs->v_opregion = rhs->v_opregion; break; case AML_OBJTYPE_PROCESSOR: + lhs->node = rhs->node; lhs->v_processor = rhs->v_processor; break; case AML_OBJTYPE_NAMEREF: @@ -995,6 +997,8 @@ aml_copyvalue(struct aml_value *lhs, str aml_addref(lhs->v_objref.ref, ""); break; case AML_OBJTYPE_DEVICE: + case AML_OBJTYPE_THERMZONE: + lhs->node = rhs->node; break; default: printf("copyvalue: %x", rhs->type); @@ -1035,10 +1039,8 @@ aml_freevalue(struct aml_value *val) acpi_os_free(val->v_buffer); break; case AML_OBJTYPE_PACKAGE: - for (idx = 0; idx < val->length; idx++) { - aml_freevalue(val->v_package[idx]); - acpi_os_free(val->v_package[idx]); - } + for (idx = 0; idx < val->length; idx++) + aml_delref(&val->v_package[idx], ""); acpi_os_free(val->v_package); break; case AML_OBJTYPE_OBJREF: @@ -1471,11 +1473,11 @@ struct aml_defval { { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi }, /* Create default scopes */ - { "_GPE" }, - { "_PR_" }, - { "_SB_" }, - { "_TZ_" }, - { "_SI_" }, + { "_GPE", AML_OBJTYPE_DEVICE }, + { "_PR_", AML_OBJTYPE_DEVICE }, + { "_SB_", AML_OBJTYPE_DEVICE }, + { "_TZ_", AML_OBJTYPE_DEVICE }, + { "_SI_", AML_OBJTYPE_DEVICE }, { NULL } }; @@ -3875,17 +3877,13 @@ aml_parse(struct aml_scope *scope, int r case AMLOP_NAMECHAR: /* opargs[0] = named object (node != NULL), or nameref */ my_ret = opargs[0]; - if (scope->type == AMLOP_PACKAGE) { + if (scope->type == AMLOP_PACKAGE && my_ret->node) { /* Special case for package */ - if (my_ret->type == AML_OBJTYPE_NAMEREF) - my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1, - aml_getname(my_ret->v_nameref)); - else if (my_ret->node) - my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1, - aml_nodename(my_ret->node)); - break; - } - if (my_ret->type == AML_OBJTYPE_OBJREF) { + my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, + AMLOP_NAMECHAR, 0); + my_ret->v_objref.ref = opargs[0]; + aml_addref(my_ret, "package"); + } else if (my_ret->type == AML_OBJTYPE_OBJREF) { my_ret = my_ret->v_objref.ref; aml_addref(my_ret, "de-alias"); } @@ -4617,15 +4615,17 @@ acpi_getdevlist(struct acpi_devlist_head struct aml_value *pkg, int off) { struct acpi_devlist *dl; - struct aml_node *node; + struct aml_value *val; int idx; - for (idx=off; idx<pkg->length; idx++) { - node = aml_searchname(root, pkg->v_package[idx]->v_string); - if (node) { + for (idx = off; idx < pkg->length; idx++) { + val = pkg->v_package[idx]; + if (val->type == AML_OBJTYPE_OBJREF) + val = val->v_objref.ref; + if (val->node) { dl = acpi_os_malloc(sizeof(*dl)); if (dl) { - dl->dev_node = node; + dl->dev_node = val->node; TAILQ_INSERT_TAIL(list, dl, dev_link); } } @@ -4642,4 +4642,5 @@ acpi_freedevlist(struct acpi_devlist_hea acpi_os_free(dl); } } + #endif /* SMALL_KERNEL */