Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/arch/x86/x86 Pull up the following, requested by msai...



details:   https://anonhg.NetBSD.org/src/rev/ca6090e74c60
branches:  netbsd-6
changeset: 776886:ca6090e74c60
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Jan 26 14:02:40 2015 +0000

description:
Pull up the following, requested by msaitoh in ticket #1241:

        sys/arch/x86/x86/identcpu.c                     1.35-1.39

- Check cpuid leaf 4 for newer Intel CPU to know the cache information.
  This code might improve performance because it changes the number of
  page colors.
- Fix calculation of the cpu model (display model) in
  cpu_probe_amd_cache().
- CPUID leaf 2 and 4 are only for Intel processors.

diffstat:

 sys/arch/x86/x86/identcpu.c |  170 ++++++++++++++++++++++++++++++-------------
 1 files changed, 117 insertions(+), 53 deletions(-)

diffs (275 lines):

diff -r 45aebe76a579 -r ca6090e74c60 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c       Mon Jan 26 13:58:05 2015 +0000
+++ b/sys/arch/x86/x86/identcpu.c       Mon Jan 26 14:02:40 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: identcpu.c,v 1.29.2.2 2012/05/07 16:37:19 riz Exp $    */
+/*     $NetBSD: identcpu.c,v 1.29.2.3 2015/01/26 14:02:40 martin 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.29.2.2 2012/05/07 16:37:19 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.29.2.3 2015/01/26 14:02:40 martin Exp $");
 
 #include "opt_xen.h"
 
@@ -97,6 +97,103 @@
        return (NULL);
 }
 
+static void
+cpu_probe_intel_cache(struct cpu_info *ci)
+{
+       const struct x86_cache_info *cai;
+       u_int descs[4];
+       int iterations, i, j;
+       uint8_t desc;
+
+       if (cpuid_level >= 2) { 
+               /* Parse the cache info from `cpuid leaf 2', if we have it. */
+               x86_cpuid(2, descs);
+               iterations = descs[0] & 0xff;
+               while (iterations-- > 0) {
+                       for (i = 0; i < 4; i++) {
+                               if (descs[i] & 0x80000000)
+                                       continue;
+                               for (j = 0; j < 4; j++) {
+                                       if (i == 0 && j == 0)
+                                               continue;
+                                       desc = (descs[i] >> (j * 8)) & 0xff;
+                                       if (desc == 0)
+                                               continue;
+                                       cai = cache_info_lookup(
+                                           intel_cpuid_cache_info, desc);
+                                       if (cai != NULL) {
+                                               ci->ci_cinfo[cai->cai_index] =
+                                                   *cai;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       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;
+               }
+       }
+}
+
+static void
+cpu_probe_intel(struct cpu_info *ci)
+{
+
+       if (cpu_vendor != CPUVENDOR_INTEL)
+               return;
+
+       cpu_probe_intel_cache(ci);
+}
 
 static void
 cpu_probe_amd_cache(struct cpu_info *ci)
@@ -107,8 +204,8 @@
        u_int descs[4];
        u_int lfunc;
 
-       family = CPUID2FAMILY(ci->ci_signature);
-       model = CPUID2MODEL(ci->ci_signature);
+       family = CPUID_TO_FAMILY(ci->ci_signature);
+       model = CPUID_TO_MODEL(ci->ci_signature);
 
        /*
         * K5 model 0 has none of this info.
@@ -117,14 +214,6 @@
                return;
 
        /*
-        * Get extended values for K8 and up.
-        */
-       if (family == 0xf) {
-               family += CPUID2EXTFAMILY(ci->ci_signature);
-               model += CPUID2EXTMODEL(ci->ci_signature);
-       }
-
-       /*
         * Determine the largest extended function value.
         */
        x86_cpuid(0x80000000, descs);
@@ -248,10 +337,10 @@
        int flag;
 
        if (cpu_vendor != CPUVENDOR_AMD ||
-           CPUID2FAMILY(ci->ci_signature) != 5)
+           CPUID_TO_FAMILY(ci->ci_signature) != 5)
                return;
 
-       if (CPUID2MODEL(ci->ci_signature) == 0) {
+       if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
                /*
                 * According to the AMD Processor Recognition App Note,
                 * the AMD-K5 Model 0 uses the wrong bit to indicate
@@ -273,7 +362,7 @@
        uint32_t descs[4];
 
        if (cpu_vendor != CPUVENDOR_AMD ||
-           CPUID2FAMILY(ci->ci_signature) < 6)
+           CPUID_TO_FAMILY(ci->ci_signature) < 6)
                return;
 
        /* Determine the extended feature flags. */
@@ -369,8 +458,8 @@
 {
 
        if (cpu_vendor != CPUVENDOR_CYRIX ||
-           CPUID2FAMILY(ci->ci_signature) < 4 ||
-           CPUID2FAMILY(ci->ci_signature) > 6)
+           CPUID_TO_FAMILY(ci->ci_signature) < 4 ||
+           CPUID_TO_FAMILY(ci->ci_signature) > 6)
                return;
 
        cpu_probe_cyrix_cmn(ci);
@@ -383,10 +472,10 @@
        if (cpu_vendor != CPUVENDOR_IDT)
                return;
 
-       switch (CPUID2FAMILY(ci->ci_signature)) {
+       switch (CPUID_TO_FAMILY(ci->ci_signature)) {
        case 5:
                /* WinChip C6 */
-               if (CPUID2MODEL(ci->ci_signature) == 4)
+               if (CPUID_TO_MODEL(ci->ci_signature) == 4)
                        ci->ci_feat_val[0] &= ~CPUID_TSC;
                break;
        case 6:
@@ -415,12 +504,12 @@
        struct x86_cache_info *cai;
 
        if (cpu_vendor != CPUVENDOR_IDT ||
-           CPUID2FAMILY(ci->ci_signature) < 6)
+           CPUID_TO_FAMILY(ci->ci_signature) < 6)
                return;
 
-       family = CPUID2FAMILY(ci->ci_signature);
-       model = CPUID2MODEL(ci->ci_signature);
-       stepping = CPUID2STEPPING(ci->ci_signature);
+       family = CPUID_TO_FAMILY(ci->ci_signature);
+       model = CPUID_TO_MODEL(ci->ci_signature);
+       stepping = CPUID_TO_STEPPING(ci->ci_signature);
 
        /* Determine the largest extended function value. */
        x86_cpuid(0x80000000, descs);
@@ -555,7 +644,7 @@
 {
 
        if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 ||
-           CPUID2FAMILY(ci->ci_signature) != 5)
+           CPUID_TO_FAMILY(ci->ci_signature) != 5)
                return;
 
        cpu_probe_cyrix_cmn(ci);
@@ -606,10 +695,8 @@
 void
 cpu_probe(struct cpu_info *ci)
 {
-       const struct x86_cache_info *cai;
        u_int descs[4];
-       int iterations, i, j;
-       uint8_t desc;
+       int i;
        uint32_t miscbytes;
        uint32_t brand[12];
 
@@ -667,7 +754,8 @@
                ci->ci_feat_val[0] = descs[3];
 
                /* Determine family + class. */
-               cpu_class = CPUID2FAMILY(ci->ci_signature) + (CPUCLASS_386 - 3);
+               cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
+                   + (CPUCLASS_386 - 3);
                if (cpu_class > CPUCLASS_686)
                        cpu_class = CPUCLASS_686;
 
@@ -677,31 +765,7 @@
                ci->ci_initapicid = (miscbytes >> 24) & 0xff;
        }
 
-       if (cpuid_level >= 2) { 
-               /* Parse the cache info from `cpuid', if we have it. */
-               x86_cpuid(2, descs);
-               iterations = descs[0] & 0xff;
-               while (iterations-- > 0) {
-                       for (i = 0; i < 4; i++) {
-                               if (descs[i] & 0x80000000)
-                                       continue;
-                               for (j = 0; j < 4; j++) {
-                                       if (i == 0 && j == 0)
-                                               continue;
-                                       desc = (descs[i] >> (j * 8)) & 0xff;
-                                       if (desc == 0)
-                                               continue;
-                                       cai = cache_info_lookup(
-                                           intel_cpuid_cache_info, desc);
-                                       if (cai != NULL) {
-                                               ci->ci_cinfo[cai->cai_index] =
-                                                   *cai;
-                                       }
-                               }
-                       }
-               }
-       }
-
+       cpu_probe_intel(ci);
        cpu_probe_k5(ci);
        cpu_probe_k678(ci);
        cpu_probe_cyrix(ci);



Home | Main Index | Thread Index | Old Index