blob: 2bf94e49888822a4d49c74dea6790955b57d317e [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASMPOWERPC_MMU_H_
#define _ASMPOWERPC_MMU_H_
#include <asm/pgtable.h>
bool mmu_enabled(void);
void mmu_enable(pgd_t *pgtable);
void mmu_disable(void);
static inline void tlbie(unsigned long rb, unsigned long rs, int ric, int prs, int r)
{
/* MMU is radix (>= POWER9), so can use P9 tlbie directly */
asm volatile(
" .machine push \n"
" .machine power9 \n"
" ptesync \n"
" tlbie %0,%1,%2,%3,%4 \n"
" eieio \n"
" tlbsync \n"
" ptesync \n"
" .machine pop "
:: "r"(rb), "r"(rs), "i"(ric), "i"(prs), "i"(r) : "memory");
}
static inline void tlbiel(unsigned long rb, unsigned long rs, int ric, int prs, int r)
{
asm volatile(
" .machine push \n"
" .machine power9 \n"
" ptesync \n"
" tlbiel %0,%1,%2,%3,%4 \n"
" ptesync \n"
" .machine pop "
:: "r"(rb), "r"(rs), "i"(ric), "i"(prs), "i"(r) : "memory");
}
static inline void flush_tlb_page(uintptr_t vaddr)
{
unsigned long rb;
unsigned long rs = (1ULL << 32); /* pid */
unsigned long ap;
/* AP should come from dt (for pseries, at least) */
if (PAGE_SIZE == SZ_4K)
ap = 0;
else if (PAGE_SIZE == SZ_64K)
ap = 5;
else if (PAGE_SIZE == SZ_2M)
ap = 1;
else if (PAGE_SIZE == SZ_1G)
ap = 2;
else
assert(0);
rb = vaddr & ~((1UL << 12) - 1);
rb |= ap << 5;
tlbie(rb, rs, 0, 1, 1);
}
static inline void flush_tlb_page_local(uintptr_t vaddr)
{
unsigned long rb;
unsigned long rs = (1ULL << 32); /* pid */
unsigned long ap;
/* AP should come from dt (for pseries, at least) */
if (PAGE_SIZE == SZ_4K)
ap = 0;
else if (PAGE_SIZE == SZ_64K)
ap = 5;
else if (PAGE_SIZE == SZ_2M)
ap = 1;
else if (PAGE_SIZE == SZ_1G)
ap = 2;
else
assert(0);
rb = vaddr & ~((1UL << 12) - 1);
rb |= ap << 5;
tlbiel(rb, rs, 0, 1, 1);
}
#endif