Source-Changes-HG archive

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

src: Pull up following revision(s) (requested by msaitoh in tick...



details:   https://anonhg.NetBSD.org/src/rev/60c94463f84c
branches:  netbsd-8
changeset: 317988:60c94463f84c
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Apr 09 18:04:32 2018 +0000
description:
Pull up following revision(s) (requested by msaitoh in ticket #715):

        sys/arch/x86/include/cacheinfo.h: revision 1.24-1.26
        usr.sbin/cpuctl/arch/i386.c: revision 1.81-1.84

- Parse the TLB info from `cpuid leaf 18H' on Intel processor. Currently,
  this change doesn't decode perfectly.  Tested with Gemini Lake. It has
  two L2 Shared TLB. One is 4MB and another is 2MB/4MB but former isn't
  printed yet:
        cpu0: ITLB 1 4KB entries 48-way
        cpu0: DTLB 1 4KB entries 32-way
        cpu0: L2 STLB 8 4MB entries 4-way
  Need some rework for struct x86_cache_info.
- Use aprint_error_dev() for error output.
 Calculate way and number of entries correctly from CPUID leaf 18H.
 Add yet another Shared L2 TLB (2M/4M pages).
XXX need redesign.

 Add 3way and 6way of L2 cache or TLB on AMD CPU.
 AMD L3 cache association bitfield is not 8bit but 4bit like others association
bitfields.

>From the latest Intel SDM:
- Add Xeon Phi 7215, 7285 and 7295
- Add Coffee Lake

diffstat:

 sys/arch/x86/include/cacheinfo.h |   11 +-
 usr.sbin/cpuctl/arch/i386.c      |  154 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 153 insertions(+), 12 deletions(-)

diffs (244 lines):

diff -r 6b255c4fbed8 -r 60c94463f84c sys/arch/x86/include/cacheinfo.h
--- a/sys/arch/x86/include/cacheinfo.h  Mon Apr 09 17:01:20 2018 +0000
+++ b/sys/arch/x86/include/cacheinfo.h  Mon Apr 09 18:04:32 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cacheinfo.h,v 1.22.10.1 2018/03/16 13:05:31 martin Exp $       */
+/*     $NetBSD: cacheinfo.h,v 1.22.10.2 2018/04/09 18:04:32 martin Exp $       */
 
 #ifndef _X86_CACHEINFO_H_
 #define _X86_CACHEINFO_H_
@@ -35,9 +35,10 @@
 #define CAI_L2_DTLB2   15              /* L2 Data TLB (2/4M pages) */
 #define CAI_L2_STLB    16              /* Shared L2 TLB (4K pages) */
 #define CAI_L2_STLB2   17              /* Shared L2 TLB (4K/2M pages) */
-#define CAI_PREFETCH   18              /* Prefetch */
+#define CAI_L2_STLB3   18              /* Shared L2 TLB (2M/4M pages) */
+#define CAI_PREFETCH   19              /* Prefetch */
 
-#define        CAI_COUNT       19
+#define        CAI_COUNT       20
 
 /*
  * AMD Cache Info:
@@ -139,7 +140,7 @@
 
 /* L3 Cache */
 #define AMD_L3_EDX_C_SIZE(x)           ((((x) >> 18) & 0xffff) * 1024 * 512)
-#define AMD_L3_EDX_C_ASSOC(x)           (((x) >> 12) & 0xff)
+#define AMD_L3_EDX_C_ASSOC(x)           (((x) >> 12) & 0xf)
 #define AMD_L3_EDX_C_LPT(x)             (((x) >> 8)  & 0xf)
 #define AMD_L3_EDX_C_LS(x)              ( (x)        & 0xff)
 
@@ -341,7 +342,9 @@
 #define AMD_L2CACHE_INFO { \
 __CI_TBL(0, 0x01,    1, 0, 0, NULL), \
 __CI_TBL(0, 0x02,    2, 0, 0, NULL), \
+__CI_TBL(0, 0x03,    3, 0, 0, NULL), \
 __CI_TBL(0, 0x04,    4, 0, 0, NULL), \
+__CI_TBL(0, 0x05,    6, 0, 0, NULL), \
 __CI_TBL(0, 0x06,    8, 0, 0, NULL), \
 __CI_TBL(0, 0x08,   16, 0, 0, NULL), \
 __CI_TBL(0, 0x0a,   32, 0, 0, NULL), \
diff -r 6b255c4fbed8 -r 60c94463f84c usr.sbin/cpuctl/arch/i386.c
--- a/usr.sbin/cpuctl/arch/i386.c       Mon Apr 09 17:01:20 2018 +0000
+++ b/usr.sbin/cpuctl/arch/i386.c       Mon Apr 09 18:04:32 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i386.c,v 1.74.6.2 2018/03/16 13:05:32 martin Exp $     */
+/*     $NetBSD: i386.c,v 1.74.6.3 2018/04/09 18:04:32 martin 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.74.6.2 2018/03/16 13:05:32 martin Exp $");
+__RCSID("$NetBSD: i386.c,v 1.74.6.3 2018/04/09 18:04:32 martin Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -381,9 +381,9 @@
                                [0x5f] = "Atom (Goldmont, Denverton)",
                                [0x66] = "Future Core (Cannon Lake)",
                                [0x7a] = "Atom (Goldmont Plus)",
-                               [0x85] = "Future Xeon Phi (Knights Mill)",
-                               [0x8e] = "7th gen Core (Kaby Lake)",
-                               [0x9e] = "7th gen Core (Kaby Lake)",
+                               [0x85] = "Xeon Phi 7215, 7285, 7295 (Knights Mill)",
+                               [0x8e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake)",
+                               [0x9e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake)",
                        },
                        "Pentium Pro, II or III",       /* Default */
                        NULL,
@@ -1025,8 +1025,10 @@
                                    desc);
                                if (cai != NULL)
                                        ci->ci_cinfo[cai->cai_index] = *cai;
-                               else if ((verbose != 0) && (desc != 0xff))
-                                       printf("Unknown cacheinfo desc %02x\n",
+                               else if ((verbose != 0) && (desc != 0xff)
+                                   && (desc != 0xfe))
+                                       aprint_error_dev(ci->ci_dev, "error:"
+                                           " Unknown cacheinfo desc %02x\n",
                                            desc);
                        }
                }
@@ -1069,7 +1071,8 @@
                        break;
                }
                if (caitype == -1) {
-                       printf("unknown cache level&type (%d & %d)\n",
+                       aprint_error_dev(ci->ci_dev,
+                           "error: unknown cache level&type (%d & %d)\n",
                            level, type);
                        continue;
                }
@@ -1084,6 +1087,140 @@
                ci->ci_cinfo[caitype].cai_associativity = ways;
                ci->ci_cinfo[caitype].cai_linesize = linesize;
        }
+
+       if (ci->ci_cpuid_level < 0x18)
+               return;
+       /* Parse the TLB info from `cpuid leaf 18H', if we have it. */
+       x86_cpuid(0x18, descs);
+       iterations = descs[0];
+       for (i = 0; i <= iterations; i++) {
+               uint32_t pgsize;
+               bool full;
+
+               x86_cpuid2(0x18, i, descs);
+               type = __SHIFTOUT(descs[3], CPUID_DATP_TCTYPE);
+               if (type == CPUID_DATP_TCTYPE_N)
+                       continue;
+               level = __SHIFTOUT(descs[3], CPUID_DATP_TCLEVEL);
+               pgsize = __SHIFTOUT(descs[1], CPUID_DATP_PGSIZE);
+               switch (level) {
+               case 1:
+                       if (type == CPUID_DATP_TCTYPE_I) {
+                               switch (pgsize) {
+                               case CPUID_DATP_PGSIZE_4KB:
+                                       caitype = CAI_ITLB;
+                                       break;
+                               case CPUID_DATP_PGSIZE_2MB
+                                   | CPUID_DATP_PGSIZE_4MB:
+                                       caitype = CAI_ITLB2;
+                                       break;
+                               case CPUID_DATP_PGSIZE_1GB:
+                                       caitype = CAI_L1_1GBITLB;
+                                       break;
+                               default:
+                                       aprint_error_dev(ci->ci_dev,
+                                           "error: unknown ITLB size (%d)\n",
+                                           pgsize);
+                                       caitype = CAI_ITLB;
+                                       break;
+                               }
+                       } else if (type == CPUID_DATP_TCTYPE_D) {
+                               switch (pgsize) {
+                               case CPUID_DATP_PGSIZE_4KB:
+                                       caitype = CAI_DTLB;
+                                       break;
+                               case CPUID_DATP_PGSIZE_2MB
+                                   | CPUID_DATP_PGSIZE_4MB:
+                                       caitype = CAI_DTLB2;
+                                       break;
+                               case CPUID_DATP_PGSIZE_1GB:
+                                       caitype = CAI_L1_1GBDTLB;
+                                       break;
+                               default:
+                                       aprint_error_dev(ci->ci_dev,
+                                           "error: unknown DTLB size (%d)\n",
+                                           pgsize);
+                                       caitype = CAI_DTLB;
+                                       break;
+                               }
+                       } else
+                               caitype = -1;
+                       break;
+               case 2:
+                       if (type == CPUID_DATP_TCTYPE_I)
+                               caitype = CAI_L2_ITLB;
+                       else if (type == CPUID_DATP_TCTYPE_D)
+                               caitype = CAI_L2_DTLB;
+                       else if (type == CPUID_DATP_TCTYPE_U) {
+                               switch (pgsize) {
+                               case CPUID_DATP_PGSIZE_4KB:
+                                       caitype = CAI_L2_STLB;
+                                       break;
+                               case CPUID_DATP_PGSIZE_4KB
+                                   | CPUID_DATP_PGSIZE_2MB:
+                                       caitype = CAI_L2_STLB2;
+                                       break;
+                               case CPUID_DATP_PGSIZE_2MB
+                                   | CPUID_DATP_PGSIZE_4MB:
+                                       caitype = CAI_L2_STLB3;
+                                       break;
+                               default:
+                                       aprint_error_dev(ci->ci_dev,
+                                           "error: unknown L2 STLB size (%d)\n",
+                                           pgsize);
+                                       caitype = CAI_DTLB;
+                                       break;
+                               }
+                       } else
+                               caitype = -1;
+                       break;
+               case 3:
+                       /* XXX need work for L3 TLB */
+                       caitype = CAI_L3CACHE;
+                       break;
+               default:
+                       caitype = -1;
+                       break;
+               }
+               if (caitype == -1) {
+                       aprint_error_dev(ci->ci_dev,
+                           "error: unknown TLB level&type (%d & %d)\n",
+                           level, type);
+                       continue;
+               }
+               switch (pgsize) {
+               case CPUID_DATP_PGSIZE_4KB:
+                       linesize = 4 * 1024;
+                       break;
+               case CPUID_DATP_PGSIZE_2MB:
+                       linesize = 2 * 1024 * 1024;
+                       break;
+               case CPUID_DATP_PGSIZE_4MB:
+                       linesize = 4 * 1024 * 1024;
+                       break;
+               case CPUID_DATP_PGSIZE_1GB:
+                       linesize = 1024 * 1024 * 1024;
+                       break;
+               case CPUID_DATP_PGSIZE_2MB | CPUID_DATP_PGSIZE_4MB:
+                       aprint_error_dev(ci->ci_dev,
+                           "WARINING: Currently 2M/4M info can't print correctly\n");
+                       linesize = 4 * 1024 * 1024;
+                       break;
+               default:
+                       aprint_error_dev(ci->ci_dev,
+                           "error: Unknown size combination\n");
+                       linesize = 4 * 1024;
+                       break;
+               }
+               ways = __SHIFTOUT(descs[1], CPUID_DATP_WAYS);
+               sets = descs[2];
+               full = descs[3] & CPUID_DATP_FULLASSOC;
+               ci->ci_cinfo[caitype].cai_totalsize
+                   = ways * sets; /* entries */
+               ci->ci_cinfo[caitype].cai_associativity
+                   = full ? 0xff : ways;
+               ci->ci_cinfo[caitype].cai_linesize = linesize; /* pg size */
+       }
 }
 
 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] = 
@@ -2193,6 +2330,7 @@
        if (ci->ci_cinfo[CAI_L2_STLB].cai_totalsize != 0) {
                sep = print_tlb_config(ci, CAI_L2_STLB, "L2 STLB", NULL);
                sep = print_tlb_config(ci, CAI_L2_STLB2, NULL, sep);
+               sep = print_tlb_config(ci, CAI_L2_STLB3, NULL, sep);
                if (sep != NULL)
                        aprint_verbose("\n");
        }



Home | Main Index | Thread Index | Old Index