aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2005-04-16 18:25:15 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:25:15 -0400
commit3dd9d514846cdca1dcef2e4fce666d85e199e844 (patch)
tree28e60a8b733db213e88b0aee8ef3861a93a6fa48
parentf2ea2750fbe56867bc8e0eb595115b14195a3e5e (diff)
[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: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/cpu/amd.c13
-rw-r--r--arch/i386/kernel/cpu/common.c28
-rw-r--r--arch/i386/kernel/cpu/intel.c23
-rw-r--r--arch/i386/kernel/cpu/proc.c8
-rw-r--r--arch/i386/kernel/smpboot.c31
-rw-r--r--arch/x86_64/kernel/setup.c64
-rw-r--r--arch/x86_64/kernel/smpboot.c24
-rw-r--r--include/asm-i386/processor.h1
-rw-r--r--include/asm-i386/smp.h1
-rw-r--r--include/asm-x86_64/smp.h2
10 files changed, 163 insertions, 32 deletions
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index ae94585d044..fa10d0a509c 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -188,6 +188,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
188 } 188 }
189 189
190 display_cacheinfo(c); 190 display_cacheinfo(c);
191
192 if (cpuid_eax(0x80000000) >= 0x80000008) {
193 c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
194 if (c->x86_num_cores & (c->x86_num_cores - 1))
195 c->x86_num_cores = 1;
196 }
197
191 detect_ht(c); 198 detect_ht(c);
192 199
193#ifdef CONFIG_X86_HT 200#ifdef CONFIG_X86_HT
@@ -199,12 +206,6 @@ static void __init init_amd(struct cpuinfo_x86 *c)
199 if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) 206 if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
200 smp_num_siblings = 1; 207 smp_num_siblings = 1;
201#endif 208#endif
202
203 if (cpuid_eax(0x80000000) >= 0x80000008) {
204 c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
205 if (c->x86_num_cores & (c->x86_num_cores - 1))
206 c->x86_num_cores = 1;
207 }
208} 209}
209 210
210static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) 211static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index ebd5d8247fa..ed4c9c3fe66 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -434,7 +434,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
434void __init detect_ht(struct cpuinfo_x86 *c) 434void __init detect_ht(struct cpuinfo_x86 *c)
435{ 435{
436 u32 eax, ebx, ecx, edx; 436 u32 eax, ebx, ecx, edx;
437 int index_lsb, index_msb, tmp; 437 int index_msb, tmp;
438 int cpu = smp_processor_id(); 438 int cpu = smp_processor_id();
439 439
440 if (!cpu_has(c, X86_FEATURE_HT)) 440 if (!cpu_has(c, X86_FEATURE_HT))
@@ -446,7 +446,6 @@ void __init detect_ht(struct cpuinfo_x86 *c)
446 if (smp_num_siblings == 1) { 446 if (smp_num_siblings == 1) {
447 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 447 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
448 } else if (smp_num_siblings > 1 ) { 448 } else if (smp_num_siblings > 1 ) {
449 index_lsb = 0;
450 index_msb = 31; 449 index_msb = 31;
451 450
452 if (smp_num_siblings > NR_CPUS) { 451 if (smp_num_siblings > NR_CPUS) {
@@ -455,21 +454,34 @@ void __init detect_ht(struct cpuinfo_x86 *c)
455 return; 454 return;
456 } 455 }
457 tmp = smp_num_siblings; 456 tmp = smp_num_siblings;
458 while ((tmp & 1) == 0) {
459 tmp >>=1 ;
460 index_lsb++;
461 }
462 tmp = smp_num_siblings;
463 while ((tmp & 0x80000000 ) == 0) { 457 while ((tmp & 0x80000000 ) == 0) {
464 tmp <<=1 ; 458 tmp <<=1 ;
465 index_msb--; 459 index_msb--;
466 } 460 }
467 if (index_lsb != index_msb ) 461 if (smp_num_siblings & (smp_num_siblings - 1))
468 index_msb++; 462 index_msb++;
469 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); 463 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
470 464
471 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 465 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
472 phys_proc_id[cpu]); 466 phys_proc_id[cpu]);
467
468 smp_num_siblings = smp_num_siblings / c->x86_num_cores;
469
470 tmp = smp_num_siblings;
471 index_msb = 31;
472 while ((tmp & 0x80000000) == 0) {
473 tmp <<=1 ;
474 index_msb--;
475 }
476
477 if (smp_num_siblings & (smp_num_siblings - 1))
478 index_msb++;
479
480 cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
481
482 if (c->x86_num_cores > 1)
483 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
484 cpu_core_id[cpu]);
473 } 485 }
474} 486}
475#endif 487#endif
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index b8d847b850d..121aa2176e6 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -77,6 +77,27 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
77} 77}
78 78
79 79
80/*
81 * find out the number of processor cores on the die
82 */
83static int __init num_cpu_cores(struct cpuinfo_x86 *c)
84{
85 unsigned int eax;
86
87 if (c->cpuid_level < 4)
88 return 1;
89
90 __asm__("cpuid"
91 : "=a" (eax)
92 : "0" (4), "c" (0)
93 : "bx", "dx");
94
95 if (eax & 0x1f)
96 return ((eax >> 26) + 1);
97 else
98 return 1;
99}
100
80static void __init init_intel(struct cpuinfo_x86 *c) 101static void __init init_intel(struct cpuinfo_x86 *c)
81{ 102{
82 unsigned int l2 = 0; 103 unsigned int l2 = 0;
@@ -139,6 +160,8 @@ static void __init init_intel(struct cpuinfo_x86 *c)
139 if ( p ) 160 if ( p )
140 strcpy(c->x86_model_id, p); 161 strcpy(c->x86_model_id, p);
141 162
163 c->x86_num_cores = num_cpu_cores(c);
164
142 detect_ht(c); 165 detect_ht(c);
143 166
144 /* Work around errata */ 167 /* Work around errata */
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 89a2956ee65..0f1125b15b7 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -129,6 +129,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
129 seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n", 129 seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
130 c->loops_per_jiffy/(500000/HZ), 130 c->loops_per_jiffy/(500000/HZ),
131 (c->loops_per_jiffy/(5000/HZ)) % 100); 131 (c->loops_per_jiffy/(5000/HZ)) % 100);
132
133#ifdef CONFIG_SMP
134 /* Put new fields at the end to lower the probability of
135 breaking user space parsers. */
136 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
137 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
138#endif
139
132 return 0; 140 return 0;
133} 141}
134 142
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 332ee7a1d1a..fd36d2f65f8 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -62,6 +62,8 @@ static int __initdata smp_b_stepping;
62int smp_num_siblings = 1; 62int smp_num_siblings = 1;
63int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ 63int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
64EXPORT_SYMBOL(phys_proc_id); 64EXPORT_SYMBOL(phys_proc_id);
65int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
66EXPORT_SYMBOL(cpu_core_id);
65 67
66/* bitmap of online cpus */ 68/* bitmap of online cpus */
67cpumask_t cpu_online_map; 69cpumask_t cpu_online_map;
@@ -885,6 +887,7 @@ static int boot_cpu_logical_apicid;
885void *xquad_portio; 887void *xquad_portio;
886 888
887cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 889cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
890cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
888 891
889static void __init smp_boot_cpus(unsigned int max_cpus) 892static void __init smp_boot_cpus(unsigned int max_cpus)
890{ 893{
@@ -907,6 +910,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
907 cpus_clear(cpu_sibling_map[0]); 910 cpus_clear(cpu_sibling_map[0]);
908 cpu_set(0, cpu_sibling_map[0]); 911 cpu_set(0, cpu_sibling_map[0]);
909 912
913 cpus_clear(cpu_core_map[0]);
914 cpu_set(0, cpu_core_map[0]);
915
910 /* 916 /*
911 * If we couldn't find an SMP configuration at boot time, 917 * If we couldn't find an SMP configuration at boot time,
912 * get out of here now! 918 * get out of here now!
@@ -919,6 +925,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
919 printk(KERN_NOTICE "Local APIC not detected." 925 printk(KERN_NOTICE "Local APIC not detected."
920 " Using dummy APIC emulation.\n"); 926 " Using dummy APIC emulation.\n");
921 map_cpu_to_logical_apicid(); 927 map_cpu_to_logical_apicid();
928 cpu_set(0, cpu_sibling_map[0]);
929 cpu_set(0, cpu_core_map[0]);
922 return; 930 return;
923 } 931 }
924 932
@@ -942,6 +950,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
942 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); 950 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
943 smpboot_clear_io_apic_irqs(); 951 smpboot_clear_io_apic_irqs();
944 phys_cpu_present_map = physid_mask_of_physid(0); 952 phys_cpu_present_map = physid_mask_of_physid(0);
953 cpu_set(0, cpu_sibling_map[0]);
954 cpu_set(0, cpu_core_map[0]);
945 return; 955 return;
946 } 956 }
947 957
@@ -955,6 +965,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
955 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); 965 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
956 smpboot_clear_io_apic_irqs(); 966 smpboot_clear_io_apic_irqs();
957 phys_cpu_present_map = physid_mask_of_physid(0); 967 phys_cpu_present_map = physid_mask_of_physid(0);
968 cpu_set(0, cpu_sibling_map[0]);
969 cpu_set(0, cpu_core_map[0]);
958 return; 970 return;
959 } 971 }
960 972
@@ -1035,10 +1047,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1035 * construct cpu_sibling_map[], so that we can tell sibling CPUs 1047 * construct cpu_sibling_map[], so that we can tell sibling CPUs
1036 * efficiently. 1048 * efficiently.
1037 */ 1049 */
1038 for (cpu = 0; cpu < NR_CPUS; cpu++) 1050 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1039 cpus_clear(cpu_sibling_map[cpu]); 1051 cpus_clear(cpu_sibling_map[cpu]);
1052 cpus_clear(cpu_core_map[cpu]);
1053 }
1040 1054
1041 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1055 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1056 struct cpuinfo_x86 *c = cpu_data + cpu;
1042 int siblings = 0; 1057 int siblings = 0;
1043 int i; 1058 int i;
1044 if (!cpu_isset(cpu, cpu_callout_map)) 1059 if (!cpu_isset(cpu, cpu_callout_map))
@@ -1048,7 +1063,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1048 for (i = 0; i < NR_CPUS; i++) { 1063 for (i = 0; i < NR_CPUS; i++) {
1049 if (!cpu_isset(i, cpu_callout_map)) 1064 if (!cpu_isset(i, cpu_callout_map))
1050 continue; 1065 continue;
1051 if (phys_proc_id[cpu] == phys_proc_id[i]) { 1066 if (cpu_core_id[cpu] == cpu_core_id[i]) {
1052 siblings++; 1067 siblings++;
1053 cpu_set(i, cpu_sibling_map[cpu]); 1068 cpu_set(i, cpu_sibling_map[cpu]);
1054 } 1069 }
@@ -1060,6 +1075,18 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1060 1075
1061 if (siblings != smp_num_siblings) 1076 if (siblings != smp_num_siblings)
1062 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); 1077 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
1078
1079 if (c->x86_num_cores > 1) {
1080 for (i = 0; i < NR_CPUS; i++) {
1081 if (!cpu_isset(i, cpu_callout_map))
1082 continue;
1083 if (phys_proc_id[cpu] == phys_proc_id[i]) {
1084 cpu_set(i, cpu_core_map[cpu]);
1085 }
1086 }
1087 } else {
1088 cpu_core_map[cpu] = cpu_sibling_map[cpu];
1089 }
1063 } 1090 }
1064 1091
1065 if (nmi_watchdog == NMI_LOCAL_APIC) 1092 if (nmi_watchdog == NMI_LOCAL_APIC)
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 57f619052ba..ef74564eede 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -774,7 +774,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
774{ 774{
775#ifdef CONFIG_SMP 775#ifdef CONFIG_SMP
776 u32 eax, ebx, ecx, edx; 776 u32 eax, ebx, ecx, edx;
777 int index_lsb, index_msb, tmp; 777 int index_msb, tmp;
778 int cpu = smp_processor_id(); 778 int cpu = smp_processor_id();
779 779
780 if (!cpu_has(c, X86_FEATURE_HT)) 780 if (!cpu_has(c, X86_FEATURE_HT))
@@ -786,7 +786,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
786 if (smp_num_siblings == 1) { 786 if (smp_num_siblings == 1) {
787 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 787 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
788 } else if (smp_num_siblings > 1) { 788 } else if (smp_num_siblings > 1) {
789 index_lsb = 0;
790 index_msb = 31; 789 index_msb = 31;
791 /* 790 /*
792 * At this point we only support two siblings per 791 * At this point we only support two siblings per
@@ -798,21 +797,33 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
798 return; 797 return;
799 } 798 }
800 tmp = smp_num_siblings; 799 tmp = smp_num_siblings;
801 while ((tmp & 1) == 0) {
802 tmp >>=1 ;
803 index_lsb++;
804 }
805 tmp = smp_num_siblings;
806 while ((tmp & 0x80000000 ) == 0) { 800 while ((tmp & 0x80000000 ) == 0) {
807 tmp <<=1 ; 801 tmp <<=1 ;
808 index_msb--; 802 index_msb--;
809 } 803 }
810 if (index_lsb != index_msb ) 804 if (smp_num_siblings & (smp_num_siblings - 1))
811 index_msb++; 805 index_msb++;
812 phys_proc_id[cpu] = phys_pkg_id(index_msb); 806 phys_proc_id[cpu] = phys_pkg_id(index_msb);
813 807
814 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 808 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
815 phys_proc_id[cpu]); 809 phys_proc_id[cpu]);
810
811 smp_num_siblings = smp_num_siblings / c->x86_num_cores;
812
813 tmp = smp_num_siblings;
814 index_msb = 31;
815 while ((tmp & 0x80000000) == 0) {
816 tmp <<=1 ;
817 index_msb--;
818 }
819 if (smp_num_siblings & (smp_num_siblings - 1))
820 index_msb++;
821
822 cpu_core_id[cpu] = phys_pkg_id(index_msb);
823
824 if (c->x86_num_cores > 1)
825 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
826 cpu_core_id[cpu]);
816 } 827 }
817#endif 828#endif
818} 829}
@@ -829,7 +840,28 @@ static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
829 smp_num_siblings = 1; 840 smp_num_siblings = 1;
830#endif 841#endif
831} 842}
832 843
844/*
845 * find out the number of processor cores on the die
846 */
847static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
848{
849 unsigned int eax;
850
851 if (c->cpuid_level < 4)
852 return 1;
853
854 __asm__("cpuid"
855 : "=a" (eax)
856 : "0" (4), "c" (0)
857 : "bx", "dx");
858
859 if (eax & 0x1f)
860 return ((eax >> 26) + 1);
861 else
862 return 1;
863}
864
833static void __init init_intel(struct cpuinfo_x86 *c) 865static void __init init_intel(struct cpuinfo_x86 *c)
834{ 866{
835 /* Cache sizes */ 867 /* Cache sizes */
@@ -847,6 +879,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
847 c->x86_cache_alignment = c->x86_clflush_size * 2; 879 c->x86_cache_alignment = c->x86_clflush_size * 2;
848 if (c->x86 >= 15) 880 if (c->x86 >= 15)
849 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); 881 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
882 c->x86_num_cores = intel_num_cpu_cores(c);
850} 883}
851 884
852void __init get_cpu_vendor(struct cpuinfo_x86 *c) 885void __init get_cpu_vendor(struct cpuinfo_x86 *c)
@@ -1153,13 +1186,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1153 seq_printf(m, " [%d]", i); 1186 seq_printf(m, " [%d]", i);
1154 } 1187 }
1155 } 1188 }
1156 seq_printf(m, "\n");
1157 1189
1158 if (c->x86_num_cores > 1) 1190 seq_printf(m, "\n");
1159 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
1160
1161 seq_printf(m, "\n\n");
1162 1191
1192#ifdef CONFIG_SMP
1193 /* Put new fields at the end to lower the probability of
1194 breaking user space parsers. */
1195 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[c - cpu_data]);
1196 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
1197#endif
1198 seq_printf(m, "\n");
1163 return 0; 1199 return 0;
1164} 1200}
1165 1201
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index e5714090b00..7e2de8925b0 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -58,7 +58,10 @@
58int smp_num_siblings = 1; 58int smp_num_siblings = 1;
59/* Package ID of each logical CPU */ 59/* Package ID of each logical CPU */
60u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 60u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
61/* Core ID of each logical CPU */
62u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
61EXPORT_SYMBOL(phys_proc_id); 63EXPORT_SYMBOL(phys_proc_id);
64EXPORT_SYMBOL(cpu_core_id);
62 65
63/* Bitmask of currently online CPUs */ 66/* Bitmask of currently online CPUs */
64cpumask_t cpu_online_map; 67cpumask_t cpu_online_map;
@@ -71,6 +74,7 @@ static cpumask_t smp_commenced_mask;
71struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 74struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
72 75
73cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 76cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
77cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
74 78
75/* 79/*
76 * Trampoline 80x86 program as an array. 80 * Trampoline 80x86 program as an array.
@@ -713,6 +717,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
713 io_apic_irqs = 0; 717 io_apic_irqs = 0;
714 cpu_online_map = cpumask_of_cpu(0); 718 cpu_online_map = cpumask_of_cpu(0);
715 cpu_set(0, cpu_sibling_map[0]); 719 cpu_set(0, cpu_sibling_map[0]);
720 cpu_set(0, cpu_core_map[0]);
716 phys_cpu_present_map = physid_mask_of_physid(0); 721 phys_cpu_present_map = physid_mask_of_physid(0);
717 if (APIC_init_uniprocessor()) 722 if (APIC_init_uniprocessor())
718 printk(KERN_NOTICE "Local APIC not detected." 723 printk(KERN_NOTICE "Local APIC not detected."
@@ -740,6 +745,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
740 io_apic_irqs = 0; 745 io_apic_irqs = 0;
741 cpu_online_map = cpumask_of_cpu(0); 746 cpu_online_map = cpumask_of_cpu(0);
742 cpu_set(0, cpu_sibling_map[0]); 747 cpu_set(0, cpu_sibling_map[0]);
748 cpu_set(0, cpu_core_map[0]);
743 phys_cpu_present_map = physid_mask_of_physid(0); 749 phys_cpu_present_map = physid_mask_of_physid(0);
744 disable_apic = 1; 750 disable_apic = 1;
745 goto smp_done; 751 goto smp_done;
@@ -756,6 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
756 io_apic_irqs = 0; 762 io_apic_irqs = 0;
757 cpu_online_map = cpumask_of_cpu(0); 763 cpu_online_map = cpumask_of_cpu(0);
758 cpu_set(0, cpu_sibling_map[0]); 764 cpu_set(0, cpu_sibling_map[0]);
765 cpu_set(0, cpu_core_map[0]);
759 phys_cpu_present_map = physid_mask_of_physid(0); 766 phys_cpu_present_map = physid_mask_of_physid(0);
760 disable_apic = 1; 767 disable_apic = 1;
761 goto smp_done; 768 goto smp_done;
@@ -833,10 +840,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
833 * Construct cpu_sibling_map[], so that we can tell the 840 * Construct cpu_sibling_map[], so that we can tell the
834 * sibling CPU efficiently. 841 * sibling CPU efficiently.
835 */ 842 */
836 for (cpu = 0; cpu < NR_CPUS; cpu++) 843 for (cpu = 0; cpu < NR_CPUS; cpu++) {
837 cpus_clear(cpu_sibling_map[cpu]); 844 cpus_clear(cpu_sibling_map[cpu]);
845 cpus_clear(cpu_core_map[cpu]);
846 }
838 847
839 for (cpu = 0; cpu < NR_CPUS; cpu++) { 848 for (cpu = 0; cpu < NR_CPUS; cpu++) {
849 struct cpuinfo_x86 *c = cpu_data + cpu;
840 int siblings = 0; 850 int siblings = 0;
841 int i; 851 int i;
842 if (!cpu_isset(cpu, cpu_callout_map)) 852 if (!cpu_isset(cpu, cpu_callout_map))
@@ -846,7 +856,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
846 for (i = 0; i < NR_CPUS; i++) { 856 for (i = 0; i < NR_CPUS; i++) {
847 if (!cpu_isset(i, cpu_callout_map)) 857 if (!cpu_isset(i, cpu_callout_map))
848 continue; 858 continue;
849 if (phys_proc_id[cpu] == phys_proc_id[i]) { 859 if (phys_proc_id[cpu] == cpu_core_id[i]) {
850 siblings++; 860 siblings++;
851 cpu_set(i, cpu_sibling_map[cpu]); 861 cpu_set(i, cpu_sibling_map[cpu]);
852 } 862 }
@@ -862,6 +872,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
862 siblings, cpu, smp_num_siblings); 872 siblings, cpu, smp_num_siblings);
863 smp_num_siblings = siblings; 873 smp_num_siblings = siblings;
864 } 874 }
875 if (c->x86_num_cores > 1) {
876 for (i = 0; i < NR_CPUS; i++) {
877 if (!cpu_isset(i, cpu_callout_map))
878 continue;
879 if (phys_proc_id[cpu] == phys_proc_id[i]) {
880 cpu_set(i, cpu_core_map[cpu]);
881 }
882 }
883 } else
884 cpu_core_map[cpu] = cpu_sibling_map[cpu];
865 } 885 }
866 886
867 Dprintk("Boot done.\n"); 887 Dprintk("Boot done.\n");
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 7149784ed40..359bb015174 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -98,6 +98,7 @@ extern struct cpuinfo_x86 cpu_data[];
98#endif 98#endif
99 99
100extern int phys_proc_id[NR_CPUS]; 100extern int phys_proc_id[NR_CPUS];
101extern int cpu_core_id[NR_CPUS];
101extern char ignore_fpu_irq; 102extern char ignore_fpu_irq;
102 103
103extern void identify_cpu(struct cpuinfo_x86 *); 104extern void identify_cpu(struct cpuinfo_x86 *);
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index dd1491225d5..e03a206dfa3 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -35,6 +35,7 @@ extern void smp_alloc_memory(void);
35extern int pic_mode; 35extern int pic_mode;
36extern int smp_num_siblings; 36extern int smp_num_siblings;
37extern cpumask_t cpu_sibling_map[]; 37extern cpumask_t cpu_sibling_map[];
38extern cpumask_t cpu_core_map[];
38 39
39extern void smp_flush_tlb(void); 40extern void smp_flush_tlb(void);
40extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); 41extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index fe523e3e2ff..f5eaa1ab48f 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -48,7 +48,9 @@ extern void (*mtrr_hook) (void);
48extern void zap_low_mappings(void); 48extern void zap_low_mappings(void);
49void smp_stop_cpu(void); 49void smp_stop_cpu(void);
50extern cpumask_t cpu_sibling_map[NR_CPUS]; 50extern cpumask_t cpu_sibling_map[NR_CPUS];
51extern cpumask_t cpu_core_map[NR_CPUS];
51extern u8 phys_proc_id[NR_CPUS]; 52extern u8 phys_proc_id[NR_CPUS];
53extern u8 cpu_core_id[NR_CPUS];
52 54
53#define SMP_TRAMPOLINE_BASE 0x6000 55#define SMP_TRAMPOLINE_BASE 0x6000
54 56