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