Module Name:    src
Committed By:   martin
Date:           Tue Dec  4 11:52:57 UTC 2018

Modified Files:
        src/sys/arch/x86/include [netbsd-8]: specialreg.h
        src/sys/arch/x86/x86 [netbsd-8]: cpu_topology.c
        src/usr.sbin/cpuctl/arch [netbsd-8]: i386.c

Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #1120):

        usr.sbin/cpuctl/arch/i386.c: revision 1.85
        usr.sbin/cpuctl/arch/i386.c: revision 1.86
        usr.sbin/cpuctl/arch/i386.c: revision 1.87
        usr.sbin/cpuctl/arch/i386.c: revision 1.88
        usr.sbin/cpuctl/arch/i386.c: revision 1.89
        usr.sbin/cpuctl/arch/i386.c: revision 1.90
        sys/arch/x86/include/specialreg.h: revision 1.132
        sys/arch/x86/include/specialreg.h: revision 1.133
        sys/arch/x86/include/specialreg.h: revision 1.134
        sys/arch/x86/include/specialreg.h: revision 1.135
        sys/arch/x86/include/specialreg.h: revision 1.136
        sys/arch/x86/x86/cpu_topology.c: revision 1.14

  Add MAWAU (for BND{LD,ST}X instruction) from the latest Intel SDM.

  Whitespace fix. No functional change.

Modify comment. No functional change:
- AMD also has CPUID 0x06 and 0x0d.
- PCOMMIT was obsoleted.
- Use ci_feat_val[7] as CPUID 7 %edx to match x86/cpu.h
- AMD also has CPUID 6.
- Remove unused code for coretemp.
- Consistently use descs[] instead of data[].
- AMD also reports CPUID 7's highest subleaf. Print it.
- Use macro.
  Add Intel CPUID Extended Topology Enumeration Fn0000000b definitions.
  Decode package, core and SMT id if CPUID 0x0b is available on Intel processor.

If the value is different from the kernel value, we should fix the kernel code.

TODO: Use 0x1f if it's available.

  Add Intel/AMD MONITOR/MWAIT leaf.
  Decode Intel/AMD MONITOR/MWAIT leaf.

  Add Intel CPUID Architectural Performance Monitoring leaf Fn0000000a.

  Print Intel CPUID Architectural Performance Monitoring leaf Fn0000000a.


To generate a diff of this commit:
cvs rdiff -u -r1.98.2.7 -r1.98.2.8 src/sys/arch/x86/include/specialreg.h
cvs rdiff -u -r1.9.22.2 -r1.9.22.3 src/sys/arch/x86/x86/cpu_topology.c
cvs rdiff -u -r1.74.6.3 -r1.74.6.4 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/specialreg.h
diff -u src/sys/arch/x86/include/specialreg.h:1.98.2.7 src/sys/arch/x86/include/specialreg.h:1.98.2.8
--- src/sys/arch/x86/include/specialreg.h:1.98.2.7	Sun Sep 23 17:35:33 2018
+++ src/sys/arch/x86/include/specialreg.h	Tue Dec  4 11:52:57 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: specialreg.h,v 1.98.2.7 2018/09/23 17:35:33 martin Exp $	*/
+/*	$NetBSD: specialreg.h,v 1.98.2.8 2018/12/04 11:52:57 martin Exp $	*/
 
 /*-
  * Copyright (c) 1991 The Regents of the University of California.
@@ -282,7 +282,25 @@
 #define CPUID_DCP_COMPLEX	__BIT(2)	/* Complex cache indexing */
 
 /*
- * Intel Digital Thermal Sensor and
+ * Intel/AMD MONITOR/MWAIT
+ * Fn0000_0005
+ */
+/* %eax */
+#define CPUID_MON_MINSIZE	__BITS(15, 0)  /* Smallest monitor-line size */
+/* %ebx */
+#define CPUID_MON_MAXSIZE	__BITS(15, 0)  /* Largest monitor-line size */
+/* %ecx */
+#define CPUID_MON_EMX		__BIT(0)       /* MONITOR/MWAIT Extensions */
+#define CPUID_MON_IBE		__BIT(1)       /* Interrupt as Break Event */
+
+#define CPUID_MON_FLAGS	"\20" \
+	"\1" "EMX"	"\2" "IBE"
+
+/* %edx: number of substates for specific C-state */
+#define CPUID_MON_SUBSTATE(edx, cstate) (((edx) >> (cstate * 4)) & 0x0000000f)
+
+/*
+ * Intel/AMD Digital Thermal Sensor and
  * Power Management, Fn0000_0006 - %eax.
  */
 #define CPUID_DSPM_DTS	__BIT(0)	/* Digital Thermal Sensor */
@@ -313,7 +331,7 @@
 	"25" "HWP_IGNIDL"
 
 /*
- * Intel Digital Thermal Sensor and
+ * Intel/AMD Digital Thermal Sensor and
  * Power Management, Fn0000_0006 - %ecx.
  */
 #define CPUID_DSPM_HWF	0x00000001	/* MSR_APERF/MSR_MPERF available */
@@ -322,7 +340,7 @@
 #define CPUID_DSPM_FLAGS1	"\20" "\1" "HWF" "\4" "EPB"
 
 /*
- * Intel Structured Extended Feature leaf Fn0000_0007
+ * Intel/AMD Structured Extended Feature leaf Fn0000_0007
  * %eax == 0: Subleaf 0
  *	%eax: The Maximum input value for supported subleaf.
  *	%ebx: Feature bits.
@@ -353,6 +371,7 @@
 #define CPUID_SEF_ADX		__BIT(19) /* ADCX/ADOX instructions */
 #define CPUID_SEF_SMAP		__BIT(20) /* Supervisor-Mode Access Prevention */
 #define CPUID_SEF_AVX512_IFMA	__BIT(21) /* AVX-512 Integer Fused Multiply Add */
+/* Bit 22 was PCOMMIT */
 #define CPUID_SEF_CLFLUSHOPT	__BIT(23) /* Cache Line FLUSH OPTimized */
 #define CPUID_SEF_CLWB		__BIT(24) /* Cache Line Write Back */
 #define CPUID_SEF_PT		__BIT(25) /* Processor Trace */
@@ -386,16 +405,18 @@
 #define CPUID_SEF_AVX512_VNNI	__BIT(11) /* Vector neural Network Instruction */
 #define CPUID_SEF_AVX512_BITALG	__BIT(12)
 #define CPUID_SEF_AVX512_VPOPCNTDQ __BIT(14)
+#define CPUID_SEF_MAWAU		__BITS(21, 17) /* MAWAU for BND{LD,ST}X */
 #define CPUID_SEF_RDPID		__BIT(22) /* RDPID and IA32_TSC_AUX */
 #define CPUID_SEF_SGXLC		__BIT(30) /* SGX Launch Configuration */
 
-#define CPUID_SEF_FLAGS1	"\20" \
-	"\1" "PREFETCHWT1" "\2" "AVX512_VBMI" "\3" "UMIP" "\4" "PKU"	\
-	"\5" "OSPKE"			"\7" "AVX512_VBMI2"		\
-	"\11" "GFNI"	"\12" "VAES"	"\13" "VPCLMULQDQ" "\14" "AVX512_VNNI"\
-	"\15" "AVX512_BITALG"		"\17" "AVX512_VPOPCNTDQ"	\
-					"\27" "RDPID"			\
-					"\37" "SGXLC"
+#define CPUID_SEF_FLAGS1	"\177\20" \
+	"b\0PREFETCHWT1\0" "b\1AVX512_VBMI\0" "b\2UMIP\0" "b\3PKU\0"	\
+	"b\4OSPKE\0"			"b\6AVX512_VBMI2\0"		\
+	"b\10GFNI\0"	"b\11VAES\0"	"b\12VPCLMULQDQ\0" "b\13AVX512_VNNI\0"\
+	"b\14AVX512_BITALG\0"		"b\16AVX512_VPOPCNTDQ\0"	\
+	"f\21\5MAWAU\0"							\
+					"b\26RDPID\0"			\
+					"b\36SGXLC\0"
 
 /* %edx */
 #define CPUID_SEF_AVX512_4VNNIW	__BIT(2)
@@ -412,7 +433,61 @@
 	"\35" "L1D_FLUSH" "\36" "ARCH_CAP"		"\40" "SSBD"
 
 /*
- * CPUID Processor extended state Enumeration Fn0000000d
+ * Intel CPUID Architectural Performance Monitoring Fn0000000a
+ *
+ * See also src/usr.sbin/tprof/arch/tprof_x86.c
+ */
+
+/* %eax */
+#define CPUID_PERF_VERSION	__BITS(7, 0)   /* Version ID */
+#define CPUID_PERF_NGPPC	__BITS(15, 8)  /* Num of G.P. perf counter */
+#define CPUID_PERF_NBWGPPC	__BITS(23, 16) /* Bit width of G.P. perfcnt */
+#define CPUID_PERF_BVECLEN	__BITS(31, 24) /* Length of EBX bit vector */
+
+#define CPUID_PERF_FLAGS0	"\177\20"	\
+	"f\0\10VERSION\0" "f\10\10GPCounter\0"	\
+	"f\20\10GPBitwidth\0" "f\30\10Vectorlen\0"
+
+/* %ebx */
+#define CPUID_PERF_CORECYCL	__BIT(0)       /* No core cycle */
+#define CPUID_PERF_INSTRETRY	__BIT(1)       /* No instruction retried */
+#define CPUID_PERF_REFCYCL	__BIT(2)       /* No reference cycles */
+#define CPUID_PERF_LLCREF	__BIT(3)       /* No LLCache reference */
+#define CPUID_PERF_LLCMISS	__BIT(4)       /* No LLCache miss */
+#define CPUID_PERF_BRINSRETR	__BIT(5)       /* No branch inst. retried */
+#define CPUID_PERF_BRMISPRRETR	__BIT(6)       /* No branch mispredict retry */
+
+#define CPUID_PERF_FLAGS1	"\177\20"				      \
+	"b\0\1CORECYCL\0" "b\1\1INSTRETRY\0" "b\2\1REFCYCL\0" "b\3\1LLCREF\0" \
+	"b\4\1LLCMISS\0" "b\5\1BRINSRETR\0" "b\6\1BRMISPRRETR\0"
+
+/* %edx */
+#define CPUID_PERF_NFFPC	__BITS(4, 0)   /* Num of fixed-funct perfcnt */
+#define CPUID_PERF_NBWFFPC	__BITS(12, 5)  /* Bit width of fixed-func pc */
+#define CPUID_PERF_ANYTHREADDEPR __BIT(15)      /* Any Thread deprecation */
+
+#define CPUID_PERF_FLAGS3	"\177\20"				\
+	"f\0\5FixedFunc\0" "f\5\10FFBitwidth\0" "b\17ANYTHREADDEPR\0"
+
+/*
+ * Intel CPUID Extended Topology Enumeration Fn0000000b
+ * %ecx == level number
+ *	%eax: See below.
+ *	%ebx: Number of logical processors at this level.
+ *	%ecx: See below.
+ *	%edx: x2APIC ID of the current logical processor.
+ */
+/* %eax */
+#define CPUID_TOP_SHIFTNUM	__BITS(4, 0) /* Topology ID shift value */
+/* %ecx */
+#define CPUID_TOP_LVLNUM	__BITS(7, 0) /* Level number */
+#define CPUID_TOP_LVLTYPE	__BITS(15, 8) /* Level type */
+#define CPUID_TOP_LVLTYPE_INVAL	0	 	/* Invalid */
+#define CPUID_TOP_LVLTYPE_SMT	1	 	/* SMT */
+#define CPUID_TOP_LVLTYPE_CORE	2	 	/* Core */
+
+/*
+ * Intel/AMD CPUID Processor extended state Enumeration Fn0000000d
  *
  * %ecx == 0: supported features info:
  *	%eax: Valid bits of lower 32bits of XCR0

Index: src/sys/arch/x86/x86/cpu_topology.c
diff -u src/sys/arch/x86/x86/cpu_topology.c:1.9.22.2 src/sys/arch/x86/x86/cpu_topology.c:1.9.22.3
--- src/sys/arch/x86/x86/cpu_topology.c:1.9.22.2	Mon Apr  9 18:12:50 2018
+++ src/sys/arch/x86/x86/cpu_topology.c	Tue Dec  4 11:52:57 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_topology.c,v 1.9.22.2 2018/04/09 18:12:50 martin Exp $	*/
+/*	$NetBSD: cpu_topology.c,v 1.9.22.3 2018/12/04 11:52:57 martin Exp $	*/
 
 /*-
  * Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>,
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.9.22.2 2018/04/09 18:12:50 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.9.22.3 2018/12/04 11:52:57 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/bitops.h>
@@ -92,7 +92,8 @@ x86_cpu_topology(struct cpu_info *ci)
 		if (ci->ci_max_cpuid >= 4) {
 			/* Maximum number of Cores per package (eax[31:26]). */
 			x86_cpuid2(4, 0, descs);
-			core_max = (descs[0] >> 26) + 1;
+			core_max = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG)
+			    + 1;
 		} else {
 			core_max = 1;
 		}

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.74.6.3 src/usr.sbin/cpuctl/arch/i386.c:1.74.6.4
--- src/usr.sbin/cpuctl/arch/i386.c:1.74.6.3	Mon Apr  9 18:04:32 2018
+++ src/usr.sbin/cpuctl/arch/i386.c	Tue Dec  4 11:52:57 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.74.6.3 2018/04/09 18:04:32 martin Exp $	*/
+/*	$NetBSD: i386.c,v 1.74.6.4 2018/12/04 11:52:57 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.3 2018/04/09 18:04:32 martin Exp $");
+__RCSID("$NetBSD: i386.c,v 1.74.6.4 2018/12/04 11:52:57 martin Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -92,13 +92,13 @@ __RCSID("$NetBSD: i386.c,v 1.74.6.3 2018
 
 struct cpu_info {
 	const char	*ci_dev;
-	int32_t		ci_cpu_type;     /* for cpu's without cpuid */
+	int32_t		ci_cpu_type;	 /* for cpu's without cpuid */
 	int32_t		ci_cpuid_level;	 /* highest cpuid supported */
 	uint32_t	ci_cpuid_extlevel; /* highest cpuid extended func lv */
 	uint32_t	ci_signature;	 /* X86 cpuid type */
 	uint32_t	ci_family;	 /* from ci_signature */
 	uint32_t	ci_model;	 /* from ci_signature */
-	uint32_t	ci_feat_val[9];	 /* X86 CPUID feature bits
+	uint32_t	ci_feat_val[10]; /* X86 CPUID feature bits
 					  *	[0] basic features %edx
 					  *	[1] basic features %ecx
 					  *	[2] extended features %edx
@@ -106,8 +106,9 @@ struct cpu_info {
 					  *	[4] VIA padlock features
 					  *	[5] structure ext. feat. %ebx
 					  *	[6] structure ext. feat. %ecx
-					  *	[7] XCR0 bits (d:0 %eax)
-					  *	[8] xsave flags (d:1 %eax)
+					  *     [7] structure ext. feat. %edx
+					  *	[8] XCR0 bits (d:0 %eax)
+					  *	[9] xsave flags (d:1 %eax)
 					  */
 	uint32_t	ci_cpu_class;	 /* CPU class */
 	uint32_t	ci_brand_id;	 /* Intel brand id */
@@ -161,9 +162,9 @@ static const struct x86_cache_info intel
 static const char * const i386_intel_brand[] = {
 	"",		    /* Unsupported */
 	"Celeron",	    /* Intel (R) Celeron (TM) processor */
-	"Pentium III",      /* Intel (R) Pentium (R) III processor */
+	"Pentium III",	    /* Intel (R) Pentium (R) III processor */
 	"Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */
-	"Pentium III",      /* Intel (R) Pentium (R) III processor */
+	"Pentium III",	    /* Intel (R) Pentium (R) III processor */
 	"",		    /* 0x05: Reserved */
 	"Mobile Pentium III",/* Mobile Intel (R) Pentium (R) III processor-M */
 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */    
@@ -177,11 +178,11 @@ static const char * const i386_intel_bra
 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
 	"",		    /* 0x10: Reserved */
 	"Mobile Genuine",   /* Moblie Genuine Intel (R) processor */
-	"Celeron M",        /* Intel (R) Celeron (R) M processor */
+	"Celeron M",	    /* Intel (R) Celeron (R) M processor */
 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
-	"Celeron",          /* Intel (R) Celeron (R) processor */
+	"Celeron",	    /* Intel (R) Celeron (R) processor */
 	"Mobile Genuine",   /* Moblie Genuine Intel (R) processor */
-	"Pentium M",        /* Intel (R) Pentium (R) M processor */
+	"Pentium M",	    /* Intel (R) Pentium (R) M processor */
 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
 };
 
@@ -215,8 +216,8 @@ static void	powernow_probe(struct cpu_in
 static void	intel_family_new_probe(struct cpu_info *);
 static void	via_cpu_probe(struct cpu_info *);
 /* (Cache) Info functions */
-static void 	intel_cpu_cacheinfo(struct cpu_info *);
-static void 	amd_cpu_cacheinfo(struct cpu_info *);
+static void	intel_cpu_cacheinfo(struct cpu_info *);
+static void	amd_cpu_cacheinfo(struct cpu_info *);
 static void	via_cpu_cacheinfo(struct cpu_info *);
 static void	tmx86_get_longrun_status(u_int *, u_int *, u_int *);
 static void	transmeta_cpu_info(struct cpu_info *);
@@ -251,7 +252,7 @@ const struct cpu_nocpuid_nameclass i386_
 	  NULL, NULL, NULL },			/* CPU_486DLC */
 	{ CPUVENDOR_CYRIX, "Cyrix", "6x86",	CPUCLASS_486,
 	  NULL, NULL, NULL },		/* CPU_6x86 */
-	{ CPUVENDOR_NEXGEN,"NexGen","586",      CPUCLASS_386,
+	{ CPUVENDOR_NEXGEN,"NexGen","586",	CPUCLASS_386,
 	  NULL, NULL, NULL },			/* CPU_NX586 */
 };
 
@@ -1672,19 +1673,20 @@ cpu_probe_base_features(struct cpu_info 
 	x86_cpuid(7, descs);
 	ci->ci_feat_val[5] = descs[1];
 	ci->ci_feat_val[6] = descs[2];
+	ci->ci_feat_val[7] = descs[3];
 
 	if (ci->ci_cpuid_level < 0xd)
 		return;
 
 	/* Get support XCR0 bits */
 	x86_cpuid2(0xd, 0, descs);
-	ci->ci_feat_val[7] = descs[0];	/* Actually 64 bits */
+	ci->ci_feat_val[8] = descs[0];	/* Actually 64 bits */
 	ci->ci_cur_xsave = descs[1];
 	ci->ci_max_xsave = descs[2];
 
 	/* Additional flags (eg xsaveopt support) */
 	x86_cpuid2(0xd, 1, descs);
-	ci->ci_feat_val[8] = descs[0];   /* Actually 64 bits */
+	ci->ci_feat_val[9] = descs[0];	 /* Actually 64 bits */
 }
 
 static void
@@ -1784,23 +1786,14 @@ print_bits(const char *cpuname, const ch
 }
 
 static void
-identifycpu_cpuids(struct cpu_info *ci)
+identifycpu_cpuids_intel_0x04(struct cpu_info *ci)
 {
-	const char *cpuname = ci->ci_dev;
 	u_int lp_max = 1;	/* logical processors per package */
 	u_int smt_max;		/* smt per core */
 	u_int core_max = 1;	/* core per package */
 	u_int smt_bits, core_bits;
 	uint32_t descs[4];
 
-	aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid);
-	ci->ci_packageid = ci->ci_initapicid;
-	ci->ci_coreid = 0;
-	ci->ci_smtid = 0;
-	if (cpu_vendor != CPUVENDOR_INTEL) {
-		return;
-	}
-
 	/*
 	 * 253668.pdf 7.10.2
 	 */
@@ -1809,32 +1802,110 @@ identifycpu_cpuids(struct cpu_info *ci)
 		x86_cpuid(1, descs);
 		lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES);
 	}
-	if (ci->ci_cpuid_level >= 4) {
-		x86_cpuid2(4, 0, descs);
-		core_max = (descs[0] >> 26) + 1;
-	}
+	x86_cpuid2(4, 0, descs);
+	core_max = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG) + 1;
+
 	assert(lp_max >= core_max);
 	smt_max = lp_max / core_max;
 	smt_bits = ilog2(smt_max - 1) + 1;
 	core_bits = ilog2(core_max - 1) + 1;
-	if (smt_bits + core_bits) {
+
+	if (smt_bits + core_bits)
 		ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits);
+
+	if (core_bits)
+		ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid,
+		    __BITS(smt_bits, smt_bits + core_bits - 1));
+
+	if (smt_bits)
+		ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid,
+		    __BITS((int)0, (int)(smt_bits - 1)));
+}
+
+static void
+identifycpu_cpuids_intel_0x0b(struct cpu_info *ci)
+{
+	const char *cpuname = ci->ci_dev;
+	u_int smt_bits, core_bits, core_shift = 0, pkg_shift = 0;
+	uint32_t descs[4];
+	int i;
+
+	x86_cpuid(0x0b, descs);
+	if (descs[1] == 0) {
+		identifycpu_cpuids_intel_0x04(ci);
+		return;
+	}
+
+	for (i = 0; ; i++) {
+		unsigned int shiftnum, lvltype;
+		x86_cpuid2(0x0b, i, descs);
+
+		/* On invalid level, (EAX and) EBX return 0 */
+		if (descs[1] == 0)
+			break;
+
+		shiftnum = __SHIFTOUT(descs[0], CPUID_TOP_SHIFTNUM);
+		lvltype = __SHIFTOUT(descs[2], CPUID_TOP_LVLTYPE);
+		switch (lvltype) {
+		case CPUID_TOP_LVLTYPE_SMT:
+			core_shift = shiftnum;
+			break;
+		case CPUID_TOP_LVLTYPE_CORE:
+			pkg_shift = shiftnum;
+			break;
+		case CPUID_TOP_LVLTYPE_INVAL:
+			aprint_verbose("%s: Invalid level type\n", cpuname);
+			break;
+		default:
+			aprint_verbose("%s: Unknown level type(%d) \n",
+			    cpuname, lvltype);
+			break;
+		}
 	}
+
+	assert(pkg_shift >= core_shift);
+	smt_bits = core_shift;
+	core_bits = pkg_shift - core_shift;
+
+	ci->ci_packageid = ci->ci_initapicid >> pkg_shift;
+
+	if (core_bits)
+		ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid,
+		    __BITS(core_shift, pkg_shift - 1));
+
+	if (smt_bits)
+		ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid,
+		    __BITS((int)0, core_shift - 1));
+}
+
+static void
+identifycpu_cpuids_intel(struct cpu_info *ci)
+{
+	const char *cpuname = ci->ci_dev;
+
+	if (ci->ci_cpuid_level >= 0x0b)
+		identifycpu_cpuids_intel_0x0b(ci);
+	else if (ci->ci_cpuid_level >= 4)
+		identifycpu_cpuids_intel_0x04(ci);
+
 	aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
 	    ci->ci_packageid);
-	if (core_bits) {
-		u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1);
+	aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
+	aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
+}
 
-		ci->ci_coreid =
-		    __SHIFTOUT(ci->ci_initapicid, core_mask);
-		aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
-	}
-	if (smt_bits) {
-		u_int smt_mask = __BITS((int)0, (int)(smt_bits - 1));
+static void
+identifycpu_cpuids(struct cpu_info *ci)
+{
+	const char *cpuname = ci->ci_dev;
 
-		ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, smt_mask);
-		aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
-	}
+	aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid);
+	ci->ci_packageid = ci->ci_initapicid;
+	ci->ci_coreid = 0;
+	ci->ci_smtid = 0;
+
+	if (cpu_vendor == CPUVENDOR_INTEL)
+		identifycpu_cpuids_intel(ci);
 }
 
 void
@@ -1928,7 +1999,7 @@ identifycpu(int fd, const char *cpuname)
 			cpufam = &cpup->cpu_family[family - CPU_MINFAMILY];
 			name = cpufam->cpu_models[ci->ci_model];
 			if (name == NULL || *name == '\0')
-			    name = cpufam->cpu_model_default;
+				name = cpufam->cpu_model_default;
 			class = cpufam->cpu_class;
 			ci->ci_info = cpufam->cpu_info;
 
@@ -1944,7 +2015,7 @@ identifycpu(int fd, const char *cpuname)
 				    __arraycount(i386_intel_brand) &&
 				    i386_intel_brand[ci->ci_brand_id])
 					name =
-					     i386_intel_brand[ci->ci_brand_id];
+					    i386_intel_brand[ci->ci_brand_id];
 			}
 
 			if (cpu_vendor == CPUVENDOR_AMD) {
@@ -2034,22 +2105,21 @@ identifycpu(int fd, const char *cpuname)
 	if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD))
 		print_bits(cpuname, "features5", CPUID_SEF_FLAGS,
 		    ci->ci_feat_val[5]);
-	if (cpu_vendor == CPUVENDOR_INTEL)
+	if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD))
 		print_bits(cpuname, "features6", CPUID_SEF_FLAGS1,
 		    ci->ci_feat_val[6]);
 
-	if ((cpu_vendor == CPUVENDOR_INTEL) && (ci->ci_cpuid_level >= 7)) {
-		x86_cpuid(7, descs);
-		print_bits(cpuname, "SEF edx", CPUID_SEF_FLAGS2, descs[3]);
-	}
+	if (cpu_vendor == CPUVENDOR_INTEL)
+		print_bits(cpuname, "features7", CPUID_SEF_FLAGS2,
+		    ci->ci_feat_val[7]);
 
-	print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[7]);
+	print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[8]);
 	print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS,
-	    ci->ci_feat_val[8]);
+	    ci->ci_feat_val[9]);
 
 	if (ci->ci_max_xsave != 0) {
 		aprint_normal("%s: xsave area size: current %d, maximum %d",
-			cpuname, ci->ci_cur_xsave, ci->ci_max_xsave);
+		    cpuname, ci->ci_cur_xsave, ci->ci_max_xsave);
 		aprint_normal(", xgetbv %sabled\n",
 		    ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis");
 		if (ci->ci_feat_val[1] & CPUID2_OSXSAVE)
@@ -2090,56 +2160,85 @@ identifycpu(int fd, const char *cpuname)
 
 	identifycpu_cpuids(ci);
 
-#ifdef INTEL_CORETEMP
-	if (cpu_vendor == CPUVENDOR_INTEL && ci->ci_cpuid_level >= 0x06)
-		coretemp_register(ci);
-#endif
+	if ((ci->ci_cpuid_level >= 5)
+	    && ((cpu_vendor == CPUVENDOR_INTEL)
+		|| (cpu_vendor == CPUVENDOR_AMD))) {
+		uint16_t lmin, lmax;
+		x86_cpuid(5, descs);
+		
+		print_bits(cpuname, "MONITOR/MWAIT extensions",
+		    CPUID_MON_FLAGS, descs[2]);
+		lmin = __SHIFTOUT(descs[0], CPUID_MON_MINSIZE);
+		lmax = __SHIFTOUT(descs[1], CPUID_MON_MAXSIZE);
+		aprint_normal("%s: monitor-line size %hu", cpuname, lmin);
+		if (lmin != lmax)
+			aprint_normal("-%hu", lmax);
+		aprint_normal("\n");
+
+		for (i = 0; i <= 7; i++) {
+			unsigned int num = CPUID_MON_SUBSTATE(descs[3], i);
+
+			if (num != 0)
+				aprint_normal("%s: C%u substates %u\n",
+				    cpuname, i, num);
+		}
+	}
+	if ((ci->ci_cpuid_level >= 6)
+	    && ((cpu_vendor == CPUVENDOR_INTEL)
+		|| (cpu_vendor == CPUVENDOR_AMD))) {
+		x86_cpuid(6, descs);
+		print_bits(cpuname, "DSPM-eax", CPUID_DSPM_FLAGS, descs[0]);
+		print_bits(cpuname, "DSPM-ecx", CPUID_DSPM_FLAGS1, descs[2]);
+	}
+	if ((ci->ci_cpuid_level >= 7)
+	    && ((cpu_vendor == CPUVENDOR_INTEL)
+		|| (cpu_vendor == CPUVENDOR_AMD))) {
+		x86_cpuid(7, descs);
+		aprint_verbose("%s: SEF highest subleaf %08x\n",
+		    cpuname, descs[0]);
+	}
 
 	if (cpu_vendor == CPUVENDOR_AMD) {
-		uint32_t data[4];
-
-		x86_cpuid(0x80000000, data);
-		if (data[0] >= 0x80000007)
+		x86_cpuid(0x80000000, descs);
+		if (descs[0] >= 0x80000007)
 			powernow_probe(ci);
 
-		if ((data[0] >= 0x8000000a)
-		   && (ci->ci_feat_val[3] & CPUID_SVM) != 0) {
-			x86_cpuid(0x8000000a, data);
+		if ((descs[0] >= 0x8000000a)
+		    && (ci->ci_feat_val[3] & CPUID_SVM) != 0) {
+			x86_cpuid(0x8000000a, descs);
 			aprint_verbose("%s: SVM Rev. %d\n", cpuname,
-			    data[0] & 0xf);
-			aprint_verbose("%s: SVM NASID %d\n", cpuname, data[1]);
-			print_bits(cpuname, "SVM features", CPUID_AMD_SVM_FLAGS,
-				   data[3]);
+			    descs[0] & 0xf);
+			aprint_verbose("%s: SVM NASID %d\n", cpuname,
+			    descs[1]);
+			print_bits(cpuname, "SVM features",
+			    CPUID_AMD_SVM_FLAGS, descs[3]);
 		}
 	} else if (cpu_vendor == CPUVENDOR_INTEL) {
-		uint32_t data[4];
 		int32_t bi_index;
 
 		for (bi_index = 1; bi_index <= ci->ci_cpuid_level; bi_index++) {
-			x86_cpuid(bi_index, data);
+			x86_cpuid(bi_index, descs);
 			switch (bi_index) {
-			case 6:
-				print_bits(cpuname, "DSPM-eax",
-				    CPUID_DSPM_FLAGS, data[0]);
-				print_bits(cpuname, "DSPM-ecx",
-				    CPUID_DSPM_FLAGS1, data[2]);
-				break;
-			case 7:
-				aprint_verbose("%s: SEF highest subleaf %08x\n",
-				    cpuname, data[0]);
+			case 0x0a:
+				print_bits(cpuname, "Perfmon-eax",
+				    CPUID_PERF_FLAGS0, descs[0]);
+				print_bits(cpuname, "Perfmon-ebx",
+				    CPUID_PERF_FLAGS1, descs[1]);
+				print_bits(cpuname, "Perfmon-edx",
+				    CPUID_PERF_FLAGS3, descs[3]);
 				break;
-#if 0
 			default:
+#if 0
 				aprint_verbose("%s: basic %08x-eax %08x\n",
-				    cpuname, bi_index, data[0]);
+				    cpuname, bi_index, descs[0]);
 				aprint_verbose("%s: basic %08x-ebx %08x\n",
-				    cpuname, bi_index, data[1]);
+				    cpuname, bi_index, descs[1]);
 				aprint_verbose("%s: basic %08x-ecx %08x\n",
-				    cpuname, bi_index, data[2]);
+				    cpuname, bi_index, descs[2]);
 				aprint_verbose("%s: basic %08x-edx %08x\n",
-				    cpuname, bi_index, data[3]);
-				break;
+				    cpuname, bi_index, descs[3]);
 #endif
+				break;
 			}
 		}
 	}
@@ -2176,7 +2275,7 @@ identifycpu(int fd, const char *cpuname)
 		printf("%s: UCode version: 0x%"PRIx64"\n", cpuname, ucvers.amd.version);
 	else if (cpu_vendor == CPUVENDOR_INTEL)
 		printf("%s: microcode version 0x%x, platform ID %d\n", cpuname,
-		       ucvers.intel1.ucodeversion, ucvers.intel1.platformid);
+		    ucvers.intel1.ucodeversion, ucvers.intel1.platformid);
 }
 
 static const struct x86_cache_info *
@@ -2213,14 +2312,14 @@ print_cache_config(struct cpu_info *ci, 
 		aprint_verbose("%s ", cai->cai_string);
 	} else {
 		(void)humanize_number(human_num, sizeof(human_num),
-			cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
+		    cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
 		aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize);
 	}
 	switch (cai->cai_associativity) {
-	case    0:
+	case	0:
 		aprint_verbose("disabled");
 		break;
-	case    1:
+	case	1:
 		aprint_verbose("direct-mapped");
 		break;
 	case 0xff:
@@ -2254,7 +2353,7 @@ print_tlb_config(struct cpu_info *ci, in
 		aprint_verbose("%s", cai->cai_string);
 	} else {
 		(void)humanize_number(human_num, sizeof(human_num),
-			cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
+		    cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
 		aprint_verbose("%d %s entries ", cai->cai_totalsize,
 		    human_num);
 		switch (cai->cai_associativity) {
@@ -2299,7 +2398,7 @@ x86_print_cache_and_tlb_info(struct cpu_
 	}
 	if (ci->ci_cinfo[CAI_PREFETCH].cai_linesize != 0) {
 		aprint_verbose_dev(ci->ci_dev, "%dB prefetching",
-			ci->ci_cinfo[CAI_PREFETCH].cai_linesize);
+		    ci->ci_cinfo[CAI_PREFETCH].cai_linesize);
 		if (sep != NULL)
 			aprint_verbose("\n");
 	}

Reply via email to