Index: src/sys/amd64/amd64/local_apic.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/local_apic.c,v retrieving revision 1.37 diff -u -r1.37 local_apic.c --- src/sys/amd64/amd64/local_apic.c 20 Mar 2007 21:53:30 -0000 1.37 +++ src/sys/amd64/amd64/local_apic.c 24 Apr 2007 17:22:16 -0000 @@ -326,6 +326,29 @@ /* XXX: Error and thermal LVTs */ + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + /* + * Detect the presence of C1E capability mostly on latest + * dual-cores (or future) k8 family. This 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(0xc0010055); + if (msr & 0x18000000) + wrmsr(0xc0010055, msr & ~0x18000000ULL); + } + } + intr_restore(eflags); } Index: src/sys/i386/i386/local_apic.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/local_apic.c,v retrieving revision 1.39 diff -u -r1.39 local_apic.c --- src/sys/i386/i386/local_apic.c 20 Mar 2007 21:53:31 -0000 1.39 +++ src/sys/i386/i386/local_apic.c 24 Apr 2007 17:22:16 -0000 @@ -328,6 +328,29 @@ /* XXX: Error and thermal LVTs */ + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + /* + * Detect the presence of C1E capability mostly on latest + * dual-cores (or future) k8 family. This 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(0xc0010055); + if (msr & 0x18000000) + wrmsr(0xc0010055, msr & ~0x18000000ULL); + } + } + intr_restore(eflags); }