[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 |