Module Name: src Committed By: martin Date: Mon Apr 9 18:04:32 UTC 2018
Modified Files: src/sys/arch/x86/include [netbsd-8]: cacheinfo.h src/usr.sbin/cpuctl/arch [netbsd-8]: i386.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.22.10.1 -r1.22.10.2 src/sys/arch/x86/include/cacheinfo.h cvs rdiff -u -r1.74.6.2 -r1.74.6.3 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/include/cacheinfo.h diff -u src/sys/arch/x86/include/cacheinfo.h:1.22.10.1 src/sys/arch/x86/include/cacheinfo.h:1.22.10.2 --- src/sys/arch/x86/include/cacheinfo.h:1.22.10.1 Fri Mar 16 13:05:31 2018 +++ src/sys/arch/x86/include/cacheinfo.h Mon Apr 9 18:04:32 2018 @@ -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 @@ struct x86_cache_info { #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 @@ struct x86_cache_info { /* 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 @@ __CI_TBL(0, 0, 0, #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), \ Index: src/usr.sbin/cpuctl/arch/i386.c diff -u src/usr.sbin/cpuctl/arch/i386.c:1.74.6.2 src/usr.sbin/cpuctl/arch/i386.c:1.74.6.3 --- src/usr.sbin/cpuctl/arch/i386.c:1.74.6.2 Fri Mar 16 13:05:32 2018 +++ src/usr.sbin/cpuctl/arch/i386.c Mon Apr 9 18:04:32 2018 @@ -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 @@ const struct cpu_cpuid_nameclass i386_cp [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 @@ intel_cpu_cacheinfo(struct cpu_info *ci) 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 @@ intel_cpu_cacheinfo(struct cpu_info *ci) 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 @@ intel_cpu_cacheinfo(struct cpu_info *ci) 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 @@ x86_print_cache_and_tlb_info(struct cpu_ 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"); }