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;