Subject: CPUID patch for recent AMD processors
To: None <tech-kern@netbsd.org>
From: Bang Jun-Young <junyoung@mogua.com>
List: tech-kern
Date: 10/04/2002 12:08:13
--cNdxnHkX5QqsyA0e
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
The title says all. :-)
Before:
cpu0: AMD Athlon Model 6 (Palomino) (686-class), 1532.12 MHz
After:
cpu0: AMD Athlon XP 1800+ (686-class), 1532.12 MHz
And it should identify model 6 and 7 of Duron processors correctly,
which are currently misidentified as Athlon.
Any objections if I commit it?
Jun-Young
--
Bang Jun-Young <junyoung@mogua.com>
--cNdxnHkX5QqsyA0e
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="amdcpuid.diff"
Index: machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.485
diff -u -r1.485 machdep.c
--- arch/i386/i386/machdep.c 2002/10/03 19:39:51 1.485
+++ arch/i386/i386/machdep.c 2002/10/04 02:58:34
@@ -323,6 +323,19 @@
"Pentium 4" /* Intel (R) Pentium (R) 4 processor */
};
+/*
+ * AMD processors don't have Brand IDs, so we need these names for probe.
+ */
+static const char * const amd_brand[] = {
+ "",
+ "Duron", /* AMD Duron(tm) */
+ "MP", /* AMD Athlon(tm) MP */
+ "XP", /* AMD Athlon(tm) XP */
+ "4" /* AMD Athlon(tm) 4 */
+};
+
+static char amd_brand_name[48];
+
#ifdef COMPAT_NOMID
static int exec_nomid __P((struct proc *, struct exec_package *));
#endif
@@ -332,6 +345,8 @@
void amd_family5_setup __P((struct cpu_info *));
void transmeta_cpu_setup __P((struct cpu_info *));
+static void amd_family6_probe __P((struct cpu_info *));
+
static void transmeta_cpu_info __P((struct cpu_info *));
static void amd_cpuid_cpu_cacheinfo __P((struct cpu_info *));
@@ -815,14 +830,13 @@
{
0, "Athlon Model 1", "Athlon Model 2",
"Duron", "Athlon Model 4 (Thunderbird)",
- 0, "Athlon Model 6 (Palomino)",
- "Athlon Model 7 (Morgan)", 0, 0, 0, 0,
+ 0, "Athlon", "Duron", "Athlon", 0, 0, 0,
0, 0, 0, 0,
"K7 (Athlon)" /* Default */
},
NULL,
+ amd_family6_probe,
amd_cpuid_cpu_cacheinfo,
- NULL,
},
/* Family > 6 */
{
@@ -1170,6 +1184,30 @@
(*cpup->cpu_family[i].cpu_probe)(ci);
}
+void
+amd_family6_probe(struct cpu_info *ci)
+{
+ u_int32_t eax;
+ u_int32_t dummy1, dummy2, dummy3;
+ u_int32_t brand[12];
+ char *p;
+ int i;
+
+ CPUID(0x80000000, eax, dummy1, dummy2, dummy3);
+ if (eax < 0x80000004)
+ return;
+
+ CPUID(0x80000002, brand[0], brand[1], brand[2], brand[3]);
+ CPUID(0x80000003, brand[4], brand[5], brand[6], brand[7]);
+ CPUID(0x80000004, brand[8], brand[9], brand[10], brand[11]);
+
+ for (i = 1; i < sizeof(amd_brand) / sizeof(amd_brand[0]); i++)
+ if ((p = strstr((char *)brand, amd_brand[i])) != NULL) {
+ ci->ci_brand_id = i;
+ strcpy(amd_brand_name, p);
+ break;
+ }
+}
void
amd_family5_setup(struct cpu_info *ci)
@@ -1665,6 +1703,19 @@
model >= 8 && ci->ci_brand_id &&
ci->ci_brand_id < 8)
brand = i386_intel_brand[ci->ci_brand_id];
+
+ if (vendor == CPUVENDOR_AMD && family == 6 &&
+ model >= 6) {
+ if (ci->ci_brand_id == 1)
+ /*
+ * It's Duron. We override the
+ * name, since it might have been
+ * misidentified as Athlon.
+ */
+ name = amd_brand[ci->ci_brand_id];
+ else
+ brand = amd_brand_name;
+ }
}
}
Index: Makefile
===================================================================
RCS file: /cvsroot/syssrc/sys/lib/libkern/Makefile,v
retrieving revision 1.65
diff -u -r1.65 Makefile
--- lib/libkern/Makefile 2002/06/18 23:46:53 1.65
+++ lib/libkern/Makefile 2002/10/03 16:50:43
@@ -39,6 +39,10 @@
SRCS+= __cmsg_alignbytes.c inet_addr.c intoa.c md4c.c md5c.c sha1.c pmatch.c
SRCS+= _que.c arc4random.c
+.if (${MACHINE_ARCH} == "i386")
+SRCS+= strstr.c
+.endif
+
# Files to clean up
CLEANFILES+= lib${LIB}.o lib${LIB}.po
--cNdxnHkX5QqsyA0e
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="strstr.c"
/* $NetBSD: strstr.c,v 1.10 1999/09/20 04:39:48 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strstr.c,v 1.10 1999/09/20 04:39:48 lukem Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <string.h>
#else
#include <lib/libkern/libkern.h>
#endif
/*
* Find the first occurrence of find in s.
*/
char *
strstr(s, find)
const char *s, *find;
{
char c, sc;
size_t len;
if ((c = *find++) != 0) {
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (char *)0;
} while (sc != c);
} while (strncmp(s, find, len) != 0);
s--;
}
/* LINTED interface specification */
return ((char *)s);
}
--cNdxnHkX5QqsyA0e--