|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |