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/3af66443e961
branches:  trunk
changeset: 837158:3af66443e961
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 f0cbd688227b -r 3af66443e961 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