diff options
-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. |