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;