Module Name:    src
Committed By:   jruoho
Date:           Sat Aug 21 05:10:43 UTC 2010

Modified Files:
        src/sys/arch/x86/acpi: acpi_cpu_md.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/x86/acpi/acpi_cpu_md.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/arch/x86/acpi/acpi_cpu_md.c
diff -u src/sys/arch/x86/acpi/acpi_cpu_md.c:1.23 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.24
--- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.23	Sat Aug 21 04:36:29 2010
+++ src/sys/arch/x86/acpi/acpi_cpu_md.c	Sat Aug 21 05:10:43 2010
@@ -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 <[email protected]>
@@ -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)

Reply via email to