1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 #ifndef _ASMPOWERPC_MMU_H_ 3 #define _ASMPOWERPC_MMU_H_ 4 5 #include <asm/pgtable.h> 6 7 bool mmu_enabled(void); 8 void mmu_enable(pgd_t *pgtable); 9 void mmu_disable(void); 10 11 static inline void tlbie(unsigned long rb, unsigned long rs, int ric, int prs, int r) 12 { 13 /* MMU is radix (>= POWER9), so can use P9 tlbie directly */ 14 asm volatile( 15 " .machine push \n" 16 " .machine power9 \n" 17 " ptesync \n" 18 " tlbie %0,%1,%2,%3,%4 \n" 19 " eieio \n" 20 " tlbsync \n" 21 " ptesync \n" 22 " .machine pop " 23 :: "r"(rb), "r"(rs), "i"(ric), "i"(prs), "i"(r) : "memory"); 24 } 25 26 static inline void tlbiel(unsigned long rb, unsigned long rs, int ric, int prs, int r) 27 { 28 asm volatile( 29 " .machine push \n" 30 " .machine power9 \n" 31 " ptesync \n" 32 " tlbiel %0,%1,%2,%3,%4 \n" 33 " ptesync \n" 34 " .machine pop " 35 :: "r"(rb), "r"(rs), "i"(ric), "i"(prs), "i"(r) : "memory"); 36 } 37 38 static inline void flush_tlb_page(uintptr_t vaddr) 39 { 40 unsigned long rb; 41 unsigned long rs = (1ULL << 32); /* pid */ 42 unsigned long ap; 43 44 /* AP should come from dt (for pseries, at least) */ 45 if (PAGE_SIZE == SZ_4K) 46 ap = 0; 47 else if (PAGE_SIZE == SZ_64K) 48 ap = 5; 49 else if (PAGE_SIZE == SZ_2M) 50 ap = 1; 51 else if (PAGE_SIZE == SZ_1G) 52 ap = 2; 53 else 54 assert(0); 55 56 rb = vaddr & ~((1UL << 12) - 1); 57 rb |= ap << 5; 58 59 tlbie(rb, rs, 0, 1, 1); 60 } 61 62 static inline void flush_tlb_page_local(uintptr_t vaddr) 63 { 64 unsigned long rb; 65 unsigned long rs = (1ULL << 32); /* pid */ 66 unsigned long ap; 67 68 /* AP should come from dt (for pseries, at least) */ 69 if (PAGE_SIZE == SZ_4K) 70 ap = 0; 71 else if (PAGE_SIZE == SZ_64K) 72 ap = 5; 73 else if (PAGE_SIZE == SZ_2M) 74 ap = 1; 75 else if (PAGE_SIZE == SZ_1G) 76 ap = 2; 77 else 78 assert(0); 79 80 rb = vaddr & ~((1UL << 12) - 1); 81 rb |= ap << 5; 82 83 tlbiel(rb, rs, 0, 1, 1); 84 } 85 86 #endif 87