#endif
#ifdef CONFIG_BOOKE
-#define COR r8 /* Critical Offset Register (COR) */
-#define BOOKE_LOAD_COR lis COR,crit_save@ha
-#define BOOKE_REST_COR mfspr COR,SPRG2
-#define BOOKE_SAVE_COR mtspr SPRG2,COR
-#else
-#define COR 0
-#define BOOKE_LOAD_COR
-#define BOOKE_REST_COR
-#define BOOKE_SAVE_COR
-#endif
-
-#ifdef CONFIG_BOOKE
+#include "head_booke.h"
.globl mcheck_transfer_to_handler
mcheck_transfer_to_handler:
- mtspr SPRG6W,r8
- lis r8,mcheck_save@ha
- lwz r0,mcheck_r10@l(r8)
+ mtspr MCHECK_SPRG,r8
+ BOOKE_LOAD_MCHECK_STACK
+ lwz r0,GPR10-INT_FRAME_SIZE(r8)
stw r0,GPR10(r11)
- lwz r0,mcheck_r11@l(r8)
+ lwz r0,GPR11-INT_FRAME_SIZE(r8)
stw r0,GPR11(r11)
- mfspr r8,SPRG6R
+ mfspr r8,MCHECK_SPRG
b transfer_to_handler_full
+
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ mtspr CRIT_SPRG,r8
+ BOOKE_LOAD_CRIT_STACK
+ lwz r0,GPR10-INT_FRAME_SIZE(r8)
+ stw r0,GPR10(r11)
+ lwz r0,GPR11-INT_FRAME_SIZE(r8)
+ stw r0,GPR11(r11)
+ mfspr r8,CRIT_SPRG
+ /* fall through */
#endif
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_40x
.globl crit_transfer_to_handler
crit_transfer_to_handler:
- BOOKE_SAVE_COR
- BOOKE_LOAD_COR
- lwz r0,crit_r10@l(COR)
+ lwz r0,crit_r10@l(0)
stw r0,GPR10(r11)
- lwz r0,crit_r11@l(COR)
+ lwz r0,crit_r11@l(0)
stw r0,GPR11(r11)
- BOOKE_REST_COR
/* fall through */
#endif
stw r9,_MSR(r11)
andi. r2,r9,MSR_PR
mfctr r12
- mfspr r2,XER
+ mfspr r2,SPRN_XER
stw r12,_CTR(r11)
stw r2,_XER(r11)
- mfspr r12,SPRG3
+ mfspr r12,SPRN_SPRG3
addi r2,r12,-THREAD
tovirt(r2,r2) /* set r2 to current */
beq 2f /* if from user, fix up THREAD.regs */
lwz r11,0(r9) /* virtual address of handler */
lwz r9,4(r9) /* where to go when done */
FIX_SRR1(r10,r12)
- mtspr SRR0,r11
- mtspr SRR1,r10
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r10
mtlr r9
SYNC
RFI /* jump to handler, enable MMU */
addi r9,r9,StackOverflow@l
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
FIX_SRR1(r10,r12)
- mtspr SRR0,r9
- mtspr SRR1,r10
+ mtspr SPRN_SRR0,r9
+ mtspr SPRN_SRR1,r10
SYNC
RFI
FIX_SRR1(r8, r0)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
- mtspr SRR0,r7
- mtspr SRR1,r8
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
SYNC
RFI
tophys(r0,r4)
CLR_TOP32(r0)
- mtspr SPRG3,r0 /* Update current THREAD phys addr */
+ mtspr SPRN_SPRG3,r0 /* Update current THREAD phys addr */
lwz r1,KSP(r4) /* Load new stack pointer */
/* save the old current 'last' for return value */
addi r1,r1,INT_FRAME_SIZE
blr
+ .globl fast_exception_return
+fast_exception_return:
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ andi. r10,r9,MSR_RI /* check for recoverable interrupt */
+ beq 1f /* if not, we've got problems */
+#endif
+
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ RFI
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+/* check if the exception happened in a restartable section */
+1: lis r3,exc_exit_restart_end@ha
+ addi r3,r3,exc_exit_restart_end@l
+ cmplw r12,r3
+ bge 3f
+ lis r4,exc_exit_restart@ha
+ addi r4,r4,exc_exit_restart@l
+ cmplw r12,r4
+ blt 3f
+ lis r3,fee_restarts@ha
+ tophys(r3,r3)
+ lwz r5,fee_restarts@l(r3)
+ addi r5,r5,1
+ stw r5,fee_restarts@l(r3)
+ mr r12,r4 /* restart at exc_exit_restart */
+ b 2b
+
+ .comm fee_restarts,4
+
+/* aargh, a nonrecoverable interrupt, panic */
+/* aargh, we don't know which trap this is */
+/* but the 601 doesn't implement the RI bit, so assume it's OK */
+3:
+BEGIN_FTR_SECTION
+ b 2b
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ li r10,-1
+ stw r10,TRAP(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r10,MSR_KERNEL@h
+ ori r10,r10,MSR_KERNEL@l
+ bl transfer_to_handler_full
+ .long nonrecoverable_exception
+ .long ret_from_except
+#endif
+
.globl sigreturn_exit
sigreturn_exit:
subi r1,r3,STACK_FRAME_OVERHEAD
lwz r10,_XER(r1)
lwz r11,_CTR(r1)
- mtspr XER,r10
+ mtspr SPRN_XER,r10
mtctr r11
PPC405_ERR77(0,r1)
lwz r9,_MSR(r1)
lwz r12,_NIP(r1)
FIX_SRR1(r9,r10)
- mtspr SRR0,r12
- mtspr SRR1,r9
+ mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r9
REST_4GPRS(9, r1)
lwz r1,GPR1(r1)
.globl exc_exit_restart_end
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
exc_exit_start:
- mtspr SRR0,r11
- mtspr SRR1,r12
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
REST_2GPRS(11, r1)
lwz r1,GPR1(r1)
.globl exc_exit_restart_end
* We have to restore various SPRs that may have been in use at the
* time of the critical interrupt.
*
- * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and
- * thus not saved in the critical handler
*/
.globl ret_from_crit_exc
ret_from_crit_exc:
lwz r10,_XER(r1)
lwz r11,_CTR(r1)
- mtspr XER,r10
+ mtspr SPRN_XER,r10
mtctr r11
PPC405_ERR77(0,r1)
mtspr SPRN_ESR,r10
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
- mtspr CSRR0,r11
- mtspr CSRR1,r12
+ mtspr SPRN_CSRR0,r11
+ mtspr SPRN_CSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
- BOOKE_SAVE_COR
- BOOKE_LOAD_COR
- lwz r10,crit_sprg0@l(COR)
- mtspr SPRN_SPRG0,r10
- lwz r10,crit_sprg1@l(COR)
- mtspr SPRN_SPRG1,r10
- lwz r10,crit_sprg4@l(COR)
- mtspr SPRN_SPRG4,r10
- lwz r10,crit_sprg5@l(COR)
- mtspr SPRN_SPRG5,r10
-#ifdef CONFIG_40x
- lwz r10,crit_sprg6@l(COR)
- mtspr SPRN_SPRG6,r10
-#endif
- lwz r10,crit_sprg7@l(COR)
- mtspr SPRN_SPRG7,r10
- lwz r10,crit_srr0@l(COR)
- mtspr SRR0,r10
- lwz r10,crit_srr1@l(COR)
- mtspr SRR1,r10
- lwz r10,crit_pid@l(COR)
- mtspr SPRN_PID,r10
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
- BOOKE_REST_COR
PPC405_ERR77_SYNC
rfci
b . /* prevent prefetch past rfci */
lwz r10,_XER(r1)
lwz r11,_CTR(r1)
- mtspr XER,r10
+ mtspr SPRN_XER,r10
mtctr r11
stwcx. r0,0,r1 /* to clear the reservation */
mtspr SPRN_ESR,r10
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
- mtspr MCSRR0,r11
- mtspr MCSRR1,r12
+ mtspr SPRN_MCSRR0,r11
+ mtspr SPRN_MCSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
- mtspr SPRG6W,r8
- lis r8,mcheck_save@ha
- lwz r10,mcheck_sprg0@l(r8)
- mtspr SPRN_SPRG0,r10
- lwz r10,mcheck_sprg1@l(r8)
- mtspr SPRN_SPRG1,r10
- lwz r10,mcheck_sprg4@l(r8)
- mtspr SPRN_SPRG4,r10
- lwz r10,mcheck_sprg5@l(r8)
- mtspr SPRN_SPRG5,r10
- lwz r10,mcheck_sprg7@l(r8)
- mtspr SPRN_SPRG7,r10
- lwz r10,mcheck_srr0@l(r8)
- mtspr SRR0,r10
- lwz r10,mcheck_srr1@l(r8)
- mtspr SRR1,r10
- lwz r10,mcheck_csrr0@l(r8)
- mtspr CSRR0,r10
- lwz r10,mcheck_csrr1@l(r8)
- mtspr CSRR1,r10
- lwz r10,mcheck_pid@l(r8)
- mtspr SPRN_PID,r10
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
- mfspr r8,SPRG6R
RFMCI
#endif /* CONFIG_BOOKE */
li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
mtlr r6
CLR_TOP32(r7)
- mtspr SPRG2,r7
- mtspr SRR0,r8
- mtspr SRR1,r9
+ mtspr SPRN_SPRG2,r7
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
RFI
1: tophys(r9,r1)
lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
FIX_SRR1(r9,r0)
addi r1,r1,INT_FRAME_SIZE
li r0,0
- mtspr SPRG2,r0
- mtspr SRR0,r8
- mtspr SRR1,r9
+ mtspr SPRN_SPRG2,r0
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
RFI /* return to caller */
.globl machine_check_in_rtas