Module Name: src Committed By: jmcneill Date: Sat Aug 21 13:12:15 UTC 2010
Modified Files: src/sys/dev/acpi: acpi_cpu_pstate.c Log Message: - don't clobber the data found by _PSS if XPSS validation fails - XPSS spec says that Status{,Mask} and Control{,Mask} buffers are 8 bytes - use ACPI_GET64 macros instead of memcpy when reading from buffers This makes acpicpu work again on my VIA C7-M, whose firmware reports malformed XPSS packages but has a working _PSS To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/dev/acpi/acpi_cpu_pstate.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/acpi_cpu_pstate.c diff -u src/sys/dev/acpi/acpi_cpu_pstate.c:1.32 src/sys/dev/acpi/acpi_cpu_pstate.c:1.33 --- src/sys/dev/acpi/acpi_cpu_pstate.c:1.32 Fri Aug 20 06:36:40 2010 +++ src/sys/dev/acpi/acpi_cpu_pstate.c Sat Aug 21 13:12:15 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_pstate.c,v 1.32 2010/08/20 06:36:40 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_pstate.c,v 1.33 2010/08/21 13:12:15 jmcneill Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.32 2010/08/20 06:36:40 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.33 2010/08/21 13:12:15 jmcneill Exp $"); #include <sys/param.h> #include <sys/evcnt.h> @@ -81,16 +81,10 @@ * systems where _PDC or _OSC may be used. */ if (sc->sc_cap == 0) { - rv = acpicpu_pstate_xpss(sc); if (ACPI_SUCCESS(rv)) sc->sc_flags |= ACPICPU_FLAG_P_XPSS; - - if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) { - str = "XPSS"; - goto fail; - } } rv = acpicpu_pstate_pct(sc); @@ -493,11 +487,11 @@ acpicpu_pstate_xpss(struct acpicpu_softc *sc) { static const size_t size = sizeof(struct acpicpu_pstate); - struct acpicpu_pstate *ps; + struct acpicpu_pstate *ps, *pstate = NULL; ACPI_OBJECT *obj; ACPI_BUFFER buf; ACPI_STATUS rv; - uint32_t count; + uint32_t count, pstate_count; uint32_t i, j; rv = acpi_eval_struct(sc->sc_node->ad_handle, "XPSS", &buf); @@ -512,7 +506,7 @@ goto out; } - count = obj->Package.Count; + pstate_count = count = obj->Package.Count; if (count == 0) { rv = AE_NOT_EXIST; @@ -524,21 +518,16 @@ goto out; } - if (sc->sc_pstate != NULL) - kmem_free(sc->sc_pstate, sc->sc_pstate_count * size); - - sc->sc_pstate = kmem_zalloc(count * size, KM_SLEEP); + pstate = kmem_zalloc(count * size, KM_SLEEP); - if (sc->sc_pstate == NULL) { + if (pstate == NULL) { rv = AE_NO_MEMORY; goto out; } - sc->sc_pstate_count = count; + for (count = i = 0; i < pstate_count; i++) { - for (count = i = 0; i < sc->sc_pstate_count; i++) { - - ps = &sc->sc_pstate[i]; + ps = &pstate[i]; rv = acpicpu_pstate_xpss_add(ps, &obj->Package.Elements[i]); if (ACPI_FAILURE(rv)) { @@ -548,7 +537,7 @@ for (j = 0; j < i; j++) { - if (ps->ps_freq >= sc->sc_pstate[j].ps_freq) { + if (ps->ps_freq >= pstate[j].ps_freq) { ps->ps_freq = 0; break; } @@ -558,7 +547,16 @@ count++; } - rv = (count != 0) ? AE_OK : AE_NOT_EXIST; + if (count > 0) { + if (sc->sc_pstate != NULL) + kmem_free(sc->sc_pstate, sc->sc_pstate_count * size); + sc->sc_pstate = pstate; + sc->sc_pstate_count = pstate_count; + rv = AE_OK; + } else { + kmem_free(pstate, pstate_count * size); + rv = AE_NOT_EXIST; + } out: if (buf.Pointer != NULL) @@ -570,7 +568,6 @@ static ACPI_STATUS acpicpu_pstate_xpss_add(struct acpicpu_pstate *ps, ACPI_OBJECT *obj) { - static const size_t size = sizeof(uint64_t); ACPI_OBJECT *elm; int i; @@ -596,7 +593,7 @@ if (elm[i].Type != ACPI_TYPE_BUFFER) return AE_TYPE; - if (elm[i].Buffer.Length > size) + if (elm[i].Buffer.Length != 8) return AE_LIMIT; } @@ -608,11 +605,10 @@ if (ps->ps_freq == 0 || ps->ps_freq > 9999) return AE_BAD_DECIMAL_CONSTANT; - (void)memcpy(&ps->ps_control, elm[4].Buffer.Pointer, size); - (void)memcpy(&ps->ps_status, elm[5].Buffer.Pointer, size); - - (void)memcpy(&ps->ps_control_mask, elm[6].Buffer.Pointer, size); - (void)memcpy(&ps->ps_status_mask, elm[7].Buffer.Pointer, size); + ps->ps_control = ACPI_GET64(elm[4].Buffer.Pointer); + ps->ps_status = ACPI_GET64(elm[5].Buffer.Pointer); + ps->ps_control_mask = ACPI_GET64(elm[6].Buffer.Pointer); + ps->ps_status_mask = ACPI_GET64(elm[7].Buffer.Pointer); /* * The latency is often defined to be