Commit 74fabcad authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc/8xx: don't use r12/SPRN_SPRG_SCRATCH2 in TLB Miss handlers

This patch reworks the TLB Miss handler in order to not use r12
register, hence avoiding having to save it into SPRN_SPRG_SCRATCH2.

In the DAR Fixup code we can now use SPRN_M_TW, freeing
SPRN_SPRG_SCRATCH2.

Then SPRN_SPRG_SCRATCH2 may be used for something else in the future.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 55c8fc3f
...@@ -302,90 +302,87 @@ SystemCall: ...@@ -302,90 +302,87 @@ SystemCall:
*/ */
#ifdef CONFIG_8xx_CPU15 #ifdef CONFIG_8xx_CPU15
#define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr) \ #define INVALIDATE_ADJACENT_PAGES_CPU15(addr) \
addi tmp, addr, PAGE_SIZE; \ addi addr, addr, PAGE_SIZE; \
tlbie tmp; \ tlbie addr; \
addi tmp, addr, -PAGE_SIZE; \ addi addr, addr, -(PAGE_SIZE << 1); \
tlbie tmp tlbie addr; \
addi addr, addr, PAGE_SIZE
#else #else
#define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr) #define INVALIDATE_ADJACENT_PAGES_CPU15(addr)
#endif #endif
InstructionTLBMiss: InstructionTLBMiss:
mtspr SPRN_SPRG_SCRATCH0, r10 mtspr SPRN_SPRG_SCRATCH0, r10
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
mtspr SPRN_SPRG_SCRATCH1, r11 mtspr SPRN_SPRG_SCRATCH1, r11
#ifdef ITLB_MISS_KERNEL
mtspr SPRN_SPRG_SCRATCH2, r12
#endif #endif
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
* kernel page tables. * kernel page tables.
*/ */
mfspr r10, SPRN_SRR0 /* Get effective address of fault */ mfspr r10, SPRN_SRR0 /* Get effective address of fault */
INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10) INVALIDATE_ADJACENT_PAGES_CPU15(r10)
mtspr SPRN_MD_EPN, r10 mtspr SPRN_MD_EPN, r10
/* Only modules will cause ITLB Misses as we always /* Only modules will cause ITLB Misses as we always
* pin the first 8MB of kernel memory */ * pin the first 8MB of kernel memory */
#ifdef ITLB_MISS_KERNEL #ifdef ITLB_MISS_KERNEL
mfcr r12 mfcr r11
#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) #if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ cmpi cr0, r10, 0 /* Address >= 0x80000000 */
#else #else
rlwinm r11, r10, 16, 0xfff8 rlwinm r10, r10, 16, 0xfff8
cmpli cr0, r11, PAGE_OFFSET@h cmpli cr0, r10, PAGE_OFFSET@h
#ifndef CONFIG_PIN_TLB_TEXT #ifndef CONFIG_PIN_TLB_TEXT
/* It is assumed that kernel code fits into the first 8M page */ /* It is assumed that kernel code fits into the first 8M page */
0: cmpli cr7, r11, (PAGE_OFFSET + 0x0800000)@h 0: cmpli cr7, r10, (PAGE_OFFSET + 0x0800000)@h
patch_site 0b, patch__itlbmiss_linmem_top patch_site 0b, patch__itlbmiss_linmem_top
#endif #endif
#endif #endif
#endif #endif
mfspr r11, SPRN_M_TWB /* Get level 1 table */ mfspr r10, SPRN_M_TWB /* Get level 1 table */
#ifdef ITLB_MISS_KERNEL #ifdef ITLB_MISS_KERNEL
#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) #if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
beq+ 3f bge+ 3f
#else #else
blt+ 3f blt+ 3f
#endif #endif
#ifndef CONFIG_PIN_TLB_TEXT #ifndef CONFIG_PIN_TLB_TEXT
blt cr7, ITLBMissLinear blt cr7, ITLBMissLinear
#endif #endif
rlwinm r11, r11, 0, 20, 31 rlwinm r10, r10, 0, 20, 31
oris r11, r11, (swapper_pg_dir - PAGE_OFFSET)@ha oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha
3: 3:
#endif #endif
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ lwz r10, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
mtspr SPRN_MI_TWC, r10 /* Set segment attributes */
mtspr SPRN_MD_TWC, r11 mtspr SPRN_MD_TWC, r10
mfspr r10, SPRN_MD_TWC mfspr r10, SPRN_MD_TWC
lwz r10, 0(r10) /* Get the pte */ lwz r10, 0(r10) /* Get the pte */
#ifdef ITLB_MISS_KERNEL #ifdef ITLB_MISS_KERNEL
mtcr r12 mtcr r11
#endif #endif
/* Load the MI_TWC with the attributes for this "segment." */
mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
#ifdef CONFIG_SWAP #ifdef CONFIG_SWAP
rlwinm r11, r10, 32-5, _PAGE_PRESENT rlwinm r11, r10, 32-5, _PAGE_PRESENT
and r11, r11, r10 and r11, r11, r10
rlwimi r10, r11, 0, _PAGE_PRESENT rlwimi r10, r11, 0, _PAGE_PRESENT
#endif #endif
li r11, RPN_PATTERN | 0x200
/* The Linux PTE won't go exactly into the MMU TLB. /* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 20 and 23 must be clear. * Software indicator bits 20 and 23 must be clear.
* Software indicator bits 22, 24, 25, 26, and 27 must be * Software indicator bits 22, 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior * set. All other Linux PTE bits control the behavior
* of the MMU. * of the MMU.
*/ */
rlwimi r11, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */ rlwimi r10, r10, 0, 0x0f00 /* Clear bits 20-23 */
rlwimi r10, r11, 0, 0x0ff0 /* Set 22, 24-27, clear 20,23 */ rlwimi r10, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */
ori r10, r10, RPN_PATTERN | 0x200 /* Set 22 and 24-27 */
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
/* Restore registers */ /* Restore registers */
0: mfspr r10, SPRN_SPRG_SCRATCH0 0: mfspr r10, SPRN_SPRG_SCRATCH0
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
#ifdef ITLB_MISS_KERNEL
mfspr r12, SPRN_SPRG_SCRATCH2
#endif #endif
rfi rfi
patch_site 0b, patch__itlbmiss_exit_1 patch_site 0b, patch__itlbmiss_exit_1
...@@ -396,9 +393,8 @@ InstructionTLBMiss: ...@@ -396,9 +393,8 @@ InstructionTLBMiss:
addi r10, r10, 1 addi r10, r10, 1
stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
mfspr r10, SPRN_SPRG_SCRATCH0 mfspr r10, SPRN_SPRG_SCRATCH0
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
#ifdef ITLB_MISS_KERNEL
mfspr r12, SPRN_SPRG_SCRATCH2
#endif #endif
rfi rfi
#endif #endif
...@@ -407,40 +403,37 @@ InstructionTLBMiss: ...@@ -407,40 +403,37 @@ InstructionTLBMiss:
DataStoreTLBMiss: DataStoreTLBMiss:
mtspr SPRN_SPRG_SCRATCH0, r10 mtspr SPRN_SPRG_SCRATCH0, r10
mtspr SPRN_SPRG_SCRATCH1, r11 mtspr SPRN_SPRG_SCRATCH1, r11
mtspr SPRN_SPRG_SCRATCH2, r12 mfcr r11
mfcr r12
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
* kernel page tables. * kernel page tables.
*/ */
mfspr r10, SPRN_MD_EPN mfspr r10, SPRN_MD_EPN
rlwinm r11, r10, 16, 0xfff8 rlwinm r10, r10, 16, 0xfff8
cmpli cr0, r11, PAGE_OFFSET@h cmpli cr0, r10, PAGE_OFFSET@h
mfspr r11, SPRN_M_TWB /* Get level 1 table */
blt+ 3f
rlwinm r11, r10, 16, 0xfff8
#ifndef CONFIG_PIN_TLB_IMMR #ifndef CONFIG_PIN_TLB_IMMR
cmpli cr0, r11, VIRT_IMMR_BASE@h cmpli cr6, r10, VIRT_IMMR_BASE@h
#endif #endif
0: cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h 0: cmpli cr7, r10, (PAGE_OFFSET + 0x1800000)@h
patch_site 0b, patch__dtlbmiss_linmem_top patch_site 0b, patch__dtlbmiss_linmem_top
mfspr r10, SPRN_M_TWB /* Get level 1 table */
blt+ 3f
#ifndef CONFIG_PIN_TLB_IMMR #ifndef CONFIG_PIN_TLB_IMMR
0: beq- DTLBMissIMMR 0: beq- cr6, DTLBMissIMMR
patch_site 0b, patch__dtlbmiss_immr_jmp patch_site 0b, patch__dtlbmiss_immr_jmp
#endif #endif
blt cr7, DTLBMissLinear blt cr7, DTLBMissLinear
mfspr r11, SPRN_M_TWB /* Get level 1 table */ rlwinm r10, r10, 0, 20, 31
rlwinm r11, r11, 0, 20, 31 oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha
oris r11, r11, (swapper_pg_dir - PAGE_OFFSET)@ha
3: 3:
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ mtcr r11
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
mtspr SPRN_MD_TWC, r11 mtspr SPRN_MD_TWC, r11
mfspr r10, SPRN_MD_TWC mfspr r10, SPRN_MD_TWC
lwz r10, 0(r10) /* Get the pte */ lwz r10, 0(r10) /* Get the pte */
mtcr r12
/* Insert the Guarded flag into the TWC from the Linux PTE. /* Insert the Guarded flag into the TWC from the Linux PTE.
* It is bit 27 of both the Linux PTE and the TWC (at least * It is bit 27 of both the Linux PTE and the TWC (at least
* I got that right :-). It will be better when we can put * I got that right :-). It will be better when we can put
...@@ -478,7 +471,6 @@ DataStoreTLBMiss: ...@@ -478,7 +471,6 @@ DataStoreTLBMiss:
0: mfspr r10, SPRN_SPRG_SCRATCH0 0: mfspr r10, SPRN_SPRG_SCRATCH0
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r12, SPRN_SPRG_SCRATCH2
rfi rfi
patch_site 0b, patch__dtlbmiss_exit_1 patch_site 0b, patch__dtlbmiss_exit_1
...@@ -489,7 +481,6 @@ DataStoreTLBMiss: ...@@ -489,7 +481,6 @@ DataStoreTLBMiss:
stw r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0) stw r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
mfspr r10, SPRN_SPRG_SCRATCH0 mfspr r10, SPRN_SPRG_SCRATCH0
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r12, SPRN_SPRG_SCRATCH2
rfi rfi
#endif #endif
...@@ -597,7 +588,7 @@ InstructionBreakpoint: ...@@ -597,7 +588,7 @@ InstructionBreakpoint:
* not enough space in the DataStoreTLBMiss area. * not enough space in the DataStoreTLBMiss area.
*/ */
DTLBMissIMMR: DTLBMissIMMR:
mtcr r12 mtcr r11
/* Set 512k byte guarded page and mark it valid */ /* Set 512k byte guarded page and mark it valid */
li r10, MD_PS512K | MD_GUARDED | MD_SVALID li r10, MD_PS512K | MD_GUARDED | MD_SVALID
mtspr SPRN_MD_TWC, r10 mtspr SPRN_MD_TWC, r10
...@@ -612,16 +603,15 @@ DTLBMissIMMR: ...@@ -612,16 +603,15 @@ DTLBMissIMMR:
0: mfspr r10, SPRN_SPRG_SCRATCH0 0: mfspr r10, SPRN_SPRG_SCRATCH0
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r12, SPRN_SPRG_SCRATCH2
rfi rfi
patch_site 0b, patch__dtlbmiss_exit_2 patch_site 0b, patch__dtlbmiss_exit_2
DTLBMissLinear: DTLBMissLinear:
mtcr r12 mtcr r11
/* Set 8M byte page and mark it valid */ /* Set 8M byte page and mark it valid */
li r11, MD_PS8MEG | MD_SVALID li r11, MD_PS8MEG | MD_SVALID
mtspr SPRN_MD_TWC, r11 mtspr SPRN_MD_TWC, r11
rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ rlwinm r10, r10, 20, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
_PAGE_PRESENT _PAGE_PRESENT
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
...@@ -631,24 +621,22 @@ DTLBMissLinear: ...@@ -631,24 +621,22 @@ DTLBMissLinear:
0: mfspr r10, SPRN_SPRG_SCRATCH0 0: mfspr r10, SPRN_SPRG_SCRATCH0
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r12, SPRN_SPRG_SCRATCH2
rfi rfi
patch_site 0b, patch__dtlbmiss_exit_3 patch_site 0b, patch__dtlbmiss_exit_3
#ifndef CONFIG_PIN_TLB_TEXT #ifndef CONFIG_PIN_TLB_TEXT
ITLBMissLinear: ITLBMissLinear:
mtcr r12 mtcr r11
/* Set 8M byte page and mark it valid */ /* Set 8M byte page and mark it valid */
li r11, MI_PS8MEG | MI_SVALID li r11, MI_PS8MEG | MI_SVALID
mtspr SPRN_MI_TWC, r11 mtspr SPRN_MI_TWC, r11
rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ rlwinm r10, r10, 20, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \ ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
_PAGE_PRESENT _PAGE_PRESENT
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
0: mfspr r10, SPRN_SPRG_SCRATCH0 0: mfspr r10, SPRN_SPRG_SCRATCH0
mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r12, SPRN_SPRG_SCRATCH2
rfi rfi
patch_site 0b, patch__itlbmiss_exit_2 patch_site 0b, patch__itlbmiss_exit_2
#endif #endif
...@@ -660,7 +648,7 @@ ITLBMissLinear: ...@@ -660,7 +648,7 @@ ITLBMissLinear:
/* define if you don't want to use self modifying code */ /* define if you don't want to use self modifying code */
#define NO_SELF_MODIFYING_CODE #define NO_SELF_MODIFYING_CODE
FixupDAR:/* Entry point for dcbx workaround. */ FixupDAR:/* Entry point for dcbx workaround. */
mtspr SPRN_SPRG_SCRATCH2, r10 mtspr SPRN_M_TW, r10
/* fetch instruction from memory. */ /* fetch instruction from memory. */
mfspr r10, SPRN_SRR0 mfspr r10, SPRN_SRR0
mtspr SPRN_MD_EPN, r10 mtspr SPRN_MD_EPN, r10
...@@ -705,7 +693,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ ...@@ -705,7 +693,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
beq+ 142f beq+ 142f
cmpwi cr0, r10, 1964 /* Is icbi? */ cmpwi cr0, r10, 1964 /* Is icbi? */
beq+ 142f beq+ 142f
141: mfspr r10,SPRN_SPRG_SCRATCH2 141: mfspr r10,SPRN_M_TW
b DARFixed /* Nope, go back to normal TLB processing */ b DARFixed /* Nope, go back to normal TLB processing */
200: 200:
...@@ -740,7 +728,7 @@ modified_instr: ...@@ -740,7 +728,7 @@ modified_instr:
bne+ 143f bne+ 143f
subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */ subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */
143: mtdar r10 /* store faulting EA in DAR */ 143: mtdar r10 /* store faulting EA in DAR */
mfspr r10,SPRN_SPRG_SCRATCH2 mfspr r10,SPRN_M_TW
b DARFixed /* Go back to normal TLB handling */ b DARFixed /* Go back to normal TLB handling */
#else #else
mfctr r10 mfctr r10
...@@ -794,7 +782,7 @@ modified_instr: ...@@ -794,7 +782,7 @@ modified_instr:
mfdar r11 mfdar r11
mtctr r11 /* restore ctr reg from DAR */ mtctr r11 /* restore ctr reg from DAR */
mtdar r10 /* save fault EA to DAR */ mtdar r10 /* save fault EA to DAR */
mfspr r10,SPRN_SPRG_SCRATCH2 mfspr r10,SPRN_M_TW
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment