xen/arm: Introduce ioremap_attr, ioremap_cache, ioremap_nocache, ioremap_wc
authorJulien Grall <julien.grall@linaro.org>
Wed, 8 May 2013 22:33:23 +0000 (23:33 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Mon, 13 May 2013 10:59:56 +0000 (11:59 +0100)
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 <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/mm.c
xen/arch/arm/setup.c
xen/drivers/video/arm_hdlcd.c
xen/include/asm-arm/mm.h
xen/include/asm-arm/page.h

index bd7eb1afa36e16e2eb6809780cfead64eed673b1..d1290cd366ef5ce232176830f849339fbc7a83ef 100644 (file)
@@ -38,6 +38,7 @@
 #include <xen/sched.h>
 #include <xen/vmap.h>
 #include <xsm/xsm.h>
+#include <xen/pfn.h>
 
 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)
index 29447effca6a109fe8fd154074f4ee1a171c41ff..a667db4b4c13fbb4acd1f2c1dfed785eb2b4f9ec 100644 (file)
@@ -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 )
index d0ec13d7c20843b9b47ecb8fa9502f007abbd908..72979ea99f9a6d110d4292358ff75cd058f502eb 100644 (file)
@@ -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");
index 26c271e747b1f8e8ebedf238d51e965d089fb904..63e1069aef5fb58eb2394390fcec793dba1aadf1 100644 (file)
@@ -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);                                            \
index fd6946e3fdf60db3a17ba0a96c1d036e99e45187..13fbd788af505950ff154a779693af87cfb4faab 100644 (file)
@@ -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
 
 /*