mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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 <julien.grall@linaro.org> Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
1 parent
73a6a932d6
commit
4e67146864
5 files changed
+37
-42
No files matched your search
+15
-37
@@ -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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void *__init arch_vmap_virt_end(void)
|
||||
{
|
||||
return (void *)early_vmap_start;
|
||||
return (void *)VMAP_VIRT_END;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||