[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] arm: setup MM using information from the device tree



# HG changeset patch
# User David Vrabel <david.vrabel@xxxxxxxxxx>
# Date 1329143590 0
# Node ID cbd7eab2d11208d30e7bd6a1f62791fe9675608f
# Parent  40879997c29fa71c2de3ccb67995c01c1a6daf10
arm: setup MM using information from the device tree

Setup memory management, heaps etc. using the location and size of the
first memory bank given in the device tree.

The DTB is also copied so it can be used afterwards.

Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx>
Acked-by: Tim Deegan <tim@xxxxxxx>
Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r 40879997c29f -r cbd7eab2d112 xen/arch/arm/kernel.c
--- a/xen/arch/arm/kernel.c     Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/arch/arm/kernel.c     Mon Feb 13 14:33:10 2012 +0000
@@ -11,6 +11,7 @@
 #include <xen/domain_page.h>
 #include <xen/sched.h>
 #include <asm/byteorder.h>
+#include <asm/setup.h>
 
 #include "kernel.h"
 
@@ -32,25 +33,28 @@
 
 #define DTB_MAGIC 0xd00dfeed
 
-static void copy_from_flash(void *dst, paddr_t flash, unsigned long len)
+/**
+ * copy_from_paddr - copy data from a physical address
+ * @dst: destination virtual address
+ * @paddr: source physical address
+ * @len: length to copy
+ */
+void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
 {
     void *src = (void *)FIXMAP_ADDR(FIXMAP_MISC);
 
-    printk("Copying %#lx bytes from flash %"PRIpaddr" to %p",
-           len, flash, dst);
-
     while (len) {
         paddr_t p;
         unsigned long l, s;
 
-        p = flash >> PAGE_SHIFT;
-        s = flash & (PAGE_SIZE-1);
+        p = paddr >> PAGE_SHIFT;
+        s = paddr & (PAGE_SIZE-1);
         l = min(PAGE_SIZE - s, len);
 
         set_fixmap(FIXMAP_MISC, p, DEV_SHARED);
         memcpy(dst, src + s, l);
 
-        flash += l;
+        paddr += l;
         dst += l;
         len -= l;
     }
@@ -108,7 +112,7 @@
     /*
      * Check for an appended DTB.
      */
-    copy_from_flash(&dtb_hdr, KERNEL_FLASH_ADDRESS + end - start, 
sizeof(dtb_hdr));
+    copy_from_paddr(&dtb_hdr, KERNEL_FLASH_ADDRESS + end - start, 
sizeof(dtb_hdr));
     if (be32_to_cpu(dtb_hdr.magic) == DTB_MAGIC) {
         end += be32_to_cpu(dtb_hdr.total_size);
     }
@@ -150,7 +154,7 @@
     if ( info->kernel_img == NULL )
         panic("Cannot allocate temporary buffer for kernel.\n");
 
-    copy_from_flash(info->kernel_img, KERNEL_FLASH_ADDRESS, KERNEL_FLASH_SIZE);
+    copy_from_paddr(info->kernel_img, KERNEL_FLASH_ADDRESS, KERNEL_FLASH_SIZE);
 
     if ( (rc = elf_init(&info->elf.elf, info->kernel_img, KERNEL_FLASH_SIZE )) 
!= 0 )
         return rc;
diff -r 40879997c29f -r cbd7eab2d112 xen/arch/arm/mm.c
--- a/xen/arch/arm/mm.c Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/arch/arm/mm.c Mon Feb 13 14:33:10 2012 +0000
@@ -39,6 +39,7 @@
 unsigned long xenheap_mfn_start, xenheap_mfn_end;
 unsigned long xenheap_virt_end;
 
+unsigned long frametable_base_mfn;
 unsigned long frametable_virt_end;
 
 /* Map a 4k page in a fixmap entry */
@@ -301,6 +302,8 @@
     unsigned long frametable_size = nr_pages * sizeof(struct page_info);
     unsigned long base_mfn;
 
+    frametable_base_mfn = ps >> PAGE_SHIFT;
+
     /* Round up to 32M boundary */
     frametable_size = (frametable_size + 0x1ffffff) & ~0x1ffffff;
     base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 5);
diff -r 40879997c29f -r cbd7eab2d112 xen/arch/arm/setup.c
--- a/xen/arch/arm/setup.c      Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/arch/arm/setup.c      Mon Feb 13 14:33:10 2012 +0000
@@ -64,17 +64,90 @@
         /* TODO: setup_idle_pagetable(); */
 }
 
+static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
+{
+    paddr_t ram_start;
+    paddr_t ram_end;
+    paddr_t ram_size;
+    unsigned long ram_pages;
+    unsigned long heap_pages, xenheap_pages, domheap_pages;
+    unsigned long dtb_pages;
+    unsigned long boot_mfn_start, boot_mfn_end;
+
+    /*
+     * TODO: only using the first RAM bank for now.  The heaps and the
+     * frame table assume RAM is physically contiguous.
+     */
+    ram_start = early_info.mem.bank[0].start;
+    ram_size  = early_info.mem.bank[0].size;
+    ram_end = ram_start + ram_size;
+    ram_pages = ram_size >> PAGE_SHIFT;
+
+    /*
+     * Calculate the sizes for the heaps using these constraints:
+     *
+     *  - heaps must be 32 MiB aligned
+     *  - must not include Xen itself
+     *  - xen heap must be at most 1 GiB
+     *
+     * XXX: needs a platform with at least 1GiB of RAM or the dom
+     * heap will be empty and no domains can be created.
+     */
+    heap_pages = (ram_size >> PAGE_SHIFT) - (32 << (20 - PAGE_SHIFT));
+    xenheap_pages = min(1ul << (30 - PAGE_SHIFT), heap_pages);
+    domheap_pages = heap_pages - xenheap_pages;
+
+    printk("Xen heap: %lu pages  Dom heap: %lu pages\n", xenheap_pages, 
domheap_pages);
+
+    setup_xenheap_mappings(ram_start >> PAGE_SHIFT, xenheap_pages);
+
+    /*
+     * Need a single mapped page for populating bootmem_region_list
+     * and 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;
+    boot_mfn_start = xenheap_mfn_end - dtb_pages - 1;
+    boot_mfn_end = xenheap_mfn_end;
+
+    init_boot_pages(pfn_to_paddr(boot_mfn_start), pfn_to_paddr(boot_mfn_end));
+
+    /*
+     * 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);
+
+    /* Add non-xenheap memory */
+    init_boot_pages(pfn_to_paddr(xenheap_mfn_start + xenheap_pages),
+                    pfn_to_paddr(xenheap_mfn_start + xenheap_pages + 
domheap_pages));
+
+    setup_frametable_mappings(ram_start, ram_end);
+
+    /* Add xenheap memory that was not already added to the boot
+       allocator. */
+    init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start),
+                       pfn_to_paddr(boot_mfn_start));
+
+    end_boot_allocator();
+}
+
 void __init start_xen(unsigned long boot_phys_offset,
                       unsigned long arm_type,
                       unsigned long atag_paddr)
 
 {
     void *fdt;
+    size_t fdt_size;
     int i;
 
     fdt = (void *)BOOT_MISC_VIRT_START
         + (atag_paddr & ((1 << SECOND_SHIFT) - 1));
-    device_tree_early_init(fdt);
+    fdt_size = device_tree_early_init(fdt);
 
     setup_pagetables(boot_phys_offset);
 
@@ -98,28 +171,7 @@
 
     init_xen_time();
 
-    /* TODO: This needs some thought, as well as device-tree mapping.
-     * For testing, assume that the whole xenheap is contiguous in RAM */
-    setup_xenheap_mappings(0x8000000, 0x40000); /* 1 GB @ 512GB */
-    /* Must pass a single mapped page for populating bootmem_region_list. */
-    init_boot_pages(pfn_to_paddr(xenheap_mfn_start),
-                    pfn_to_paddr(xenheap_mfn_start+1));
-
-    /* Add non-xenheap memory */
-    init_boot_pages(0x8040000000, 0x80c0000000); /* 2 GB @513GB */
-
-    /* TODO Make sure Xen's own pages aren't added
-     *     -- the memory above doesn't include our relocation target.  */
-    /* TODO Handle payloads too */
-
-    /* TODO Need to find actual memory, for now use 4GB at 512GB */
-    setup_frametable_mappings(0x8000000000ULL, 0x8100000000UL);
-
-    /* Add xenheap memory */
-    init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start+1),
-                       pfn_to_paddr(xenheap_mfn_end));
-
-    end_boot_allocator();
+    setup_mm(atag_paddr, fdt_size);
 
     /* Setup Hyp vector base */
     WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR);
diff -r 40879997c29f -r cbd7eab2d112 xen/common/device_tree.c
--- a/xen/common/device_tree.c  Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/common/device_tree.c  Mon Feb 13 14:33:10 2012 +0000
@@ -22,6 +22,7 @@
 #include <libfdt.h>
 
 struct dt_early_info __initdata early_info;
+void *device_tree_flattened;
 
 static void __init get_val(const u32 **cell, u32 cells, u64 *val)
 {
@@ -126,8 +127,10 @@
 /**
  * device_tree_early_init - initialize early info from a DTB
  * @fdt: flattened device tree binary
+ *
+ * Returns the size of the DTB.
  */
-void __init device_tree_early_init(const void *fdt)
+size_t __init device_tree_early_init(const void *fdt)
 {
     int ret;
 
@@ -137,6 +140,8 @@
 
     early_scan(fdt);
     early_print_info();
+
+    return fdt_totalsize(fdt);
 }
 
 /**
diff -r 40879997c29f -r cbd7eab2d112 xen/include/asm-arm/mm.h
--- a/xen/include/asm-arm/mm.h  Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/include/asm-arm/mm.h  Mon Feb 13 14:33:10 2012 +0000
@@ -128,6 +128,8 @@
     struct page_info *page, int readonly);
 
 #define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
+/* MFN of the first page in the frame table. */
+extern unsigned long frametable_base_mfn;
 
 extern unsigned long max_page;
 extern unsigned long total_pages;
@@ -151,15 +153,14 @@
 })
 
 #define max_pdx                 max_page
-/* XXX Assume everything in the 40-bit physical alias 0x8000000000 for now */
-#define pfn_to_pdx(pfn)         ((pfn) - 0x8000000UL)
-#define pdx_to_pfn(pdx)         ((pdx) + 0x8000000UL)
+#define pfn_to_pdx(pfn)         (pfn)
+#define pdx_to_pfn(pdx)         (pdx)
 #define virt_to_pdx(va)         virt_to_mfn(va)
 #define pdx_to_virt(pdx)        mfn_to_virt(pdx)
 
 /* Convert between machine frame numbers and page-info structures. */
-#define mfn_to_page(mfn)  (frame_table + pfn_to_pdx(mfn))
-#define page_to_mfn(pg)   pdx_to_pfn((unsigned long)((pg) - frame_table))
+#define mfn_to_page(mfn)  (frame_table + (pfn_to_pdx(mfn) - 
frametable_base_mfn))
+#define page_to_mfn(pg)   pdx_to_pfn((unsigned long)((pg) - frame_table) + 
frametable_base_mfn)
 #define __page_to_mfn(pg)  page_to_mfn(pg)
 #define __mfn_to_page(mfn) mfn_to_page(mfn)
 
diff -r 40879997c29f -r cbd7eab2d112 xen/include/asm-arm/setup.h
--- a/xen/include/asm-arm/setup.h       Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/include/asm-arm/setup.h       Mon Feb 13 14:33:10 2012 +0000
@@ -3,6 +3,8 @@
 
 #include <public/version.h>
 
+void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
+
 void arch_get_xen_caps(xen_capabilities_info_t *info);
 
 int construct_dom0(struct domain *d);
diff -r 40879997c29f -r cbd7eab2d112 xen/include/xen/device_tree.h
--- a/xen/include/xen/device_tree.h     Mon Feb 13 14:24:49 2012 +0000
+++ b/xen/include/xen/device_tree.h     Mon Feb 13 14:33:10 2012 +0000
@@ -29,8 +29,9 @@
 };
 
 extern struct dt_early_info early_info;
+extern void *device_tree_flattened;
 
-void device_tree_early_init(const void *fdt);
+size_t device_tree_early_init(const void *fdt);
 paddr_t device_tree_get_xen_paddr(void);
 
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.