From 4e6714686495f5446c85228aaa6ffe525029d4e3 Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Wed, 8 May 2013 23:33:23 +0100 Subject: xen/arm: Introduce ioremap_attr, ioremap_cache, ioremap_nocache, ioremap_wc Map physical range in virtual memory with a specific mapping attribute. Also add new mapping attributes for ARM: PAGE_HYPERVISOR_NOCACHE and PAGE_HYPERVISOR_WC. This function replaces early_ioremap which is only able to deal with 2Mb aligned mapping. Therefore, vmap initialization has been moved earlier. Signed-off-by: Julien Grall Acked-by: Ian Campbell --- xen/arch/arm/mm.c | 48 ++++++++++++------------------------------- xen/arch/arm/setup.c | 4 ++-- xen/drivers/video/arm_hdlcd.c | 2 +- xen/include/asm-arm/mm.h | 19 +++++++++++++++-- xen/include/asm-arm/page.h | 2 ++ 5 files changed, 35 insertions(+), 40 deletions(-) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index bd7eb1afa3..d1290cd366 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -38,6 +38,7 @@ #include #include #include +#include struct domain *dom_xen, *dom_io, *dom_cow; @@ -567,45 +568,22 @@ void __init setup_frametable_mappings(paddr_t ps, paddr_t pe) frametable_virt_end = FRAMETABLE_VIRT_START + (nr_pages * sizeof(struct page_info)); } -/* Map the physical memory range start - start + len into virtual - * memory and return the virtual address of the mapping. - * start has to be 2MB aligned. - * len has to be < VMAP_VIRT_END - VMAP_VIRT_START. - */ -static __initdata unsigned long early_vmap_start = VMAP_VIRT_END; -void* __init early_ioremap(paddr_t start, size_t len, unsigned attributes) +void *__init arch_vmap_virt_end(void) { - paddr_t end = start + len; - unsigned long map_start; - - len = (len + SECOND_SIZE - 1) & ~SECOND_MASK; - early_vmap_start -= len; - - ASSERT(!(start & (~SECOND_MASK))); - ASSERT(!(early_vmap_start & (~SECOND_MASK))); - - /* The range we need to map is too big */ - if ( early_vmap_start >= VMAP_VIRT_START ) - return NULL; - - map_start = early_vmap_start; - while ( start < end ) - { - lpae_t e = mfn_to_xen_entry(start >> PAGE_SHIFT); - e.pt.ai = attributes; - write_pte(xen_second + second_table_offset(map_start), e); - - start += SECOND_SIZE; - map_start += SECOND_SIZE; - } - flush_xen_data_tlb_range_va(early_vmap_start, len); - - return (void*)early_vmap_start; + return (void *)VMAP_VIRT_END; } -void *__init arch_vmap_virt_end(void) +/* + * This function should only be used to remap device address ranges + * TODO: add a check to verify this assumption + */ +void *ioremap_attr(paddr_t pa, size_t len, unsigned int attributes) { - return (void *)early_vmap_start; + unsigned long pfn = PFN_DOWN(pa); + unsigned int offs = pa & (PAGE_SIZE - 1); + unsigned int nr = PFN_UP(offs + len); + + return (__vmap(&pfn, nr, 1, 1, attributes) + offs); } static int create_xen_table(lpae_t *entry) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 29447effca..a667db4b4c 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -429,6 +429,8 @@ void __init start_xen(unsigned long boot_phys_offset, setup_pagetables(boot_phys_offset, get_xen_paddr()); setup_mm(fdt_paddr, fdt_size); + vm_init(); + #ifdef EARLY_UART_ADDRESS /* TODO Need to get device tree or command line for UART address */ pl011_init(0, FIXMAP_ADDR(FIXMAP_CONSOLE)); @@ -483,8 +485,6 @@ void __init start_xen(unsigned long boot_phys_offset, console_init_postirq(); - vm_init(); - do_presmp_initcalls(); for_each_present_cpu ( i ) diff --git a/xen/drivers/video/arm_hdlcd.c b/xen/drivers/video/arm_hdlcd.c index d0ec13d7c2..72979ea99f 100644 --- a/xen/drivers/video/arm_hdlcd.c +++ b/xen/drivers/video/arm_hdlcd.c @@ -211,7 +211,7 @@ void __init video_init(void) printk(KERN_INFO "Initializing HDLCD driver\n"); - lfb = early_ioremap(framebuffer_start, framebuffer_size, DEV_WC); + lfb = ioremap_wc(framebuffer_start, framebuffer_size); if ( !lfb ) { printk(KERN_ERR "Couldn't map the framebuffer\n"); diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index 26c271e747..63e1069aef 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -153,8 +153,23 @@ extern void setup_frametable_mappings(paddr_t ps, paddr_t pe); extern void set_fixmap(unsigned map, unsigned long mfn, unsigned attributes); /* Remove a mapping from a fixmap entry */ extern void clear_fixmap(unsigned map); -/* map a 2MB aligned physical range in virtual memory. */ -void* early_ioremap(paddr_t start, size_t len, unsigned attributes); +/* map a physical range in virtual memory */ +void __iomem *ioremap_attr(paddr_t start, size_t len, unsigned attributes); + +static inline void __iomem *ioremap_nocache(paddr_t start, size_t len) +{ + return ioremap_attr(start, len, PAGE_HYPERVISOR_NOCACHE); +} + +static inline void __iomem *ioremap_cache(paddr_t start, size_t len) +{ + return ioremap_attr(start, len, PAGE_HYPERVISOR); +} + +static inline void __iomem *ioremap_wc(paddr_t start, size_t len) +{ + return ioremap_attr(start, len, PAGE_HYPERVISOR_WC); +} #define mfn_valid(mfn) ({ \ unsigned long __m_f_n = (mfn); \ diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h index fd6946e3fd..13fbd788af 100644 --- a/xen/include/asm-arm/page.h +++ b/xen/include/asm-arm/page.h @@ -59,6 +59,8 @@ #define DEV_CACHED WRITEBACK #define PAGE_HYPERVISOR (MATTR_MEM) +#define PAGE_HYPERVISOR_NOCACHE (DEV_SHARED) +#define PAGE_HYPERVISOR_WC (DEV_WC) #define MAP_SMALL_PAGES PAGE_HYPERVISOR /* -- cgit v1.2.3