aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/setup.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-05-31 17:22:32 -0400
committerRussell King <rmk@dyn-67.arm.linux.org.uk>2005-05-31 17:22:32 -0400
commitccea7a19e54349d4f40778304e1bb88da83d39e7 (patch)
treedd42dbff31b2dff8b226f1b61eff4b958fca5496 /arch/arm/kernel/setup.c
parent49f680ea7bac5c679fb6374a326a164a3fba07cc (diff)
[PATCH] ARM SMP: Fix vector entry
The current vector entry system does not allow for SMP. In order to work around this, we need to eliminate our reliance on the fixed save areas, which breaks the way we enable alignment traps. This patch changes the way we handle the save areas such that we can have one per CPU. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r--arch/arm/kernel/setup.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c2a7da3ac0f1..7ecdda3f1253 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user;
92struct cpu_cache_fns cpu_cache; 92struct cpu_cache_fns cpu_cache;
93#endif 93#endif
94 94
95struct stack {
96 u32 irq[3];
97 u32 abt[3];
98 u32 und[3];
99} ____cacheline_aligned;
100
101static struct stack stacks[NR_CPUS];
102
95char elf_platform[ELF_PLATFORM_SIZE]; 103char elf_platform[ELF_PLATFORM_SIZE];
96EXPORT_SYMBOL(elf_platform); 104EXPORT_SYMBOL(elf_platform);
97 105
@@ -307,8 +315,6 @@ static void __init setup_processor(void)
307 cpu_name, processor_id, (int)processor_id & 15, 315 cpu_name, processor_id, (int)processor_id & 15,
308 proc_arch[cpu_architecture()]); 316 proc_arch[cpu_architecture()]);
309 317
310 dump_cpu_info(smp_processor_id());
311
312 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); 318 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
313 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); 319 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
314 elf_hwcap = list->elf_hwcap; 320 elf_hwcap = list->elf_hwcap;
@@ -316,6 +322,46 @@ static void __init setup_processor(void)
316 cpu_proc_init(); 322 cpu_proc_init();
317} 323}
318 324
325/*
326 * cpu_init - initialise one CPU.
327 *
328 * cpu_init dumps the cache information, initialises SMP specific
329 * information, and sets up the per-CPU stacks.
330 */
331void __init cpu_init(void)
332{
333 unsigned int cpu = smp_processor_id();
334 struct stack *stk = &stacks[cpu];
335
336 if (cpu >= NR_CPUS) {
337 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
338 BUG();
339 }
340
341 dump_cpu_info(cpu);
342
343 /*
344 * setup stacks for re-entrant exception handlers
345 */
346 __asm__ (
347 "msr cpsr_c, %1\n\t"
348 "add sp, %0, %2\n\t"
349 "msr cpsr_c, %3\n\t"
350 "add sp, %0, %4\n\t"
351 "msr cpsr_c, %5\n\t"
352 "add sp, %0, %6\n\t"
353 "msr cpsr_c, %7"
354 :
355 : "r" (stk),
356 "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
357 "I" (offsetof(struct stack, irq[0])),
358 "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
359 "I" (offsetof(struct stack, abt[0])),
360 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
361 "I" (offsetof(struct stack, und[0])),
362 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE));
363}
364
319static struct machine_desc * __init setup_machine(unsigned int nr) 365static struct machine_desc * __init setup_machine(unsigned int nr)
320{ 366{
321 struct machine_desc *list; 367 struct machine_desc *list;
@@ -715,6 +761,8 @@ void __init setup_arch(char **cmdline_p)
715 paging_init(&meminfo, mdesc); 761 paging_init(&meminfo, mdesc);
716 request_standard_resources(&meminfo, mdesc); 762 request_standard_resources(&meminfo, mdesc);
717 763
764 cpu_init();
765
718 /* 766 /*
719 * Set up various architecture-specific pointers 767 * Set up various architecture-specific pointers
720 */ 768 */