xref: /kvm-unit-tests/lib/riscv/asm/mmu.h (revision 6b801c8981f74d75419d77e031dd37f5ad356efe)
1ad435a71SAndrew Jones /* SPDX-License-Identifier: GPL-2.0-only */
2ad435a71SAndrew Jones #ifndef _ASMRISCV_MMU_H_
3ad435a71SAndrew Jones #define _ASMRISCV_MMU_H_
4ad435a71SAndrew Jones #include <libcflat.h>
5ad435a71SAndrew Jones #include <asm/csr.h>
6ad435a71SAndrew Jones #include <asm/page.h>
7ad435a71SAndrew Jones #include <asm/pgtable.h>
8ad435a71SAndrew Jones 
912e0faacSAndrew Jones #define PHYS_MASK	((phys_addr_t)SATP_PPN << PAGE_SHIFT | (PAGE_SIZE - 1))
10*88f594c8SAndrew Jones #define PHYS_PAGE_MASK	(~((phys_addr_t)PAGE_SIZE - 1))
1112e0faacSAndrew Jones 
current_pgtable(void)12ad435a71SAndrew Jones static inline pgd_t *current_pgtable(void)
13ad435a71SAndrew Jones {
14ad435a71SAndrew Jones 	return (pgd_t *)((csr_read(CSR_SATP) & SATP_PPN) << PAGE_SHIFT);
15ad435a71SAndrew Jones }
16ad435a71SAndrew Jones 
17ad435a71SAndrew Jones void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset,
18ad435a71SAndrew Jones 			phys_addr_t phys_start, phys_addr_t phys_end,
19ad435a71SAndrew Jones 			pgprot_t prot, bool flush);
20ad435a71SAndrew Jones void __mmu_enable(unsigned long satp);
21ad435a71SAndrew Jones void mmu_enable(unsigned long mode, pgd_t *pgtable);
22ad435a71SAndrew Jones void mmu_disable(void);
23ad435a71SAndrew Jones 
local_flush_tlb_page(unsigned long addr)24ad435a71SAndrew Jones static inline void local_flush_tlb_page(unsigned long addr)
25ad435a71SAndrew Jones {
26ad435a71SAndrew Jones 	asm volatile("sfence.vma %0" : : "r" (addr) : "memory");
27ad435a71SAndrew Jones }
28ad435a71SAndrew Jones 
29ad435a71SAndrew Jones /*
30ad435a71SAndrew Jones  * Get the pte pointer for a virtual address, even if it's not mapped.
31ad435a71SAndrew Jones  * Constructs upper levels of the table as necessary.
32ad435a71SAndrew Jones  */
33ad435a71SAndrew Jones pte_t *get_pte(pgd_t *pgtable, uintptr_t vaddr);
34ad435a71SAndrew Jones 
35ad435a71SAndrew Jones #endif /* _ASMRISCV_MMU_H_ */
36