diff options
author | Andi Kleen <ak@suse.de> | 2005-04-16 18:25:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:25:15 -0400 |
commit | 3dd9d514846cdca1dcef2e4fce666d85e199e844 (patch) | |
tree | 28e60a8b733db213e88b0aee8ef3861a93a6fa48 /arch/x86_64/kernel/setup.c | |
parent | f2ea2750fbe56867bc8e0eb595115b14195a3e5e (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>
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r-- | arch/x86_64/kernel/setup.c | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 57f619052bad..ef74564eedeb 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 | */ | ||
847 | static 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 | |||
833 | static void __init init_intel(struct cpuinfo_x86 *c) | 865 | static 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 | ||
852 | void __init get_cpu_vendor(struct cpuinfo_x86 *c) | 885 | void __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 | ||