Module Name: src Committed By: jruoho Date: Sun Jul 18 13:09:05 UTC 2010
Modified Files: src/sys/dev/acpi: acpi_cpu_cstate.c Log Message: The first bug: do not error out if the latency values supplied in _CST are larger than the upper limit constants. Only sanity check against these defaults when operating with FADT. This is also noted in a fine print of the specification (ACPI 4.0, p. 314): "[...] The worst-case latency to enter and exit the C State (in microseconds). There are no latency restrictions." To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/acpi/acpi_cpu_cstate.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_cstate.c diff -u src/sys/dev/acpi/acpi_cpu_cstate.c:1.2 src/sys/dev/acpi/acpi_cpu_cstate.c:1.3 --- src/sys/dev/acpi/acpi_cpu_cstate.c:1.2 Sun Jul 18 09:39:45 2010 +++ src/sys/dev/acpi/acpi_cpu_cstate.c Sun Jul 18 13:09:04 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_cstate.c,v 1.2 2010/07/18 09:39:45 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_cstate.c,v 1.3 2010/07/18 13:09:04 jruoho 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_cstate.c,v 1.2 2010/07/18 09:39:45 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.3 2010/07/18 13:09:04 jruoho Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -292,6 +292,9 @@ (void)memset(sc->sc_cstate, 0, sizeof(*sc->sc_cstate) * ACPI_C_STATE_COUNT); + CTASSERT(ACPI_STATE_C0 == 0 && ACPI_STATE_C1 == 1); + CTASSERT(ACPI_STATE_C2 == 2 && ACPI_STATE_C3 == 3); + for (count = 0, i = 1; i <= n; i++) { elm = &obj->Package.Elements[i]; @@ -324,7 +327,6 @@ ACPI_STATUS rv = AE_OK; ACPI_OBJECT *obj; uint32_t type; - int i; (void)memset(&state, 0, sizeof(*cs)); @@ -350,6 +352,11 @@ type = obj->Integer.Value; + if (type < ACPI_STATE_C1 || type > ACPI_STATE_C3) { + rv = AE_TYPE; + goto out; + } + /* * Latency. */ @@ -408,6 +415,19 @@ goto out; } + /* + * Check only that the address is in the mapped space. + * Systems are allowed to change it when operating + * with _CST (see ACPI 4.0, pp. 94-95). For instance, + * the offset of P_LVL3 may change depending on whether + * acpiacad(4) is connected or disconnected. + */ + if (reg->reg_addr > ao->ao_pblkaddr + ao->ao_pblklen) { + rv = AE_BAD_ADDRESS; + goto out; + } + + state.cs_addr = reg->reg_addr; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: @@ -437,58 +457,7 @@ goto out; } - state.cs_addr = reg->reg_addr; - - CTASSERT(ACPICPU_C_C2_LATENCY_MAX == 100); - CTASSERT(ACPICPU_C_C3_LATENCY_MAX == 1000); - - CTASSERT(ACPI_STATE_C0 == 0 && ACPI_STATE_C1 == 1); - CTASSERT(ACPI_STATE_C2 == 2 && ACPI_STATE_C3 == 3); - - switch (type) { - - case ACPI_STATE_C1: - i = 1; - break; - - case ACPI_STATE_C2: - - if (state.cs_latency > ACPICPU_C_C2_LATENCY_MAX) { - rv = AE_BAD_VALUE; - goto out; - } - - i = 2; - break; - - case ACPI_STATE_C3: - - if (state.cs_latency > ACPICPU_C_C3_LATENCY_MAX) { - rv = AE_BAD_VALUE; - goto out; - } - - i = 3; - break; - - default: - rv = AE_TYPE; - goto out; - } - - /* - * Check only that the address is in the mapped space. - * Systems are allowed to change it when operating - * with _CST (see ACPI 4.0, pp. 94-95). For instance, - * the offset of P_LVL3 may change depending on whether - * acpiacad(4) is connected or disconnected. - */ - if (state.cs_addr > ao->ao_pblkaddr + ao->ao_pblklen) { - rv = AE_BAD_ADDRESS; - goto out; - } - - if (cs[i].cs_method != 0) { + if (cs[type].cs_method != 0) { rv = AE_ALREADY_EXISTS; goto out; } @@ -500,16 +469,16 @@ * haphazardly, depending on how long the system slept. * For now, we disable the C3 state unconditionally. */ - if (i == ACPI_STATE_C3) { + if (type == ACPI_STATE_C3) { sc->sc_flags |= ACPICPU_FLAG_C_NOC3; goto out; } #endif - cs[i].cs_addr = state.cs_addr; - cs[i].cs_power = state.cs_power; - cs[i].cs_latency = state.cs_latency; - cs[i].cs_method = state.cs_method; + cs[type].cs_addr = state.cs_addr; + cs[type].cs_power = state.cs_power; + cs[type].cs_latency = state.cs_latency; + cs[type].cs_method = state.cs_method; out: if (ACPI_FAILURE(rv)) @@ -627,6 +596,9 @@ if (sc->sc_object.ao_pblklen < 6) cs[ACPI_STATE_C3].cs_method = 0; + CTASSERT(ACPICPU_C_C2_LATENCY_MAX == 100); + CTASSERT(ACPICPU_C_C3_LATENCY_MAX == 1000); + if (AcpiGbl_FADT.C2Latency > ACPICPU_C_C2_LATENCY_MAX) cs[ACPI_STATE_C2].cs_method = 0;