diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2013-08-08 13:15:17 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2013-08-20 15:44:36 +0100 |
commit | 5263507b1b4ad5417871d8297f315d7b204426d4 (patch) | |
tree | 7c40030cb93096fe8c7a30d2d65f91c17462d697 /xen/arch/arm/setup.c | |
parent | 2c092bb6ee902997363b338cde447fe11b3a75c6 (diff) | |
download | xen-5263507b1b4ad5417871d8297f315d7b204426d4.tar.gz xen-5263507b1b4ad5417871d8297f315d7b204426d4.tar.bz2 xen-5263507b1b4ad5417871d8297f315d7b204426d4.zip |
xen: arm: Use a direct mapping of RAM on arm64
We have plenty of virtual address space so we can avoid needing to map and
unmap pages all the time.
A totally arbitrarily chosen 32GB frame table leads to support for 5TB of RAM.
I haven't tested with anything near that amount of RAM though. There is plenty
of room to expand further when that becomes necessary.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'xen/arch/arm/setup.c')
-rw-r--r-- | xen/arch/arm/setup.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index b184721f0c..f8a3d04583 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -278,6 +278,7 @@ static paddr_t __init get_xen_paddr(void) return paddr; } +#ifdef CONFIG_ARM_32 static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) { paddr_t ram_start; @@ -402,6 +403,82 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) end_boot_allocator(); } +#else /* CONFIG_ARM_64 */ +static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) +{ + paddr_t ram_start = ~0; + paddr_t ram_end = 0; + int bank; + unsigned long xenheap_pages = 0; + unsigned long dtb_pages; + + total_pages = 0; + for ( bank = 0 ; bank < early_info.mem.nr_banks; bank++ ) + { + paddr_t bank_start = early_info.mem.bank[bank].start; + paddr_t bank_size = early_info.mem.bank[bank].size; + paddr_t bank_end = bank_start + bank_size; + unsigned long bank_pages = bank_size >> PAGE_SHIFT; + paddr_t s, e; + + total_pages += bank_pages; + + if ( bank_start < ram_start ) + ram_start = bank_start; + if ( bank_end > ram_end ) + ram_end = bank_end; + + xenheap_pages += (bank_size >> PAGE_SHIFT); + + /* XXX we assume that the ram regions are ordered */ + s = bank_start; + while ( s < bank_end ) + { + paddr_t n = bank_end; + + e = next_module(s, &n); + + if ( e == ~(paddr_t)0 ) + { + e = n = bank_end; + } + + setup_xenheap_mappings(s>>PAGE_SHIFT, (e-s)>>PAGE_SHIFT); + + xenheap_mfn_end = e; + + init_boot_pages(s, e); + s = n; + } + } + + xenheap_virt_end = XENHEAP_VIRT_START + ram_end - ram_start; + xenheap_mfn_start = ram_start >> PAGE_SHIFT; + xenheap_mfn_end = ram_end >> PAGE_SHIFT; + xenheap_max_mfn(xenheap_mfn_end); + + /* + * Need enough mapped pages for copying the DTB. + * + * TODO: The DTB (and other payloads) are assumed to be towards + * the start of RAM. + */ + dtb_pages = (dtb_size + PAGE_SIZE-1) >> PAGE_SHIFT; + + /* + * Copy the DTB. + * + * TODO: handle other payloads too. + */ + device_tree_flattened = mfn_to_virt(alloc_boot_pages(dtb_pages, 1)); + copy_from_paddr(device_tree_flattened, dtb_paddr, dtb_size, BUFFERABLE); + + setup_frametable_mappings(ram_start, ram_end); + max_page = PFN_DOWN(ram_end); + + end_boot_allocator(); +} +#endif size_t __read_mostly cacheline_bytes; |