diff options
Diffstat (limited to 'arch/powerpc/kernel/setup_64.c')
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 120 |
1 files changed, 6 insertions, 114 deletions
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 275d86ddd612..6b52cce872be 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -181,114 +181,8 @@ static int __init early_smt_enabled(char *p) | |||
181 | } | 181 | } |
182 | early_param("smt-enabled", early_smt_enabled); | 182 | early_param("smt-enabled", early_smt_enabled); |
183 | 183 | ||
184 | /** | 184 | #else |
185 | * setup_cpu_maps - initialize the following cpu maps: | 185 | #define check_smt_enabled() |
186 | * cpu_possible_map | ||
187 | * cpu_present_map | ||
188 | * cpu_sibling_map | ||
189 | * | ||
190 | * Having the possible map set up early allows us to restrict allocations | ||
191 | * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. | ||
192 | * | ||
193 | * We do not initialize the online map here; cpus set their own bits in | ||
194 | * cpu_online_map as they come up. | ||
195 | * | ||
196 | * This function is valid only for Open Firmware systems. finish_device_tree | ||
197 | * must be called before using this. | ||
198 | * | ||
199 | * While we're here, we may as well set the "physical" cpu ids in the paca. | ||
200 | */ | ||
201 | static void __init setup_cpu_maps(void) | ||
202 | { | ||
203 | struct device_node *dn = NULL; | ||
204 | int cpu = 0; | ||
205 | int swap_cpuid = 0; | ||
206 | |||
207 | check_smt_enabled(); | ||
208 | |||
209 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { | ||
210 | u32 *intserv; | ||
211 | int j, len = sizeof(u32), nthreads; | ||
212 | |||
213 | intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s", | ||
214 | &len); | ||
215 | if (!intserv) | ||
216 | intserv = (u32 *)get_property(dn, "reg", NULL); | ||
217 | |||
218 | nthreads = len / sizeof(u32); | ||
219 | |||
220 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { | ||
221 | cpu_set(cpu, cpu_present_map); | ||
222 | set_hard_smp_processor_id(cpu, intserv[j]); | ||
223 | |||
224 | if (intserv[j] == boot_cpuid_phys) | ||
225 | swap_cpuid = cpu; | ||
226 | cpu_set(cpu, cpu_possible_map); | ||
227 | cpu++; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that | ||
232 | * boot cpu is logical 0. | ||
233 | */ | ||
234 | if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { | ||
235 | u32 tmp; | ||
236 | tmp = get_hard_smp_processor_id(0); | ||
237 | set_hard_smp_processor_id(0, boot_cpuid_phys); | ||
238 | set_hard_smp_processor_id(swap_cpuid, tmp); | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * On pSeries LPAR, we need to know how many cpus | ||
243 | * could possibly be added to this partition. | ||
244 | */ | ||
245 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR && | ||
246 | (dn = of_find_node_by_path("/rtas"))) { | ||
247 | int num_addr_cell, num_size_cell, maxcpus; | ||
248 | unsigned int *ireg; | ||
249 | |||
250 | num_addr_cell = prom_n_addr_cells(dn); | ||
251 | num_size_cell = prom_n_size_cells(dn); | ||
252 | |||
253 | ireg = (unsigned int *) | ||
254 | get_property(dn, "ibm,lrdr-capacity", NULL); | ||
255 | |||
256 | if (!ireg) | ||
257 | goto out; | ||
258 | |||
259 | maxcpus = ireg[num_addr_cell + num_size_cell]; | ||
260 | |||
261 | /* Double maxcpus for processors which have SMT capability */ | ||
262 | if (cpu_has_feature(CPU_FTR_SMT)) | ||
263 | maxcpus *= 2; | ||
264 | |||
265 | if (maxcpus > NR_CPUS) { | ||
266 | printk(KERN_WARNING | ||
267 | "Partition configured for %d cpus, " | ||
268 | "operating system maximum is %d.\n", | ||
269 | maxcpus, NR_CPUS); | ||
270 | maxcpus = NR_CPUS; | ||
271 | } else | ||
272 | printk(KERN_INFO "Partition configured for %d cpus.\n", | ||
273 | maxcpus); | ||
274 | |||
275 | for (cpu = 0; cpu < maxcpus; cpu++) | ||
276 | cpu_set(cpu, cpu_possible_map); | ||
277 | out: | ||
278 | of_node_put(dn); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Do the sibling map; assume only two threads per processor. | ||
283 | */ | ||
284 | for_each_cpu(cpu) { | ||
285 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
286 | if (cpu_has_feature(CPU_FTR_SMT)) | ||
287 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); | ||
288 | } | ||
289 | |||
290 | systemcfg->processorCount = num_present_cpus(); | ||
291 | } | ||
292 | #endif /* CONFIG_SMP */ | 186 | #endif /* CONFIG_SMP */ |
293 | 187 | ||
294 | extern struct machdep_calls pSeries_md; | 188 | extern struct machdep_calls pSeries_md; |
@@ -417,6 +311,8 @@ void smp_release_cpus(void) | |||
417 | 311 | ||
418 | DBG(" <- smp_release_cpus()\n"); | 312 | DBG(" <- smp_release_cpus()\n"); |
419 | } | 313 | } |
314 | #else | ||
315 | #define smp_release_cpus() | ||
420 | #endif /* CONFIG_SMP || CONFIG_KEXEC */ | 316 | #endif /* CONFIG_SMP || CONFIG_KEXEC */ |
421 | 317 | ||
422 | /* | 318 | /* |
@@ -608,17 +504,13 @@ void __init setup_system(void) | |||
608 | 504 | ||
609 | parse_early_param(); | 505 | parse_early_param(); |
610 | 506 | ||
611 | #ifdef CONFIG_SMP | 507 | check_smt_enabled(); |
612 | /* | 508 | smp_setup_cpu_maps(); |
613 | * iSeries has already initialized the cpu maps at this point. | ||
614 | */ | ||
615 | setup_cpu_maps(); | ||
616 | 509 | ||
617 | /* Release secondary cpus out of their spinloops at 0x60 now that | 510 | /* Release secondary cpus out of their spinloops at 0x60 now that |
618 | * we can map physical -> logical CPU ids | 511 | * we can map physical -> logical CPU ids |
619 | */ | 512 | */ |
620 | smp_release_cpus(); | 513 | smp_release_cpus(); |
621 | #endif | ||
622 | 514 | ||
623 | printk("Starting Linux PPC64 %s\n", system_utsname.version); | 515 | printk("Starting Linux PPC64 %s\n", system_utsname.version); |
624 | 516 | ||