diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2008-04-28 02:21:22 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-04-29 01:57:34 -0400 |
commit | 85218827cc4ca900867807f19345418164ffc108 (patch) | |
tree | 1813b7fadb7c077acd0ef62f57385b7424ca0121 /arch/powerpc/kernel/setup_32.c | |
parent | dd18434ff0b7d9b9ad3d596985fc84b329d2f9a8 (diff) |
[POWERPC] Add IRQSTACKS support on ppc32
This makes it possible to use separate stacks for hard and soft IRQs
on 32-bit powerpc as well as on 64-bit. The code for 32-bit is just
the 32-bit analog of the 64-bit code.
* Added allocation and initialization of the irq stacks. We limit the
stacks to be in lowmem for ppc32.
* Implemented ppc32 versions of call_do_softirq() and call_handle_irq()
to switch the stack pointers
* Reworked how we do stack overflow detection. We now keep around the
limit of the stack in the thread_struct and compare against the limit
to see if we've overflowed. We can now use this on ppc64 if desired.
[ paulus@samba.org: Fixed bug on 6xx where we need to reload r9 with the
thread_info pointer. ]
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/setup_32.c')
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 36f6779c88d4..5112a4aa801d 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/root_dev.h> | 16 | #include <linux/root_dev.h> |
17 | #include <linux/cpu.h> | 17 | #include <linux/cpu.h> |
18 | #include <linux/console.h> | 18 | #include <linux/console.h> |
19 | #include <linux/lmb.h> | ||
19 | 20 | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
@@ -229,6 +230,24 @@ int __init ppc_init(void) | |||
229 | 230 | ||
230 | arch_initcall(ppc_init); | 231 | arch_initcall(ppc_init); |
231 | 232 | ||
233 | #ifdef CONFIG_IRQSTACKS | ||
234 | static void __init irqstack_early_init(void) | ||
235 | { | ||
236 | unsigned int i; | ||
237 | |||
238 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 | ||
239 | * as the lmb is limited to lowmem by LMB_REAL_LIMIT */ | ||
240 | for_each_possible_cpu(i) { | ||
241 | softirq_ctx[i] = (struct thread_info *) | ||
242 | __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE)); | ||
243 | hardirq_ctx[i] = (struct thread_info *) | ||
244 | __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE)); | ||
245 | } | ||
246 | } | ||
247 | #else | ||
248 | #define irqstack_early_init() | ||
249 | #endif | ||
250 | |||
232 | /* Warning, IO base is not yet inited */ | 251 | /* Warning, IO base is not yet inited */ |
233 | void __init setup_arch(char **cmdline_p) | 252 | void __init setup_arch(char **cmdline_p) |
234 | { | 253 | { |
@@ -286,6 +305,8 @@ void __init setup_arch(char **cmdline_p) | |||
286 | init_mm.end_data = (unsigned long) _edata; | 305 | init_mm.end_data = (unsigned long) _edata; |
287 | init_mm.brk = klimit; | 306 | init_mm.brk = klimit; |
288 | 307 | ||
308 | irqstack_early_init(); | ||
309 | |||
289 | /* set up the bootmem stuff with available memory */ | 310 | /* set up the bootmem stuff with available memory */ |
290 | do_init_bootmem(); | 311 | do_init_bootmem(); |
291 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); | 312 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); |