Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/acpi Add a quirk for Turbo Boost.



details:   https://anonhg.NetBSD.org/src/rev/61a304fab0bf
branches:  trunk
changeset: 757236:61a304fab0bf
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Sat Aug 21 05:10:43 2010 +0000

description:
Add a quirk for Turbo Boost.

It was observed that at least Sverre Froyen's ThinkPad T500 reports values
that do not match readings from the IA32_PERF_STATUS register. This only
applied to the P0-state. Thus, for now, skip the status check if Turbo
Boost has been detected and the requested state is P0.

This needs to be revisited once Turbo Boost actually works in NetBSD. It is
unclear whether this is a BIOS flaw or not; these values may well be what we
get from IA32_PERF_STATUS once the CPU actually uses the +133.33 MHz boost.

diffstat:

 sys/arch/x86/acpi/acpi_cpu_md.c |  43 +++++++++++++++++++++++++++++++++-------
 1 files changed, 35 insertions(+), 8 deletions(-)

diffs (99 lines):

diff -r 25c0cabccedf -r 61a304fab0bf sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c   Sat Aug 21 04:36:29 2010 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c   Sat Aug 21 05:10:43 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.23 2010/08/21 04:36:29 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.24 2010/08/21 05:10:43 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.23 2010/08/21 04:36:29 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.24 2010/08/21 05:10:43 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -156,8 +156,8 @@
                        if ((regs[2] & __BIT(0)) != 0)        /* ECX.06[0] */
                                val |= ACPICPU_FLAG_P_HW;
 
-                       if ((regs[0] & __BIT(1)) != 0)
-                               val |= ACPICPU_FLAG_P_TURBO;  /* EAX.06[1] */
+                       if ((regs[0] & __BIT(1)) != 0)        /* EAX.06[1] */
+                               val |= ACPICPU_FLAG_P_TURBO;
                }
 
                /*
@@ -166,7 +166,7 @@
                 * at constant rate. Depending on the CPU, this may
                 * affect P- and T-state changes, but especially
                 * relevant are C-states; with variant TSC, states
-                * larger than C1 will completely stop the timer.
+                * larger than C1 may completely stop the counter.
                 */
                x86_cpuid(0x80000000, regs);
 
@@ -415,6 +415,30 @@
                i++;
        }
 
+       /*
+        * When the state is P0 and Turbo Boost has been
+        * detected, we need to skip the status check as
+        * BIOS may not report right comparison values for
+        * the IA32_PERF_STATUS MSR. Note that this is a
+        * BIOS issue, and that for instance AMD documents
+        * clearly state that vendors should never expose
+        * "turbo" in the ACPI objects (namely, in _PSS).
+        *
+        * For discussion, see:
+        *
+        *      Intel Corporation: Intel Turbo Boost Technology
+        *      in Intel Core(tm) Microarchitectures (Nehalem)
+        *      Based Processors. White Paper, November 2008.
+        */
+       if (cpu_vendor != CPUVENDOR_INTEL)
+               return 0;
+
+       if ((sc->sc_flags & ACPICPU_FLAG_P_TURBO) == 0)
+               return 0;
+
+       if (sc->sc_pstate[1].ps_freq + 1 == sc->sc_pstate[0].ps_freq)
+               sc->sc_pstate[0].ps_flags |= ACPICPU_FLAG_P_TURBO;
+
        return 0;
 }
 
@@ -471,7 +495,7 @@
        msr.msr_type  = ps->ps_control_addr;
        msr.msr_value = ps->ps_control;
 
-       if (ps->ps_control_mask != 0) {
+       if (__predict_true(ps->ps_control_mask != 0)) {
                msr.msr_mask = ps->ps_control_mask;
                msr.msr_read = true;
        }
@@ -479,7 +503,10 @@
        xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL);
        xc_wait(xc);
 
-       if (ps->ps_status_addr == 0)
+       if (__predict_false(ps->ps_status_addr == 0))
+               return 0;
+
+       if ((ps->ps_flags & ACPICPU_FLAG_P_TURBO) != 0)
                return 0;
 
        xc = xc_broadcast(0, (xcfunc_t)acpicpu_md_pstate_status, ps, &rv);
@@ -499,7 +526,7 @@
 
                val = rdmsr(ps->ps_status_addr);
 
-               if (ps->ps_status_mask != 0)
+               if (__predict_true(ps->ps_status_mask != 0))
                        val = val & ps->ps_status_mask;
 
                if (val == ps->ps_status)



Home | Main Index | Thread Index | Old Index