svn commit: r271082 - in head/sys: i386/i386 x86/x86

John Baldwin jhb at FreeBSD.org
Thu Sep 4 02:26:00 UTC 2014


Author: jhb
Date: Thu Sep  4 02:25:59 2014
New Revision: 271082
URL: http://svnweb.freebsd.org/changeset/base/271082

Log:
  - Move blacklists of broken TSCs out of the printcpuinfo() function
    and into the TSC probe routine.
  - Initialize cpu_exthigh once in finishidentcpu() which is called
    before printcpuinfo() (and matches the behavior on amd64).

Modified:
  head/sys/i386/i386/identcpu.c
  head/sys/x86/x86/tsc.c

Modified: head/sys/i386/i386/identcpu.c
==============================================================================
--- head/sys/i386/i386/identcpu.c	Thu Sep  4 02:14:57 2014	(r271081)
+++ head/sys/i386/i386/identcpu.c	Thu Sep  4 02:25:59 2014	(r271082)
@@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$");
 #define	IDENTBLUE_CYRIXM2	2
 
 static void identifycyrix(void);
-static void init_exthigh(void);
 static u_int find_cpu_vendor_id(void);
 static void print_AMD_info(void);
 static void print_INTEL_info(void);
@@ -147,28 +146,6 @@ static struct {
 #endif
 };
 
-static void
-init_exthigh(void)
-{
-	static int done = 0;
-	u_int regs[4];
-
-	if (done == 0) {
-		if (cpu_high > 0 &&
-		    (cpu_vendor_id == CPU_VENDOR_INTEL ||
-		    cpu_vendor_id == CPU_VENDOR_AMD ||
-		    cpu_vendor_id == CPU_VENDOR_TRANSMETA ||
-		    cpu_vendor_id == CPU_VENDOR_CENTAUR ||
-		    cpu_vendor_id == CPU_VENDOR_NSC)) {
-			do_cpuid(0x80000000, regs);
-			if (regs[0] >= 0x80000000)
-				cpu_exthigh = regs[0];
-		}
-
-		done = 1;
-	}
-}
-
 void
 printcpuinfo(void)
 {
@@ -180,7 +157,6 @@ printcpuinfo(void)
 	strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof (cpu_model));
 
 	/* Check for extended CPUID information and a processor name. */
-	init_exthigh();
 	if (cpu_exthigh >= 0x80000004) {
 		brand = cpu_brand;
 		for (i = 0x80000002; i < 0x80000005; i++) {
@@ -354,7 +330,6 @@ printcpuinfo(void)
 			break;
 		case 0x500:
 			strcat(cpu_model, "K5 model 0");
-			tsc_freq = 0;
 			break;
 		case 0x510:
 			strcat(cpu_model, "K5 model 1");
@@ -553,13 +528,6 @@ printcpuinfo(void)
 		switch (cpu_id & 0xff0) {
 		case 0x540:
 			strcpy(cpu_model, "IDT WinChip C6");
-			/*
-			 * http://www.centtech.com/c6_data_sheet.pdf
-			 *
-			 * I-12 RDTSC may return incoherent values in EDX:EAX
-			 * I-13 RDTSC hangs when certain event counters are used
-			 */
-			tsc_freq = 0;
 			break;
 		case 0x580:
 			strcpy(cpu_model, "IDT WinChip 2");
@@ -599,8 +567,6 @@ printcpuinfo(void)
 		case 0x540:
 			strcpy(cpu_model, "Geode SC1100");
 			cpu = CPU_GEODE1100;
-			if ((cpu_id & CPUID_STEPPING) == 0)
-				tsc_freq = 0;
 			break;
 		default:
 			strcpy(cpu_model, "Geode/NSC unknown");
@@ -1110,10 +1076,20 @@ finishidentcpu(void)
 		cpu_mon_max_size = regs[1] &  CPUID5_MON_MAX_SIZE;
 	}
 
+	if (cpu_high > 0 &&
+	    (cpu_vendor_id == CPU_VENDOR_INTEL ||
+	     cpu_vendor_id == CPU_VENDOR_AMD ||
+	     cpu_vendor_id == CPU_VENDOR_TRANSMETA ||
+	     cpu_vendor_id == CPU_VENDOR_CENTAUR ||
+	     cpu_vendor_id == CPU_VENDOR_NSC)) {
+		do_cpuid(0x80000000, regs);
+		if (regs[0] >= 0x80000000)
+			cpu_exthigh = 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) {
-		init_exthigh();
 		if (cpu_exthigh >= 0x80000001) {
 			do_cpuid(0x80000001, regs);
 			amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
@@ -1128,7 +1104,6 @@ finishidentcpu(void)
 			cpu_procinfo2 = regs[2];
 		}
 	} else if (cpu_vendor_id == CPU_VENDOR_CENTAUR) {
-		init_exthigh();
 		if (cpu_exthigh >= 0x80000001) {
 			do_cpuid(0x80000001, regs);
 			amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);

Modified: head/sys/x86/x86/tsc.c
==============================================================================
--- head/sys/x86/x86/tsc.c	Thu Sep  4 02:14:57 2014	(r271081)
+++ head/sys/x86/x86/tsc.c	Thu Sep  4 02:25:59 2014	(r271082)
@@ -324,6 +324,39 @@ init_TSC(void)
 	if ((cpu_feature & CPUID_TSC) == 0 || tsc_disabled)
 		return;
 
+#ifdef __i386__
+	/* The TSC is known to be broken on certain CPUs. */
+	switch (cpu_vendor_id) {
+	case CPU_VENDOR_AMD:
+		switch (cpu_id & 0xFF0) {
+		case 0x500:
+			/* K5 Model 0 */
+			return;
+		}
+		break;
+	case CPU_VENDOR_CENTAUR:
+		switch (cpu_id & 0xff0) {
+		case 0x540:
+			/*
+			 * http://www.centtech.com/c6_data_sheet.pdf
+			 *
+			 * I-12 RDTSC may return incoherent values in EDX:EAX
+			 * I-13 RDTSC hangs when certain event counters are used
+			 */
+			return;
+		}
+		break;
+	case CPU_VENDOR_NSC:
+		switch (cpu_id & 0xff0) {
+		case 0x540:
+			if ((cpu_id & CPUID_STEPPING) == 0)
+				return;
+			break;
+		}
+		break;
+	}
+#endif
+		
 	probe_tsc_freq();
 
 	/*


More information about the svn-src-all mailing list