Disable the fantastics mis-feature on some newer Turion CPUs called C1E.
authorart <art@openbsd.org>
Wed, 13 Aug 2008 15:46:21 +0000 (15:46 +0000)
committerart <art@openbsd.org>
Wed, 13 Aug 2008 15:46:21 +0000 (15:46 +0000)
This "power saving" disables the apic when both cpu cores hit the hlt
instruction which kills our timer.

From FreeBSD.

(poked by kettenis)

sys/arch/i386/i386/lapic.c
sys/arch/i386/include/specialreg.h

index 5fcee28..c193d26 100644 (file)
@@ -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
index 3efc505..af65c0b 100644 (file)
@@ -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 $       */
 
 /*-
 #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.