aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/head_booke.h
diff options
context:
space:
mode:
authorKumar Gala <galak@freescale.com>2005-06-21 20:15:27 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:25 -0400
commit1492ec8069ea6f82bc32df27cabbec72e554e2b8 (patch)
tree09e52d150482a105a63dc4b71758a7aa99ecb28c /arch/ppc/kernel/head_booke.h
parent5be061eee931db2718feecaf10df17610386202b (diff)
[PATCH] ppc32: Factor out common exception code into macro's for 4xx/Book-E
4xx and Book-E PPC's have several exception levels. The code to handle each level is fairly regular. Turning the code into macro's will ease the handling of future exception levels (debug) in forth coming chips. Signed-off-by: Kumar Gala <kumar.gala@freescale.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/kernel/head_booke.h')
-rw-r--r--arch/ppc/kernel/head_booke.h94
1 files changed, 24 insertions, 70 deletions
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index f213d12eec0..9c50f9d2657 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -67,46 +67,36 @@
67#define CRIT_STACK_TOP (exception_stack_top) 67#define CRIT_STACK_TOP (exception_stack_top)
68 68
69#ifdef CONFIG_SMP 69#ifdef CONFIG_SMP
70#define BOOKE_LOAD_CRIT_STACK \ 70#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
71 mfspr r8,SPRN_PIR; \ 71 mfspr r8,SPRN_PIR; \
72 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \ 72 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
73 neg r8,r8; \ 73 neg r8,r8; \
74 addis r8,r8,CRIT_STACK_TOP@ha; \ 74 addis r8,r8,level##_STACK_TOP@ha; \
75 addi r8,r8,CRIT_STACK_TOP@l 75 addi r8,r8,level##_STACK_TOP@l
76#define BOOKE_LOAD_MCHECK_STACK \
77 mfspr r8,SPRN_PIR; \
78 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
79 neg r8,r8; \
80 addis r8,r8,MCHECK_STACK_TOP@ha; \
81 addi r8,r8,MCHECK_STACK_TOP@l
82#else 76#else
83#define BOOKE_LOAD_CRIT_STACK \ 77#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
84 lis r8,CRIT_STACK_TOP@h; \ 78 lis r8,level##_STACK_TOP@h; \
85 ori r8,r8,CRIT_STACK_TOP@l 79 ori r8,r8,level##_STACK_TOP@l
86#define BOOKE_LOAD_MCHECK_STACK \
87 lis r8,MCHECK_STACK_TOP@h; \
88 ori r8,r8,MCHECK_STACK_TOP@l
89#endif 80#endif
90 81
91/* 82/*
92 * Exception prolog for critical exceptions. This is a little different 83 * Exception prolog for critical/machine check exceptions. This is a
93 * from the normal exception prolog above since a critical exception 84 * little different from the normal exception prolog above since a
94 * can potentially occur at any point during normal exception processing. 85 * critical/machine check exception can potentially occur at any point
95 * Thus we cannot use the same SPRG registers as the normal prolog above. 86 * during normal exception processing. Thus we cannot use the same SPRG
96 * Instead we use a portion of the critical exception stack at low physical 87 * registers as the normal prolog above. Instead we use a portion of the
97 * addresses. 88 * critical/machine check exception stack at low physical addresses.
98 */ 89 */
99 90#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
100#define CRITICAL_EXCEPTION_PROLOG \ 91 mtspr exc_level##_SPRG,r8; \
101 mtspr CRIT_SPRG,r8; \ 92 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
102 BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
103 stw r10,GPR10-INT_FRAME_SIZE(r8); \ 93 stw r10,GPR10-INT_FRAME_SIZE(r8); \
104 stw r11,GPR11-INT_FRAME_SIZE(r8); \ 94 stw r11,GPR11-INT_FRAME_SIZE(r8); \
105 mfcr r10; /* save CR in r10 for now */\ 95 mfcr r10; /* save CR in r10 for now */\
106 mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\ 96 mfspr r11,exc_level_srr1; /* check whether user or kernel */\
107 andi. r11,r11,MSR_PR; \ 97 andi. r11,r11,MSR_PR; \
108 mr r11,r8; \ 98 mr r11,r8; \
109 mfspr r8,CRIT_SPRG; \ 99 mfspr r8,exc_level##_SPRG; \
110 beq 1f; \ 100 beq 1f; \
111 /* COMING FROM USER MODE */ \ 101 /* COMING FROM USER MODE */ \
112 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ 102 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
@@ -122,9 +112,9 @@
122 stw r12,_DEAR(r11); /* since they may have had stuff */\ 112 stw r12,_DEAR(r11); /* since they may have had stuff */\
123 mfspr r9,SPRN_ESR; /* in them at the point where the */\ 113 mfspr r9,SPRN_ESR; /* in them at the point where the */\
124 stw r9,_ESR(r11); /* exception was taken */\ 114 stw r9,_ESR(r11); /* exception was taken */\
125 mfspr r12,SPRN_CSRR0; \ 115 mfspr r12,exc_level_srr0; \
126 stw r1,GPR1(r11); \ 116 stw r1,GPR1(r11); \
127 mfspr r9,SPRN_CSRR1; \ 117 mfspr r9,exc_level_srr1; \
128 stw r1,0(r11); \ 118 stw r1,0(r11); \
129 mr r1,r11; \ 119 mr r1,r11; \
130 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ 120 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
@@ -132,45 +122,10 @@
132 SAVE_4GPRS(3, r11); \ 122 SAVE_4GPRS(3, r11); \
133 SAVE_2GPRS(7, r11) 123 SAVE_2GPRS(7, r11)
134 124
135/* 125#define CRITICAL_EXCEPTION_PROLOG \
136 * Exception prolog for machine check exceptions. This is similar to 126 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
137 * the critical exception prolog, except that machine check exceptions 127#define MCHECK_EXCEPTION_PROLOG \
138 * have their stack. 128 EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
139 */
140#define MCHECK_EXCEPTION_PROLOG \
141 mtspr MCHECK_SPRG,r8; \
142 BOOKE_LOAD_MCHECK_STACK; /* r8 points to the mcheck stack */\
143 stw r10,GPR10-INT_FRAME_SIZE(r8); \
144 stw r11,GPR11-INT_FRAME_SIZE(r8); \
145 mfcr r10; /* save CR in r10 for now */\
146 mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\
147 andi. r11,r11,MSR_PR; \
148 mr r11,r8; \
149 mfspr r8,MCHECK_SPRG; \
150 beq 1f; \
151 /* COMING FROM USER MODE */ \
152 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
153 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
154 addi r11,r11,THREAD_SIZE; \
1551: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
156 stw r10,_CCR(r11); /* save various registers */\
157 stw r12,GPR12(r11); \
158 stw r9,GPR9(r11); \
159 mflr r10; \
160 stw r10,_LINK(r11); \
161 mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
162 stw r12,_DEAR(r11); /* since they may have had stuff */\
163 mfspr r9,SPRN_ESR; /* in them at the point where the */\
164 stw r9,_ESR(r11); /* exception was taken */\
165 mfspr r12,SPRN_MCSRR0; \
166 stw r1,GPR1(r11); \
167 mfspr r9,SPRN_MCSRR1; \
168 stw r1,0(r11); \
169 mr r1,r11; \
170 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
171 stw r0,GPR0(r11); \
172 SAVE_4GPRS(3, r11); \
173 SAVE_2GPRS(7, r11)
174 129
175/* 130/*
176 * Exception vectors. 131 * Exception vectors.
@@ -237,7 +192,6 @@ label:
237 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ 192 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
238 ret_from_except) 193 ret_from_except)
239 194
240
241/* Check for a single step debug exception while in an exception 195/* Check for a single step debug exception while in an exception
242 * handler before state has been saved. This is to catch the case 196 * handler before state has been saved. This is to catch the case
243 * where an instruction that we are trying to single step causes 197 * where an instruction that we are trying to single step causes
@@ -291,7 +245,7 @@ label:
291 lwz r9,GPR9(r11); \ 245 lwz r9,GPR9(r11); \
292 lwz r12,GPR12(r11); \ 246 lwz r12,GPR12(r11); \
293 mtspr CRIT_SPRG,r8; \ 247 mtspr CRIT_SPRG,r8; \
294 BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \ 248 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
295 lwz r10,GPR10-INT_FRAME_SIZE(r8); \ 249 lwz r10,GPR10-INT_FRAME_SIZE(r8); \
296 lwz r11,GPR11-INT_FRAME_SIZE(r8); \ 250 lwz r11,GPR11-INT_FRAME_SIZE(r8); \
297 mfspr r8,CRIT_SPRG; \ 251 mfspr r8,CRIT_SPRG; \