[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 5/6] xen/riscv: implement relocate_fdt()
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@xxxxxxxxx> --- 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(-) diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h index 699ed23f0d..25fd38531f 100644 --- a/xen/arch/riscv/include/asm/mm.h +++ b/xen/arch/riscv/include/asm/mm.h @@ -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); } /* diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h index 0f297141d3..c245a4273f 100644 --- a/xen/arch/riscv/include/asm/page.h +++ b/xen/arch/riscv/include/asm/page.h @@ -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. */ diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index f2bf279bac..c614d547a6 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -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); } diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index 9680332fee..ff667260ec 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -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) { -- 2.47.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |