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