svn commit: r191788 - in head/sys: amd64/amd64 i386/i386

Jung-uk Kim jkim at FreeBSD.org
Mon May 4 18:05:28 UTC 2009


Author: jkim
Date: Mon May  4 18:05:27 2009
New Revision: 191788
URL: http://svn.freebsd.org/changeset/base/191788

Log:
  Unlock the largest standard CPUID on Intel CPUs for both amd64 and i386 and
  fix SMP topology detection.  On i386, we extend it to cover Core, Core 2,
  and Core i7 processors, not just Pentium 4 family, and move it to better
  place.  On amd64, all supported Intel CPUs should have this MSR.

Modified:
  head/sys/amd64/amd64/identcpu.c
  head/sys/i386/i386/identcpu.c

Modified: head/sys/amd64/amd64/identcpu.c
==============================================================================
--- head/sys/amd64/amd64/identcpu.c	Mon May  4 17:30:20 2009	(r191787)
+++ head/sys/amd64/amd64/identcpu.c	Mon May  4 18:05:27 2009	(r191788)
@@ -472,6 +472,22 @@ identify_cpu(void)
 	cpu_feature = regs[3];
 	cpu_feature2 = regs[2];
 
+	/*
+	 * Clear "Limit CPUID Maxval" bit and get the largest standard CPUID
+	 * function number again if it is set from BIOS.  It is necessary
+	 * for probing correct CPU topology later.
+	 * XXX This is only done on the BSP package.
+	 */
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high > 0 && cpu_high < 4) {
+		uint64_t msr;
+		msr = rdmsr(MSR_IA32_MISC_ENABLE);
+		if ((msr & 0x400000ULL) != 0) {
+			wrmsr(MSR_IA32_MISC_ENABLE, msr & ~0x400000ULL);
+			do_cpuid(0, regs);
+			cpu_high = regs[0];
+		}
+	}
+
 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
 	    cpu_vendor_id == CPU_VENDOR_AMD ||
 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {

Modified: head/sys/i386/i386/identcpu.c
==============================================================================
--- head/sys/i386/i386/identcpu.c	Mon May  4 17:30:20 2009	(r191787)
+++ head/sys/i386/i386/identcpu.c	Mon May  4 18:05:27 2009	(r191788)
@@ -209,7 +209,6 @@ printcpuinfo(void)
 	if (cpu_vendor_id == CPU_VENDOR_INTEL) {
 		if ((cpu_id & 0xf00) > 0x300) {
 			u_int brand_index;
-			u_int model;
 
 			cpu_model[0] = '\0';
 
@@ -322,16 +321,6 @@ printcpuinfo(void)
 			case 0xf00:
 				strcat(cpu_model, "Pentium 4");
 				cpu = CPU_P4;
-				model = (cpu_id & 0x0f0) >> 4;
-				if (model == 3 || model == 4 || model == 6) {
-					uint64_t tmp;
-
-					tmp = rdmsr(MSR_IA32_MISC_ENABLE);
-					wrmsr(MSR_IA32_MISC_ENABLE,
-					      tmp & ~(1LL << 22));
-					do_cpuid(0, regs);
-					cpu_high = regs[0];
-				}
 				break;
 			default:
 				strcat(cpu_model, "unknown");
@@ -1110,6 +1099,24 @@ finishidentcpu(void)
 
 	cpu_vendor_id = find_cpu_vendor_id();
 
+	/*
+	 * Clear "Limit CPUID Maxval" bit and get the largest standard CPUID
+	 * function number again if it is set from BIOS.  It is necessary
+	 * for probing correct CPU topology later.
+	 * XXX This is only done on the BSP package.
+	 */
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high > 0 && cpu_high < 4 &&
+	    ((I386_CPU_FAMILY(cpu_id) == 0xf && I386_CPU_MODEL(cpu_id) >= 0x3) ||
+	    (I386_CPU_FAMILY(cpu_id) == 0x6 && I386_CPU_MODEL(cpu_id) >= 0xe))) {
+		uint64_t msr;
+		msr = rdmsr(MSR_IA32_MISC_ENABLE);
+		if ((msr & 0x400000ULL) != 0) {
+			wrmsr(MSR_IA32_MISC_ENABLE, msr & ~0x400000ULL);
+			do_cpuid(0, regs);
+			cpu_high = regs[0];
+		}
+	}
+
 	/* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
 	    cpu_vendor_id == CPU_VENDOR_AMD) {


More information about the svn-src-all mailing list