18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * This file contains low-level functions for performing various 48c2ecf20Sopenharmony_ci * types of TLB invalidations on various processors with no hash 58c2ecf20Sopenharmony_ci * table. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This file implements the following functions for all no-hash 88c2ecf20Sopenharmony_ci * processors. Some aren't implemented for some variants. Some 98c2ecf20Sopenharmony_ci * are inline in tlbflush.h 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * - tlbil_va 128c2ecf20Sopenharmony_ci * - tlbil_pid 138c2ecf20Sopenharmony_ci * - tlbil_all 148c2ecf20Sopenharmony_ci * - tlbivax_bcast 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Code mostly moved over from misc_32.S 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Partially rewritten by Cort Dougan (cort@cs.nmt.edu) 218c2ecf20Sopenharmony_ci * Paul Mackerras, Kumar Gala and Benjamin Herrenschmidt. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include <asm/reg.h> 258c2ecf20Sopenharmony_ci#include <asm/page.h> 268c2ecf20Sopenharmony_ci#include <asm/cputable.h> 278c2ecf20Sopenharmony_ci#include <asm/mmu.h> 288c2ecf20Sopenharmony_ci#include <asm/ppc_asm.h> 298c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 308c2ecf20Sopenharmony_ci#include <asm/processor.h> 318c2ecf20Sopenharmony_ci#include <asm/bug.h> 328c2ecf20Sopenharmony_ci#include <asm/asm-compat.h> 338c2ecf20Sopenharmony_ci#include <asm/feature-fixups.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#if defined(CONFIG_40x) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * 40x implementation needs only tlbil_va 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ci_GLOBAL(__tlbil_va) 418c2ecf20Sopenharmony_ci /* We run the search with interrupts disabled because we have to change 428c2ecf20Sopenharmony_ci * the PID and I don't want to preempt when that happens. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci mfmsr r5 458c2ecf20Sopenharmony_ci mfspr r6,SPRN_PID 468c2ecf20Sopenharmony_ci wrteei 0 478c2ecf20Sopenharmony_ci mtspr SPRN_PID,r4 488c2ecf20Sopenharmony_ci tlbsx. r3, 0, r3 498c2ecf20Sopenharmony_ci mtspr SPRN_PID,r6 508c2ecf20Sopenharmony_ci wrtee r5 518c2ecf20Sopenharmony_ci bne 1f 528c2ecf20Sopenharmony_ci sync 538c2ecf20Sopenharmony_ci /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is 548c2ecf20Sopenharmony_ci * clear. Since 25 is the V bit in the TLB_TAG, loading this value 558c2ecf20Sopenharmony_ci * will invalidate the TLB entry. */ 568c2ecf20Sopenharmony_ci tlbwe r3, r3, TLB_TAG 578c2ecf20Sopenharmony_ci isync 588c2ecf20Sopenharmony_ci1: blr 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#elif defined(CONFIG_PPC_8xx) 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* 638c2ecf20Sopenharmony_ci * Nothing to do for 8xx, everything is inline 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#elif defined(CONFIG_44x) /* Includes 47x */ 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * 440 implementation uses tlbsx/we for tlbil_va and a full sweep 708c2ecf20Sopenharmony_ci * of the TLB for everything else. 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_ci_GLOBAL(__tlbil_va) 738c2ecf20Sopenharmony_ci mfspr r5,SPRN_MMUCR 748c2ecf20Sopenharmony_ci mfmsr r10 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci /* 778c2ecf20Sopenharmony_ci * We write 16 bits of STID since 47x supports that much, we 788c2ecf20Sopenharmony_ci * will never be passed out of bounds values on 440 (hopefully) 798c2ecf20Sopenharmony_ci */ 808c2ecf20Sopenharmony_ci rlwimi r5,r4,0,16,31 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* We have to run the search with interrupts disabled, otherwise 838c2ecf20Sopenharmony_ci * an interrupt which causes a TLB miss can clobber the MMUCR 848c2ecf20Sopenharmony_ci * between the mtspr and the tlbsx. 858c2ecf20Sopenharmony_ci * 868c2ecf20Sopenharmony_ci * Critical and Machine Check interrupts take care of saving 878c2ecf20Sopenharmony_ci * and restoring MMUCR, so only normal interrupts have to be 888c2ecf20Sopenharmony_ci * taken care of. 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci wrteei 0 918c2ecf20Sopenharmony_ci mtspr SPRN_MMUCR,r5 928c2ecf20Sopenharmony_ci tlbsx. r6,0,r3 938c2ecf20Sopenharmony_ci bne 10f 948c2ecf20Sopenharmony_ci sync 958c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 968c2ecf20Sopenharmony_ci b 2f 978c2ecf20Sopenharmony_ciEND_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) 988c2ecf20Sopenharmony_ci /* On 440 There are only 64 TLB entries, so r3 < 64, which means bit 998c2ecf20Sopenharmony_ci * 22, is clear. Since 22 is the V bit in the TLB_PAGEID, loading this 1008c2ecf20Sopenharmony_ci * value will invalidate the TLB entry. 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci tlbwe r6,r6,PPC44x_TLB_PAGEID 1038c2ecf20Sopenharmony_ci isync 1048c2ecf20Sopenharmony_ci10: wrtee r10 1058c2ecf20Sopenharmony_ci blr 1068c2ecf20Sopenharmony_ci2: 1078c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_47x 1088c2ecf20Sopenharmony_ci oris r7,r6,0x8000 /* specify way explicitly */ 1098c2ecf20Sopenharmony_ci clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ 1108c2ecf20Sopenharmony_ci ori r4,r4,PPC47x_TLBE_SIZE 1118c2ecf20Sopenharmony_ci tlbwe r4,r7,0 /* write it */ 1128c2ecf20Sopenharmony_ci isync 1138c2ecf20Sopenharmony_ci wrtee r10 1148c2ecf20Sopenharmony_ci blr 1158c2ecf20Sopenharmony_ci#else /* CONFIG_PPC_47x */ 1168c2ecf20Sopenharmony_ci1: trap 1178c2ecf20Sopenharmony_ci EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; 1188c2ecf20Sopenharmony_ci#endif /* !CONFIG_PPC_47x */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_all) 1218c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_pid) 1228c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 1238c2ecf20Sopenharmony_ci b 2f 1248c2ecf20Sopenharmony_ciEND_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) 1258c2ecf20Sopenharmony_ci li r3,0 1268c2ecf20Sopenharmony_ci sync 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* Load high watermark */ 1298c2ecf20Sopenharmony_ci lis r4,tlb_44x_hwater@ha 1308c2ecf20Sopenharmony_ci lwz r5,tlb_44x_hwater@l(r4) 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci1: tlbwe r3,r3,PPC44x_TLB_PAGEID 1338c2ecf20Sopenharmony_ci addi r3,r3,1 1348c2ecf20Sopenharmony_ci cmpw 0,r3,r5 1358c2ecf20Sopenharmony_ci ble 1b 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci isync 1388c2ecf20Sopenharmony_ci blr 1398c2ecf20Sopenharmony_ci2: 1408c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_47x 1418c2ecf20Sopenharmony_ci /* 476 variant. There's not simple way to do this, hopefully we'll 1428c2ecf20Sopenharmony_ci * try to limit the amount of such full invalidates 1438c2ecf20Sopenharmony_ci */ 1448c2ecf20Sopenharmony_ci mfmsr r11 /* Interrupts off */ 1458c2ecf20Sopenharmony_ci wrteei 0 1468c2ecf20Sopenharmony_ci li r3,-1 /* Current set */ 1478c2ecf20Sopenharmony_ci lis r10,tlb_47x_boltmap@h 1488c2ecf20Sopenharmony_ci ori r10,r10,tlb_47x_boltmap@l 1498c2ecf20Sopenharmony_ci lis r7,0x8000 /* Specify way explicitly */ 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci b 9f /* For each set */ 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci1: li r9,4 /* Number of ways */ 1548c2ecf20Sopenharmony_ci li r4,0 /* Current way */ 1558c2ecf20Sopenharmony_ci li r6,0 /* Default entry value 0 */ 1568c2ecf20Sopenharmony_ci andi. r0,r8,1 /* Check if way 0 is bolted */ 1578c2ecf20Sopenharmony_ci mtctr r9 /* Load way counter */ 1588c2ecf20Sopenharmony_ci bne- 3f /* Bolted, skip loading it */ 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci2: /* For each way */ 1618c2ecf20Sopenharmony_ci or r5,r3,r4 /* Make way|index for tlbre */ 1628c2ecf20Sopenharmony_ci rlwimi r5,r5,16,8,15 /* Copy index into position */ 1638c2ecf20Sopenharmony_ci tlbre r6,r5,0 /* Read entry */ 1648c2ecf20Sopenharmony_ci3: addis r4,r4,0x2000 /* Next way */ 1658c2ecf20Sopenharmony_ci andi. r0,r6,PPC47x_TLB0_VALID /* Valid entry ? */ 1668c2ecf20Sopenharmony_ci beq 4f /* Nope, skip it */ 1678c2ecf20Sopenharmony_ci rlwimi r7,r5,0,1,2 /* Insert way number */ 1688c2ecf20Sopenharmony_ci rlwinm r6,r6,0,21,19 /* Clear V */ 1698c2ecf20Sopenharmony_ci tlbwe r6,r7,0 /* Write it */ 1708c2ecf20Sopenharmony_ci4: bdnz 2b /* Loop for each way */ 1718c2ecf20Sopenharmony_ci srwi r8,r8,1 /* Next boltmap bit */ 1728c2ecf20Sopenharmony_ci9: cmpwi cr1,r3,255 /* Last set done ? */ 1738c2ecf20Sopenharmony_ci addi r3,r3,1 /* Next set */ 1748c2ecf20Sopenharmony_ci beq cr1,1f /* End of loop */ 1758c2ecf20Sopenharmony_ci andi. r0,r3,0x1f /* Need to load a new boltmap word ? */ 1768c2ecf20Sopenharmony_ci bne 1b /* No, loop */ 1778c2ecf20Sopenharmony_ci lwz r8,0(r10) /* Load boltmap entry */ 1788c2ecf20Sopenharmony_ci addi r10,r10,4 /* Next word */ 1798c2ecf20Sopenharmony_ci b 1b /* Then loop */ 1808c2ecf20Sopenharmony_ci1: isync /* Sync shadows */ 1818c2ecf20Sopenharmony_ci wrtee r11 1828c2ecf20Sopenharmony_ci#else /* CONFIG_PPC_47x */ 1838c2ecf20Sopenharmony_ci1: trap 1848c2ecf20Sopenharmony_ci EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; 1858c2ecf20Sopenharmony_ci#endif /* !CONFIG_PPC_47x */ 1868c2ecf20Sopenharmony_ci blr 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_47x 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci/* 1918c2ecf20Sopenharmony_ci * _tlbivax_bcast is only on 47x. We don't bother doing a runtime 1928c2ecf20Sopenharmony_ci * check though, it will blow up soon enough if we mistakenly try 1938c2ecf20Sopenharmony_ci * to use it on a 440. 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_ci_GLOBAL(_tlbivax_bcast) 1968c2ecf20Sopenharmony_ci mfspr r5,SPRN_MMUCR 1978c2ecf20Sopenharmony_ci mfmsr r10 1988c2ecf20Sopenharmony_ci rlwimi r5,r4,0,16,31 1998c2ecf20Sopenharmony_ci wrteei 0 2008c2ecf20Sopenharmony_ci mtspr SPRN_MMUCR,r5 2018c2ecf20Sopenharmony_ci isync 2028c2ecf20Sopenharmony_ci PPC_TLBIVAX(0, R3) 2038c2ecf20Sopenharmony_ci isync 2048c2ecf20Sopenharmony_ci eieio 2058c2ecf20Sopenharmony_ci tlbsync 2068c2ecf20Sopenharmony_ciBEGIN_FTR_SECTION 2078c2ecf20Sopenharmony_ci b 1f 2088c2ecf20Sopenharmony_ciEND_FTR_SECTION_IFSET(CPU_FTR_476_DD2) 2098c2ecf20Sopenharmony_ci sync 2108c2ecf20Sopenharmony_ci wrtee r10 2118c2ecf20Sopenharmony_ci blr 2128c2ecf20Sopenharmony_ci/* 2138c2ecf20Sopenharmony_ci * DD2 HW could hang if in instruction fetch happens before msync completes. 2148c2ecf20Sopenharmony_ci * Touch enough instruction cache lines to ensure cache hits 2158c2ecf20Sopenharmony_ci */ 2168c2ecf20Sopenharmony_ci1: mflr r9 2178c2ecf20Sopenharmony_ci bl 2f 2188c2ecf20Sopenharmony_ci2: mflr r6 2198c2ecf20Sopenharmony_ci li r7,32 2208c2ecf20Sopenharmony_ci PPC_ICBT(0,R6,R7) /* touch next cache line */ 2218c2ecf20Sopenharmony_ci add r6,r6,r7 2228c2ecf20Sopenharmony_ci PPC_ICBT(0,R6,R7) /* touch next cache line */ 2238c2ecf20Sopenharmony_ci add r6,r6,r7 2248c2ecf20Sopenharmony_ci PPC_ICBT(0,R6,R7) /* touch next cache line */ 2258c2ecf20Sopenharmony_ci sync 2268c2ecf20Sopenharmony_ci nop 2278c2ecf20Sopenharmony_ci nop 2288c2ecf20Sopenharmony_ci nop 2298c2ecf20Sopenharmony_ci nop 2308c2ecf20Sopenharmony_ci nop 2318c2ecf20Sopenharmony_ci nop 2328c2ecf20Sopenharmony_ci nop 2338c2ecf20Sopenharmony_ci nop 2348c2ecf20Sopenharmony_ci mtlr r9 2358c2ecf20Sopenharmony_ci wrtee r10 2368c2ecf20Sopenharmony_ci blr 2378c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_47x */ 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci#elif defined(CONFIG_FSL_BOOKE) 2408c2ecf20Sopenharmony_ci/* 2418c2ecf20Sopenharmony_ci * FSL BookE implementations. 2428c2ecf20Sopenharmony_ci * 2438c2ecf20Sopenharmony_ci * Since feature sections are using _SECTION_ELSE we need 2448c2ecf20Sopenharmony_ci * to have the larger code path before the _SECTION_ELSE 2458c2ecf20Sopenharmony_ci */ 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci/* 2488c2ecf20Sopenharmony_ci * Flush MMU TLB on the local processor 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_all) 2518c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 2528c2ecf20Sopenharmony_ci li r3,(MMUCSR0_TLBFI)@l 2538c2ecf20Sopenharmony_ci mtspr SPRN_MMUCSR0, r3 2548c2ecf20Sopenharmony_ci1: 2558c2ecf20Sopenharmony_ci mfspr r3,SPRN_MMUCSR0 2568c2ecf20Sopenharmony_ci andi. r3,r3,MMUCSR0_TLBFI@l 2578c2ecf20Sopenharmony_ci bne 1b 2588c2ecf20Sopenharmony_ciMMU_FTR_SECTION_ELSE 2598c2ecf20Sopenharmony_ci PPC_TLBILX_ALL(0,R0) 2608c2ecf20Sopenharmony_ciALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX) 2618c2ecf20Sopenharmony_ci msync 2628c2ecf20Sopenharmony_ci isync 2638c2ecf20Sopenharmony_ci blr 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_pid) 2668c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 2678c2ecf20Sopenharmony_ci slwi r3,r3,16 2688c2ecf20Sopenharmony_ci mfmsr r10 2698c2ecf20Sopenharmony_ci wrteei 0 2708c2ecf20Sopenharmony_ci mfspr r4,SPRN_MAS6 /* save MAS6 */ 2718c2ecf20Sopenharmony_ci mtspr SPRN_MAS6,r3 2728c2ecf20Sopenharmony_ci PPC_TLBILX_PID(0,R0) 2738c2ecf20Sopenharmony_ci mtspr SPRN_MAS6,r4 /* restore MAS6 */ 2748c2ecf20Sopenharmony_ci wrtee r10 2758c2ecf20Sopenharmony_ciMMU_FTR_SECTION_ELSE 2768c2ecf20Sopenharmony_ci li r3,(MMUCSR0_TLBFI)@l 2778c2ecf20Sopenharmony_ci mtspr SPRN_MMUCSR0, r3 2788c2ecf20Sopenharmony_ci1: 2798c2ecf20Sopenharmony_ci mfspr r3,SPRN_MMUCSR0 2808c2ecf20Sopenharmony_ci andi. r3,r3,MMUCSR0_TLBFI@l 2818c2ecf20Sopenharmony_ci bne 1b 2828c2ecf20Sopenharmony_ciALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX) 2838c2ecf20Sopenharmony_ci msync 2848c2ecf20Sopenharmony_ci isync 2858c2ecf20Sopenharmony_ci blr 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci/* 2888c2ecf20Sopenharmony_ci * Flush MMU TLB for a particular address, but only on the local processor 2898c2ecf20Sopenharmony_ci * (no broadcast) 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_ci_GLOBAL(__tlbil_va) 2928c2ecf20Sopenharmony_ci mfmsr r10 2938c2ecf20Sopenharmony_ci wrteei 0 2948c2ecf20Sopenharmony_ci slwi r4,r4,16 2958c2ecf20Sopenharmony_ci ori r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l 2968c2ecf20Sopenharmony_ci mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ 2978c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 2988c2ecf20Sopenharmony_ci tlbsx 0,r3 2998c2ecf20Sopenharmony_ci mfspr r4,SPRN_MAS1 /* check valid */ 3008c2ecf20Sopenharmony_ci andis. r3,r4,MAS1_VALID@h 3018c2ecf20Sopenharmony_ci beq 1f 3028c2ecf20Sopenharmony_ci rlwinm r4,r4,0,1,31 3038c2ecf20Sopenharmony_ci mtspr SPRN_MAS1,r4 3048c2ecf20Sopenharmony_ci tlbwe 3058c2ecf20Sopenharmony_ciMMU_FTR_SECTION_ELSE 3068c2ecf20Sopenharmony_ci PPC_TLBILX_VA(0,R3) 3078c2ecf20Sopenharmony_ciALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX) 3088c2ecf20Sopenharmony_ci msync 3098c2ecf20Sopenharmony_ci isync 3108c2ecf20Sopenharmony_ci1: wrtee r10 3118c2ecf20Sopenharmony_ci blr 3128c2ecf20Sopenharmony_ci#elif defined(CONFIG_PPC_BOOK3E) 3138c2ecf20Sopenharmony_ci/* 3148c2ecf20Sopenharmony_ci * New Book3E (>= 2.06) implementation 3158c2ecf20Sopenharmony_ci * 3168c2ecf20Sopenharmony_ci * Note: We may be able to get away without the interrupt masking stuff 3178c2ecf20Sopenharmony_ci * if we save/restore MAS6 on exceptions that might modify it 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_pid) 3208c2ecf20Sopenharmony_ci slwi r4,r3,MAS6_SPID_SHIFT 3218c2ecf20Sopenharmony_ci mfmsr r10 3228c2ecf20Sopenharmony_ci wrteei 0 3238c2ecf20Sopenharmony_ci mtspr SPRN_MAS6,r4 3248c2ecf20Sopenharmony_ci PPC_TLBILX_PID(0,R0) 3258c2ecf20Sopenharmony_ci wrtee r10 3268c2ecf20Sopenharmony_ci msync 3278c2ecf20Sopenharmony_ci isync 3288c2ecf20Sopenharmony_ci blr 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_pid_noind) 3318c2ecf20Sopenharmony_ci slwi r4,r3,MAS6_SPID_SHIFT 3328c2ecf20Sopenharmony_ci mfmsr r10 3338c2ecf20Sopenharmony_ci ori r4,r4,MAS6_SIND 3348c2ecf20Sopenharmony_ci wrteei 0 3358c2ecf20Sopenharmony_ci mtspr SPRN_MAS6,r4 3368c2ecf20Sopenharmony_ci PPC_TLBILX_PID(0,R0) 3378c2ecf20Sopenharmony_ci wrtee r10 3388c2ecf20Sopenharmony_ci msync 3398c2ecf20Sopenharmony_ci isync 3408c2ecf20Sopenharmony_ci blr 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_all) 3438c2ecf20Sopenharmony_ci PPC_TLBILX_ALL(0,R0) 3448c2ecf20Sopenharmony_ci msync 3458c2ecf20Sopenharmony_ci isync 3468c2ecf20Sopenharmony_ci blr 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci_GLOBAL(_tlbil_va) 3498c2ecf20Sopenharmony_ci mfmsr r10 3508c2ecf20Sopenharmony_ci wrteei 0 3518c2ecf20Sopenharmony_ci cmpwi cr0,r6,0 3528c2ecf20Sopenharmony_ci slwi r4,r4,MAS6_SPID_SHIFT 3538c2ecf20Sopenharmony_ci rlwimi r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK 3548c2ecf20Sopenharmony_ci beq 1f 3558c2ecf20Sopenharmony_ci rlwimi r4,r6,MAS6_SIND_SHIFT,MAS6_SIND 3568c2ecf20Sopenharmony_ci1: mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ 3578c2ecf20Sopenharmony_ci PPC_TLBILX_VA(0,R3) 3588c2ecf20Sopenharmony_ci msync 3598c2ecf20Sopenharmony_ci isync 3608c2ecf20Sopenharmony_ci wrtee r10 3618c2ecf20Sopenharmony_ci blr 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci_GLOBAL(_tlbivax_bcast) 3648c2ecf20Sopenharmony_ci mfmsr r10 3658c2ecf20Sopenharmony_ci wrteei 0 3668c2ecf20Sopenharmony_ci cmpwi cr0,r6,0 3678c2ecf20Sopenharmony_ci slwi r4,r4,MAS6_SPID_SHIFT 3688c2ecf20Sopenharmony_ci rlwimi r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK 3698c2ecf20Sopenharmony_ci beq 1f 3708c2ecf20Sopenharmony_ci rlwimi r4,r6,MAS6_SIND_SHIFT,MAS6_SIND 3718c2ecf20Sopenharmony_ci1: mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ 3728c2ecf20Sopenharmony_ci PPC_TLBIVAX(0,R3) 3738c2ecf20Sopenharmony_ci eieio 3748c2ecf20Sopenharmony_ci tlbsync 3758c2ecf20Sopenharmony_ci sync 3768c2ecf20Sopenharmony_ci wrtee r10 3778c2ecf20Sopenharmony_ci blr 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci_GLOBAL(set_context) 3808c2ecf20Sopenharmony_ci#ifdef CONFIG_BDI_SWITCH 3818c2ecf20Sopenharmony_ci /* Context switch the PTE pointer for the Abatron BDI2000. 3828c2ecf20Sopenharmony_ci * The PGDIR is the second parameter. 3838c2ecf20Sopenharmony_ci */ 3848c2ecf20Sopenharmony_ci lis r5, abatron_pteptrs@h 3858c2ecf20Sopenharmony_ci ori r5, r5, abatron_pteptrs@l 3868c2ecf20Sopenharmony_ci stw r4, 0x4(r5) 3878c2ecf20Sopenharmony_ci#endif 3888c2ecf20Sopenharmony_ci mtspr SPRN_PID,r3 3898c2ecf20Sopenharmony_ci isync /* Force context change */ 3908c2ecf20Sopenharmony_ci blr 3918c2ecf20Sopenharmony_ci#else 3928c2ecf20Sopenharmony_ci#error Unsupported processor type ! 3938c2ecf20Sopenharmony_ci#endif 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci#if defined(CONFIG_PPC_FSL_BOOK3E) 3968c2ecf20Sopenharmony_ci/* 3978c2ecf20Sopenharmony_ci * extern void loadcam_entry(unsigned int index) 3988c2ecf20Sopenharmony_ci * 3998c2ecf20Sopenharmony_ci * Load TLBCAM[index] entry in to the L2 CAM MMU 4008c2ecf20Sopenharmony_ci * Must preserve r7, r8, r9, r10 and r11 4018c2ecf20Sopenharmony_ci */ 4028c2ecf20Sopenharmony_ci_GLOBAL(loadcam_entry) 4038c2ecf20Sopenharmony_ci mflr r5 4048c2ecf20Sopenharmony_ci LOAD_REG_ADDR_PIC(r4, TLBCAM) 4058c2ecf20Sopenharmony_ci mtlr r5 4068c2ecf20Sopenharmony_ci mulli r5,r3,TLBCAM_SIZE 4078c2ecf20Sopenharmony_ci add r3,r5,r4 4088c2ecf20Sopenharmony_ci lwz r4,TLBCAM_MAS0(r3) 4098c2ecf20Sopenharmony_ci mtspr SPRN_MAS0,r4 4108c2ecf20Sopenharmony_ci lwz r4,TLBCAM_MAS1(r3) 4118c2ecf20Sopenharmony_ci mtspr SPRN_MAS1,r4 4128c2ecf20Sopenharmony_ci PPC_LL r4,TLBCAM_MAS2(r3) 4138c2ecf20Sopenharmony_ci mtspr SPRN_MAS2,r4 4148c2ecf20Sopenharmony_ci lwz r4,TLBCAM_MAS3(r3) 4158c2ecf20Sopenharmony_ci mtspr SPRN_MAS3,r4 4168c2ecf20Sopenharmony_ciBEGIN_MMU_FTR_SECTION 4178c2ecf20Sopenharmony_ci lwz r4,TLBCAM_MAS7(r3) 4188c2ecf20Sopenharmony_ci mtspr SPRN_MAS7,r4 4198c2ecf20Sopenharmony_ciEND_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) 4208c2ecf20Sopenharmony_ci isync 4218c2ecf20Sopenharmony_ci tlbwe 4228c2ecf20Sopenharmony_ci isync 4238c2ecf20Sopenharmony_ci blr 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci/* 4268c2ecf20Sopenharmony_ci * Load multiple TLB entries at once, using an alternate-space 4278c2ecf20Sopenharmony_ci * trampoline so that we don't have to care about whether the same 4288c2ecf20Sopenharmony_ci * TLB entry maps us before and after. 4298c2ecf20Sopenharmony_ci * 4308c2ecf20Sopenharmony_ci * r3 = first entry to write 4318c2ecf20Sopenharmony_ci * r4 = number of entries to write 4328c2ecf20Sopenharmony_ci * r5 = temporary tlb entry 4338c2ecf20Sopenharmony_ci */ 4348c2ecf20Sopenharmony_ci_GLOBAL(loadcam_multi) 4358c2ecf20Sopenharmony_ci mflr r8 4368c2ecf20Sopenharmony_ci /* Don't switch to AS=1 if already there */ 4378c2ecf20Sopenharmony_ci mfmsr r11 4388c2ecf20Sopenharmony_ci andi. r11,r11,MSR_IS 4398c2ecf20Sopenharmony_ci bne 10f 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci /* 4428c2ecf20Sopenharmony_ci * Set up temporary TLB entry that is the same as what we're 4438c2ecf20Sopenharmony_ci * running from, but in AS=1. 4448c2ecf20Sopenharmony_ci */ 4458c2ecf20Sopenharmony_ci bl 1f 4468c2ecf20Sopenharmony_ci1: mflr r6 4478c2ecf20Sopenharmony_ci tlbsx 0,r8 4488c2ecf20Sopenharmony_ci mfspr r6,SPRN_MAS1 4498c2ecf20Sopenharmony_ci ori r6,r6,MAS1_TS 4508c2ecf20Sopenharmony_ci mtspr SPRN_MAS1,r6 4518c2ecf20Sopenharmony_ci mfspr r6,SPRN_MAS0 4528c2ecf20Sopenharmony_ci rlwimi r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK 4538c2ecf20Sopenharmony_ci mr r7,r5 4548c2ecf20Sopenharmony_ci mtspr SPRN_MAS0,r6 4558c2ecf20Sopenharmony_ci isync 4568c2ecf20Sopenharmony_ci tlbwe 4578c2ecf20Sopenharmony_ci isync 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci /* Switch to AS=1 */ 4608c2ecf20Sopenharmony_ci mfmsr r6 4618c2ecf20Sopenharmony_ci ori r6,r6,MSR_IS|MSR_DS 4628c2ecf20Sopenharmony_ci mtmsr r6 4638c2ecf20Sopenharmony_ci isync 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci10: 4668c2ecf20Sopenharmony_ci mr r9,r3 4678c2ecf20Sopenharmony_ci add r10,r3,r4 4688c2ecf20Sopenharmony_ci2: bl loadcam_entry 4698c2ecf20Sopenharmony_ci addi r9,r9,1 4708c2ecf20Sopenharmony_ci cmpw r9,r10 4718c2ecf20Sopenharmony_ci mr r3,r9 4728c2ecf20Sopenharmony_ci blt 2b 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci /* Don't return to AS=0 if we were in AS=1 at function start */ 4758c2ecf20Sopenharmony_ci andi. r11,r11,MSR_IS 4768c2ecf20Sopenharmony_ci bne 3f 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* Return to AS=0 and clear the temporary entry */ 4798c2ecf20Sopenharmony_ci mfmsr r6 4808c2ecf20Sopenharmony_ci rlwinm. r6,r6,0,~(MSR_IS|MSR_DS) 4818c2ecf20Sopenharmony_ci mtmsr r6 4828c2ecf20Sopenharmony_ci isync 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci li r6,0 4858c2ecf20Sopenharmony_ci mtspr SPRN_MAS1,r6 4868c2ecf20Sopenharmony_ci rlwinm r6,r7,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK 4878c2ecf20Sopenharmony_ci oris r6,r6,MAS0_TLBSEL(1)@h 4888c2ecf20Sopenharmony_ci mtspr SPRN_MAS0,r6 4898c2ecf20Sopenharmony_ci isync 4908c2ecf20Sopenharmony_ci tlbwe 4918c2ecf20Sopenharmony_ci isync 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci3: 4948c2ecf20Sopenharmony_ci mtlr r8 4958c2ecf20Sopenharmony_ci blr 4968c2ecf20Sopenharmony_ci#endif 497