aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-04-30 05:17:22 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-06-02 15:56:06 -0400
commit369e757b65d4a5e49bae7cfaf671e784f891cfbe (patch)
treeaa144c5db61f00384a552c33ace99c454fe5ea23
parentbcf0b0880710409420a4e3b15dbf4b9a63542c0b (diff)
[POWERPC] Rework EXC_LEVEL_EXCEPTION_PROLOG code
* Cleanup the code a bit my allocating an INT_FRAME on our exception stack there by make references go from GPR11-INT_FRAME_SIZE(r8) to just GPR11(r8) * simplify {lvl}_transfer_to_handler code by moving the copying of the temp registers we use if we come from user space into the PROLOG * If the exception came from kernel mode copy thread_info flags, preempt, and task pointer from the process thread_info. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Acked-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/entry_32.S13
-rw-r--r--arch/powerpc/kernel/head_booke.h54
2 files changed, 35 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 888a364043a8..c94aba54b5dd 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -44,29 +44,16 @@
44#endif 44#endif
45 45
46#ifdef CONFIG_BOOKE 46#ifdef CONFIG_BOOKE
47#include "head_booke.h"
48#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
49 mtspr exc_level##_SPRG,r8; \
50 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
51 lwz r0,GPR10-INT_FRAME_SIZE(r8); \
52 stw r0,GPR10(r11); \
53 lwz r0,GPR11-INT_FRAME_SIZE(r8); \
54 stw r0,GPR11(r11); \
55 mfspr r8,exc_level##_SPRG
56
57 .globl mcheck_transfer_to_handler 47 .globl mcheck_transfer_to_handler
58mcheck_transfer_to_handler: 48mcheck_transfer_to_handler:
59 TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
60 b transfer_to_handler_full 49 b transfer_to_handler_full
61 50
62 .globl debug_transfer_to_handler 51 .globl debug_transfer_to_handler
63debug_transfer_to_handler: 52debug_transfer_to_handler:
64 TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
65 b transfer_to_handler_full 53 b transfer_to_handler_full
66 54
67 .globl crit_transfer_to_handler 55 .globl crit_transfer_to_handler
68crit_transfer_to_handler: 56crit_transfer_to_handler:
69 TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
70 /* fall through */ 57 /* fall through */
71#endif 58#endif
72 59
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 9eacf4ca442a..b0874d228eaf 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -72,18 +72,20 @@
72#define DEBUG_STACK_BASE dbgirq_ctx 72#define DEBUG_STACK_BASE dbgirq_ctx
73#define DEBUG_SPRG SPRN_SPRG6W 73#define DEBUG_SPRG SPRN_SPRG6W
74 74
75#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE)
76
75#ifdef CONFIG_SMP 77#ifdef CONFIG_SMP
76#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ 78#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
77 mfspr r8,SPRN_PIR; \ 79 mfspr r8,SPRN_PIR; \
78 slwi r8,r8,2; \ 80 slwi r8,r8,2; \
79 addis r8,r8,level##_STACK_BASE@ha; \ 81 addis r8,r8,level##_STACK_BASE@ha; \
80 lwz r8,level##_STACK_BASE@l(r8); \ 82 lwz r8,level##_STACK_BASE@l(r8); \
81 addi r8,r8,THREAD_SIZE; 83 addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
82#else 84#else
83#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ 85#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
84 lis r8,level##_STACK_BASE@ha; \ 86 lis r8,level##_STACK_BASE@ha; \
85 lwz r8,level##_STACK_BASE@l(r8); \ 87 lwz r8,level##_STACK_BASE@l(r8); \
86 addi r8,r8,THREAD_SIZE; 88 addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
87#endif 89#endif
88 90
89/* 91/*
@@ -97,22 +99,36 @@
97#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \ 99#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
98 mtspr exc_level##_SPRG,r8; \ 100 mtspr exc_level##_SPRG,r8; \
99 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ 101 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
100 stw r10,GPR10-INT_FRAME_SIZE(r8); \ 102 stw r9,GPR9(r8); /* save various registers */\
101 stw r11,GPR11-INT_FRAME_SIZE(r8); \ 103 mfcr r9; /* save CR in r9 for now */\
102 mfcr r10; /* save CR in r10 for now */\ 104 stw r10,GPR10(r8); \
103 mfspr r11,exc_level_srr1; /* check whether user or kernel */\ 105 stw r11,GPR11(r8); \
104 andi. r11,r11,MSR_PR; \ 106 stw r9,_CCR(r8); /* save CR on stack */\
105 mr r11,r8; \ 107 mfspr r10,exc_level_srr1; /* check whether user or kernel */\
106 mfspr r8,exc_level##_SPRG; \ 108 andi. r10,r10,MSR_PR; \
107 beq 1f; \
108 /* COMING FROM USER MODE */ \
109 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ 109 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
110 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ 110 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
111 addi r11,r11,THREAD_SIZE; \ 111 addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\
1121: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ 112 beq 1f; \
113 stw r10,_CCR(r11); /* save various registers */\ 113 /* COMING FROM USER MODE */ \
114 stw r12,GPR12(r11); \ 114 stw r9,_CCR(r11); /* save CR */\
115 lwz r10,GPR10(r8); /* copy regs from exception stack */\
116 lwz r9,GPR9(r8); \
117 stw r10,GPR10(r11); \
118 lwz r10,GPR11(r8); \
115 stw r9,GPR9(r11); \ 119 stw r9,GPR9(r11); \
120 stw r10,GPR11(r11); \
121 b 2f; \
122 /* COMING FROM PRIV MODE */ \
1231: lwz r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r11); \
124 lwz r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r11); \
125 stw r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r8); \
126 stw r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r8); \
127 lwz r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11); \
128 stw r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8); \
129 mr r11,r8; \
1302: mfspr r8,exc_level##_SPRG; \
131 stw r12,GPR12(r11); /* save various registers */\
116 mflr r10; \ 132 mflr r10; \
117 stw r10,_LINK(r11); \ 133 stw r10,_LINK(r11); \
118 mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ 134 mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
@@ -255,8 +271,8 @@ label:
255 lwz r12,GPR12(r11); \ 271 lwz r12,GPR12(r11); \
256 mtspr DEBUG_SPRG,r8; \ 272 mtspr DEBUG_SPRG,r8; \
257 BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \ 273 BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
258 lwz r10,GPR10-INT_FRAME_SIZE(r8); \ 274 lwz r10,GPR10(r8); \
259 lwz r11,GPR11-INT_FRAME_SIZE(r8); \ 275 lwz r11,GPR11(r8); \
260 mfspr r8,DEBUG_SPRG; \ 276 mfspr r8,DEBUG_SPRG; \
261 \ 277 \
262 RFDI; \ 278 RFDI; \
@@ -308,8 +324,8 @@ label:
308 lwz r12,GPR12(r11); \ 324 lwz r12,GPR12(r11); \
309 mtspr CRIT_SPRG,r8; \ 325 mtspr CRIT_SPRG,r8; \
310 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \ 326 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
311 lwz r10,GPR10-INT_FRAME_SIZE(r8); \ 327 lwz r10,GPR10(r8); \
312 lwz r11,GPR11-INT_FRAME_SIZE(r8); \ 328 lwz r11,GPR11(r8); \
313 mfspr r8,CRIT_SPRG; \ 329 mfspr r8,CRIT_SPRG; \
314 \ 330 \
315 rfci; \ 331 rfci; \