Module Name:    src
Committed By:   bouyer
Date:           Mon May 18 19:43:56 UTC 2009

Modified Files:
        src/sys/arch/x86/include [netbsd-5]: cacheinfo.h
        src/usr.sbin/cpuctl/arch [netbsd-5]: i386.c

Log Message:
Pull up following revision(s) (requested by pgoyette in ticket #761):
        sys/arch/x86/include/cacheinfo.h: revisions 1.11, 1.12
        usr.sbin/cpuctl/arch/i386.c: revisions 1.18, 1.19 via patch
1. Extend CPU probe of Intel processors to handle extended-models.  This
    allows us to properly identify new Intel 45nm processors, Core i7,
    Atom, and the 45nm Xeon MP.
2. Properly decode several new Intel cache descriptors, as listed in the
    most recent (March 2009) edition of Intel's Application Note 485.
Addresses my PR bin/41289
Addresses my PR bin/41290


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.9.8.1 src/sys/arch/x86/include/cacheinfo.h
cvs rdiff -u -r1.13.2.2 -r1.13.2.3 src/usr.sbin/cpuctl/arch/i386.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/include/cacheinfo.h
diff -u src/sys/arch/x86/include/cacheinfo.h:1.9 src/sys/arch/x86/include/cacheinfo.h:1.9.8.1
--- src/sys/arch/x86/include/cacheinfo.h:1.9	Fri May 30 21:53:00 2008
+++ src/sys/arch/x86/include/cacheinfo.h	Mon May 18 19:43:55 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: cacheinfo.h,v 1.9 2008/05/30 21:53:00 christos Exp $	*/
+/*	$NetBSD: cacheinfo.h,v 1.9.8.1 2009/05/18 19:43:55 bouyer Exp $	*/
 
 #ifndef _X86_CACHEINFO_H_
 #define _X86_CACHEINFO_H_
@@ -199,6 +199,10 @@
 #define __CI_TBL(a,b,c,d,e,f) { a, b, c, d, e, f }
 #endif
 
+/*
+ * XXX Currently organized mostly by cache type, but would be
+ * XXX easier to maintain if it were in descriptor type order.
+ */
 #define INTEL_CACHE_INFO { \
 __CI_TBL(CAI_ITLB,     0x01,    4, 32,        4 * 1024, NULL), \
 __CI_TBL(CAI_ITLB,     0xb0,    4,128,        4 * 1024, NULL), \
@@ -211,14 +215,23 @@
 __CI_TBL(CAI_ITLB,     0x50, 0xff, 64,        4 * 1024, "4K/4M: 64 entries"), \
 __CI_TBL(CAI_ITLB,     0x51, 0xff, 64,        4 * 1024, "4K/4M: 128 entries"),\
 __CI_TBL(CAI_ITLB,     0x52, 0xff, 64,        4 * 1024, "4K/4M: 256 entries"),\
+__CI_TBL(CAI_ITLB,     0x55, 0xff, 64,        4 * 1024, "2M/4M: 7 entries"), \
+__CI_TBL(CAI_DTLB2,    0x56,    4, 16, 4 * 1024 * 1024, NULL), \
+__CI_TBL(CAI_DTLB2,    0x57,    4, 16,        4 * 1024, NULL), \
+__CI_TBL(CAI_DTLB,     0x5a, 0xff, 64,        4 * 1024, "2M/4M: 32 entries (L0)"), \
 __CI_TBL(CAI_DTLB,     0x5b, 0xff, 64,        4 * 1024, "4K/4M: 64 entries"), \
 __CI_TBL(CAI_DTLB,     0x5c, 0xff, 64,        4 * 1024, "4K/4M: 128 entries"),\
 __CI_TBL(CAI_DTLB,     0x5d, 0xff, 64,        4 * 1024, "4K/4M: 256 entries"),\
+__CI_TBL(CAI_ITLB,     0xb1,    4, 64,               0, "8 2M/4 4M entries"), \
+__CI_TBL(CAI_ITLB,     0xb2,    4, 64,        4 * 1024, NULL), \
 __CI_TBL(CAI_ICACHE,   0x06,    4,        8 * 1024, 32, NULL), \
 __CI_TBL(CAI_ICACHE,   0x08,    4,       16 * 1024, 32, NULL), \
+__CI_TBL(CAI_ICACHE,   0x09,    4,       32 * 1024, 64, NULL), \
 __CI_TBL(CAI_ICACHE,   0x30,    8,       32 * 1024, 64, NULL), \
 __CI_TBL(CAI_DCACHE,   0x0a,    2,        8 * 1024, 32, NULL), \
 __CI_TBL(CAI_DCACHE,   0x0c,    4,       16 * 1024, 32, NULL), \
+__CI_TBL(CAI_DCACHE,   0x0d,    4,       16 * 1024, 32, NULL), \
+__CI_TBL(CAI_L2CACHE,  0x21,    8,      256 * 1024, 64, NULL), /* L2 (MLC) */ \
 __CI_TBL(CAI_L2CACHE,  0x39,    4,      128 * 1024, 64, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x3a,    6,      192 * 1024, 64, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x3b,    2,      128 * 1024, 64, NULL), \
@@ -231,6 +244,9 @@
 __CI_TBL(CAI_L2CACHE,  0x43,    4,      512 * 1024, 32, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x44,    4, 1 * 1024 * 1024, 32, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x45,    4, 2 * 1024 * 1024, 32, NULL), \
+__CI_TBL(CAI_L2CACHE,  0x48,   12, 3 * 1024 * 1024, 64, NULL), \
+								\
+/* 0x49 Is L2 on Xeon MP (Family 0f, Model 06), L3 otherwise */	\
 __CI_TBL(CAI_L2CACHE,  0x49,   16, 4 * 1024 * 1024, 64, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x4e,   24, 6 * 1024 * 1024, 64, NULL), \
 __CI_TBL(CAI_DCACHE,   0x60,    8,       16 * 1024, 64, NULL), \
@@ -255,6 +271,32 @@
 __CI_TBL(CAI_L2CACHE,  0x85,    8, 2 * 1024 * 1024, 32, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x86,    4,      512 * 1024, 64, NULL), \
 __CI_TBL(CAI_L2CACHE,  0x87,    8, 1 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x22, 0xff,      512 * 1024, 64, "sectored, 4-way "), \
+__CI_TBL(CAI_L3CACHE,  0x23, 0xff, 1 * 1024 * 1024, 64, "sectored, 8-way "), \
+__CI_TBL(CAI_L3CACHE,  0x25, 0xff, 2 * 1024 * 1024, 64, "sectored, 8-way "), \
+__CI_TBL(CAI_L3CACHE,  0x29, 0xff, 4 * 1024 * 1024, 64, "sectored, 8-way "), \
+__CI_TBL(CAI_L3CACHE,  0x46,    4, 4 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x47,    8, 8 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x49,   16, 4 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x4a,   12, 6 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x4b,   16, 8 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x4c,   12,12 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0x4d,   16,16 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd0,    4,      512 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd1,    4, 1 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd2,    4, 2 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd6,    8, 1 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd7,    8, 2 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xd8,    8, 4 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xdc,   12, 3 *  512 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xdd,   12, 3 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xde,   12, 6 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xe2,   16, 2 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xe3,   16, 4 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xe4,   16, 8 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xea,   24,12 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xeb,   24,24 * 1024 * 1024, 64, NULL), \
+__CI_TBL(CAI_L3CACHE,  0xec,   24,24 * 1024 * 1024, 64, NULL), \
 __CI_TBL(0,               0,    0,               0,  0, NULL)  \
 }
 

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.13.2.2 src/usr.sbin/cpuctl/arch/i386.c:1.13.2.3
--- src/usr.sbin/cpuctl/arch/i386.c:1.13.2.2	Tue Mar 24 20:34:56 2009
+++ src/usr.sbin/cpuctl/arch/i386.c	Mon May 18 19:43:55 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.13.2.2 2009/03/24 20:34:56 snj Exp $	*/
+/*	$NetBSD: i386.c,v 1.13.2.3 2009/05/18 19:43:55 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: i386.c,v 1.13.2.2 2009/03/24 20:34:56 snj Exp $");
+__RCSID("$NetBSD: i386.c,v 1.13.2.3 2009/05/18 19:43:55 bouyer Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -122,6 +122,10 @@
 	void (*cpu_info)(struct cpu_info *);
 };
 
+struct cpu_extend_nameclass {
+	int ext_model;
+	const char *cpu_models[CPU_MAXMODEL+1];
+};
 
 struct cpu_cpuid_nameclass {
 	const char *cpu_id;
@@ -133,6 +137,7 @@
 		void (*cpu_setup)(struct cpu_info *);
 		void (*cpu_probe)(struct cpu_info *);
 		void (*cpu_info)(struct cpu_info *);
+		struct cpu_extend_nameclass *cpu_extended_names;
 	} cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
 };
 
@@ -237,6 +242,21 @@
 	""
 };
 
+struct cpu_extend_nameclass intel_family6_ext_models[] = {
+	{ /* Extended models 1x */
+	  0x01, { NULL,			NULL,
+		  NULL,			NULL,
+		  NULL,			"EP80579 Integrated Processor",
+		  "Celeron (45nm)",	"Core 2 Extreme",
+		  NULL,			NULL,
+		  "Core i7 (Nehalem)",	NULL,
+		  "Atom",		"XeonMP (Nehalem)",
+		   NULL,		NULL} },
+	{ /* End of list */
+	  0x00, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+};
+
 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
 	{
 		"GenuineIntel",
@@ -254,6 +274,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5 */
 		{
@@ -269,6 +290,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 6 */
 		{
@@ -291,6 +313,7 @@
 			NULL,
 			intel_family_new_probe,
 			NULL,
+			&intel_family6_ext_models[0],
 		},
 		/* Family > 6 */
 		{
@@ -303,6 +326,7 @@
 			NULL,
 			intel_family_new_probe,
 			NULL,
+			NULL,
 		} }
 	},
 	{
@@ -324,6 +348,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5 */
 		{
@@ -337,6 +362,7 @@
 			amd_family5_setup,
 			NULL,
 			amd_cpu_cacheinfo,
+			NULL,
 		},
 		/* Family 6 */
 		{
@@ -351,6 +377,7 @@
 			NULL,
 			amd_family6_probe,
 			amd_cpu_cacheinfo,
+			NULL,
 		},
 		/* Family > 6 */
 		{
@@ -363,6 +390,7 @@
 			NULL,
 			amd_family6_probe,
 			amd_cpu_cacheinfo,
+			NULL,
 		} }
 	},
 	{
@@ -381,6 +409,7 @@
 			cyrix6x86_cpu_setup, /* XXX ?? */
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5 */
 		{
@@ -394,6 +423,7 @@
 			cyrix6x86_cpu_setup,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 6 */
 		{
@@ -406,6 +436,7 @@
 			cyrix6x86_cpu_setup,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family > 6 */
 		{
@@ -418,6 +449,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		} }
 	},
 	{	/* MediaGX is now owned by National Semiconductor */
@@ -435,6 +467,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5: Geode family, formerly MediaGX */
 		{
@@ -448,6 +481,7 @@
 			cyrix6x86_cpu_setup,
 			NULL,
 			amd_cpu_cacheinfo,
+			NULL,
 		},
 		/* Family 6, not yet available from NSC */
 		{
@@ -460,6 +494,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family > 6, not yet available from NSC */
 		{
@@ -472,6 +507,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		} }
 	},
 	{
@@ -489,6 +525,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5 */
 		{
@@ -501,6 +538,7 @@
 			winchip_cpu_setup,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 6, VIA acquired IDT Centaur design subsidiary */
 		{
@@ -514,6 +552,7 @@
 			NULL,
 			via_cpu_probe,
 			via_cpu_cacheinfo,
+			NULL,
 		},
 		/* Family > 6, not yet available from VIA */
 		{
@@ -526,6 +565,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		} }
 	},
 	{
@@ -543,6 +583,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family 5 */
 		{
@@ -555,6 +596,7 @@
 			NULL,
 			NULL,
 			transmeta_cpu_info,
+			NULL,
 		},
 		/* Family 6, not yet available from Transmeta */
 		{
@@ -567,6 +609,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		},
 		/* Family > 6, not yet available from Transmeta */
 		{
@@ -579,6 +622,7 @@
 			NULL,
 			NULL,
 			NULL,
+			NULL,
 		} }
 	}
 };
@@ -1181,9 +1225,10 @@
 void
 identifycpu(const char *cpuname)
 {
-	const char *name, *modifier, *vendorname, *brand = "";
+	const char *name = "", *modifier, *vendorname, *brand = "";
 	int class = CPUCLASS_386, i, xmax;
-	int modif, family, model;
+	int modif, family, model, ext_model;
+	const struct cpu_extend_nameclass *modlist;
 	const struct cpu_cpuid_nameclass *cpup = NULL;
 	const struct cpu_cpuid_family *cpufam;
 	const char *feature_str[5];
@@ -1217,6 +1262,7 @@
 		if (family < CPU_MINFAMILY)
 			errx(1, "identifycpu: strange family value");
 		model = CPUID2MODEL(ci->ci_signature);
+		ext_model = CPUID2EXTMODEL(ci->ci_signature);
 
 		for (i = 0; i < xmax; i++) {
 			if (!strncmp((char *)ci->ci_vendor,
@@ -1245,11 +1291,29 @@
 			if (family > CPU_MAXFAMILY) {
 				family = CPU_MAXFAMILY;
 				model = CPU_DEFMODEL;
-			} else if (model > CPU_MAXMODEL)
+			} else if (model > CPU_MAXMODEL) {
 				model = CPU_DEFMODEL;
+				ext_model = 0;
+			}
 			cpufam = &cpup->cpu_family[family - CPU_MINFAMILY];
-			name = cpufam->cpu_models[model];
-			if (name == NULL)
+			if (cpufam->cpu_extended_names == NULL ||
+			    ext_model == 0)
+				name = cpufam->cpu_models[model];
+			else {
+				/*
+				 * Scan list(s) of extended model names
+				 */
+				modlist = cpufam->cpu_extended_names;
+				while (modlist->ext_model != 0) {
+					if (modlist->ext_model == ext_model) {
+						name =
+						     modlist->cpu_models[model];
+						break;
+					}
+					modlist++;
+				}
+			}
+			if (name == NULL || *name == '\0')
 			    name = cpufam->cpu_models[CPU_DEFMODEL];
 			class = cpufam->cpu_class;
 			ci->ci_info = cpufam->cpu_info;

Reply via email to