Subject: Re: port-i386/19163: VIA C3 processor isn't recognized correctly
To: Takahiro Kambe <taca@back-street.net>
From: Bang Jun-Young <junyoung@netbsd.org>
List: netbsd-bugs
Date: 12/06/2002 10:13:20
On Thu, Dec 05, 2002 at 11:40:40PM +0900, Takahiro Kambe wrote:
> What's differ about "3DNOW" cpu feature?
Could you try with the following patch?
Index: i386/machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.500
diff -u -r1.500 machdep.c
--- i386/machdep.c 2002/12/05 16:19:08 1.500
+++ i386/machdep.c 2002/12/06 01:08:47
@@ -341,6 +341,7 @@
void amd_family5_setup __P((struct cpu_info *));
void transmeta_cpu_setup __P((struct cpu_info *));
+static void via_cpu_probe __P((struct cpu_info *));
static void amd_family6_probe __P((struct cpu_info *));
static void transmeta_cpu_info __P((struct cpu_info *));
@@ -792,8 +793,8 @@
"K5 or K6" /* Default */
},
amd_family5_setup,
- amd_cpuid_cpu_cacheinfo,
NULL,
+ amd_cpuid_cpu_cacheinfo,
},
/* Family 6 */
{
@@ -818,7 +819,7 @@
"Unknown K7 (Athlon)" /* Default */
},
NULL,
- amd_cpuid_cpu_cacheinfo,
+ NULL,
NULL,
} }
},
@@ -969,8 +970,8 @@
"C3" /* Default */
},
NULL,
+ via_cpu_probe,
NULL,
- NULL,
},
/* Family > 6, not yet available from VIA */
{
@@ -1098,6 +1099,29 @@
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
: "a" (code));
+void
+via_cpu_probe(struct cpu_info *ci)
+{
+ u_int descs[4];
+ u_int lfunc;
+
+ /*
+ * Determine the largest extended function value.
+ */
+ CPUID(0x80000000, descs[0], descs[1], descs[2], descs[3]);
+ lfunc = descs[0];
+
+ /*
+ * Determine the extended feature flags.
+ */
+ if (lfunc >= 0x80000001) {
+ CPUID(0x80000001, descs[0], descs[1], descs[2], descs[3]);
+ ci->ci_feature_flags = descs[3];
+ ci->ci_feature_str2 = CPUID_EXT_FLAGS2;
+ ci->ci_feature_str3 = CPUID_EXT_FLAGS3;
+ }
+}
+
static void
cpu_probe_base_features(struct cpu_info *ci)
{
@@ -1121,6 +1145,14 @@
CPUID(1, ci->ci_signature, miscbytes, dummy1, ci->ci_feature_flags);
+ /*
+ * These may be overridden with vendor specific strings in
+ * (*ci_info)() later.
+ */
+ ci->ci_feature_str1 = CPUID_FLAGS1;
+ ci->ci_feature_str2 = CPUID_FLAGS2;
+ ci->ci_feature_str3 = CPUID_FLAGS3;
+
/* Brand is low order 8 bits of ebx */
ci->ci_brand_id = miscbytes & 0xff;
@@ -1213,14 +1245,25 @@
void
amd_family6_probe(struct cpu_info *ci)
{
- u_int32_t eax;
- u_int32_t dummy1, dummy2, dummy3;
+ u_int32_t lfunc;
+ u_int32_t descs[4];
u_int32_t brand[12];
char *p;
int i;
+
+ CPUID(0x80000000, lfunc, descs[1], descs[2], descs[3]);
+
+ /*
+ * Determine the extended feature flags.
+ */
+ if (lfunc >= 0x80000001) {
+ CPUID(0x80000001, descs[0], descs[1], descs[2], descs[3]);
+ ci->ci_feature_flags |= descs[3];
+ ci->ci_feature_str2 = CPUID_EXT_FLAGS2;
+ ci->ci_feature_str3 = CPUID_EXT_FLAGS3;
+ }
- CPUID(0x80000000, eax, dummy1, dummy2, dummy3);
- if (eax < 0x80000004)
+ if (lfunc < 0x80000004)
return;
CPUID(0x80000002, brand[0], brand[1], brand[2], brand[3]);
@@ -1795,18 +1838,18 @@
if (ci->ci_feature_flags) {
if ((ci->ci_feature_flags & CPUID_MASK1) != 0) {
- bitmask_snprintf(ci->ci_feature_flags, CPUID_FLAGS1,
- buf, sizeof(buf));
+ bitmask_snprintf(ci->ci_feature_flags,
+ ci->ci_feature_str1, buf, sizeof(buf));
printf("%s: features %s\n", cpuname, buf);
}
if ((ci->ci_feature_flags & CPUID_MASK2) != 0) {
- bitmask_snprintf(ci->ci_feature_flags, CPUID_FLAGS2,
- buf, sizeof(buf));
+ bitmask_snprintf(ci->ci_feature_flags,
+ ci->ci_feature_str2, buf, sizeof(buf));
printf("%s: features %s\n", cpuname, buf);
}
if ((ci->ci_feature_flags & CPUID_MASK3) != 0) {
- bitmask_snprintf(ci->ci_feature_flags, CPUID_FLAGS3,
- buf, sizeof(buf));
+ bitmask_snprintf(ci->ci_feature_flags,
+ ci->ci_feature_str3, buf, sizeof(buf));
printf("%s: features %s\n", cpuname, buf);
}
}
Index: include/cpu.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/cpu.h,v
retrieving revision 1.90
diff -u -r1.90 cpu.h
--- include/cpu.h 2002/11/28 21:43:55 1.90
+++ include/cpu.h 2002/12/06 01:08:47
@@ -127,6 +127,9 @@
int32_t ci_cpuid_level;
u_int32_t ci_signature; /* X86 cpuid type */
u_int32_t ci_feature_flags;/* X86 CPUID feature bits */
+ char * ci_feature_str1; /* Vendor specific feature strings */
+ char * ci_feature_str2;
+ char * ci_feature_str3;
u_int32_t ci_cpu_class; /* CPU class */
u_int32_t ci_brand_id; /* Intel brand id */
u_int32_t ci_vendor[4]; /* vendor string */
Index: include/specialreg.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/specialreg.h,v
retrieving revision 1.25
diff -u -r1.25 specialreg.h
--- include/specialreg.h 2002/12/05 17:25:26 1.25
+++ include/specialreg.h 2002/12/06 01:08:47
@@ -133,6 +133,20 @@
#define CPUID_FLAGS3 "\20\31FXSR\32SSE\33SSE2\34SS\35HTT\36TM\37B30\40SBF"
#define CPUID_MASK3 0xff000000
+/*
+ * AMD/VIA processor specific flags.
+ */
+
+#define CPUID_MPC 0x00080000 /* Multiprocessing Capable */
+#define CPUID_MMXX 0x00400000 /* AMD MMX Extensions */
+#define CPUID_3DNOW2 0x40000000 /* 3DNow! Instruction Extension */
+#define CPUID_3DNOW 0x80000000 /* 3DNow! Instructions */
+
+#define CPUID_EXT_FLAGS2 "\20\16PGE\17MCA\20CMOV\21PAT\22PSE36\23PN" \
+ "\24MPC\25B20\26B21\27MMXX\30MMX"
+#define CPUID_EXT_FLAGS3 "\20\31FXSR\32SSE\33B26\34B27\35B28\36B29" \
+ "\0373DNOW2\0403DNOW"
+
#define CPUID2FAMILY(cpuid) (((cpuid) >> 8) & 15)
#define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15)
#define CPUID2STEPPING(cpuid) ((cpuid) & 15)
Jun-Young
--
Bang Jun-Young <junyoung@netbsd.org>