Author: jeff
Date: Wed Apr 29 06:54:40 2009
New Revision: 191648
URL: http://svn.freebsd.org/changeset/base/191648

Log:
   - Add support for cpuid leaf 0xb.  This allows us to determine the
     topology of nehalem/corei7 based systems.
   - Remove the cpu_cores/cpu_logical detection from identcpu.
   - Describe the layout of the system in cpu_mp_announce().
  
  Sponsored by:   Nokia

Modified:
  head/sys/amd64/amd64/identcpu.c
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/include/smp.h
  head/sys/amd64/include/specialreg.h
  head/sys/i386/i386/identcpu.c
  head/sys/i386/i386/mp_machdep.c
  head/sys/i386/include/smp.h
  head/sys/i386/include/specialreg.h

Modified: head/sys/amd64/amd64/identcpu.c
==============================================================================
--- head/sys/amd64/amd64/identcpu.c     Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/amd64/amd64/identcpu.c     Wed Apr 29 06:54:40 2009        
(r191648)
@@ -106,9 +106,6 @@ static struct {
        { CENTAUR_VENDOR_ID,    CPU_VENDOR_CENTAUR },   /* CentaurHauls */
 };
 
-int cpu_cores;
-int cpu_logical;
-
 
 extern int pq_l2size;
 extern int pq_l2nways;
@@ -195,7 +192,6 @@ printcpuinfo(void)
            cpu_vendor_id == CPU_VENDOR_CENTAUR) {
                printf("  Stepping = %u", cpu_id & 0xf);
                if (cpu_high > 0) {
-                       u_int cmp = 1, htt = 1;
 
                        /*
                         * Here we should probably set up flags indicating
@@ -400,28 +396,6 @@ printcpuinfo(void)
                        if (tsc_is_invariant)
                                printf("\n  TSC: P-state invariant");
 
-                       /*
-                        * If this CPU supports HTT or CMP then mention the
-                        * number of physical/logical cores it contains.
-                        */
-                       if (cpu_feature & CPUID_HTT)
-                               htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
-                       if (cpu_vendor_id == CPU_VENDOR_AMD &&
-                           (amd_feature2 & AMDID2_CMP))
-                               cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
-                       else if (cpu_vendor_id == CPU_VENDOR_INTEL &&
-                           (cpu_high >= 4)) {
-                               cpuid_count(4, 0, regs);
-                               if ((regs[0] & 0x1f) != 0)
-                                       cmp = ((regs[0] >> 26) & 0x3f) + 1;
-                       }
-                       cpu_cores = cmp;
-                       cpu_logical = htt / cmp;
-                       if (cmp > 1)
-                               printf("\n  Cores per package: %d", cmp);
-                       if ((htt / cmp) > 1)
-                               printf("\n  Logical CPUs per core: %d",
-                                   cpu_logical);
                }
        }
        /* Avoid ugly blank lines: only print newline when we have to. */

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c   Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/amd64/amd64/mp_machdep.c   Wed Apr 29 06:54:40 2009        
(r191648)
@@ -160,6 +160,8 @@ int apic_cpuids[MAX_APIC_ID + 1];
 static volatile u_int cpu_ipi_pending[MAXCPU];
 
 static u_int boot_address;
+static int cpu_logical;
+static int cpu_cores;
 
 static void    assign_cpu_ids(void);
 static void    set_interrupt_apic_ids(void);
@@ -181,13 +183,142 @@ mem_range_AP_init(void)
                mem_range_softc.mr_op->initAP(&mem_range_softc);
 }
 
-struct cpu_group *
-cpu_topo(void)
+static void
+topo_probe_0xb(void)
+{
+       int logical;
+       int p[4];
+       int bits;
+       int type;
+       int cnt;
+       int i;
+       int x;
+
+       /* We only support two levels for now. */
+       for (i = 0; i < 3; i++) {
+               cpuid_count(0x0B, i, p);
+               bits = p[0] & 0x1f;
+               logical = p[1] &= 0xffff;
+               type = (p[2] >> 8) & 0xff;
+               if (type == 0 || logical == 0)
+                       break;
+               for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
+                       if (!cpu_info[x].cpu_present ||
+                           cpu_info[x].cpu_disabled)
+                               continue;
+                       if (x >> bits == boot_cpu_id >> bits)
+                               cnt++;
+               }
+               if (type == CPUID_TYPE_SMT)
+                       cpu_logical = cnt;
+               else if (type == CPUID_TYPE_CORE)
+                       cpu_cores = cnt;
+       }
+       if (cpu_logical == 0)
+               cpu_logical = 1;
+       cpu_cores /= cpu_logical;
+}
+
+static void
+topo_probe_0x4(void)
+{
+       u_int threads_per_cache, p[4];
+       u_int htt, cmp;
+       int i;
+
+       htt = cmp = 1;
+       /*
+        * If this CPU supports HTT or CMP then mention the
+        * number of physical/logical cores it contains.
+        */
+       if (cpu_feature & CPUID_HTT)
+               htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+       if (cpu_vendor_id == CPU_VENDOR_AMD && (amd_feature2 & AMDID2_CMP))
+               cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+       else if (cpu_vendor_id == CPU_VENDOR_INTEL && (cpu_high >= 4)) {
+               cpuid_count(4, 0, p);
+               if ((p[0] & 0x1f) != 0)
+                       cmp = ((p[0] >> 26) & 0x3f) + 1;
+       }
+       cpu_cores = cmp;
+       cpu_logical = htt / cmp;
+
+       /* Setup the initial logical CPUs info. */
+       if (cpu_feature & CPUID_HTT)
+               logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+
+       /*
+        * Work out if hyperthreading is *really* enabled.  This
+        * is made really ugly by the fact that processors lie: Dual
+        * core processors claim to be hyperthreaded even when they're
+        * not, presumably because they want to be treated the same
+        * way as HTT with respect to per-cpu software licensing.
+        * At the time of writing (May 12, 2005) the only hyperthreaded
+        * cpus are from Intel, and Intel's dual-core processors can be
+        * identified via the "deterministic cache parameters" cpuid
+        * calls.
+        */
+       /*
+        * First determine if this is an Intel processor which claims
+        * to have hyperthreading support.
+        */
+       if ((cpu_feature & CPUID_HTT) && cpu_vendor_id == CPU_VENDOR_INTEL) {
+               /*
+                * If the "deterministic cache parameters" cpuid calls
+                * are available, use them.
+                */
+               if (cpu_high >= 4) {
+                       /* Ask the processor about the L1 cache. */
+                       for (i = 0; i < 1; i++) {
+                               cpuid_count(4, i, p);
+                               threads_per_cache = ((p[0] & 0x3ffc000) >> 14) 
+ 1;
+                               if (hyperthreading_cpus < threads_per_cache)
+                                       hyperthreading_cpus = threads_per_cache;
+                               if ((p[0] & 0x1f) == 0)
+                                       break;
+                       }
+               }
+
+               /*
+                * If the deterministic cache parameters are not
+                * available, or if no caches were reported to exist,
+                * just accept what the HTT flag indicated.
+                */
+               if (hyperthreading_cpus == 0)
+                       hyperthreading_cpus = logical_cpus;
+       }
+}
+
+static void
+topo_probe(void)
 {
+
+       logical_cpus = logical_cpus_mask = 0;
+       if (cpu_high >= 0xb)
+               topo_probe_0xb();
+       else if (cpu_high)
+               topo_probe_0x4();
        if (cpu_cores == 0)
-               cpu_cores = 1;
+               cpu_cores = mp_ncpus;
        if (cpu_logical == 0)
                cpu_logical = 1;
+}
+
+struct cpu_group *
+cpu_topo(void)
+{
+       int cg_flags;
+
+       /*
+        * Determine whether any threading flags are
+        * necessry.
+        */
+       if (cpu_logical > 1 && hyperthreading_cpus)
+               cg_flags = CG_FLAG_HTT;
+       else if (cpu_logical > 1)
+               cg_flags = CG_FLAG_SMT;
+       else
+               cg_flags = 0;
        if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
                printf("WARNING: Non-uniform processors.\n");
                printf("WARNING: Using suboptimal topology.\n");
@@ -202,17 +333,17 @@ cpu_topo(void)
         * Only HTT no multi-core.
         */
        if (cpu_logical > 1 && cpu_cores == 1)
-               return (smp_topo_1level(CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
+               return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
        /*
         * Only multi-core no HTT.
         */
        if (cpu_cores > 1 && cpu_logical == 1)
-               return (smp_topo_1level(CG_SHARE_NONE, cpu_cores, 0));
+               return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
        /*
         * Both HTT and multi-core.
         */
-       return (smp_topo_2level(CG_SHARE_NONE, cpu_cores,
-           CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
+       return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
+           CG_SHARE_L1, cpu_logical, cg_flags));
 }
 
 /*
@@ -318,7 +449,6 @@ void
 cpu_mp_start(void)
 {
        int i;
-       u_int threads_per_cache, p[4];
 
        /* Initialize the logical ID to APIC ID table. */
        for (i = 0; i < MAXCPU; i++) {
@@ -355,51 +485,8 @@ cpu_mp_start(void)
                KASSERT(boot_cpu_id == PCPU_GET(apic_id),
                    ("BSP's APIC ID doesn't match boot_cpu_id"));
 
-       /* Setup the initial logical CPUs info. */
-       logical_cpus = logical_cpus_mask = 0;
-       if (cpu_feature & CPUID_HTT)
-               logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
-
-       /*
-        * Work out if hyperthreading is *really* enabled.  This
-        * is made really ugly by the fact that processors lie: Dual
-        * core processors claim to be hyperthreaded even when they're
-        * not, presumably because they want to be treated the same
-        * way as HTT with respect to per-cpu software licensing.
-        * At the time of writing (May 12, 2005) the only hyperthreaded
-        * cpus are from Intel, and Intel's dual-core processors can be
-        * identified via the "deterministic cache parameters" cpuid
-        * calls.
-        */
-       /*
-        * First determine if this is an Intel processor which claims
-        * to have hyperthreading support.
-        */
-       if ((cpu_feature & CPUID_HTT) && cpu_vendor_id == CPU_VENDOR_INTEL) {
-               /*
-                * If the "deterministic cache parameters" cpuid calls
-                * are available, use them.
-                */
-               if (cpu_high >= 4) {
-                       /* Ask the processor about the L1 cache. */
-                       for (i = 0; i < 1; i++) {
-                               cpuid_count(4, i, p);
-                               threads_per_cache = ((p[0] & 0x3ffc000) >> 14) 
+ 1;
-                               if (hyperthreading_cpus < threads_per_cache)
-                                       hyperthreading_cpus = threads_per_cache;
-                               if ((p[0] & 0x1f) == 0)
-                                       break;
-                       }
-               }
-
-               /*
-                * If the deterministic cache parameters are not
-                * available, or if no caches were reported to exist,
-                * just accept what the HTT flag indicated.
-                */
-               if (hyperthreading_cpus == 0)
-                       hyperthreading_cpus = logical_cpus;
-       }
+       /* Probe logical/physical core configuration. */
+       topo_probe();
 
        assign_cpu_ids();
 
@@ -419,6 +506,14 @@ cpu_mp_announce(void)
        const char *hyperthread;
        int i;
 
+       printf("FreeBSD/SMP: %d package(s) x %d core(s)",
+           mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
+       if (hyperthreading_cpus > 1)
+           printf(" x %d HTT threads", cpu_logical);
+       else if (cpu_logical > 1)
+           printf(" x %d SMT threads", cpu_logical);
+       printf("\n");
+
        /* List active CPUs first. */
        printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
        for (i = 1; i < mp_ncpus; i++) {

Modified: head/sys/amd64/include/smp.h
==============================================================================
--- head/sys/amd64/include/smp.h        Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/amd64/include/smp.h        Wed Apr 29 06:54:40 2009        
(r191648)
@@ -36,10 +36,6 @@ extern int                   boot_cpu_id;
 extern struct pcb              stoppcbs[];
 extern int                     cpu_apic_ids[];
 
-/* global data in identcpu.c */
-extern int                     cpu_cores;
-extern int                     cpu_logical;
-
 /* IPI handlers */
 inthand_t
        IDTVEC(invltlb),        /* TLB shootdowns - global */

Modified: head/sys/amd64/include/specialreg.h
==============================================================================
--- head/sys/amd64/include/specialreg.h Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/amd64/include/specialreg.h Wed Apr 29 06:54:40 2009        
(r191648)
@@ -183,6 +183,13 @@
 #define        CPUID_HTT_CORES         0x00ff0000
 #define        CPUID_LOCAL_APIC_ID     0xff000000
 
+/* 
+ * CPUID instruction 0xb ebx info.
+ */
+#define        CPUID_TYPE_INVAL        0
+#define        CPUID_TYPE_SMT          1
+#define        CPUID_TYPE_CORE         2
+
 /*
  * AMD extended function 8000_0007h edx info
  */

Modified: head/sys/i386/i386/identcpu.c
==============================================================================
--- head/sys/i386/i386/identcpu.c       Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/i386/i386/identcpu.c       Wed Apr 29 06:54:40 2009        
(r191648)
@@ -159,9 +159,6 @@ static struct {
 #endif
 };
 
-int cpu_cores;
-int cpu_logical;
-
 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
 int has_f00f_bug = 0;          /* Initialized so that it can be patched. */
 #endif
@@ -690,7 +687,6 @@ printcpuinfo(void)
                if (cpu_vendor_id == CPU_VENDOR_CYRIX)
                        printf("  DIR=0x%04x", cyrix_did);
                if (cpu_high > 0) {
-                       u_int cmp = 1, htt = 1;
 
                        /*
                         * Here we should probably set up flags indicating
@@ -895,28 +891,6 @@ printcpuinfo(void)
                        if (tsc_is_invariant)
                                printf("\n  TSC: P-state invariant");
 
-                       /*
-                        * If this CPU supports HTT or CMP then mention the
-                        * number of physical/logical cores it contains.
-                        */
-                       if (cpu_feature & CPUID_HTT)
-                               htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
-                       if (cpu_vendor_id == CPU_VENDOR_AMD &&
-                           (amd_feature2 & AMDID2_CMP))
-                               cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
-                       else if (cpu_vendor_id == CPU_VENDOR_INTEL &&
-                           (cpu_high >= 4)) {
-                               cpuid_count(4, 0, regs);
-                               if ((regs[0] & 0x1f) != 0)
-                                       cmp = ((regs[0] >> 26) & 0x3f) + 1;
-                       }
-                       cpu_cores = cmp;
-                       cpu_logical = htt / cmp;
-                       if (cmp > 1)
-                               printf("\n  Cores per package: %d", cmp);
-                       if ((htt / cmp) > 1)
-                               printf("\n  Logical CPUs per core: %d",
-                                   cpu_logical);
                }
        } else if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
                printf("  DIR=0x%04x", cyrix_did);

Modified: head/sys/i386/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c     Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/i386/i386/mp_machdep.c     Wed Apr 29 06:54:40 2009        
(r191648)
@@ -213,6 +213,8 @@ int apic_cpuids[MAX_APIC_ID + 1];
 static volatile u_int cpu_ipi_pending[MAXCPU];
 
 static u_int boot_address;
+static int cpu_logical;
+static int cpu_cores;
 
 static void    assign_cpu_ids(void);
 static void    install_ap_tramp(void);
@@ -234,13 +236,142 @@ mem_range_AP_init(void)
                mem_range_softc.mr_op->initAP(&mem_range_softc);
 }
 
-struct cpu_group *
-cpu_topo(void)
+static void
+topo_probe_0xb(void)
+{
+       int logical;
+       int p[4];
+       int bits;
+       int type;
+       int cnt;
+       int i;
+       int x;
+
+       /* We only support two levels for now. */
+       for (i = 0; i < 3; i++) {
+               cpuid_count(0x0B, i, p);
+               bits = p[0] & 0x1f;
+               logical = p[1] &= 0xffff;
+               type = (p[2] >> 8) & 0xff;
+               if (type == 0 || logical == 0)
+                       break;
+               for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
+                       if (!cpu_info[x].cpu_present ||
+                           cpu_info[x].cpu_disabled)
+                               continue;
+                       if (x >> bits == boot_cpu_id >> bits)
+                               cnt++;
+               }
+               if (type == CPUID_TYPE_SMT)
+                       cpu_logical = cnt;
+               else if (type == CPUID_TYPE_CORE)
+                       cpu_cores = cnt;
+       }
+       if (cpu_logical == 0)
+               cpu_logical = 1;
+       cpu_cores /= cpu_logical;
+}
+
+static void
+topo_probe_0x4(void)
+{
+       u_int threads_per_cache, p[4];
+       u_int htt, cmp;
+       int i;
+
+       htt = cmp = 1;
+       /*
+        * If this CPU supports HTT or CMP then mention the
+        * number of physical/logical cores it contains.
+        */
+       if (cpu_feature & CPUID_HTT)
+               htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+       if (cpu_vendor_id == CPU_VENDOR_AMD && (amd_feature2 & AMDID2_CMP))
+               cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+       else if (cpu_vendor_id == CPU_VENDOR_INTEL && (cpu_high >= 4)) {
+               cpuid_count(4, 0, p);
+               if ((p[0] & 0x1f) != 0)
+                       cmp = ((p[0] >> 26) & 0x3f) + 1;
+       }
+       cpu_cores = cmp;
+       cpu_logical = htt / cmp;
+
+       /* Setup the initial logical CPUs info. */
+       if (cpu_feature & CPUID_HTT)
+               logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+
+       /*
+        * Work out if hyperthreading is *really* enabled.  This
+        * is made really ugly by the fact that processors lie: Dual
+        * core processors claim to be hyperthreaded even when they're
+        * not, presumably because they want to be treated the same
+        * way as HTT with respect to per-cpu software licensing.
+        * At the time of writing (May 12, 2005) the only hyperthreaded
+        * cpus are from Intel, and Intel's dual-core processors can be
+        * identified via the "deterministic cache parameters" cpuid
+        * calls.
+        */
+       /*
+        * First determine if this is an Intel processor which claims
+        * to have hyperthreading support.
+        */
+       if ((cpu_feature & CPUID_HTT) && cpu_vendor_id == CPU_VENDOR_INTEL) {
+               /*
+                * If the "deterministic cache parameters" cpuid calls
+                * are available, use them.
+                */
+               if (cpu_high >= 4) {
+                       /* Ask the processor about the L1 cache. */
+                       for (i = 0; i < 1; i++) {
+                               cpuid_count(4, i, p);
+                               threads_per_cache = ((p[0] & 0x3ffc000) >> 14) 
+ 1;
+                               if (hyperthreading_cpus < threads_per_cache)
+                                       hyperthreading_cpus = threads_per_cache;
+                               if ((p[0] & 0x1f) == 0)
+                                       break;
+                       }
+               }
+
+               /*
+                * If the deterministic cache parameters are not
+                * available, or if no caches were reported to exist,
+                * just accept what the HTT flag indicated.
+                */
+               if (hyperthreading_cpus == 0)
+                       hyperthreading_cpus = logical_cpus;
+       }
+}
+
+static void
+topo_probe(void)
 {
+
+       logical_cpus = logical_cpus_mask = 0;
+       if (cpu_high >= 0xb)
+               topo_probe_0xb();
+       else if (cpu_high)
+               topo_probe_0x4();
        if (cpu_cores == 0)
-               cpu_cores = 1;
+               cpu_cores = mp_ncpus;
        if (cpu_logical == 0)
                cpu_logical = 1;
+}
+
+struct cpu_group *
+cpu_topo(void)
+{
+       int cg_flags;
+
+       /*
+        * Determine whether any threading flags are
+        * necessry.
+        */
+       if (cpu_logical > 1 && hyperthreading_cpus)
+               cg_flags = CG_FLAG_HTT;
+       else if (cpu_logical > 1)
+               cg_flags = CG_FLAG_SMT;
+       else
+               cg_flags = 0;
        if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
                printf("WARNING: Non-uniform processors.\n");
                printf("WARNING: Using suboptimal topology.\n");
@@ -255,17 +386,17 @@ cpu_topo(void)
         * Only HTT no multi-core.
         */
        if (cpu_logical > 1 && cpu_cores == 1)
-               return (smp_topo_1level(CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
+               return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
        /*
         * Only multi-core no HTT.
         */
        if (cpu_cores > 1 && cpu_logical == 1)
-               return (smp_topo_1level(CG_SHARE_NONE, cpu_cores, 0));
+               return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
        /*
         * Both HTT and multi-core.
         */
-       return (smp_topo_2level(CG_SHARE_NONE, cpu_cores,
-           CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
+       return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
+           CG_SHARE_L1, cpu_logical, cg_flags));
 }
 
 
@@ -354,7 +485,6 @@ void
 cpu_mp_start(void)
 {
        int i;
-       u_int threads_per_cache, p[4];
 
        /* Initialize the logical ID to APIC ID table. */
        for (i = 0; i < MAXCPU; i++) {
@@ -399,51 +529,8 @@ cpu_mp_start(void)
                KASSERT(boot_cpu_id == PCPU_GET(apic_id),
                    ("BSP's APIC ID doesn't match boot_cpu_id"));
 
-       /* Setup the initial logical CPUs info. */
-       logical_cpus = logical_cpus_mask = 0;
-       if (cpu_feature & CPUID_HTT)
-               logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
-
-       /*
-        * Work out if hyperthreading is *really* enabled.  This
-        * is made really ugly by the fact that processors lie: Dual
-        * core processors claim to be hyperthreaded even when they're
-        * not, presumably because they want to be treated the same
-        * way as HTT with respect to per-cpu software licensing.
-        * At the time of writing (May 12, 2005) the only hyperthreaded
-        * cpus are from Intel, and Intel's dual-core processors can be
-        * identified via the "deterministic cache parameters" cpuid
-        * calls.
-        */
-       /*
-        * First determine if this is an Intel processor which claims
-        * to have hyperthreading support.
-        */
-       if ((cpu_feature & CPUID_HTT) && cpu_vendor_id == CPU_VENDOR_INTEL) {
-               /*
-                * If the "deterministic cache parameters" cpuid calls
-                * are available, use them.
-                */
-               if (cpu_high >= 4) {
-                       /* Ask the processor about the L1 cache. */
-                       for (i = 0; i < 1; i++) {
-                               cpuid_count(4, i, p);
-                               threads_per_cache = ((p[0] & 0x3ffc000) >> 14) 
+ 1;
-                               if (hyperthreading_cpus < threads_per_cache)
-                                       hyperthreading_cpus = threads_per_cache;
-                               if ((p[0] & 0x1f) == 0)
-                                       break;
-                       }
-               }
-
-               /*
-                * If the deterministic cache parameters are not
-                * available, or if no caches were reported to exist,
-                * just accept what the HTT flag indicated.
-                */
-               if (hyperthreading_cpus == 0)
-                       hyperthreading_cpus = logical_cpus;
-       }
+       /* Probe logical/physical core configuration. */
+       topo_probe();
 
        assign_cpu_ids();
 
@@ -463,6 +550,14 @@ cpu_mp_announce(void)
        const char *hyperthread;
        int i;
 
+       printf("FreeBSD/SMP: %d package(s) x %d core(s)",
+           mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
+       if (hyperthreading_cpus > 1)
+           printf(" x %d HTT threads", cpu_logical);
+       else if (cpu_logical > 1)
+           printf(" x %d SMT threads", cpu_logical);
+       printf("\n");
+
        /* List active CPUs first. */
        printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
        for (i = 1; i < mp_ncpus; i++) {

Modified: head/sys/i386/include/smp.h
==============================================================================
--- head/sys/i386/include/smp.h Wed Apr 29 06:52:04 2009        (r191647)
+++ head/sys/i386/include/smp.h Wed Apr 29 06:54:40 2009        (r191648)
@@ -45,10 +45,6 @@ extern u_long *ipi_rendezvous_counts[MAX
 extern u_long *ipi_lazypmap_counts[MAXCPU];
 #endif
 
-/* global data in identcpu.c */
-extern int                     cpu_cores;
-extern int                     cpu_logical;
-
 /* IPI handlers */
 inthand_t
        IDTVEC(invltlb),        /* TLB shootdowns - global */

Modified: head/sys/i386/include/specialreg.h
==============================================================================
--- head/sys/i386/include/specialreg.h  Wed Apr 29 06:52:04 2009        
(r191647)
+++ head/sys/i386/include/specialreg.h  Wed Apr 29 06:54:40 2009        
(r191648)
@@ -182,6 +182,13 @@
 #define        CPUID_HTT_CORES         0x00ff0000
 #define        CPUID_LOCAL_APIC_ID     0xff000000
 
+/* 
+ * CPUID instruction 0xb ebx info.
+ */
+#define        CPUID_TYPE_INVAL        0
+#define        CPUID_TYPE_SMT          1
+#define        CPUID_TYPE_CORE         2
+
 /*
  * AMD extended function 8000_0007h edx info
  */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to