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");
 	}

Reply via email to