Subject: port-amd64/35302: identifycpu() use wrong cpuid features flags for Intel processors
To: None <port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <njoly@pasteur.fr>
List: netbsd-bugs
Date: 12/21/2006 00:55:01
>Number:         35302
>Category:       port-amd64
>Synopsis:       identifycpu() use wrong cpuid features flags for Intel processors
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-amd64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 21 00:55:01 +0000 2006
>Originator:     Nicolas Joly
>Release:        NetBSD 4.99.6
>Organization:
Institut Pasteur
>Environment:
-current NetBSD/amd64
Architecture: x86_64
Machine: amd64
>Description:
I just noticed that amd64 identifycpu() function use CPUID_EXT_FLAGS{2,3}
strings to display CPUs features. This is incorrect for Intel processors,
which should use CPUID_FLAGS{2,3} instead.

cpu0 at mainbus0: apid 0 (boot processor)
cpu0:               Intel(R) Pentium(R) D CPU 3.00GHz, 3000.21 MHz
cpu0: features: bffbfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR>
cpu0: features: bffbfbff<PGE,MCA,CMOV,PAT,PSE36,MPC,NOX,B21,MMXX,MMX>
cpu0: features: bffbfbff<FXSR,SSE,SSE2,B27,HTT,LONG,3DNOW>
cpu0: L2 cache 2 MB 64B/line 8-way
cpu0: calibrating local timer
cpu0: apic clock running at 199 MHz
cpu0: 64 page colors

>How-To-Repeat:
Boot NetBSD/amd64 on a machine with an Intel procssor, and check CPU features
display.
>Fix:
Index: sys/arch/amd64/amd64/identcpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/identcpu.c,v
retrieving revision 1.7
diff -u -r1.7 identcpu.c
--- sys/arch/amd64/amd64/identcpu.c	4 Oct 2006 13:18:10 -0000	1.7
+++ sys/arch/amd64/amd64/identcpu.c	20 Dec 2006 23:25:56 -0000
@@ -58,6 +58,7 @@
 	u_int32_t dummy, val;
 	char buf[512];
 	u_int32_t brand[12];
+	const char *feature_str[3];
 
 	CPUID(1, ci->ci_signature, val, dummy, ci->ci_feature_flags);
 	CPUID(0x80000001, dummy, dummy, dummy, val);
@@ -84,19 +85,29 @@
 		    ((ci->ci_tsc_freq + 4999) / 10000) % 100);
 	printf("\n");
 
+	if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
+		feature_str[0] = CPUID_FLAGS1;
+		feature_str[1] = CPUID_FLAGS2;
+		feature_str[2] = CPUID_FLAGS3;
+	} else {
+		feature_str[0] = CPUID_FLAGS1;
+		feature_str[1] = CPUID_EXT_FLAGS2;
+		feature_str[2] = CPUID_EXT_FLAGS3;
+	}
+
 	if ((ci->ci_feature_flags & CPUID_MASK1) != 0) {
 		bitmask_snprintf(ci->ci_feature_flags,
-		    CPUID_FLAGS1, buf, sizeof(buf));
+		    feature_str[0], buf, sizeof(buf));
 		printf("%s: features: %s\n", ci->ci_dev->dv_xname, buf);
 	}
 	if ((ci->ci_feature_flags & CPUID_MASK2) != 0) {
 		bitmask_snprintf(ci->ci_feature_flags,
-		    CPUID_EXT_FLAGS2, buf, sizeof(buf));
+		    feature_str[1], buf, sizeof(buf));
 		printf("%s: features: %s\n", ci->ci_dev->dv_xname, buf);
 	}
 	if ((ci->ci_feature_flags & CPUID_MASK3) != 0) {
 		bitmask_snprintf(ci->ci_feature_flags,
-		    CPUID_EXT_FLAGS3, buf, sizeof(buf));
+		    feature_str[2], buf, sizeof(buf));
 		printf("%s: features: %s\n", ci->ci_dev->dv_xname, buf);
 	}