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

[Xen-devel] [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT



Signed-off-by: Thomas Leonard <talex5@xxxxxxxxx>
---
 extras/mini-os/arch/arm/mm.c    | 70 ++++++++++++++++++++++++++++++++++++++---
 extras/mini-os/arch/arm/setup.c | 12 ++++++-
 extras/mini-os/include/arm/os.h |  2 ++
 extras/mini-os/mm.c             |  4 +--
 4 files changed, 80 insertions(+), 8 deletions(-)

diff --git a/extras/mini-os/arch/arm/mm.c b/extras/mini-os/arch/arm/mm.c
index bb6aa0e..be8e747 100644
--- a/extras/mini-os/arch/arm/mm.c
+++ b/extras/mini-os/arch/arm/mm.c
@@ -1,5 +1,7 @@
 #include <console.h>
 #include <arch_mm.h>
+#include <libfdt.h>
+#include <lib.h>
 
 #define PHYS_START (0x80008000 + (1000 * 4 * 1024))
 #define PHYS_SIZE (40*1024*1024)
@@ -25,12 +27,70 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned 
long* max_pfn_p)
     printk("    stack start: %p(VA)\n", stack);
     printk("    _end: %p(VA)\n", &_end);
 
-    // FIXME Get from dt!
-    *start_pfn_p = (((unsigned long)&_end) >> PAGE_SHIFT) + 1000;
-    *max_pfn_p = ((unsigned long)&_end + PHYS_SIZE) >> PAGE_SHIFT;
+    *start_pfn_p = 0;
+    *max_pfn_p = 0;
 
-    printk("    start_pfn: %lx\n", *start_pfn_p);
-    printk("    max_pfn: %lx\n", *max_pfn_p);
+    if (fdt_num_mem_rsv(device_tree) != 0)
+        printk("WARNING: reserved memory not supported!\n");
+
+    int node = 0;
+    int depth = 0;
+    for (;;)
+    {
+        node = fdt_next_node(device_tree, node, &depth);
+        if (node <= 0 || depth < 0)
+            break;
+        /*
+           int name_len = 0;
+           const char *name = fdt_get_name(device_tree, node, &name_len);
+           printk("Found node: %d (%.*s)\n", node, name_len, name);
+         */
+
+        const char *device_type = fdt_getprop(device_tree, node, 
"device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */
+            int len = 0;
+            const uint64_t *regs = fdt_getprop(device_tree, node, "reg", &len);
+            if (regs == NULL || len != 16) {
+                printk("Bad 'reg' property: %p %d\n", regs, len);
+                continue;
+            }
+            unsigned int start = (unsigned int) &_text;
+            unsigned int end = (unsigned int) &_end;
+            unsigned int mem_base = fdt64_to_cpu(regs[0]);
+            unsigned int mem_size = fdt64_to_cpu(regs[1]);
+            printk("Found memory at %p (len 0x%x)\n", mem_base, mem_size);
+
+            BUG_ON(mem_base > start);          /* Our image isn't in our RAM! 
*/
+            *start_pfn_p = PFN_UP(end);
+            int heap_len = mem_size - ((*start_pfn_p << PAGE_SHIFT) - 
mem_base);
+            *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+            printk("Using pages %d to %d as free space for heap.\n", 
*start_pfn_p, *max_pfn_p);
+            break;
+        }
+    }
+
+    if (*max_pfn_p == 0)
+    {
+        printk("No memory found in FDT!\n");
+        BUG();
+    }
+
+    /* The device tree is probably in memory that we're about to hand over to 
the page
+     * allocator, so move it to the end and reserve that space.
+     */
+    int fdt_size = fdt_totalsize(device_tree);
+    void *new_device_tree = (void *) (((*max_pfn_p << PAGE_SHIFT) - fdt_size) 
& PAGE_MASK);
+    if (new_device_tree != device_tree) {
+       memmove(new_device_tree, device_tree, fdt_size);
+    }
+    device_tree = new_device_tree;
+    *max_pfn_p = ((unsigned long) new_device_tree) >> PAGE_SHIFT;
 
     build_pagetable(start_pfn_p, max_pfn_p);
 }
diff --git a/extras/mini-os/arch/arm/setup.c b/extras/mini-os/arch/arm/setup.c
index 3499b37..e59665e 100644
--- a/extras/mini-os/arch/arm/setup.c
+++ b/extras/mini-os/arch/arm/setup.c
@@ -4,6 +4,7 @@
 #include <xen/memory.h>
 #include <xen/hvm/params.h>
 #include <arch_mm.h>
+#include <libfdt.h>
 
 /*
  * This structure contains start-of-day info, such as pagetable base pointer,
@@ -20,6 +21,8 @@ shared_info_t *HYPERVISOR_shared_info;
 
 extern char shared_info_page[PAGE_SIZE];
 
+void *device_tree;
+
 static int hvm_get_parameter(int idx, uint64_t *value)
 {
     struct xen_hvm_param xhv;
@@ -72,7 +75,14 @@ void arch_init(void *dtb_pointer)
 
     memset(&__bss_start, 0, &_end - &__bss_start);
 
-    printk("dtb_pointer : %x\n", dtb_pointer);
+    printk("Checking DTB at %x...\n", dtb_pointer);
+
+    int r;
+    if ((r = fdt_check_header(dtb_pointer))) {
+        printk("Invalid DTB from Xen: %s\n", fdt_strerror(r));
+        BUG();
+    }
+    device_tree = dtb_pointer;
 
     /* Map shared_info page */
     xatp.domid = DOMID_SELF;
diff --git a/extras/mini-os/include/arm/os.h b/extras/mini-os/include/arm/os.h
index 8d76089..2f423c0 100644
--- a/extras/mini-os/include/arm/os.h
+++ b/extras/mini-os/include/arm/os.h
@@ -10,6 +10,8 @@
 void arch_fini(void);
 void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
 
+extern void *device_tree;
+
 #define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined 
instruction; will call our fault handler. */
 
 #define smp_processor_id() 0
diff --git a/extras/mini-os/mm.c b/extras/mini-os/mm.c
index d2d5264..d31ef97 100644
--- a/extras/mini-os/mm.c
+++ b/extras/mini-os/mm.c
@@ -409,8 +409,8 @@ void init_mm(void)
      * now we can initialise the page allocator
      */
     printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
-           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
-           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
+           (u_long)to_virt(PFN_PHYS(start_pfn)), (u_long)PFN_PHYS(start_pfn), 
+           (u_long)to_virt(PFN_PHYS(max_pfn)), (u_long)PFN_PHYS(max_pfn));
     init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
     printk("MM: done\n");
 
-- 
2.0.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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