Module Name: src
Committed By: jruoho
Date: Sat Aug 21 03:55:24 UTC 2010
Modified Files:
src/sys/arch/x86/acpi: acpi_cpu_md.c
src/sys/dev/acpi: acpi_cpu.h
Log Message:
Detect whether TSC is invariant, which may be the case on both new AMD and
Intel processors. The invariance means that TSC runs at a constant rate
during all ACPI state changes. If it is variant, skew may occur and TSC is
generally unsuitable for wall clock services. This is especially relevant
with C-states; with variant TSC, the whole counter may be stopped with states
larger than C1. All x86 CPUs before circa mid-2000s can be assumed to have a
variant time stamp counter.
To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/x86/acpi/acpi_cpu_md.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/acpi/acpi_cpu.h
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.21 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.22
--- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.21 Sat Aug 21 02:47:37 2010
+++ src/sys/arch/x86/acpi/acpi_cpu_md.c Sat Aug 21 03:55:24 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.21 2010/08/21 02:47:37 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.22 2010/08/21 03:55:24 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.21 2010/08/21 02:47:37 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.22 2010/08/21 03:55:24 jruoho Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -48,6 +48,8 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
+#define CPUID_INTEL_TSC __BIT(8)
+
#define MSR_0FH_CONTROL 0xc0010041 /* Family 0Fh (and K7). */
#define MSR_0FH_STATUS 0xc0010042
@@ -119,10 +121,11 @@
if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0)
val |= ACPICPU_FLAG_C_FFH;
+ val |= ACPICPU_FLAG_C_TSC;
+
switch (cpu_vendor) {
case CPUVENDOR_IDT:
- case CPUVENDOR_INTEL:
if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
val |= ACPICPU_FLAG_P_FFH;
@@ -130,7 +133,36 @@
if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0)
val |= ACPICPU_FLAG_T_FFH;
+ break;
+
+ case CPUVENDOR_INTEL:
+
val |= ACPICPU_FLAG_C_BM | ACPICPU_FLAG_C_ARB;
+
+ if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
+ val |= ACPICPU_FLAG_P_FFH;
+
+ if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0)
+ val |= ACPICPU_FLAG_T_FFH;
+
+ /*
+ * Detect whether TSC is invariant. If it is not,
+ * we keep the flag to note that TSC will not run
+ * 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.
+ */
+ x86_cpuid(0x80000000, regs);
+
+ if (regs[0] >= 0x80000007) {
+
+ x86_cpuid(0x80000007, regs);
+
+ if ((regs[3] & CPUID_INTEL_TSC) != 0)
+ val &= ~ACPICPU_FLAG_C_TSC;
+ }
+
break;
case CPUVENDOR_AMD:
@@ -142,11 +174,15 @@
switch (family) {
+ case 0x0f:
case 0x10:
case 0x11:
x86_cpuid(0x80000007, regs);
+ if ((regs[3] & CPUID_APM_TSC) != 0)
+ val &= ~ACPICPU_FLAG_C_TSC;
+
if ((regs[3] & CPUID_APM_HWP) != 0)
val |= ACPICPU_FLAG_P_FFH;
Index: src/sys/dev/acpi/acpi_cpu.h
diff -u src/sys/dev/acpi/acpi_cpu.h:1.20 src/sys/dev/acpi/acpi_cpu.h:1.21
--- src/sys/dev/acpi/acpi_cpu.h:1.20 Fri Aug 20 12:20:23 2010
+++ src/sys/dev/acpi/acpi_cpu.h Sat Aug 21 03:55:24 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.h,v 1.20 2010/08/20 12:20:23 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.21 2010/08/21 03:55:24 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <[email protected]>
@@ -100,15 +100,16 @@
#define ACPICPU_FLAG_C_BM __BIT(6) /* Bus master control */
#define ACPICPU_FLAG_C_BM_STS __BIT(7) /* Bus master check required */
#define ACPICPU_FLAG_C_ARB __BIT(8) /* Bus master arbitration */
-#define ACPICPU_FLAG_C_C1E __BIT(9) /* AMD C1E detected */
+#define ACPICPU_FLAG_C_TSC __BIT(9) /* TSC broken with > C1 */
+#define ACPICPU_FLAG_C_C1E __BIT(10) /* AMD C1E detected */
-#define ACPICPU_FLAG_P_FFH __BIT(10) /* Native P-states */
-#define ACPICPU_FLAG_P_HW __BIT(11) /* HW coordination supported */
-#define ACPICPU_FLAG_P_XPSS __BIT(12) /* Microsoft XPSS in use */
-#define ACPICPU_FLAG_P_TURBO __BIT(13) /* Turbo Boost / Turbo Core */
+#define ACPICPU_FLAG_P_FFH __BIT(11) /* Native P-states */
+#define ACPICPU_FLAG_P_HW __BIT(12) /* HW coordination supported */
+#define ACPICPU_FLAG_P_XPSS __BIT(13) /* Microsoft XPSS in use */
+#define ACPICPU_FLAG_P_TURBO __BIT(14) /* Turbo Boost / Turbo Core */
-#define ACPICPU_FLAG_T_FFH __BIT(14) /* Native throttling */
-#define ACPICPU_FLAG_T_FADT __BIT(15) /* Throttling with FADT */
+#define ACPICPU_FLAG_T_FFH __BIT(15) /* Native throttling */
+#define ACPICPU_FLAG_T_FADT __BIT(16) /* Throttling with FADT */
/*
* This is AML_RESOURCE_GENERIC_REGISTER,