@@ -8,11 +8,13 @@
#include <xen/const.h>
#include <xen/mm-frame.h>
#include <xen/pdx.h>
+#include <xen/pfn.h>
#include <xen/types.h>
#include <asm/page-bits.h>
extern vaddr_t directmap_virt_start;
+extern vaddr_t directmap_virt_end;
#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT)
#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT))
@@ -148,8 +150,12 @@ static inline void *page_to_virt(const struct page_info *pg)
/* Convert between Xen-heap virtual addresses and page-info structures. */
static inline struct page_info *virt_to_page(const void *v)
{
- BUG_ON("unimplemented");
- return NULL;
+ unsigned long va = (unsigned long)v;
+
+ ASSERT(va >= DIRECTMAP_VIRT_START);
+ ASSERT(va <= directmap_virt_end);
+
+ return frametable_virt_start + PFN_DOWN(va - directmap_virt_start);
}
/*
@@ -7,6 +7,7 @@
#include <xen/bug.h>
#include <xen/const.h>
+#include <xen/domain_page.h>
#include <xen/errno.h>
#include <xen/types.h>
@@ -172,10 +173,15 @@ static inline void invalidate_icache(void)
#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");
+ void *v = map_domain_page(_mfn(mfn));
+
+ clean_and_invalidate_dcache_va_range(v, PAGE_SIZE);
+ unmap_domain_page(v);
+
+ if ( sync_icache )
+ invalidate_icache();
}
/* Write a pagetable entry. */
@@ -419,6 +419,7 @@ void * __init early_fdt_map(paddr_t fdt_paddr)
}
vaddr_t __ro_after_init directmap_virt_start = DIRECTMAP_VIRT_START;
+vaddr_t __ro_after_init directmap_virt_end;
struct page_info *__ro_after_init frametable_virt_start = frame_table;
@@ -556,6 +557,8 @@ void __init setup_mm(void)
setup_directmap_mappings(PFN_DOWN(bank_start), PFN_DOWN(bank_size));
}
+ directmap_virt_end = directmap_virt_start + ram_end - 1;
+
setup_frametable_mappings(ram_start, ram_end);
max_page = PFN_DOWN(ram_end);
}
@@ -12,6 +12,7 @@
#include <public/version.h>
#include <asm/early_printk.h>
+#include <asm/fixmap.h>
#include <asm/sbi.h>
#include <asm/setup.h>
#include <asm/smp.h>
@@ -26,6 +27,46 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
__aligned(STACK_SIZE);
+/**
+ * copy_from_paddr - copy data from a physical address
+ * @dst: destination virtual address
+ * @paddr: source physical address
+ * @len: length to copy
+ */
+void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
+{
+ void *src = (void *)FIXMAP_ADDR(FIX_MISC);
+
+ while (len) {
+ unsigned long l, s;
+
+ s = paddr & (PAGE_SIZE - 1);
+ l = min(PAGE_SIZE - s, len);
+
+ set_fixmap(FIX_MISC, maddr_to_mfn(paddr), PAGE_HYPERVISOR_RW);
+ memcpy(dst, src + s, l);
+ clean_dcache_va_range(dst, l);
+ clear_fixmap(FIX_MISC);
+
+ paddr += l;
+ dst += l;
+ len -= l;
+ }
+}
+
+/* Relocate the FDT in Xen heap */
+static void * __init relocate_fdt(paddr_t dtb_paddr, size_t dtb_size)
+{
+ void *fdt = xmalloc_bytes(dtb_size);
+
+ if ( !fdt )
+ panic("Unable to allocate memory for relocating the Device-Tree.\n");
+
+ copy_from_paddr(fdt, dtb_paddr, dtb_size);
+
+ return fdt;
+}
+
void __init noreturn start_xen(unsigned long bootcpu_id,
paddr_t dtb_addr)
{
relocate_fdt() relocates FDT to Xen heap instead of using early mapping as it is expected that discard_initial_modules() ( is supposed to call in the future ) discards the FDT boot module and remove_early_mappings() destroys the early mapping. To implement that the following things are introduced as they are called by internals of xmalloc_bytes() which is used in relocate_fdt(): 1. As RISC-V may have non-coherent access for RAM ( f.e., in case of non-coherent IO devices ) flush_page_to_ram() is implemented to ensure that cache and RAM are consistent for such platforms. 2. copy_from_paddr() to copy FDT from a physical address to allocated by xmalloc_bytes() in Xen heap. 3. virt_to_page() to convert virtual address to page. Also introduce directmap_virt_end to check that VA argument of virt_to_page() is inside directmap region. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- xen/arch/riscv/include/asm/mm.h | 10 ++++++-- xen/arch/riscv/include/asm/page.h | 10 ++++++-- xen/arch/riscv/mm.c | 3 +++ xen/arch/riscv/setup.c | 41 +++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-)