Module Name:    src
Committed By:   msaitoh
Date:           Mon Oct 21 06:33:11 UTC 2013

Modified Files:
        src/sys/arch/x86/x86: identcpu.c
        src/usr.sbin/cpuctl/arch: i386.c

Log Message:
Check cpuid leaf 4 for newer Intel CPU to know the cache information.


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.44 -r1.45 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/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.34 src/sys/arch/x86/x86/identcpu.c:1.35
--- src/sys/arch/x86/x86/identcpu.c:1.34	Thu Jun 27 00:38:18 2013
+++ src/sys/arch/x86/x86/identcpu.c	Mon Oct 21 06:33:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: identcpu.c,v 1.34 2013/06/27 00:38:18 christos Exp $	*/
+/*	$NetBSD: identcpu.c,v 1.35 2013/10/21 06:33:11 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.34 2013/06/27 00:38:18 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.35 2013/10/21 06:33:11 msaitoh Exp $");
 
 #include "opt_xen.h"
 
@@ -678,7 +678,7 @@ cpu_probe(struct cpu_info *ci)
 	}
 
 	if (cpuid_level >= 2) { 
-		/* Parse the cache info from `cpuid', if we have it. */
+		/* Parse the cache info from `cpuid leaf 2', if we have it. */
 		x86_cpuid(2, descs);
 		iterations = descs[0] & 0xff;
 		while (iterations-- > 0) {
@@ -702,6 +702,60 @@ cpu_probe(struct cpu_info *ci)
 		}
 	}
 
+	if (cpuid_level >= 4) {
+		int type, level;
+		int ways, partitions, linesize, sets;
+		int caitype = -1;
+		int totalsize;
+		
+		/* Parse the cache info from `cpuid leaf 4', if we have it. */
+		for (i = 0; ; i++) {
+			x86_cpuid2(4, i, descs);
+			type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
+			if (type == CPUID_DCP_CACHETYPE_N)
+				break;
+			level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
+			switch (level) {
+			case 1:
+				if (type == CPUID_DCP_CACHETYPE_I)
+					caitype = CAI_ICACHE;
+				else if (type == CPUID_DCP_CACHETYPE_D)
+					caitype = CAI_DCACHE;
+				else
+					caitype = -1;
+				break;
+			case 2:
+				if (type == CPUID_DCP_CACHETYPE_U)
+					caitype = CAI_L2CACHE;
+				else
+					caitype = -1;
+				break;
+			case 3:
+				if (type == CPUID_DCP_CACHETYPE_U)
+					caitype = CAI_L3CACHE;
+				else
+					caitype = -1;
+				break;
+			default:
+				caitype = -1;
+				break;
+			}
+			if (caitype == -1)
+				continue;
+
+			ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
+			partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
+			    + 1;
+			linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
+			    + 1;
+			sets = descs[2] + 1;
+			totalsize = ways * partitions * linesize * sets;
+			ci->ci_cinfo[caitype].cai_totalsize = totalsize;
+			ci->ci_cinfo[caitype].cai_associativity = ways;
+			ci->ci_cinfo[caitype].cai_linesize = linesize;
+		}
+	}
+		
 	cpu_probe_k5(ci);
 	cpu_probe_k678(ci);
 	cpu_probe_cyrix(ci);

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.44 src/usr.sbin/cpuctl/arch/i386.c:1.45
--- src/usr.sbin/cpuctl/arch/i386.c:1.44	Mon Oct 21 06:28:15 2013
+++ src/usr.sbin/cpuctl/arch/i386.c	Mon Oct 21 06:33:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.44 2013/10/21 06:28:15 msaitoh Exp $	*/
+/*	$NetBSD: i386.c,v 1.45 2013/10/21 06:33:11 msaitoh 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.44 2013/10/21 06:28:15 msaitoh Exp $");
+__RCSID("$NetBSD: i386.c,v 1.45 2013/10/21 06:33:11 msaitoh Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -1306,6 +1306,10 @@ cpu_probe_base_features(struct cpu_info 
 	const struct x86_cache_info *cai;
 	u_int descs[4];
 	int iterations, i, j;
+	int type, level;
+	int ways, partitions, linesize, sets;
+	int caitype = -1;
+	int totalsize;
 	uint8_t desc;
 	uint32_t brand[12];
 
@@ -1362,7 +1366,7 @@ cpu_probe_base_features(struct cpu_info 
 		return;
 
 	/*
-	 * Parse the cache info from `cpuid', if we have it.
+	 * Parse the cache info from `cpuid leaf 2', if we have it.
 	 * XXX This is kinda ugly, but hey, so is the architecture...
 	 */
 
@@ -1402,6 +1406,58 @@ cpu_probe_base_features(struct cpu_info 
 		ci->ci_cpu_serial[1] = descs[3];
 	}
 
+	if (ci->ci_cpuid_level < 4)
+		return;
+
+	/* Parse the cache info from `cpuid leaf 4', if we have it. */
+	for (i = 0; ; i++) {
+		x86_cpuid2(4, i, descs);
+		type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
+		if (type == CPUID_DCP_CACHETYPE_N)
+			break;
+		level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
+		switch (level) {
+		case 1:
+			if (type == CPUID_DCP_CACHETYPE_I)
+				caitype = CAI_ICACHE;
+			else if (type == CPUID_DCP_CACHETYPE_D)
+				caitype = CAI_DCACHE;
+			else
+				caitype = -1;
+			break;
+		case 2:
+			if (type == CPUID_DCP_CACHETYPE_U)
+				caitype = CAI_L2CACHE;
+			else
+				caitype = -1;
+			break;
+		case 3:
+			if (type == CPUID_DCP_CACHETYPE_U)
+				caitype = CAI_L3CACHE;
+			else
+				caitype = -1;
+			break;
+		default:
+			caitype = -1;
+			break;
+		}
+		if (caitype == -1) {
+			printf("unknown cache level&type (%d & %d)\n",
+			    level, type);
+			continue;
+		}
+		ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
+		partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
+		    + 1;
+		linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
+		    + 1;
+		sets = descs[2] + 1;
+		totalsize = ways * partitions * linesize * sets;
+		ci->ci_cinfo[caitype].cai_totalsize = totalsize;
+		ci->ci_cinfo[caitype].cai_associativity = ways;
+		ci->ci_cinfo[caitype].cai_linesize = linesize;
+	}
+
 	if (ci->ci_cpuid_level < 0xd)
 		return;
 

Reply via email to