Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Detect whether TSC is invariant, which may be the case o...
details: https://anonhg.NetBSD.org/src/rev/404d918a80c9
branches: trunk
changeset: 757234:404d918a80c9
user: jruoho <jruoho%NetBSD.org@localhost>
date: Sat Aug 21 03:55:24 2010 +0000
description:
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.
diffstat:
sys/arch/x86/acpi/acpi_cpu_md.c | 42 ++++++++++++++++++++++++++++++++++++++--
sys/dev/acpi/acpi_cpu.h | 17 ++++++++-------
2 files changed, 48 insertions(+), 11 deletions(-)
diffs (126 lines):
diff -r c8346be75d4d -r 404d918a80c9 sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c Sat Aug 21 03:06:37 2010 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c Sat Aug 21 03:55:24 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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;
diff -r c8346be75d4d -r 404d918a80c9 sys/dev/acpi/acpi_cpu.h
--- a/sys/dev/acpi/acpi_cpu.h Sat Aug 21 03:06:37 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.h Sat Aug 21 03:55:24 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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,
Home |
Main Index |
Thread Index |
Old Index