Commit 3dd9d514 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: add support for Intel dual-core detection and displaying

Appended patch adds the support for Intel dual-core detection and displaying
the core related information in /proc/cpuinfo.  

It adds two new fields "core id" and "cpu cores" to x86 /proc/cpuinfo and the
"core id" field for x86_64("cpu cores" field is already present in x86_64).

Number of processor cores in a die is detected using cpuid(4) and this is
documented in IA-32 Intel Architecture Software Developer's Manual (vol 2a)
(http://developer.intel.com/design/pentium4/manuals/index_new.htm#sdm_vol2a)

This patch also adds cpu_core_map similar to cpu_sibling_map.

Slightly hacked by AK.
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f2ea2750
...@@ -188,6 +188,13 @@ static void __init init_amd(struct cpuinfo_x86 *c) ...@@ -188,6 +188,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
} }
display_cacheinfo(c); display_cacheinfo(c);
if (cpuid_eax(0x80000000) >= 0x80000008) {
c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
if (c->x86_num_cores & (c->x86_num_cores - 1))
c->x86_num_cores = 1;
}
detect_ht(c); detect_ht(c);
#ifdef CONFIG_X86_HT #ifdef CONFIG_X86_HT
...@@ -199,12 +206,6 @@ static void __init init_amd(struct cpuinfo_x86 *c) ...@@ -199,12 +206,6 @@ static void __init init_amd(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
smp_num_siblings = 1; smp_num_siblings = 1;
#endif #endif
if (cpuid_eax(0x80000000) >= 0x80000008) {
c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
if (c->x86_num_cores & (c->x86_num_cores - 1))
c->x86_num_cores = 1;
}
} }
static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
......
...@@ -434,7 +434,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) ...@@ -434,7 +434,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
void __init detect_ht(struct cpuinfo_x86 *c) void __init detect_ht(struct cpuinfo_x86 *c)
{ {
u32 eax, ebx, ecx, edx; u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp; int index_msb, tmp;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (!cpu_has(c, X86_FEATURE_HT)) if (!cpu_has(c, X86_FEATURE_HT))
...@@ -446,7 +446,6 @@ void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -446,7 +446,6 @@ void __init detect_ht(struct cpuinfo_x86 *c)
if (smp_num_siblings == 1) { if (smp_num_siblings == 1) {
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
} else if (smp_num_siblings > 1 ) { } else if (smp_num_siblings > 1 ) {
index_lsb = 0;
index_msb = 31; index_msb = 31;
if (smp_num_siblings > NR_CPUS) { if (smp_num_siblings > NR_CPUS) {
...@@ -455,21 +454,34 @@ void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -455,21 +454,34 @@ void __init detect_ht(struct cpuinfo_x86 *c)
return; return;
} }
tmp = smp_num_siblings; tmp = smp_num_siblings;
while ((tmp & 1) == 0) {
tmp >>=1 ;
index_lsb++;
}
tmp = smp_num_siblings;
while ((tmp & 0x80000000 ) == 0) { while ((tmp & 0x80000000 ) == 0) {
tmp <<=1 ; tmp <<=1 ;
index_msb--; index_msb--;
} }
if (index_lsb != index_msb ) if (smp_num_siblings & (smp_num_siblings - 1))
index_msb++; index_msb++;
phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
printk(KERN_INFO "CPU: Physical Processor ID: %d\n", printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]); phys_proc_id[cpu]);
smp_num_siblings = smp_num_siblings / c->x86_num_cores;
tmp = smp_num_siblings;
index_msb = 31;
while ((tmp & 0x80000000) == 0) {
tmp <<=1 ;
index_msb--;
}
if (smp_num_siblings & (smp_num_siblings - 1))
index_msb++;
cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
if (c->x86_num_cores > 1)
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
cpu_core_id[cpu]);
} }
} }
#endif #endif
......
...@@ -77,6 +77,27 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) ...@@ -77,6 +77,27 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
} }
/*
* find out the number of processor cores on the die
*/
static int __init num_cpu_cores(struct cpuinfo_x86 *c)
{
unsigned int eax;
if (c->cpuid_level < 4)
return 1;
__asm__("cpuid"
: "=a" (eax)
: "0" (4), "c" (0)
: "bx", "dx");
if (eax & 0x1f)
return ((eax >> 26) + 1);
else
return 1;
}
static void __init init_intel(struct cpuinfo_x86 *c) static void __init init_intel(struct cpuinfo_x86 *c)
{ {
unsigned int l2 = 0; unsigned int l2 = 0;
...@@ -139,6 +160,8 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -139,6 +160,8 @@ static void __init init_intel(struct cpuinfo_x86 *c)
if ( p ) if ( p )
strcpy(c->x86_model_id, p); strcpy(c->x86_model_id, p);
c->x86_num_cores = num_cpu_cores(c);
detect_ht(c); detect_ht(c);
/* Work around errata */ /* Work around errata */
......
...@@ -129,6 +129,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) ...@@ -129,6 +129,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n", seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
c->loops_per_jiffy/(500000/HZ), c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100); (c->loops_per_jiffy/(5000/HZ)) % 100);
#ifdef CONFIG_SMP
/* Put new fields at the end to lower the probability of
breaking user space parsers. */
seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
#endif
return 0; return 0;
} }
......
...@@ -62,6 +62,8 @@ static int __initdata smp_b_stepping; ...@@ -62,6 +62,8 @@ static int __initdata smp_b_stepping;
int smp_num_siblings = 1; int smp_num_siblings = 1;
int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
EXPORT_SYMBOL(phys_proc_id); EXPORT_SYMBOL(phys_proc_id);
int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
EXPORT_SYMBOL(cpu_core_id);
/* bitmap of online cpus */ /* bitmap of online cpus */
cpumask_t cpu_online_map; cpumask_t cpu_online_map;
...@@ -885,6 +887,7 @@ static int boot_cpu_logical_apicid; ...@@ -885,6 +887,7 @@ static int boot_cpu_logical_apicid;
void *xquad_portio; void *xquad_portio;
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
static void __init smp_boot_cpus(unsigned int max_cpus) static void __init smp_boot_cpus(unsigned int max_cpus)
{ {
...@@ -907,6 +910,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -907,6 +910,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpus_clear(cpu_sibling_map[0]); cpus_clear(cpu_sibling_map[0]);
cpu_set(0, cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]);
cpus_clear(cpu_core_map[0]);
cpu_set(0, cpu_core_map[0]);
/* /*
* If we couldn't find an SMP configuration at boot time, * If we couldn't find an SMP configuration at boot time,
* get out of here now! * get out of here now!
...@@ -919,6 +925,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -919,6 +925,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_NOTICE "Local APIC not detected." printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n"); " Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid(); map_cpu_to_logical_apicid();
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return; return;
} }
...@@ -942,6 +950,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -942,6 +950,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs(); smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0); phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return; return;
} }
...@@ -955,6 +965,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -955,6 +965,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
smpboot_clear_io_apic_irqs(); smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0); phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
return; return;
} }
...@@ -1035,10 +1047,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1035,10 +1047,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
* construct cpu_sibling_map[], so that we can tell sibling CPUs * construct cpu_sibling_map[], so that we can tell sibling CPUs
* efficiently. * efficiently.
*/ */
for (cpu = 0; cpu < NR_CPUS; cpu++) for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_sibling_map[cpu]);
cpus_clear(cpu_core_map[cpu]);
}
for (cpu = 0; cpu < NR_CPUS; cpu++) { for (cpu = 0; cpu < NR_CPUS; cpu++) {
struct cpuinfo_x86 *c = cpu_data + cpu;
int siblings = 0; int siblings = 0;
int i; int i;
if (!cpu_isset(cpu, cpu_callout_map)) if (!cpu_isset(cpu, cpu_callout_map))
...@@ -1048,7 +1063,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1048,7 +1063,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
if (!cpu_isset(i, cpu_callout_map)) if (!cpu_isset(i, cpu_callout_map))
continue; continue;
if (phys_proc_id[cpu] == phys_proc_id[i]) { if (cpu_core_id[cpu] == cpu_core_id[i]) {
siblings++; siblings++;
cpu_set(i, cpu_sibling_map[cpu]); cpu_set(i, cpu_sibling_map[cpu]);
} }
...@@ -1060,6 +1075,18 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1060,6 +1075,18 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
if (siblings != smp_num_siblings) if (siblings != smp_num_siblings)
printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
if (c->x86_num_cores > 1) {
for (i = 0; i < NR_CPUS; i++) {
if (!cpu_isset(i, cpu_callout_map))
continue;
if (phys_proc_id[cpu] == phys_proc_id[i]) {
cpu_set(i, cpu_core_map[cpu]);
}
}
} else {
cpu_core_map[cpu] = cpu_sibling_map[cpu];
}
} }
if (nmi_watchdog == NMI_LOCAL_APIC) if (nmi_watchdog == NMI_LOCAL_APIC)
......
...@@ -774,7 +774,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -774,7 +774,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
u32 eax, ebx, ecx, edx; u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp; int index_msb, tmp;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (!cpu_has(c, X86_FEATURE_HT)) if (!cpu_has(c, X86_FEATURE_HT))
...@@ -786,7 +786,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -786,7 +786,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
if (smp_num_siblings == 1) { if (smp_num_siblings == 1) {
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
} else if (smp_num_siblings > 1) { } else if (smp_num_siblings > 1) {
index_lsb = 0;
index_msb = 31; index_msb = 31;
/* /*
* At this point we only support two siblings per * At this point we only support two siblings per
...@@ -798,21 +797,33 @@ static void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -798,21 +797,33 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
return; return;
} }
tmp = smp_num_siblings; tmp = smp_num_siblings;
while ((tmp & 1) == 0) {
tmp >>=1 ;
index_lsb++;
}
tmp = smp_num_siblings;
while ((tmp & 0x80000000 ) == 0) { while ((tmp & 0x80000000 ) == 0) {
tmp <<=1 ; tmp <<=1 ;
index_msb--; index_msb--;
} }
if (index_lsb != index_msb ) if (smp_num_siblings & (smp_num_siblings - 1))
index_msb++; index_msb++;
phys_proc_id[cpu] = phys_pkg_id(index_msb); phys_proc_id[cpu] = phys_pkg_id(index_msb);
printk(KERN_INFO "CPU: Physical Processor ID: %d\n", printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]); phys_proc_id[cpu]);
smp_num_siblings = smp_num_siblings / c->x86_num_cores;
tmp = smp_num_siblings;
index_msb = 31;
while ((tmp & 0x80000000) == 0) {
tmp <<=1 ;
index_msb--;
}
if (smp_num_siblings & (smp_num_siblings - 1))
index_msb++;
cpu_core_id[cpu] = phys_pkg_id(index_msb);
if (c->x86_num_cores > 1)
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
cpu_core_id[cpu]);
} }
#endif #endif
} }
...@@ -830,6 +841,27 @@ static void __init sched_cmp_hack(struct cpuinfo_x86 *c) ...@@ -830,6 +841,27 @@ static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
#endif #endif
} }
/*
* find out the number of processor cores on the die
*/
static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
{
unsigned int eax;
if (c->cpuid_level < 4)
return 1;
__asm__("cpuid"
: "=a" (eax)
: "0" (4), "c" (0)
: "bx", "dx");
if (eax & 0x1f)
return ((eax >> 26) + 1);
else
return 1;
}
static void __init init_intel(struct cpuinfo_x86 *c) static void __init init_intel(struct cpuinfo_x86 *c)
{ {
/* Cache sizes */ /* Cache sizes */
...@@ -847,6 +879,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -847,6 +879,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
c->x86_cache_alignment = c->x86_clflush_size * 2; c->x86_cache_alignment = c->x86_clflush_size * 2;
if (c->x86 >= 15) if (c->x86 >= 15)
set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
c->x86_num_cores = intel_num_cpu_cores(c);
} }
void __init get_cpu_vendor(struct cpuinfo_x86 *c) void __init get_cpu_vendor(struct cpuinfo_x86 *c)
...@@ -1153,13 +1186,16 @@ static int show_cpuinfo(struct seq_file *m, void *v) ...@@ -1153,13 +1186,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, " [%d]", i); seq_printf(m, " [%d]", i);
} }
} }
seq_printf(m, "\n"); seq_printf(m, "\n");
if (c->x86_num_cores > 1) #ifdef CONFIG_SMP
/* Put new fields at the end to lower the probability of
breaking user space parsers. */
seq_printf(m, "core id\t\t: %d\n", cpu_core_id[c - cpu_data]);
seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores); seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
#endif
seq_printf(m, "\n\n"); seq_printf(m, "\n");
return 0; return 0;
} }
......
...@@ -58,7 +58,10 @@ ...@@ -58,7 +58,10 @@
int smp_num_siblings = 1; int smp_num_siblings = 1;
/* Package ID of each logical CPU */ /* Package ID of each logical CPU */
u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
/* Core ID of each logical CPU */
u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
EXPORT_SYMBOL(phys_proc_id); EXPORT_SYMBOL(phys_proc_id);
EXPORT_SYMBOL(cpu_core_id);
/* Bitmask of currently online CPUs */ /* Bitmask of currently online CPUs */
cpumask_t cpu_online_map; cpumask_t cpu_online_map;
...@@ -71,6 +74,7 @@ static cpumask_t smp_commenced_mask; ...@@ -71,6 +74,7 @@ static cpumask_t smp_commenced_mask;
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
/* /*
* Trampoline 80x86 program as an array. * Trampoline 80x86 program as an array.
...@@ -713,6 +717,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -713,6 +717,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
io_apic_irqs = 0; io_apic_irqs = 0;
cpu_online_map = cpumask_of_cpu(0); cpu_online_map = cpumask_of_cpu(0);
cpu_set(0, cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
phys_cpu_present_map = physid_mask_of_physid(0); phys_cpu_present_map = physid_mask_of_physid(0);
if (APIC_init_uniprocessor()) if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected." printk(KERN_NOTICE "Local APIC not detected."
...@@ -740,6 +745,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -740,6 +745,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
io_apic_irqs = 0; io_apic_irqs = 0;
cpu_online_map = cpumask_of_cpu(0); cpu_online_map = cpumask_of_cpu(0);
cpu_set(0, cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
phys_cpu_present_map = physid_mask_of_physid(0); phys_cpu_present_map = physid_mask_of_physid(0);
disable_apic = 1; disable_apic = 1;
goto smp_done; goto smp_done;
...@@ -756,6 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -756,6 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
io_apic_irqs = 0; io_apic_irqs = 0;
cpu_online_map = cpumask_of_cpu(0); cpu_online_map = cpumask_of_cpu(0);
cpu_set(0, cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);
phys_cpu_present_map = physid_mask_of_physid(0); phys_cpu_present_map = physid_mask_of_physid(0);
disable_apic = 1; disable_apic = 1;
goto smp_done; goto smp_done;
...@@ -833,10 +840,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -833,10 +840,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
* Construct cpu_sibling_map[], so that we can tell the * Construct cpu_sibling_map[], so that we can tell the
* sibling CPU efficiently. * sibling CPU efficiently.
*/ */
for (cpu = 0; cpu < NR_CPUS; cpu++) for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_sibling_map[cpu]);
cpus_clear(cpu_core_map[cpu]);
}
for (cpu = 0; cpu < NR_CPUS; cpu++) { for (cpu = 0; cpu < NR_CPUS; cpu++) {
struct cpuinfo_x86 *c = cpu_data + cpu;
int siblings = 0; int siblings = 0;
int i; int i;
if (!cpu_isset(cpu, cpu_callout_map)) if (!cpu_isset(cpu, cpu_callout_map))
...@@ -846,7 +856,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -846,7 +856,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
if (!cpu_isset(i, cpu_callout_map)) if (!cpu_isset(i, cpu_callout_map))
continue; continue;
if (phys_proc_id[cpu] == phys_proc_id[i]) { if (phys_proc_id[cpu] == cpu_core_id[i]) {
siblings++; siblings++;
cpu_set(i, cpu_sibling_map[cpu]); cpu_set(i, cpu_sibling_map[cpu]);
} }
...@@ -862,6 +872,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -862,6 +872,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
siblings, cpu, smp_num_siblings); siblings, cpu, smp_num_siblings);
smp_num_siblings = siblings; smp_num_siblings = siblings;
} }
if (c->x86_num_cores > 1) {
for (i = 0; i < NR_CPUS; i++) {
if (!cpu_isset(i, cpu_callout_map))
continue;
if (phys_proc_id[cpu] == phys_proc_id[i]) {
cpu_set(i, cpu_core_map[cpu]);
}
}
} else
cpu_core_map[cpu] = cpu_sibling_map[cpu];
} }
Dprintk("Boot done.\n"); Dprintk("Boot done.\n");
......
...@@ -98,6 +98,7 @@ extern struct cpuinfo_x86 cpu_data[]; ...@@ -98,6 +98,7 @@ extern struct cpuinfo_x86 cpu_data[];
#endif #endif
extern int phys_proc_id[NR_CPUS]; extern int phys_proc_id[NR_CPUS];
extern int cpu_core_id[NR_CPUS];
extern char ignore_fpu_irq; extern char ignore_fpu_irq;
extern void identify_cpu(struct cpuinfo_x86 *); extern void identify_cpu(struct cpuinfo_x86 *);
......
...@@ -35,6 +35,7 @@ extern void smp_alloc_memory(void); ...@@ -35,6 +35,7 @@ extern void smp_alloc_memory(void);
extern int pic_mode; extern int pic_mode;
extern int smp_num_siblings; extern int smp_num_siblings;
extern cpumask_t cpu_sibling_map[]; extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[];
extern void smp_flush_tlb(void); extern void smp_flush_tlb(void);
extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
......
...@@ -48,7 +48,9 @@ extern void (*mtrr_hook) (void); ...@@ -48,7 +48,9 @@ extern void (*mtrr_hook) (void);
extern void zap_low_mappings(void); extern void zap_low_mappings(void);
void smp_stop_cpu(void); void smp_stop_cpu(void);
extern cpumask_t cpu_sibling_map[NR_CPUS]; extern cpumask_t cpu_sibling_map[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
extern u8 phys_proc_id[NR_CPUS]; extern u8 phys_proc_id[NR_CPUS];
extern u8 cpu_core_id[NR_CPUS];
#define SMP_TRAMPOLINE_BASE 0x6000 #define SMP_TRAMPOLINE_BASE 0x6000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment