xref: /openbmc/linux/arch/powerpc/mm/nohash/tlb_low.S (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
227e23b5fSChristophe Leroy/*
327e23b5fSChristophe Leroy * This file contains low-level functions for performing various
427e23b5fSChristophe Leroy * types of TLB invalidations on various processors with no hash
527e23b5fSChristophe Leroy * table.
627e23b5fSChristophe Leroy *
727e23b5fSChristophe Leroy * This file implements the following functions for all no-hash
827e23b5fSChristophe Leroy * processors. Some aren't implemented for some variants. Some
927e23b5fSChristophe Leroy * are inline in tlbflush.h
1027e23b5fSChristophe Leroy *
1127e23b5fSChristophe Leroy *	- tlbil_va
1227e23b5fSChristophe Leroy *	- tlbil_pid
1327e23b5fSChristophe Leroy *	- tlbil_all
1427e23b5fSChristophe Leroy *	- tlbivax_bcast
1527e23b5fSChristophe Leroy *
1627e23b5fSChristophe Leroy * Code mostly moved over from misc_32.S
1727e23b5fSChristophe Leroy *
1827e23b5fSChristophe Leroy *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
1927e23b5fSChristophe Leroy *
2027e23b5fSChristophe Leroy * Partially rewritten by Cort Dougan (cort@cs.nmt.edu)
2127e23b5fSChristophe Leroy * Paul Mackerras, Kumar Gala and Benjamin Herrenschmidt.
2227e23b5fSChristophe Leroy */
2327e23b5fSChristophe Leroy
2427e23b5fSChristophe Leroy#include <asm/reg.h>
2527e23b5fSChristophe Leroy#include <asm/page.h>
2627e23b5fSChristophe Leroy#include <asm/cputable.h>
2727e23b5fSChristophe Leroy#include <asm/mmu.h>
2827e23b5fSChristophe Leroy#include <asm/ppc_asm.h>
2927e23b5fSChristophe Leroy#include <asm/asm-offsets.h>
3027e23b5fSChristophe Leroy#include <asm/processor.h>
3127e23b5fSChristophe Leroy#include <asm/bug.h>
3227e23b5fSChristophe Leroy#include <asm/asm-compat.h>
3327e23b5fSChristophe Leroy#include <asm/feature-fixups.h>
3427e23b5fSChristophe Leroy
3527e23b5fSChristophe Leroy#if defined(CONFIG_40x)
3627e23b5fSChristophe Leroy
3727e23b5fSChristophe Leroy/*
3827e23b5fSChristophe Leroy * 40x implementation needs only tlbil_va
3927e23b5fSChristophe Leroy */
4027e23b5fSChristophe Leroy_GLOBAL(__tlbil_va)
4127e23b5fSChristophe Leroy	/* We run the search with interrupts disabled because we have to change
4227e23b5fSChristophe Leroy	 * the PID and I don't want to preempt when that happens.
4327e23b5fSChristophe Leroy	 */
4427e23b5fSChristophe Leroy	mfmsr	r5
4527e23b5fSChristophe Leroy	mfspr	r6,SPRN_PID
4627e23b5fSChristophe Leroy	wrteei	0
4727e23b5fSChristophe Leroy	mtspr	SPRN_PID,r4
4827e23b5fSChristophe Leroy	tlbsx.	r3, 0, r3
4927e23b5fSChristophe Leroy	mtspr	SPRN_PID,r6
5027e23b5fSChristophe Leroy	wrtee	r5
5127e23b5fSChristophe Leroy	bne	1f
5227e23b5fSChristophe Leroy	sync
5327e23b5fSChristophe Leroy	/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is
5427e23b5fSChristophe Leroy	 * clear. Since 25 is the V bit in the TLB_TAG, loading this value
5527e23b5fSChristophe Leroy	 * will invalidate the TLB entry. */
5627e23b5fSChristophe Leroy	tlbwe	r3, r3, TLB_TAG
5727e23b5fSChristophe Leroy	isync
5827e23b5fSChristophe Leroy1:	blr
5927e23b5fSChristophe Leroy
6027e23b5fSChristophe Leroy#elif defined(CONFIG_PPC_8xx)
6127e23b5fSChristophe Leroy
6227e23b5fSChristophe Leroy/*
6327e23b5fSChristophe Leroy * Nothing to do for 8xx, everything is inline
6427e23b5fSChristophe Leroy */
6527e23b5fSChristophe Leroy
6627e23b5fSChristophe Leroy#elif defined(CONFIG_44x) /* Includes 47x */
6727e23b5fSChristophe Leroy
6827e23b5fSChristophe Leroy/*
6927e23b5fSChristophe Leroy * 440 implementation uses tlbsx/we for tlbil_va and a full sweep
7027e23b5fSChristophe Leroy * of the TLB for everything else.
7127e23b5fSChristophe Leroy */
7227e23b5fSChristophe Leroy_GLOBAL(__tlbil_va)
7327e23b5fSChristophe Leroy	mfspr	r5,SPRN_MMUCR
7427e23b5fSChristophe Leroy	mfmsr   r10
7527e23b5fSChristophe Leroy
7627e23b5fSChristophe Leroy	/*
7727e23b5fSChristophe Leroy	 * We write 16 bits of STID since 47x supports that much, we
7827e23b5fSChristophe Leroy	 * will never be passed out of bounds values on 440 (hopefully)
7927e23b5fSChristophe Leroy	 */
8027e23b5fSChristophe Leroy	rlwimi  r5,r4,0,16,31
8127e23b5fSChristophe Leroy
8227e23b5fSChristophe Leroy	/* We have to run the search with interrupts disabled, otherwise
8327e23b5fSChristophe Leroy	 * an interrupt which causes a TLB miss can clobber the MMUCR
8427e23b5fSChristophe Leroy	 * between the mtspr and the tlbsx.
8527e23b5fSChristophe Leroy	 *
8627e23b5fSChristophe Leroy	 * Critical and Machine Check interrupts take care of saving
8727e23b5fSChristophe Leroy	 * and restoring MMUCR, so only normal interrupts have to be
8827e23b5fSChristophe Leroy	 * taken care of.
8927e23b5fSChristophe Leroy	 */
9027e23b5fSChristophe Leroy	wrteei	0
9127e23b5fSChristophe Leroy	mtspr	SPRN_MMUCR,r5
9227e23b5fSChristophe Leroy	tlbsx.	r6,0,r3
9327e23b5fSChristophe Leroy	bne	10f
9427e23b5fSChristophe Leroy	sync
951f69aa0bSChristophe Leroy#ifndef CONFIG_PPC_47x
9627e23b5fSChristophe Leroy	/* On 440 There are only 64 TLB entries, so r3 < 64, which means bit
9727e23b5fSChristophe Leroy	 * 22, is clear.  Since 22 is the V bit in the TLB_PAGEID, loading this
9827e23b5fSChristophe Leroy	 * value will invalidate the TLB entry.
9927e23b5fSChristophe Leroy	 */
10027e23b5fSChristophe Leroy	tlbwe	r6,r6,PPC44x_TLB_PAGEID
1011f69aa0bSChristophe Leroy#else
10227e23b5fSChristophe Leroy	oris	r7,r6,0x8000	/* specify way explicitly */
10327e23b5fSChristophe Leroy	clrrwi	r4,r3,12	/* get an EPN for the hashing with V = 0 */
10427e23b5fSChristophe Leroy	ori	r4,r4,PPC47x_TLBE_SIZE
10527e23b5fSChristophe Leroy	tlbwe   r4,r7,0		/* write it */
10627e23b5fSChristophe Leroy#endif /* !CONFIG_PPC_47x */
1071f69aa0bSChristophe Leroy	isync
1081f69aa0bSChristophe Leroy10:	wrtee	r10
1091f69aa0bSChristophe Leroy	blr
11027e23b5fSChristophe Leroy
11127e23b5fSChristophe Leroy_GLOBAL(_tlbil_all)
11227e23b5fSChristophe Leroy_GLOBAL(_tlbil_pid)
1131f69aa0bSChristophe Leroy#ifndef CONFIG_PPC_47x
11427e23b5fSChristophe Leroy	li	r3,0
11527e23b5fSChristophe Leroy	sync
11627e23b5fSChristophe Leroy
11727e23b5fSChristophe Leroy	/* Load high watermark */
11827e23b5fSChristophe Leroy	lis	r4,tlb_44x_hwater@ha
11927e23b5fSChristophe Leroy	lwz	r5,tlb_44x_hwater@l(r4)
12027e23b5fSChristophe Leroy
12127e23b5fSChristophe Leroy1:	tlbwe	r3,r3,PPC44x_TLB_PAGEID
12227e23b5fSChristophe Leroy	addi	r3,r3,1
12327e23b5fSChristophe Leroy	cmpw	0,r3,r5
12427e23b5fSChristophe Leroy	ble	1b
12527e23b5fSChristophe Leroy
12627e23b5fSChristophe Leroy	isync
12727e23b5fSChristophe Leroy	blr
1281f69aa0bSChristophe Leroy#else
12927e23b5fSChristophe Leroy	/* 476 variant. There's not simple way to do this, hopefully we'll
13027e23b5fSChristophe Leroy	 * try to limit the amount of such full invalidates
13127e23b5fSChristophe Leroy	 */
13227e23b5fSChristophe Leroy	mfmsr	r11		/* Interrupts off */
13327e23b5fSChristophe Leroy	wrteei	0
13427e23b5fSChristophe Leroy	li	r3,-1		/* Current set */
13527e23b5fSChristophe Leroy	lis	r10,tlb_47x_boltmap@h
13627e23b5fSChristophe Leroy	ori	r10,r10,tlb_47x_boltmap@l
13727e23b5fSChristophe Leroy	lis	r7,0x8000	/* Specify way explicitly */
13827e23b5fSChristophe Leroy
13927e23b5fSChristophe Leroy	b	9f		/* For each set */
14027e23b5fSChristophe Leroy
14127e23b5fSChristophe Leroy1:	li	r9,4		/* Number of ways */
14227e23b5fSChristophe Leroy	li	r4,0		/* Current way */
14327e23b5fSChristophe Leroy	li	r6,0		/* Default entry value 0 */
14427e23b5fSChristophe Leroy	andi.	r0,r8,1		/* Check if way 0 is bolted */
14527e23b5fSChristophe Leroy	mtctr	r9		/* Load way counter */
14627e23b5fSChristophe Leroy	bne-	3f		/* Bolted, skip loading it */
14727e23b5fSChristophe Leroy
14827e23b5fSChristophe Leroy2:	/* For each way */
14927e23b5fSChristophe Leroy	or	r5,r3,r4	/* Make way|index for tlbre */
15027e23b5fSChristophe Leroy	rlwimi	r5,r5,16,8,15	/* Copy index into position */
15127e23b5fSChristophe Leroy	tlbre	r6,r5,0		/* Read entry */
15227e23b5fSChristophe Leroy3:	addis	r4,r4,0x2000	/* Next way */
15327e23b5fSChristophe Leroy	andi.	r0,r6,PPC47x_TLB0_VALID /* Valid entry ? */
15427e23b5fSChristophe Leroy	beq	4f		/* Nope, skip it */
15527e23b5fSChristophe Leroy	rlwimi	r7,r5,0,1,2	/* Insert way number */
15627e23b5fSChristophe Leroy	rlwinm	r6,r6,0,21,19	/* Clear V */
15727e23b5fSChristophe Leroy	tlbwe   r6,r7,0		/* Write it */
15827e23b5fSChristophe Leroy4:	bdnz	2b		/* Loop for each way */
15927e23b5fSChristophe Leroy	srwi	r8,r8,1		/* Next boltmap bit */
16027e23b5fSChristophe Leroy9:	cmpwi	cr1,r3,255	/* Last set done ? */
16127e23b5fSChristophe Leroy	addi	r3,r3,1		/* Next set */
16227e23b5fSChristophe Leroy	beq	cr1,1f		/* End of loop */
16327e23b5fSChristophe Leroy	andi.	r0,r3,0x1f	/* Need to load a new boltmap word ? */
16427e23b5fSChristophe Leroy	bne	1b		/* No, loop */
16527e23b5fSChristophe Leroy	lwz	r8,0(r10)	/* Load boltmap entry */
16627e23b5fSChristophe Leroy	addi	r10,r10,4	/* Next word */
16727e23b5fSChristophe Leroy	b	1b		/* Then loop */
16827e23b5fSChristophe Leroy1:	isync			/* Sync shadows */
16927e23b5fSChristophe Leroy	wrtee	r11
17027e23b5fSChristophe Leroy	blr
1711f69aa0bSChristophe Leroy#endif /* !CONFIG_PPC_47x */
17227e23b5fSChristophe Leroy
17327e23b5fSChristophe Leroy#ifdef CONFIG_PPC_47x
17427e23b5fSChristophe Leroy
17527e23b5fSChristophe Leroy/*
17627e23b5fSChristophe Leroy * _tlbivax_bcast is only on 47x. We don't bother doing a runtime
17727e23b5fSChristophe Leroy * check though, it will blow up soon enough if we mistakenly try
17827e23b5fSChristophe Leroy * to use it on a 440.
17927e23b5fSChristophe Leroy */
18027e23b5fSChristophe Leroy_GLOBAL(_tlbivax_bcast)
18127e23b5fSChristophe Leroy	mfspr	r5,SPRN_MMUCR
18227e23b5fSChristophe Leroy	mfmsr	r10
18327e23b5fSChristophe Leroy	rlwimi	r5,r4,0,16,31
18427e23b5fSChristophe Leroy	wrteei	0
18527e23b5fSChristophe Leroy	mtspr	SPRN_MMUCR,r5
18627e23b5fSChristophe Leroy	isync
18727e23b5fSChristophe Leroy	PPC_TLBIVAX(0, R3)
18827e23b5fSChristophe Leroy	isync
1892255411dSChristophe Leroy	mbar
19027e23b5fSChristophe Leroy	tlbsync
19127e23b5fSChristophe LeroyBEGIN_FTR_SECTION
19227e23b5fSChristophe Leroy	b	1f
19327e23b5fSChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
19427e23b5fSChristophe Leroy	sync
19527e23b5fSChristophe Leroy	wrtee	r10
19627e23b5fSChristophe Leroy	blr
19727e23b5fSChristophe Leroy/*
19827e23b5fSChristophe Leroy * DD2 HW could hang if in instruction fetch happens before msync completes.
19927e23b5fSChristophe Leroy * Touch enough instruction cache lines to ensure cache hits
20027e23b5fSChristophe Leroy */
20127e23b5fSChristophe Leroy1:	mflr	r9
202f5007dbfSChristophe Leroy	bcl	20,31,$+4
20327e23b5fSChristophe Leroy2:	mflr	r6
20427e23b5fSChristophe Leroy	li	r7,32
20527e23b5fSChristophe Leroy	PPC_ICBT(0,R6,R7)		/* touch next cache line */
20627e23b5fSChristophe Leroy	add	r6,r6,r7
20727e23b5fSChristophe Leroy	PPC_ICBT(0,R6,R7)		/* touch next cache line */
20827e23b5fSChristophe Leroy	add	r6,r6,r7
20927e23b5fSChristophe Leroy	PPC_ICBT(0,R6,R7)		/* touch next cache line */
21027e23b5fSChristophe Leroy	sync
21127e23b5fSChristophe Leroy	nop
21227e23b5fSChristophe Leroy	nop
21327e23b5fSChristophe Leroy	nop
21427e23b5fSChristophe Leroy	nop
21527e23b5fSChristophe Leroy	nop
21627e23b5fSChristophe Leroy	nop
21727e23b5fSChristophe Leroy	nop
21827e23b5fSChristophe Leroy	nop
21927e23b5fSChristophe Leroy	mtlr	r9
22027e23b5fSChristophe Leroy	wrtee	r10
22127e23b5fSChristophe Leroy	blr
22227e23b5fSChristophe Leroy#endif /* CONFIG_PPC_47x */
22327e23b5fSChristophe Leroy
224dfc3095cSChristophe Leroy#elif defined(CONFIG_PPC_85xx)
22527e23b5fSChristophe Leroy/*
22627e23b5fSChristophe Leroy * FSL BookE implementations.
22727e23b5fSChristophe Leroy *
22827e23b5fSChristophe Leroy * Since feature sections are using _SECTION_ELSE we need
22927e23b5fSChristophe Leroy * to have the larger code path before the _SECTION_ELSE
23027e23b5fSChristophe Leroy */
23127e23b5fSChristophe Leroy
23227e23b5fSChristophe Leroy/*
23327e23b5fSChristophe Leroy * Flush MMU TLB on the local processor
23427e23b5fSChristophe Leroy */
23527e23b5fSChristophe Leroy_GLOBAL(_tlbil_all)
23627e23b5fSChristophe LeroyBEGIN_MMU_FTR_SECTION
23727e23b5fSChristophe Leroy	li	r3,(MMUCSR0_TLBFI)@l
23827e23b5fSChristophe Leroy	mtspr	SPRN_MMUCSR0, r3
23927e23b5fSChristophe Leroy1:
24027e23b5fSChristophe Leroy	mfspr	r3,SPRN_MMUCSR0
24127e23b5fSChristophe Leroy	andi.	r3,r3,MMUCSR0_TLBFI@l
24227e23b5fSChristophe Leroy	bne	1b
24327e23b5fSChristophe LeroyMMU_FTR_SECTION_ELSE
24427e23b5fSChristophe Leroy	PPC_TLBILX_ALL(0,R0)
24527e23b5fSChristophe LeroyALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
24627e23b5fSChristophe Leroy	msync
24727e23b5fSChristophe Leroy	isync
24827e23b5fSChristophe Leroy	blr
24927e23b5fSChristophe Leroy
25027e23b5fSChristophe Leroy_GLOBAL(_tlbil_pid)
25127e23b5fSChristophe LeroyBEGIN_MMU_FTR_SECTION
25227e23b5fSChristophe Leroy	slwi	r3,r3,16
25327e23b5fSChristophe Leroy	mfmsr	r10
25427e23b5fSChristophe Leroy	wrteei	0
25527e23b5fSChristophe Leroy	mfspr	r4,SPRN_MAS6	/* save MAS6 */
25627e23b5fSChristophe Leroy	mtspr	SPRN_MAS6,r3
25727e23b5fSChristophe Leroy	PPC_TLBILX_PID(0,R0)
25827e23b5fSChristophe Leroy	mtspr	SPRN_MAS6,r4	/* restore MAS6 */
25927e23b5fSChristophe Leroy	wrtee	r10
26027e23b5fSChristophe LeroyMMU_FTR_SECTION_ELSE
26127e23b5fSChristophe Leroy	li	r3,(MMUCSR0_TLBFI)@l
26227e23b5fSChristophe Leroy	mtspr	SPRN_MMUCSR0, r3
26327e23b5fSChristophe Leroy1:
26427e23b5fSChristophe Leroy	mfspr	r3,SPRN_MMUCSR0
26527e23b5fSChristophe Leroy	andi.	r3,r3,MMUCSR0_TLBFI@l
26627e23b5fSChristophe Leroy	bne	1b
26727e23b5fSChristophe LeroyALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX)
26827e23b5fSChristophe Leroy	msync
26927e23b5fSChristophe Leroy	isync
27027e23b5fSChristophe Leroy	blr
27127e23b5fSChristophe Leroy
27227e23b5fSChristophe Leroy/*
27327e23b5fSChristophe Leroy * Flush MMU TLB for a particular address, but only on the local processor
27427e23b5fSChristophe Leroy * (no broadcast)
27527e23b5fSChristophe Leroy */
27627e23b5fSChristophe Leroy_GLOBAL(__tlbil_va)
27727e23b5fSChristophe Leroy	mfmsr	r10
27827e23b5fSChristophe Leroy	wrteei	0
27927e23b5fSChristophe Leroy	slwi	r4,r4,16
28027e23b5fSChristophe Leroy	ori	r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l
28127e23b5fSChristophe Leroy	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
28227e23b5fSChristophe LeroyBEGIN_MMU_FTR_SECTION
28327e23b5fSChristophe Leroy	tlbsx	0,r3
28427e23b5fSChristophe Leroy	mfspr	r4,SPRN_MAS1		/* check valid */
28527e23b5fSChristophe Leroy	andis.	r3,r4,MAS1_VALID@h
28627e23b5fSChristophe Leroy	beq	1f
28727e23b5fSChristophe Leroy	rlwinm	r4,r4,0,1,31
28827e23b5fSChristophe Leroy	mtspr	SPRN_MAS1,r4
28927e23b5fSChristophe Leroy	tlbwe
29027e23b5fSChristophe LeroyMMU_FTR_SECTION_ELSE
29127e23b5fSChristophe Leroy	PPC_TLBILX_VA(0,R3)
29227e23b5fSChristophe LeroyALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
29327e23b5fSChristophe Leroy	msync
29427e23b5fSChristophe Leroy	isync
29527e23b5fSChristophe Leroy1:	wrtee	r10
29627e23b5fSChristophe Leroy	blr
297e0d68273SChristophe Leroy#elif defined(CONFIG_PPC_BOOK3E_64)
29827e23b5fSChristophe Leroy/*
29927e23b5fSChristophe Leroy * New Book3E (>= 2.06) implementation
30027e23b5fSChristophe Leroy *
30127e23b5fSChristophe Leroy * Note: We may be able to get away without the interrupt masking stuff
30227e23b5fSChristophe Leroy * if we save/restore MAS6 on exceptions that might modify it
30327e23b5fSChristophe Leroy */
30427e23b5fSChristophe Leroy_GLOBAL(_tlbil_pid)
30527e23b5fSChristophe Leroy	slwi	r4,r3,MAS6_SPID_SHIFT
30627e23b5fSChristophe Leroy	mfmsr	r10
30727e23b5fSChristophe Leroy	wrteei	0
30827e23b5fSChristophe Leroy	mtspr	SPRN_MAS6,r4
30927e23b5fSChristophe Leroy	PPC_TLBILX_PID(0,R0)
31027e23b5fSChristophe Leroy	wrtee	r10
31127e23b5fSChristophe Leroy	msync
31227e23b5fSChristophe Leroy	isync
31327e23b5fSChristophe Leroy	blr
31427e23b5fSChristophe Leroy
31527e23b5fSChristophe Leroy_GLOBAL(_tlbil_pid_noind)
31627e23b5fSChristophe Leroy	slwi	r4,r3,MAS6_SPID_SHIFT
31727e23b5fSChristophe Leroy	mfmsr	r10
31827e23b5fSChristophe Leroy	ori	r4,r4,MAS6_SIND
31927e23b5fSChristophe Leroy	wrteei	0
32027e23b5fSChristophe Leroy	mtspr	SPRN_MAS6,r4
32127e23b5fSChristophe Leroy	PPC_TLBILX_PID(0,R0)
32227e23b5fSChristophe Leroy	wrtee	r10
32327e23b5fSChristophe Leroy	msync
32427e23b5fSChristophe Leroy	isync
32527e23b5fSChristophe Leroy	blr
32627e23b5fSChristophe Leroy
32727e23b5fSChristophe Leroy_GLOBAL(_tlbil_all)
32827e23b5fSChristophe Leroy	PPC_TLBILX_ALL(0,R0)
32927e23b5fSChristophe Leroy	msync
33027e23b5fSChristophe Leroy	isync
33127e23b5fSChristophe Leroy	blr
33227e23b5fSChristophe Leroy
33327e23b5fSChristophe Leroy_GLOBAL(_tlbil_va)
33427e23b5fSChristophe Leroy	mfmsr	r10
33527e23b5fSChristophe Leroy	wrteei	0
33627e23b5fSChristophe Leroy	cmpwi	cr0,r6,0
33727e23b5fSChristophe Leroy	slwi	r4,r4,MAS6_SPID_SHIFT
33827e23b5fSChristophe Leroy	rlwimi	r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
33927e23b5fSChristophe Leroy	beq	1f
34027e23b5fSChristophe Leroy	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
34127e23b5fSChristophe Leroy1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
34227e23b5fSChristophe Leroy	PPC_TLBILX_VA(0,R3)
34327e23b5fSChristophe Leroy	msync
34427e23b5fSChristophe Leroy	isync
34527e23b5fSChristophe Leroy	wrtee	r10
34627e23b5fSChristophe Leroy	blr
34727e23b5fSChristophe Leroy
34827e23b5fSChristophe Leroy_GLOBAL(_tlbivax_bcast)
34927e23b5fSChristophe Leroy	mfmsr	r10
35027e23b5fSChristophe Leroy	wrteei	0
35127e23b5fSChristophe Leroy	cmpwi	cr0,r6,0
35227e23b5fSChristophe Leroy	slwi	r4,r4,MAS6_SPID_SHIFT
35327e23b5fSChristophe Leroy	rlwimi	r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
35427e23b5fSChristophe Leroy	beq	1f
35527e23b5fSChristophe Leroy	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
35627e23b5fSChristophe Leroy1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
35727e23b5fSChristophe Leroy	PPC_TLBIVAX(0,R3)
3582255411dSChristophe Leroy	mbar
35927e23b5fSChristophe Leroy	tlbsync
36027e23b5fSChristophe Leroy	sync
36127e23b5fSChristophe Leroy	wrtee	r10
36227e23b5fSChristophe Leroy	blr
36327e23b5fSChristophe Leroy#else
36427e23b5fSChristophe Leroy#error Unsupported processor type !
36527e23b5fSChristophe Leroy#endif
36627e23b5fSChristophe Leroy
367*3e731858SChristophe Leroy#if defined(CONFIG_PPC_E500)
36827e23b5fSChristophe Leroy/*
36927e23b5fSChristophe Leroy * extern void loadcam_entry(unsigned int index)
37027e23b5fSChristophe Leroy *
37127e23b5fSChristophe Leroy * Load TLBCAM[index] entry in to the L2 CAM MMU
372a97dd9e2SChristophe Leroy * Must preserve r7, r8, r9, r10, r11, r12
37327e23b5fSChristophe Leroy */
37427e23b5fSChristophe Leroy_GLOBAL(loadcam_entry)
37527e23b5fSChristophe Leroy	mflr	r5
37627e23b5fSChristophe Leroy	LOAD_REG_ADDR_PIC(r4, TLBCAM)
37727e23b5fSChristophe Leroy	mtlr	r5
37827e23b5fSChristophe Leroy	mulli	r5,r3,TLBCAM_SIZE
37927e23b5fSChristophe Leroy	add	r3,r5,r4
38027e23b5fSChristophe Leroy	lwz	r4,TLBCAM_MAS0(r3)
38127e23b5fSChristophe Leroy	mtspr	SPRN_MAS0,r4
38227e23b5fSChristophe Leroy	lwz	r4,TLBCAM_MAS1(r3)
38327e23b5fSChristophe Leroy	mtspr	SPRN_MAS1,r4
38427e23b5fSChristophe Leroy	PPC_LL	r4,TLBCAM_MAS2(r3)
38527e23b5fSChristophe Leroy	mtspr	SPRN_MAS2,r4
38627e23b5fSChristophe Leroy	lwz	r4,TLBCAM_MAS3(r3)
38727e23b5fSChristophe Leroy	mtspr	SPRN_MAS3,r4
38827e23b5fSChristophe LeroyBEGIN_MMU_FTR_SECTION
38927e23b5fSChristophe Leroy	lwz	r4,TLBCAM_MAS7(r3)
39027e23b5fSChristophe Leroy	mtspr	SPRN_MAS7,r4
39127e23b5fSChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
39227e23b5fSChristophe Leroy	isync
39327e23b5fSChristophe Leroy	tlbwe
39427e23b5fSChristophe Leroy	isync
39527e23b5fSChristophe Leroy	blr
39627e23b5fSChristophe Leroy
39727e23b5fSChristophe Leroy/*
39827e23b5fSChristophe Leroy * Load multiple TLB entries at once, using an alternate-space
39927e23b5fSChristophe Leroy * trampoline so that we don't have to care about whether the same
40027e23b5fSChristophe Leroy * TLB entry maps us before and after.
40127e23b5fSChristophe Leroy *
40227e23b5fSChristophe Leroy * r3 = first entry to write
40327e23b5fSChristophe Leroy * r4 = number of entries to write
404a97dd9e2SChristophe Leroy * r5 = temporary tlb entry (0 means no switch to AS1)
40527e23b5fSChristophe Leroy */
40627e23b5fSChristophe Leroy_GLOBAL(loadcam_multi)
40727e23b5fSChristophe Leroy	mflr	r8
408aa411334SLaurentiu Tudor	/* Don't switch to AS=1 if already there */
409aa411334SLaurentiu Tudor	mfmsr	r11
410aa411334SLaurentiu Tudor	andi.	r11,r11,MSR_IS
411aa411334SLaurentiu Tudor	bne	10f
412a97dd9e2SChristophe Leroy	mr.	r12, r5
413a97dd9e2SChristophe Leroy	beq	10f
41427e23b5fSChristophe Leroy
41527e23b5fSChristophe Leroy	/*
41627e23b5fSChristophe Leroy	 * Set up temporary TLB entry that is the same as what we're
41727e23b5fSChristophe Leroy	 * running from, but in AS=1.
41827e23b5fSChristophe Leroy	 */
419f5007dbfSChristophe Leroy	bcl	20,31,$+4
42027e23b5fSChristophe Leroy1:	mflr	r6
42127e23b5fSChristophe Leroy	tlbsx	0,r8
42227e23b5fSChristophe Leroy	mfspr	r6,SPRN_MAS1
42327e23b5fSChristophe Leroy	ori	r6,r6,MAS1_TS
42427e23b5fSChristophe Leroy	mtspr	SPRN_MAS1,r6
42527e23b5fSChristophe Leroy	mfspr	r6,SPRN_MAS0
42627e23b5fSChristophe Leroy	rlwimi	r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
42727e23b5fSChristophe Leroy	mr	r7,r5
42827e23b5fSChristophe Leroy	mtspr	SPRN_MAS0,r6
42927e23b5fSChristophe Leroy	isync
43027e23b5fSChristophe Leroy	tlbwe
43127e23b5fSChristophe Leroy	isync
43227e23b5fSChristophe Leroy
43327e23b5fSChristophe Leroy	/* Switch to AS=1 */
43427e23b5fSChristophe Leroy	mfmsr	r6
43527e23b5fSChristophe Leroy	ori	r6,r6,MSR_IS|MSR_DS
43627e23b5fSChristophe Leroy	mtmsr	r6
43727e23b5fSChristophe Leroy	isync
43827e23b5fSChristophe Leroy
439aa411334SLaurentiu Tudor10:
44027e23b5fSChristophe Leroy	mr	r9,r3
44127e23b5fSChristophe Leroy	add	r10,r3,r4
44227e23b5fSChristophe Leroy2:	bl	loadcam_entry
44327e23b5fSChristophe Leroy	addi	r9,r9,1
44427e23b5fSChristophe Leroy	cmpw	r9,r10
44527e23b5fSChristophe Leroy	mr	r3,r9
44627e23b5fSChristophe Leroy	blt	2b
44727e23b5fSChristophe Leroy
448aa411334SLaurentiu Tudor	/* Don't return to AS=0 if we were in AS=1 at function start */
449aa411334SLaurentiu Tudor	andi.	r11,r11,MSR_IS
450aa411334SLaurentiu Tudor	bne	3f
451a97dd9e2SChristophe Leroy	cmpwi	r12, 0
452a97dd9e2SChristophe Leroy	beq	3f
453aa411334SLaurentiu Tudor
45427e23b5fSChristophe Leroy	/* Return to AS=0 and clear the temporary entry */
45527e23b5fSChristophe Leroy	mfmsr	r6
45627e23b5fSChristophe Leroy	rlwinm.	r6,r6,0,~(MSR_IS|MSR_DS)
45727e23b5fSChristophe Leroy	mtmsr	r6
45827e23b5fSChristophe Leroy	isync
45927e23b5fSChristophe Leroy
46027e23b5fSChristophe Leroy	li	r6,0
46127e23b5fSChristophe Leroy	mtspr	SPRN_MAS1,r6
46227e23b5fSChristophe Leroy	rlwinm	r6,r7,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
46327e23b5fSChristophe Leroy	oris	r6,r6,MAS0_TLBSEL(1)@h
46427e23b5fSChristophe Leroy	mtspr	SPRN_MAS0,r6
46527e23b5fSChristophe Leroy	isync
46627e23b5fSChristophe Leroy	tlbwe
46727e23b5fSChristophe Leroy	isync
46827e23b5fSChristophe Leroy
469aa411334SLaurentiu Tudor3:
47027e23b5fSChristophe Leroy	mtlr	r8
47127e23b5fSChristophe Leroy	blr
47227e23b5fSChristophe Leroy#endif
473