summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm/tlb_nohash_low.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash_low.S')
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S78
1 files changed, 70 insertions, 8 deletions
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 626ad08..71b67ee 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -247,6 +247,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
* to have the larger code path before the _SECTION_ELSE
*/
+.macro tlb_lock
+.endm
+
+.macro tlb_unlock
+.endm
+
/*
* Flush MMU TLB on the local processor
*/
@@ -313,6 +319,44 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
1: wrtee r10
blr
#elif defined(CONFIG_PPC_BOOK3E)
+
+#ifdef CONFIG_FSL_ERRATUM_A_004801
+.macro tlb_lock
+ ld r7,PACA_TLB_PER_CORE_PTR(r13)
+ mtocrf 0x01,r7
+ addi r8,r7,PACA_TLB_LOCK-1 /* -1 to compensate for low bit set */
+ bf 31,1f /* no lock if TLB_PER_CORE_HAS_LOCK clear */
+2: lbarx r9,0,r8
+ cmpdi r9,0
+ bne 3f
+ li r9,1
+ stbcx. r9,0,r8
+ bne 2b
+ .subsection 1
+3: lbz r9,0(r8)
+ cmpdi r9,0
+ bne 3b
+ b 2b
+ .previous
+1:
+.endm
+
+.macro tlb_unlock
+ mtocrf 0x01,r7
+ bf 31,1f /* no lock if TLB_PER_CORE_HAS_LOCK clear */
+ li r9,0
+ isync
+ stb r9,0(r8)
+1:
+.endm
+#else
+.macro tlb_lock
+.endm
+
+.macro tlb_unlock
+.endm
+#endif
+
/*
* New Book3E (>= 2.06) implementation
*
@@ -322,10 +366,12 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
_GLOBAL(_tlbil_pid)
slwi r4,r3,MAS6_SPID_SHIFT
mfmsr r10
- wrteei 0
+ fsl_erratum_a006198_wrteei0 r0 r7
+ tlb_lock
mtspr SPRN_MAS6,r4
PPC_TLBILX_PID(0,R0)
- wrtee r10
+ tlb_unlock
+ fsl_erratum_a006198_mtmsr r10 r0 r7
msync
isync
blr
@@ -334,23 +380,31 @@ _GLOBAL(_tlbil_pid_noind)
slwi r4,r3,MAS6_SPID_SHIFT
mfmsr r10
ori r4,r4,MAS6_SIND
- wrteei 0
+ fsl_erratum_a006198_wrteei0 r0 r7
+ tlb_lock
mtspr SPRN_MAS6,r4
PPC_TLBILX_PID(0,R0)
- wrtee r10
+ tlb_unlock
+ fsl_erratum_a006198_mtmsr r10 r0 r7
msync
isync
blr
_GLOBAL(_tlbil_all)
+ mfmsr r10
+ fsl_erratum_a006198_wrteei0 r0 r7
+ tlb_lock
PPC_TLBILX_ALL(0,R0)
msync
isync
+ tlb_unlock
+ fsl_erratum_a006198_mtmsr r10 r0 r7
blr
_GLOBAL(_tlbil_va)
mfmsr r10
- wrteei 0
+ fsl_erratum_a006198_wrteei0 r0 r7
+ tlb_lock
cmpwi cr0,r6,0
slwi r4,r4,MAS6_SPID_SHIFT
rlwimi r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
@@ -360,12 +414,13 @@ _GLOBAL(_tlbil_va)
PPC_TLBILX_VA(0,R3)
msync
isync
- wrtee r10
+ tlb_unlock
+ fsl_erratum_a006198_mtmsr r10 r0 r7
blr
_GLOBAL(_tlbivax_bcast)
mfmsr r10
- wrteei 0
+ fsl_erratum_a006198_wrteei0 r0 r7
cmpwi cr0,r6,0
slwi r4,r4,MAS6_SPID_SHIFT
rlwimi r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
@@ -376,7 +431,7 @@ _GLOBAL(_tlbivax_bcast)
eieio
tlbsync
sync
- wrtee r10
+ fsl_erratum_a006198_mtmsr r10 r0 r7
blr
_GLOBAL(set_context)
@@ -402,6 +457,10 @@ _GLOBAL(set_context)
* Load TLBCAM[index] entry in to the L2 CAM MMU
*/
_GLOBAL(loadcam_entry)
+ mfmsr r10
+ fsl_erratum_a006198_wrteei0 r0 r7
+ tlb_lock
+
LOAD_REG_ADDR(r4, TLBCAM)
mulli r5,r3,TLBCAM_SIZE
add r3,r5,r4
@@ -420,5 +479,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
isync
tlbwe
isync
+
+ tlb_unlock
+ fsl_erratum_a006198_mtmsr r10 r0 r7
blr
#endif