Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Check cpuid leaf 4 for newer Intel CPU to know the cache inf...



details:   https://anonhg.NetBSD.org/src/rev/0a135525b833
branches:  trunk
changeset: 790791:0a135525b833
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Mon Oct 21 06:33:11 2013 +0000

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

diffstat:

 sys/arch/x86/x86/identcpu.c |  60 +++++++++++++++++++++++++++++++++++++++++--
 usr.sbin/cpuctl/arch/i386.c |  62 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 116 insertions(+), 6 deletions(-)

diffs (185 lines):

diff -r e5b69f2da497 -r 0a135525b833 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c       Mon Oct 21 06:28:15 2013 +0000
+++ b/sys/arch/x86/x86/identcpu.c       Mon Oct 21 06:33:11 2013 +0000
@@ -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 @@
        }
 
        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 @@
                }
        }
 
+       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);
diff -r e5b69f2da497 -r 0a135525b833 usr.sbin/cpuctl/arch/i386.c
--- a/usr.sbin/cpuctl/arch/i386.c       Mon Oct 21 06:28:15 2013 +0000
+++ b/usr.sbin/cpuctl/arch/i386.c       Mon Oct 21 06:33:11 2013 +0000
@@ -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 @@
        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 @@
                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 @@
                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;
 



Home | Main Index | Thread Index | Old Index