diff options
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash_low.S')
-rw-r--r-- | arch/powerpc/mm/tlb_nohash_low.S | 78 |
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 |