Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/cpuctl/arch Decode package, core and SMT id if CPUI...
details: https://anonhg.NetBSD.org/src/rev/b9b47e294657
branches: trunk
changeset: 446042:b9b47e294657
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Nov 21 12:19:51 2018 +0000
description:
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.
diffstat:
usr.sbin/cpuctl/arch/i386.c | 125 ++++++++++++++++++++++++++++++++++---------
1 files changed, 97 insertions(+), 28 deletions(-)
diffs (170 lines):
diff -r c31984fdf11e -r b9b47e294657 usr.sbin/cpuctl/arch/i386.c
--- a/usr.sbin/cpuctl/arch/i386.c Wed Nov 21 12:18:53 2018 +0000
+++ b/usr.sbin/cpuctl/arch/i386.c Wed Nov 21 12:19:51 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: i386.c,v 1.87 2018/11/21 10:34:53 msaitoh Exp $ */
+/* $NetBSD: i386.c,v 1.88 2018/11/21 12:19:51 msaitoh 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.87 2018/11/21 10:34:53 msaitoh Exp $");
+__RCSID("$NetBSD: i386.c,v 1.88 2018/11/21 12:19:51 msaitoh Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -1786,23 +1786,14 @@
}
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
*/
@@ -1811,32 +1802,110 @@
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 = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG) + 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
Home |
Main Index |
Thread Index |
Old Index