aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/head_booke.h
diff options
context:
space:
mode:
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 f213d12eec08..9c50f9d2657c 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -67,46 +67,36 @@
#define CRIT_STACK_TOP (exception_stack_top)
#ifdef CONFIG_SMP
-#define BOOKE_LOAD_CRIT_STACK \
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
mfspr r8,SPRN_PIR; \
mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
neg r8,r8; \
- addis r8,r8,CRIT_STACK_TOP@ha; \
- addi r8,r8,CRIT_STACK_TOP@l
-#define BOOKE_LOAD_MCHECK_STACK \
- mfspr r8,SPRN_PIR; \
- mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
- neg r8,r8; \
- addis r8,r8,MCHECK_STACK_TOP@ha; \
- addi r8,r8,MCHECK_STACK_TOP@l
+ addis r8,r8,level##_STACK_TOP@ha; \
+ addi r8,r8,level##_STACK_TOP@l
#else
-#define BOOKE_LOAD_CRIT_STACK \
- lis r8,CRIT_STACK_TOP@h; \
- ori r8,r8,CRIT_STACK_TOP@l
-#define BOOKE_LOAD_MCHECK_STACK \
- lis r8,MCHECK_STACK_TOP@h; \
- ori r8,r8,MCHECK_STACK_TOP@l
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
+ lis r8,level##_STACK_TOP@h; \
+ ori r8,r8,level##_STACK_TOP@l
#endif
/*
- * Exception prolog for critical exceptions. This is a little different
- * from the normal exception prolog above since a critical exception
- * can potentially occur at any point during normal exception processing.
- * Thus we cannot use the same SPRG registers as the normal prolog above.
- * Instead we use a portion of the critical exception stack at low physical
- * addresses.
+ * Exception prolog for critical/machine check exceptions. This is a
+ * little different from the normal exception prolog above since a
+ * critical/machine check exception can potentially occur at any point
+ * during normal exception processing. Thus we cannot use the same SPRG
+ * registers as the normal prolog above. Instead we use a portion of the
+ * critical/machine check exception stack at low physical addresses.
*/
-
-#define CRITICAL_EXCEPTION_PROLOG \
- mtspr CRIT_SPRG,r8; \
- BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
+#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
+ mtspr exc_level##_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
stw r10,GPR10-INT_FRAME_SIZE(r8); \
stw r11,GPR11-INT_FRAME_SIZE(r8); \
mfcr r10; /* save CR in r10 for now */\
- mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\
+ mfspr r11,exc_level_srr1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
mr r11,r8; \
- mfspr r8,CRIT_SPRG; \
+ mfspr r8,exc_level##_SPRG; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
@@ -122,9 +112,9 @@
stw r12,_DEAR(r11); /* since they may have had stuff */\
mfspr r9,SPRN_ESR; /* in them at the point where the */\
stw r9,_ESR(r11); /* exception was taken */\
- mfspr r12,SPRN_CSRR0; \
+ mfspr r12,exc_level_srr0; \
stw r1,GPR1(r11); \
- mfspr r9,SPRN_CSRR1; \
+ mfspr r9,exc_level_srr1; \
stw r1,0(r11); \
mr r1,r11; \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
@@ -132,45 +122,10 @@
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)
-/*
- * Exception prolog for machine check exceptions. This is similar to
- * the critical exception prolog, except that machine check exceptions
- * have their stack.
- */
-#define MCHECK_EXCEPTION_PROLOG \
- mtspr MCHECK_SPRG,r8; \
- BOOKE_LOAD_MCHECK_STACK; /* r8 points to the mcheck stack */\
- stw r10,GPR10-INT_FRAME_SIZE(r8); \
- stw r11,GPR11-INT_FRAME_SIZE(r8); \
- mfcr r10; /* save CR in r10 for now */\
- mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\
- andi. r11,r11,MSR_PR; \
- mr r11,r8; \
- mfspr r8,MCHECK_SPRG; \
- beq 1f; \
- /* COMING FROM USER MODE */ \
- mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
- lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
- addi r11,r11,THREAD_SIZE; \
-1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
- stw r10,_CCR(r11); /* save various registers */\
- stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
- mflr r10; \
- stw r10,_LINK(r11); \
- mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
- stw r12,_DEAR(r11); /* since they may have had stuff */\
- mfspr r9,SPRN_ESR; /* in them at the point where the */\
- stw r9,_ESR(r11); /* exception was taken */\
- mfspr r12,SPRN_MCSRR0; \
- stw r1,GPR1(r11); \
- mfspr r9,SPRN_MCSRR1; \
- stw r1,0(r11); \
- mr r1,r11; \
- rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
- stw r0,GPR0(r11); \
- SAVE_4GPRS(3, r11); \
- SAVE_2GPRS(7, r11)
+#define CRITICAL_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
+#define MCHECK_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
/*
* Exception vectors.
@@ -237,7 +192,6 @@ label:
EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
ret_from_except)
-
/* Check for a single step debug exception while in an exception
* handler before state has been saved. This is to catch the case
* where an instruction that we are trying to single step causes
@@ -291,7 +245,7 @@ label:
lwz r9,GPR9(r11); \
lwz r12,GPR12(r11); \
mtspr CRIT_SPRG,r8; \
- BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
+ BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
lwz r10,GPR10-INT_FRAME_SIZE(r8); \
lwz r11,GPR11-INT_FRAME_SIZE(r8); \
mfspr r8,CRIT_SPRG; \