diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-09-05 03:21:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-05 03:21:21 -0400 |
commit | 9042763808c5285a1a61b45b0fe98a710a4c903c (patch) | |
tree | 349be736a3b56a64c8835df03f127959bfc6e0e0 /arch | |
parent | 446d27338d3b422dd3dfe496d0f362230994d059 (diff) | |
parent | aa3341a168883654d1b13f5931c5ed2762537831 (diff) |
Merge branch 'x86/x2apic' into x86/core
Conflicts:
arch/x86/kernel/cpu/common_64.c
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/addon_cpuid_features.c | 88 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common_64.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_64.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/genx2apic_cluster.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/genx2apic_phys.c | 7 |
6 files changed, 107 insertions, 16 deletions
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index a6ef672adbba..0d9c993aa93e 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <asm/pat.h> | 7 | #include <asm/pat.h> |
8 | #include <asm/processor.h> | 8 | #include <asm/processor.h> |
9 | 9 | ||
10 | #include <mach_apic.h> | ||
11 | |||
10 | struct cpuid_bit { | 12 | struct cpuid_bit { |
11 | u16 feature; | 13 | u16 feature; |
12 | u8 reg; | 14 | u8 reg; |
@@ -48,6 +50,92 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
48 | } | 50 | } |
49 | } | 51 | } |
50 | 52 | ||
53 | /* leaf 0xb SMT level */ | ||
54 | #define SMT_LEVEL 0 | ||
55 | |||
56 | /* leaf 0xb sub-leaf types */ | ||
57 | #define INVALID_TYPE 0 | ||
58 | #define SMT_TYPE 1 | ||
59 | #define CORE_TYPE 2 | ||
60 | |||
61 | #define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff) | ||
62 | #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) | ||
63 | #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) | ||
64 | |||
65 | /* | ||
66 | * Check for extended topology enumeration cpuid leaf 0xb and if it | ||
67 | * exists, use it for populating initial_apicid and cpu topology | ||
68 | * detection. | ||
69 | */ | ||
70 | void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c) | ||
71 | { | ||
72 | #ifdef CONFIG_SMP | ||
73 | unsigned int eax, ebx, ecx, edx, sub_index; | ||
74 | unsigned int ht_mask_width, core_plus_mask_width; | ||
75 | unsigned int core_select_mask, core_level_siblings; | ||
76 | |||
77 | if (c->cpuid_level < 0xb) | ||
78 | return; | ||
79 | |||
80 | cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); | ||
81 | |||
82 | /* | ||
83 | * check if the cpuid leaf 0xb is actually implemented. | ||
84 | */ | ||
85 | if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) | ||
86 | return; | ||
87 | |||
88 | set_cpu_cap(c, X86_FEATURE_XTOPOLOGY); | ||
89 | |||
90 | /* | ||
91 | * initial apic id, which also represents 32-bit extended x2apic id. | ||
92 | */ | ||
93 | c->initial_apicid = edx; | ||
94 | |||
95 | /* | ||
96 | * Populate HT related information from sub-leaf level 0. | ||
97 | */ | ||
98 | core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); | ||
99 | core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | ||
100 | |||
101 | sub_index = 1; | ||
102 | do { | ||
103 | cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx); | ||
104 | |||
105 | /* | ||
106 | * Check for the Core type in the implemented sub leaves. | ||
107 | */ | ||
108 | if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) { | ||
109 | core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); | ||
110 | core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | sub_index++; | ||
115 | } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); | ||
116 | |||
117 | core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; | ||
118 | |||
119 | #ifdef CONFIG_X86_32 | ||
120 | c->cpu_core_id = phys_pkg_id(c->initial_apicid, ht_mask_width) | ||
121 | & core_select_mask; | ||
122 | c->phys_proc_id = phys_pkg_id(c->initial_apicid, core_plus_mask_width); | ||
123 | #else | ||
124 | c->cpu_core_id = phys_pkg_id(ht_mask_width) & core_select_mask; | ||
125 | c->phys_proc_id = phys_pkg_id(core_plus_mask_width); | ||
126 | #endif | ||
127 | c->x86_max_cores = (core_level_siblings / smp_num_siblings); | ||
128 | |||
129 | |||
130 | printk(KERN_INFO "CPU: Physical Processor ID: %d\n", | ||
131 | c->phys_proc_id); | ||
132 | if (c->x86_max_cores > 1) | ||
133 | printk(KERN_INFO "CPU: Processor Core ID: %d\n", | ||
134 | c->cpu_core_id); | ||
135 | return; | ||
136 | #endif | ||
137 | } | ||
138 | |||
51 | #ifdef CONFIG_X86_PAT | 139 | #ifdef CONFIG_X86_PAT |
52 | void __cpuinit validate_pat_support(struct cpuinfo_x86 *c) | 140 | void __cpuinit validate_pat_support(struct cpuinfo_x86 *c) |
53 | { | 141 | { |
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index ae007b3521cb..bcb48ce05d23 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c | |||
@@ -150,6 +150,9 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) | |||
150 | if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) | 150 | if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) |
151 | goto out; | 151 | goto out; |
152 | 152 | ||
153 | if (cpu_has(c, X86_FEATURE_XTOPOLOGY)) | ||
154 | return; | ||
155 | |||
153 | cpuid(1, &eax, &ebx, &ecx, &edx); | 156 | cpuid(1, &eax, &ebx, &ecx, &edx); |
154 | 157 | ||
155 | smp_num_siblings = (ebx & 0xff0000) >> 16; | 158 | smp_num_siblings = (ebx & 0xff0000) >> 16; |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index c5ac08124adc..959417b8cd64 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -176,9 +176,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
176 | if (p) | 176 | if (p) |
177 | strcpy(c->x86_model_id, p); | 177 | strcpy(c->x86_model_id, p); |
178 | 178 | ||
179 | c->x86_max_cores = num_cpu_cores(c); | 179 | detect_extended_topology(c); |
180 | 180 | ||
181 | detect_ht(c); | 181 | if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) { |
182 | /* | ||
183 | * let's use the legacy cpuid vector 0x1 and 0x4 for topology | ||
184 | * detection. | ||
185 | */ | ||
186 | c->x86_max_cores = num_cpu_cores(c); | ||
187 | detect_ht(c); | ||
188 | } | ||
182 | 189 | ||
183 | /* Work around errata */ | 190 | /* Work around errata */ |
184 | Intel_errata_workarounds(c); | 191 | Intel_errata_workarounds(c); |
diff --git a/arch/x86/kernel/cpu/intel_64.c b/arch/x86/kernel/cpu/intel_64.c index 0a8128a240df..0c0a58dfe099 100644 --- a/arch/x86/kernel/cpu/intel_64.c +++ b/arch/x86/kernel/cpu/intel_64.c | |||
@@ -80,7 +80,10 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
80 | if (c->x86 == 6) | 80 | if (c->x86 == 6) |
81 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | 81 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); |
82 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | 82 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); |
83 | c->x86_max_cores = intel_num_cpu_cores(c); | 83 | |
84 | detect_extended_topology(c); | ||
85 | if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) | ||
86 | c->x86_max_cores = intel_num_cpu_cores(c); | ||
84 | 87 | ||
85 | srat_detect_node(); | 88 | srat_detect_node(); |
86 | } | 89 | } |
diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index fed9f68efd66..e4bf2cc0d743 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c | |||
@@ -120,14 +120,9 @@ static unsigned long set_apic_id(unsigned int id) | |||
120 | return x; | 120 | return x; |
121 | } | 121 | } |
122 | 122 | ||
123 | static unsigned int x2apic_read_id(void) | ||
124 | { | ||
125 | return apic_read(APIC_ID); | ||
126 | } | ||
127 | |||
128 | static unsigned int phys_pkg_id(int index_msb) | 123 | static unsigned int phys_pkg_id(int index_msb) |
129 | { | 124 | { |
130 | return x2apic_read_id() >> index_msb; | 125 | return current_cpu_data.initial_apicid >> index_msb; |
131 | } | 126 | } |
132 | 127 | ||
133 | static void x2apic_send_IPI_self(int vector) | 128 | static void x2apic_send_IPI_self(int vector) |
diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index 958d537b4cc9..8f1343df2627 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c | |||
@@ -118,14 +118,9 @@ static unsigned long set_apic_id(unsigned int id) | |||
118 | return x; | 118 | return x; |
119 | } | 119 | } |
120 | 120 | ||
121 | static unsigned int x2apic_read_id(void) | ||
122 | { | ||
123 | return apic_read(APIC_ID); | ||
124 | } | ||
125 | |||
126 | static unsigned int phys_pkg_id(int index_msb) | 121 | static unsigned int phys_pkg_id(int index_msb) |
127 | { | 122 | { |
128 | return x2apic_read_id() >> index_msb; | 123 | return current_cpu_data.initial_apicid >> index_msb; |
129 | } | 124 | } |
130 | 125 | ||
131 | void x2apic_send_IPI_self(int vector) | 126 | void x2apic_send_IPI_self(int vector) |