xref: /kvm-unit-tests/lib/ppc64/asm/mmu.h (revision b9289d76b946dc45c5221e142c5473ebfff1ca86)
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 
tlbie(unsigned long rb,unsigned long rs,int ric,int prs,int r)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 
tlbiel(unsigned long rb,unsigned long rs,int ric,int prs,int r)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 
flush_tlb_page(uintptr_t vaddr)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 
flush_tlb_page_local(uintptr_t vaddr)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