svn commit: r191648 - in head/sys: amd64/amd64 amd64/include
i386/i386 i386/include
Jeff Roberson
jeff at FreeBSD.org
Wed Apr 29 06:54:41 UTC 2009
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
*/
More information about the svn-src-all
mailing list