diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2008-08-13 15:46:22 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2008-08-13 15:46:22 +0000 |
commit | 77b098353d39395969c7f9f95b90d104a884ca8a (patch) | |
tree | e468ebd24157a14e712ea7daa362853c0b275e50 /sys/arch | |
parent | 7c0b6e385e1a3db611671cc0e443279a4d50f2b2 (diff) |
Disable the fantastics mis-feature on some newer Turion CPUs called C1E.
This "power saving" disables the apic when both cpu cores hit the hlt
instruction which kills our timer.
From FreeBSD.
(poked by kettenis)
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/lapic.c | 27 | ||||
-rw-r--r-- | sys/arch/i386/include/specialreg.h | 6 |
2 files changed, 31 insertions, 2 deletions
diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c index 5fcee282bd4..c193d26faac 100644 --- a/sys/arch/i386/i386/lapic.c +++ b/sys/arch/i386/i386/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.23 2008/06/26 05:42:10 ray Exp $ */ +/* $OpenBSD: lapic.c,v 1.24 2008/08/13 15:46:21 art Exp $ */ /* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */ /*- @@ -130,6 +130,31 @@ lapic_set_lvt(void) } #endif + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + /* + * Detect the presence of C1E capability mostly on latest + * dual-cores (or future) k8 family. This mis-feature renders + * the local APIC timer dead, so we disable it by reading + * the Interrupt Pending Message register and clearing both + * C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27). + * + * Reference: + * "BIOS and Kernel Developer's Guide for AMD NPT + * Family 0Fh Processors" + * #32559 revision 3.00 + */ + if ((cpu_id & 0x00000f00) == 0x00000f00 && + (cpu_id & 0x0fff0000) >= 0x00040000) { + uint64_t msr; + + msr = rdmsr(MSR_INT_PEN_MSG); + if (msr & (IPM_C1E_CMP_HLT|IPM_SMI_CMP_HLT)) { + msr &= ~(IPM_C1E_CMP_HLT|IPM_SMI_CMP_HLT); + wrmsr(MSR_INT_PEN_MSG, msr); + } + } + } + for (i = 0; i < mp_nintrs; i++) { mpi = &mp_intrs[i]; if (mpi->ioapic == NULL && (mpi->cpu_id == MPS_ALL_APICS diff --git a/sys/arch/i386/include/specialreg.h b/sys/arch/i386/include/specialreg.h index 3efc505c191..af65c0be9ea 100644 --- a/sys/arch/i386/include/specialreg.h +++ b/sys/arch/i386/include/specialreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: specialreg.h,v 1.33 2008/06/13 00:00:45 jsg Exp $ */ +/* $OpenBSD: specialreg.h,v 1.34 2008/08/13 15:46:21 art Exp $ */ /* $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $ */ /*- @@ -274,6 +274,10 @@ #define MSR_FSBASE 0xc0000100 /* 64bit offset for fs: */ #define MSR_GSBASE 0xc0000101 /* 64bit offset for gs: */ #define MSR_KERNELGSBASE 0xc0000102 /* storage for swapgs ins */ +#define MSR_INT_PEN_MSG 0xc0010055 /* Interrupt pending message */ + +#define IPM_C1E_CMP_HLT 0x10000000 +#define IPM_SMI_CMP_HLT 0x08000000 /* * These require a 'passcode' for access. See cpufunc.h. |