aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/setup_64.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-04 18:33:55 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-04 18:33:55 -0500
commit5ad570786158e327a1c5d32dd3d66f26d8de6340 (patch)
tree0b4aafe469c72e5887ed0379d62a0ee390db3160 /arch/powerpc/kernel/setup_64.c
parentc3df69cd854551cf70e9c63aa509c26621084f60 (diff)
powerpc: Merge smp.c and smp.h
This also moves setup_cpu_maps to setup-common.c (calling it smp_setup_cpu_maps) and uses it on both 32-bit and 64-bit. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/setup_64.c')
-rw-r--r--arch/powerpc/kernel/setup_64.c120
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}
182early_param("smt-enabled", early_smt_enabled); 182early_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 */
201static 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
294extern struct machdep_calls pSeries_md; 188extern 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