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 <jruoho...@iki.fi> @@ -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 <jruoho...@iki.fi> @@ -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,