/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * This file contains low-level functions for performing various * types of TLB invalidations on various processors with no hash * table. * * This file implements the following functions for all no-hash * processors. Some aren't implemented for some variants. Some * are inline in tlbflush.h * * - tlbil_va * - tlbil_pid * - tlbil_all * - tlbivax_bcast * * Code mostly moved over from misc_32.S * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Partially rewritten by Cort Dougan (cort@cs.nmt.edu) * Paul Mackerras, Kumar Gala and Benjamin Herrenschmidt.
*/
/* * Nothing to do for 8xx, everything is inline
*/
#elif defined(CONFIG_44x) /* Includes 47x */
/* * 440 implementation uses tlbsx/we for tlbil_va and a full sweep * of the TLB for everything else.
*/
_GLOBAL(__tlbil_va)
mfspr r5,SPRN_MMUCR
mfmsr r10
/* * We write 16 bits of STID since 47x supports that much, we * will never be passed out of bounds values on 440 (hopefully)
*/
rlwimi r5,r4,0,16,31
/* We have to run the search with interrupts disabled, otherwise * an interrupt which causes a TLB miss can clobber the MMUCR * between the mtspr and the tlbsx. * * Critical and Machine Check interrupts take care of saving * and restoring MMUCR, so only normal interrupts have to be * taken care of.
*/
wrteei 0
mtspr SPRN_MMUCR,r5
tlbsx. r6,0,r3
bne 10f
sync
#ifndef CONFIG_PPC_47x /* On 440 There are only 64 TLB entries, so r3 < 64, which means bit * 22, is clear. Since 22 is the V bit in the TLB_PAGEID, loading this * value will invalidate the TLB entry.
*/
tlbwe r6,r6,PPC44x_TLB_PAGEID
#else
oris r7,r6,0x8000 /* specify way explicitly */
clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */
ori r4,r4,PPC47x_TLBE_SIZE
tlbwe r4,r7,0 /* write it */
#endif /* !CONFIG_PPC_47x */
isync
10: wrtee r10
blr
_GLOBAL(_tlbil_all)
_GLOBAL(_tlbil_pid)
#ifndef CONFIG_PPC_47x
li r3,0
sync
/* Load high watermark */
lis r4,tlb_44x_hwater@ha
lwz r5,tlb_44x_hwater@l(r4)
1: tlbwe r3,r3,PPC44x_TLB_PAGEID
addi r3,r3,1
cmpw 0,r3,r5
ble 1b
isync
blr
#else /* 476 variant. There's not simple way to do this, hopefully we'll * try to limit the amount of such full invalidates
*/
mfmsr r11 /* Interrupts off */
wrteei 0
li r3,-1 /* Current set */
lis r10,tlb_47x_boltmap@h
ori r10,r10,tlb_47x_boltmap@l
lis r7,0x8000 /* Specify way explicitly */
b 9f /* For each set */
1: li r9,4 /* Number of ways */
li r4,0 /* Current way */
li r6,0 /* Default entry value 0 */
andi. r0,r8,1 /* Check if way 0 is bolted */
mtctr r9 /* Load way counter */
bne- 3f /* Bolted, skip loading it */
2: /* For each way */
or r5,r3,r4 /* Make way|index for tlbre */
rlwimi r5,r5,16,8,15 /* Copy index into position */
tlbre r6,r5,0 /* Read entry */
3: addis r4,r4,0x2000 /* Next way */
andi. r0,r6,PPC47x_TLB0_VALID /* Valid entry ? */
beq 4f /* Nope, skip it */
rlwimi r7,r5,0,1,2 /* Insert way number */
rlwinm r6,r6,0,21,19 /* Clear V */
tlbwe r6,r7,0 /* Write it */
4: bdnz 2b /* Loop for each way */
srwi r8,r8,1 /* Next boltmap bit */
9: cmpwi cr1,r3,255 /* Last set done ? */
addi r3,r3,1 /* Next set */
beq cr1,1f /* End of loop */
andi. r0,r3,0x1f /* Need to load a new boltmap word ? */
bne 1b /* No, loop */
lwz r8,0(r10) /* Load boltmap entry */
addi r10,r10,4 /* Next word */
b 1b /* Then loop */
1: isync /* Sync shadows */
wrtee r11
blr
#endif /* !CONFIG_PPC_47x */
#ifdef CONFIG_PPC_47x
/* * _tlbivax_bcast is only on 47x. We don't bother doing a runtime * check though, it will blow up soon enough if we mistakenly try * to use it on a 440.
*/
_GLOBAL(_tlbivax_bcast)
mfspr r5,SPRN_MMUCR
mfmsr r10
rlwimi r5,r4,0,16,31
wrteei 0
mtspr SPRN_MMUCR,r5
isync
PPC_TLBIVAX(0, R3)
isync
mbar
tlbsync
BEGIN_FTR_SECTION
b 1f
END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
sync
wrtee r10
blr /* * DD2 HW could hang if in instruction fetch happens before msync completes. * Touch enough instruction cache lines to ensure cache hits
*/
1: mflr r9
bcl 20,31,$+4
2: mflr r6
li r7,32
PPC_ICBT(0,R6,R7) /* touch next cache line */
add r6,r6,r7
PPC_ICBT(0,R6,R7) /* touch next cache line */
add r6,r6,r7
PPC_ICBT(0,R6,R7) /* touch next cache line */
sync
nop
nop
nop
nop
nop
nop
nop
nop
mtlr r9
wrtee r10
blr
#endif /* CONFIG_PPC_47x */
#elif defined(CONFIG_PPC_85xx) /* * FSL BookE implementations. * * Since feature sections are using _SECTION_ELSE we need * to have the larger code path before the _SECTION_ELSE
*/
/* * Flush MMU TLB on the local processor
*/
_GLOBAL(_tlbil_all)
BEGIN_MMU_FTR_SECTION
li r3,(MMUCSR0_TLBFI)@l
mtspr SPRN_MMUCSR0, r3
1:
mfspr r3,SPRN_MMUCSR0
andi. r3,r3,MMUCSR0_TLBFI@l
bne 1b
MMU_FTR_SECTION_ELSE
PPC_TLBILX_ALL(0,R0)
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
msync
isync
blr
/* * Flush MMU TLB for a particular address, but only on the local processor * (no broadcast)
*/
_GLOBAL(__tlbil_va)
mfmsr r10
wrteei 0
slwi r4,r4,16
ori r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l
mtspr SPRN_MAS6,r4 /* assume AS=0 for now */
BEGIN_MMU_FTR_SECTION
tlbsx 0,r3
mfspr r4,SPRN_MAS1 /* check valid */
andis. r3,r4,MAS1_VALID@h
beq 1f
rlwinm r4,r4,0,1,31
mtspr SPRN_MAS1,r4
tlbwe
MMU_FTR_SECTION_ELSE
PPC_TLBILX_VA(0,R3)
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
msync
isync
1: wrtee r10
blr
#elif defined(CONFIG_PPC_BOOK3E_64) /* * New Book3E (>= 2.06) implementation * * Note: We may be able to get away without the interrupt masking stuff * if we save/restore MAS6 on exceptions that might modify it
*/
_GLOBAL(_tlbil_pid)
slwi r4,r3,MAS6_SPID_SHIFT
mfmsr r10
wrteei 0
mtspr SPRN_MAS6,r4
PPC_TLBILX_PID(0,R0)
wrtee r10
msync
isync
blr
/* * Load multiple TLB entries at once, using an alternate-space * trampoline so that we don't have to care about whether the same * TLB entry maps us before and after. * * r3 = first entry to write * r4 = number of entries to write * r5 = temporary tlb entry (0 means no switch to AS1)
*/
_GLOBAL(loadcam_multi)
mflr r8 /* Don't switch to AS=1 if already there */
mfmsr r11
andi. r11,r11,MSR_IS
bne 10f
mr. r12, r5
beq 10f
/* * Set up temporary TLB entry that is the same as what we're * running from, but in AS=1.
*/
bcl 20,31,$+4
1: mflr r6
tlbsx 0,r8
mfspr r6,SPRN_MAS1
ori r6,r6,MAS1_TS
mtspr SPRN_MAS1,r6
mfspr r6,SPRN_MAS0
rlwimi r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
mr r7,r5
mtspr SPRN_MAS0,r6
isync
tlbwe
isync
/* Switch to AS=1 */
mfmsr r6
ori r6,r6,MSR_IS|MSR_DS
mtmsr r6
isync
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.