aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/head_40x.S18
-rw-r--r--arch/powerpc/kernel/head_44x.S9
-rw-r--r--arch/powerpc/kernel/head_booke.h29
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S9
-rw-r--r--arch/powerpc/kernel/irq.c33
-rw-r--r--arch/powerpc/kernel/setup_32.c24
-rw-r--r--include/asm-powerpc/irq.h13
7 files changed, 85 insertions, 50 deletions
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 8552e67e3a8b..f2cf60d38f78 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -148,14 +148,14 @@ _ENTRY(crit_r11)
148 mfcr r10; /* save CR in r10 for now */\ 148 mfcr r10; /* save CR in r10 for now */\
149 mfspr r11,SPRN_SRR3; /* check whether user or kernel */\ 149 mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
150 andi. r11,r11,MSR_PR; \ 150 andi. r11,r11,MSR_PR; \
151 lis r11,critical_stack_top@h; \ 151 lis r11,critirq_ctx@ha; \
152 ori r11,r11,critical_stack_top@l; \ 152 tophys(r11,r11); \
153 lwz r11,critirq_ctx@l(r11); \
153 beq 1f; \ 154 beq 1f; \
154 /* COMING FROM USER MODE */ \ 155 /* COMING FROM USER MODE */ \
155 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ 156 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
156 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ 157 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
157 addi r11,r11,THREAD_SIZE; \ 1581: addi r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm */\
1581: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
159 tophys(r11,r11); \ 159 tophys(r11,r11); \
160 stw r10,_CCR(r11); /* save various registers */\ 160 stw r10,_CCR(r11); /* save various registers */\
161 stw r12,GPR12(r11); \ 161 stw r12,GPR12(r11); \
@@ -996,16 +996,6 @@ empty_zero_page:
996swapper_pg_dir: 996swapper_pg_dir:
997 .space PGD_TABLE_SIZE 997 .space PGD_TABLE_SIZE
998 998
999
1000/* Stack for handling critical exceptions from kernel mode */
1001 .section .bss
1002 .align 12
1003exception_stack_bottom:
1004 .space 4096
1005critical_stack_top:
1006 .globl exception_stack_top
1007exception_stack_top:
1008
1009/* Room for two PTE pointers, usually the kernel and current user pointers 999/* Room for two PTE pointers, usually the kernel and current user pointers
1010 * to their respective root page table. 1000 * to their respective root page table.
1011 */ 1001 */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index c2b9dc4fce5d..47ea8affad23 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -737,15 +737,6 @@ empty_zero_page:
737swapper_pg_dir: 737swapper_pg_dir:
738 .space PGD_TABLE_SIZE 738 .space PGD_TABLE_SIZE
739 739
740/* Reserved 4k for the critical exception stack & 4k for the machine
741 * check stack per CPU for kernel mode exceptions */
742 .section .bss
743 .align 12
744exception_stack_bottom:
745 .space BOOKE_EXCEPTION_STACK_SIZE
746 .globl exception_stack_top
747exception_stack_top:
748
749/* 740/*
750 * Room for two PTE pointers, usually the kernel and current user pointers 741 * Room for two PTE pointers, usually the kernel and current user pointers
751 * to their respective root page table. 742 * to their respective root page table.
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 721faef87095..9eacf4ca442a 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -43,9 +43,7 @@
43 SAVE_2GPRS(7, r11) 43 SAVE_2GPRS(7, r11)
44 44
45/* To handle the additional exception priority levels on 40x and Book-E 45/* To handle the additional exception priority levels on 40x and Book-E
46 * processors we allocate a 4k stack per additional priority level. The various 46 * processors we allocate a stack per additional priority level.
47 * head_xxx.S files allocate space (exception_stack_top) for each priority's
48 * stack times the number of CPUs
49 * 47 *
50 * On 40x critical is the only additional level 48 * On 40x critical is the only additional level
51 * On 44x/e500 we have critical and machine check 49 * On 44x/e500 we have critical and machine check
@@ -61,36 +59,31 @@
61 * going to critical or their own debug level we aren't currently 59 * going to critical or their own debug level we aren't currently
62 * providing configurations that micro-optimize space usage. 60 * providing configurations that micro-optimize space usage.
63 */ 61 */
64#ifdef CONFIG_44x
65#define NUM_EXCEPTION_LVLS 2
66#else
67#define NUM_EXCEPTION_LVLS 3
68#endif
69#define BOOKE_EXCEPTION_STACK_SIZE (4096 * NUM_EXCEPTION_LVLS)
70 62
71/* CRIT_SPRG only used in critical exception handling */ 63/* CRIT_SPRG only used in critical exception handling */
72#define CRIT_SPRG SPRN_SPRG2 64#define CRIT_SPRG SPRN_SPRG2
73/* MCHECK_SPRG only used in machine check exception handling */ 65/* MCHECK_SPRG only used in machine check exception handling */
74#define MCHECK_SPRG SPRN_SPRG6W 66#define MCHECK_SPRG SPRN_SPRG6W
75 67
76#define MCHECK_STACK_TOP (exception_stack_top - 4096) 68#define MCHECK_STACK_BASE mcheckirq_ctx
77#define CRIT_STACK_TOP (exception_stack_top) 69#define CRIT_STACK_BASE critirq_ctx
78 70
79/* only on e200 for now */ 71/* only on e200 for now */
80#define DEBUG_STACK_TOP (exception_stack_top - 8192) 72#define DEBUG_STACK_BASE dbgirq_ctx
81#define DEBUG_SPRG SPRN_SPRG6W 73#define DEBUG_SPRG SPRN_SPRG6W
82 74
83#ifdef CONFIG_SMP 75#ifdef CONFIG_SMP
84#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ 76#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
85 mfspr r8,SPRN_PIR; \ 77 mfspr r8,SPRN_PIR; \
86 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \ 78 slwi r8,r8,2; \
87 neg r8,r8; \ 79 addis r8,r8,level##_STACK_BASE@ha; \
88 addis r8,r8,level##_STACK_TOP@ha; \ 80 lwz r8,level##_STACK_BASE@l(r8); \
89 addi r8,r8,level##_STACK_TOP@l 81 addi r8,r8,THREAD_SIZE;
90#else 82#else
91#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ 83#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
92 lis r8,level##_STACK_TOP@h; \ 84 lis r8,level##_STACK_BASE@ha; \
93 ori r8,r8,level##_STACK_TOP@l 85 lwz r8,level##_STACK_BASE@l(r8); \
86 addi r8,r8,THREAD_SIZE;
94#endif 87#endif
95 88
96/* 89/*
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index e581524d85bc..503f86030b6e 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1080,15 +1080,6 @@ empty_zero_page:
1080swapper_pg_dir: 1080swapper_pg_dir:
1081 .space PGD_TABLE_SIZE 1081 .space PGD_TABLE_SIZE
1082 1082
1083/* Reserved 4k for the critical exception stack & 4k for the machine
1084 * check stack per CPU for kernel mode exceptions */
1085 .section .bss
1086 .align 12
1087exception_stack_bottom:
1088 .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
1089 .globl exception_stack_top
1090exception_stack_top:
1091
1092/* 1083/*
1093 * Room for two PTE pointers, usually the kernel and current user pointers 1084 * Room for two PTE pointers, usually the kernel and current user pointers
1094 * to their respective root page table. 1085 * to their respective root page table.
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2f73f705d564..b5199752ac60 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -356,9 +356,42 @@ void __init init_IRQ(void)
356{ 356{
357 if (ppc_md.init_IRQ) 357 if (ppc_md.init_IRQ)
358 ppc_md.init_IRQ(); 358 ppc_md.init_IRQ();
359
360 exc_lvl_ctx_init();
361
359 irq_ctx_init(); 362 irq_ctx_init();
360} 363}
361 364
365#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
366struct thread_info *critirq_ctx[NR_CPUS] __read_mostly;
367struct thread_info *dbgirq_ctx[NR_CPUS] __read_mostly;
368struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
369
370void exc_lvl_ctx_init(void)
371{
372 struct thread_info *tp;
373 int i;
374
375 for_each_possible_cpu(i) {
376 memset((void *)critirq_ctx[i], 0, THREAD_SIZE);
377 tp = critirq_ctx[i];
378 tp->cpu = i;
379 tp->preempt_count = 0;
380
381#ifdef CONFIG_BOOKE
382 memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE);
383 tp = dbgirq_ctx[i];
384 tp->cpu = i;
385 tp->preempt_count = 0;
386
387 memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE);
388 tp = mcheckirq_ctx[i];
389 tp->cpu = i;
390 tp->preempt_count = HARDIRQ_OFFSET;
391#endif
392 }
393}
394#endif
362 395
363#ifdef CONFIG_IRQSTACKS 396#ifdef CONFIG_IRQSTACKS
364struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; 397struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 5112a4aa801d..bef0be3fd98b 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -248,6 +248,28 @@ static void __init irqstack_early_init(void)
248#define irqstack_early_init() 248#define irqstack_early_init()
249#endif 249#endif
250 250
251#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
252static void __init exc_lvl_early_init(void)
253{
254 unsigned int i;
255
256 /* interrupt stacks must be in lowmem, we get that for free on ppc32
257 * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
258 for_each_possible_cpu(i) {
259 critirq_ctx[i] = (struct thread_info *)
260 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
261#ifdef CONFIG_BOOKE
262 dbgirq_ctx[i] = (struct thread_info *)
263 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
264 mcheckirq_ctx[i] = (struct thread_info *)
265 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
266#endif
267 }
268}
269#else
270#define exc_lvl_early_init()
271#endif
272
251/* Warning, IO base is not yet inited */ 273/* Warning, IO base is not yet inited */
252void __init setup_arch(char **cmdline_p) 274void __init setup_arch(char **cmdline_p)
253{ 275{
@@ -305,6 +327,8 @@ void __init setup_arch(char **cmdline_p)
305 init_mm.end_data = (unsigned long) _edata; 327 init_mm.end_data = (unsigned long) _edata;
306 init_mm.brk = klimit; 328 init_mm.brk = klimit;
307 329
330 exc_lvl_early_init();
331
308 irqstack_early_init(); 332 irqstack_early_init();
309 333
310 /* set up the bootmem stuff with available memory */ 334 /* set up the bootmem stuff with available memory */
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index 5089deb8fec3..1ef8e304e0ea 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -619,6 +619,19 @@ struct pt_regs;
619 619
620#define __ARCH_HAS_DO_SOFTIRQ 620#define __ARCH_HAS_DO_SOFTIRQ
621 621
622#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
623/*
624 * Per-cpu stacks for handling critical, debug and machine check
625 * level interrupts.
626 */
627extern struct thread_info *critirq_ctx[NR_CPUS];
628extern struct thread_info *dbgirq_ctx[NR_CPUS];
629extern struct thread_info *mcheckirq_ctx[NR_CPUS];
630extern void exc_lvl_ctx_init(void);
631#else
632#define exc_lvl_ctx_init()
633#endif
634
622#ifdef CONFIG_IRQSTACKS 635#ifdef CONFIG_IRQSTACKS
623/* 636/*
624 * Per-cpu stacks for handling hard and soft interrupts. 637 * Per-cpu stacks for handling hard and soft interrupts.