提交 92625d49 编写于 作者: L LEROY Christophe 提交者: Scott Wood

powerpc/8xx: Use SCRATCH0 and SCRATCH1 also for TLB handlers

SCRATCH0 and SCRATCH1 are only used in Exceptions prologs where no other
exception can happen. There is therefore no need to preserve them accross
TLB handlers, we can use them there as in other exceptions. One of the
advantages is that they do not suffer CPU6 errata unlike M_TW register.
Signed-off-by: NChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: NScott Wood <scottwood@freescale.com>
上级 ae466bde
...@@ -104,12 +104,15 @@ turn_on_mmu: ...@@ -104,12 +104,15 @@ turn_on_mmu:
* task's thread_struct. * task's thread_struct.
*/ */
#define EXCEPTION_PROLOG \ #define EXCEPTION_PROLOG \
mtspr SPRN_SPRG_SCRATCH0,r10; \ EXCEPTION_PROLOG_0; \
mtspr SPRN_SPRG_SCRATCH1,r11; \
mfcr r10; \
EXCEPTION_PROLOG_1; \ EXCEPTION_PROLOG_1; \
EXCEPTION_PROLOG_2 EXCEPTION_PROLOG_2
#define EXCEPTION_PROLOG_0 \
mtspr SPRN_SPRG_SCRATCH0,r10; \
mtspr SPRN_SPRG_SCRATCH1,r11; \
mfcr r10
#define EXCEPTION_PROLOG_1 \ #define EXCEPTION_PROLOG_1 \
mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
andi. r11,r11,MSR_PR; \ andi. r11,r11,MSR_PR; \
...@@ -144,6 +147,14 @@ turn_on_mmu: ...@@ -144,6 +147,14 @@ turn_on_mmu:
SAVE_4GPRS(3, r11); \ SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11) SAVE_2GPRS(7, r11)
/*
* Exception exit code.
*/
#define EXCEPTION_EPILOG_0 \
mtcr r10; \
mfspr r10,SPRN_SPRG_SCRATCH0; \
mfspr r11,SPRN_SPRG_SCRATCH1
/* /*
* Note: code which follows this uses cr0.eq (set if from kernel), * Note: code which follows this uses cr0.eq (set if from kernel),
* r11, r12 (SRR0), and r9 (SRR1). * r11, r12 (SRR0), and r9 (SRR1).
...@@ -293,16 +304,8 @@ InstructionTLBMiss: ...@@ -293,16 +304,8 @@ InstructionTLBMiss:
#ifdef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0) stw r3, 8(r0)
#endif #endif
DO_8xx_CPU6(0x3f80, r3) EXCEPTION_PROLOG_0
mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mtspr SPRN_SPRG_SCRATCH2, r10
mfcr r10
#ifdef CONFIG_8xx_CPU6
stw r10, 0(r0)
stw r11, 4(r0)
#else
mtspr SPRN_DAR, r10
mtspr SPRN_SPRG_SCRATCH2, r11
#endif
mfspr r10, SPRN_SRR0 /* Get effective address of fault */ mfspr r10, SPRN_SRR0 /* Get effective address of fault */
#ifdef CONFIG_8xx_CPU15 #ifdef CONFIG_8xx_CPU15
addi r11, r10, 0x1000 addi r11, r10, 0x1000
...@@ -359,18 +362,11 @@ InstructionTLBMiss: ...@@ -359,18 +362,11 @@ InstructionTLBMiss:
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
/* Restore registers */ /* Restore registers */
#ifndef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
mfspr r10, SPRN_DAR
mtcr r10
mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r11, SPRN_SPRG_SCRATCH2
#else
lwz r11, 0(r0)
mtcr r11
lwz r11, 4(r0)
lwz r3, 8(r0) lwz r3, 8(r0)
#endif #endif
mfspr r10, SPRN_M_TW mfspr r10, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
rfi rfi
2: 2:
mfspr r11, SPRN_SRR1 mfspr r11, SPRN_SRR1
...@@ -381,19 +377,11 @@ InstructionTLBMiss: ...@@ -381,19 +377,11 @@ InstructionTLBMiss:
mtspr SPRN_SRR1, r11 mtspr SPRN_SRR1, r11
/* Restore registers */ /* Restore registers */
#ifndef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
mfspr r10, SPRN_DAR
mtcr r10
li r11, 0x00f0
mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r11, SPRN_SPRG_SCRATCH2
#else
lwz r11, 0(r0)
mtcr r11
lwz r11, 4(r0)
lwz r3, 8(r0) lwz r3, 8(r0)
#endif #endif
mfspr r10, SPRN_M_TW mfspr r10, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
b InstructionAccess b InstructionAccess
. = 0x1200 . = 0x1200
...@@ -401,16 +389,8 @@ DataStoreTLBMiss: ...@@ -401,16 +389,8 @@ DataStoreTLBMiss:
#ifdef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0) stw r3, 8(r0)
#endif #endif
DO_8xx_CPU6(0x3f80, r3) EXCEPTION_PROLOG_0
mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mtspr SPRN_SPRG_SCRATCH2, r10
mfcr r10
#ifdef CONFIG_8xx_CPU6
stw r10, 0(r0)
stw r11, 4(r0)
#else
mtspr SPRN_DAR, r10
mtspr SPRN_SPRG_SCRATCH2, r11
#endif
mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
...@@ -483,19 +463,12 @@ DataStoreTLBMiss: ...@@ -483,19 +463,12 @@ DataStoreTLBMiss:
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
/* Restore registers */ /* Restore registers */
#ifndef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
mfspr r10, SPRN_DAR
mtcr r10
mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r11, SPRN_SPRG_SCRATCH2
#else
mtspr SPRN_DAR, r11 /* Tag DAR */
lwz r11, 0(r0)
mtcr r11
lwz r11, 4(r0)
lwz r3, 8(r0) lwz r3, 8(r0)
#endif #endif
mfspr r10, SPRN_M_TW mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r10, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
rfi rfi
/* This is an instruction TLB error on the MPC8xx. This could be due /* This is an instruction TLB error on the MPC8xx. This could be due
...@@ -519,23 +492,18 @@ DataTLBError: ...@@ -519,23 +492,18 @@ DataTLBError:
#ifdef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0) stw r3, 8(r0)
#endif #endif
DO_8xx_CPU6(0x3f80, r3) EXCEPTION_PROLOG_0
mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mtspr SPRN_SPRG_SCRATCH2, r10
mfcr r10
stw r10, 0(r0)
stw r11, 4(r0)
mfspr r10, SPRN_DAR mfspr r10, SPRN_DAR
cmpwi cr0, r10, 0x00f0 cmpwi cr0, r10, 0x00f0
beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
mfspr r10, SPRN_M_TW /* Restore registers */
lwz r11, 0(r0)
mtcr r11
lwz r11, 4(r0)
#ifdef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0) lwz r3, 8(r0)
#endif #endif
mfspr r10,SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
b DataAccess b DataAccess
EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
...@@ -619,8 +587,8 @@ FixupDAR:/* Entry point for dcbx workaround. */ ...@@ -619,8 +587,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
stw r11,0(r10) /* store add/and instruction */ stw r11,0(r10) /* store add/and instruction */
dcbf 0,r10 /* flush new instr. to memory. */ dcbf 0,r10 /* flush new instr. to memory. */
icbi 0,r10 /* invalidate instr. cache line */ icbi 0,r10 /* invalidate instr. cache line */
lwz r11, 4(r0) /* restore r11 from memory */ mfspr r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
mfspr r10, SPRN_M_TW /* restore r10 from M_TW */ mfspr r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
isync /* Wait until new instr is loaded from memory */ isync /* Wait until new instr is loaded from memory */
modified_instr: modified_instr:
.space 4 /* this is where the add instr. is stored */ .space 4 /* this is where the add instr. is stored */
...@@ -683,9 +651,9 @@ modified_instr: ...@@ -683,9 +651,9 @@ modified_instr:
b DARFixed /* Go back to normal TLB handling */ b DARFixed /* Go back to normal TLB handling */
/* special handling for r10,r11 since these are modified already */ /* special handling for r10,r11 since these are modified already */
153: lwz r11, 4(r0) /* load r11 from memory */ 153: mfspr r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
b 155f b 155f
154: mfspr r11, SPRN_M_TW /* load r10 from M_TW */ 154: mfspr r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
155: add r10, r10, r11 /* add it */ 155: add r10, r10, r11 /* add it */
mfctr r11 /* restore r11 */ mfctr r11 /* restore r11 */
b 151b b 151b
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册