Files
xen/xen/arch/riscv/include/asm/page.h
T
Oleksii Kurochko 13684f539e xen/riscv: set up fixmap mappings
Set up fixmap mappings and the L0 page table for fixmap support.

Modify the PTEs (xen_fixmap[]) directly in arch_pmap_map() instead
of using set_fixmap() which is expected to be implemented using
map_pages_to_xen(), which, in turn, is expected to use
arch_pmap_map() during early boot, resulting in a loop.

Define new macros in riscv/config.h for calculating
the FIXMAP_BASE address, including BOOT_FDT_VIRT_{START, SIZE},
XEN_VIRT_SIZE, and XEN_VIRT_END.

Update the check for Xen size in riscv/xen.lds.S to use
XEN_VIRT_SIZE instead of a hardcoded constant.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2024-09-30 10:08:51 +02:00

100 lines
2.6 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_RISCV_PAGE_H
#define _ASM_RISCV_PAGE_H
#ifndef __ASSEMBLY__
#include <xen/const.h>
#include <xen/bug.h>
#include <xen/types.h>
#include <asm/atomic.h>
#include <asm/mm.h>
#include <asm/page-bits.h>
#define VPN_MASK (PAGETABLE_ENTRIES - 1UL)
#define XEN_PT_LEVEL_ORDER(lvl) ((lvl) * PAGETABLE_ORDER)
#define XEN_PT_LEVEL_SHIFT(lvl) (XEN_PT_LEVEL_ORDER(lvl) + PAGE_SHIFT)
#define XEN_PT_LEVEL_SIZE(lvl) (_AT(paddr_t, 1) << XEN_PT_LEVEL_SHIFT(lvl))
#define XEN_PT_LEVEL_MAP_MASK(lvl) (~(XEN_PT_LEVEL_SIZE(lvl) - 1))
#define XEN_PT_LEVEL_MASK(lvl) (VPN_MASK << XEN_PT_LEVEL_SHIFT(lvl))
#define PTE_VALID BIT(0, UL)
#define PTE_READABLE BIT(1, UL)
#define PTE_WRITABLE BIT(2, UL)
#define PTE_EXECUTABLE BIT(3, UL)
#define PTE_USER BIT(4, UL)
#define PTE_GLOBAL BIT(5, UL)
#define PTE_ACCESSED BIT(6, UL)
#define PTE_DIRTY BIT(7, UL)
#define PTE_RSW (BIT(8, UL) | BIT(9, UL))
#define PTE_LEAF_DEFAULT (PTE_VALID | PTE_READABLE | PTE_WRITABLE)
#define PTE_TABLE (PTE_VALID)
#define PAGE_HYPERVISOR_RW (PTE_VALID | PTE_READABLE | PTE_WRITABLE)
#define PAGE_HYPERVISOR PAGE_HYPERVISOR_RW
/* Calculate the offsets into the pagetables for a given VA */
#define pt_linear_offset(lvl, va) ((va) >> XEN_PT_LEVEL_SHIFT(lvl))
#define pt_index(lvl, va) (pt_linear_offset((lvl), (va)) & VPN_MASK)
/* Page Table entry */
typedef struct {
#ifdef CONFIG_RISCV_64
uint64_t pte;
#else
uint32_t pte;
#endif
} pte_t;
static inline pte_t paddr_to_pte(paddr_t paddr,
unsigned int permissions)
{
return (pte_t) { .pte = (paddr_to_pfn(paddr) << PTE_PPN_SHIFT) | permissions };
}
static inline paddr_t pte_to_paddr(pte_t pte)
{
return pfn_to_paddr(pte.pte >> PTE_PPN_SHIFT);
}
static inline bool pte_is_valid(pte_t p)
{
return p.pte & PTE_VALID;
}
static inline void invalidate_icache(void)
{
BUG_ON("unimplemented");
}
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define copy_page(dp, sp) memcpy(dp, sp, PAGE_SIZE)
/* TODO: Flush the dcache for an entire page. */
static inline void flush_page_to_ram(unsigned long mfn, bool sync_icache)
{
BUG_ON("unimplemented");
}
/* Write a pagetable entry. */
static inline void write_pte(pte_t *p, pte_t pte)
{
write_atomic(p, pte);
}
/* Read a pagetable entry. */
static inline pte_t read_pte(const pte_t *p)
{
return read_atomic(p);
}
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_PAGE_H */