This code walks the OF dev tree, finding end-of-memory and memory holes.
All memory beyond the hypervisor's RMA is added to domheap. (Previously
only memory upto 1st hole was used.) Finally, parts of setup.c have been
swept into memory.c as cleanup.
diff -r 9c72449e4370 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c Fri Aug 18 17:52:04 2006 -0500
+++ b/xen/arch/powerpc/setup.c Tue Aug 22 09:52:03 2006 -0400
@@ -43,6 +43,7 @@
#include <asm/percpu.h>
#include "exceptions.h"
#include "of-devtree.h"
+#include "memory.h"
#define DEBUG
unsigned long xenheap_phys_end;
@@ -195,7 +196,7 @@ void startup_cpu_idle_loop(void)
reset_stack_and_jump(idle_loop);
}
-static ulong free_xenheap(ulong start, ulong end)
+ulong free_xenheap(ulong start, ulong end)
{
start = ALIGN_UP(start, PAGE_SIZE);
end = ALIGN_DOWN(end, PAGE_SIZE);
@@ -217,10 +218,6 @@ static void __init __start_xen(multiboot
{
char *cmdline;
module_t *mod = (module_t *)((ulong)mbi->mods_addr);
- ulong heap_start;
- ulong eomem = 0;
- ulong heap_size = 0;
- ulong bytes = 0;
ulong freemem;
ulong dom0_start, dom0_len;
ulong initrd_start, initrd_len;
@@ -267,61 +264,8 @@ static void __init __start_xen(multiboot
mod[mbi->mods_count-1].mod_end = 0;
--mbi->mods_count;
- printk("Physical RAM map:\n");
-
- /* lets find out how much memory there is */
- while (bytes < mbi->mmap_length) {
- u64 end;
- u64 addr;
- u64 size;
-
- memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr + bytes);
- addr = ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
- size = ((u64)map->length_high << 32) | (u64)map->length_low;
- end = addr + size;
-
- printk(" %016lx - %016lx (usable)\n", addr, end);
-
- if (addr > eomem) {
- printk("found a hole skipping remainder of memory at:\n"
- " %016lx and beyond\n", addr);
- break;
- }
- if (end > eomem) {
- eomem = end;
- }
- bytes += map->size + 4;
- }
-
- printk("System RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
-
- /* top of memory */
- max_page = PFN_DOWN(ALIGN_DOWN(eomem, PAGE_SIZE));
- total_pages = max_page;
-
- /* Architecturally the first 4 pages are exception hendlers, we
- * will also be copying down some code there */
- heap_start = 4 << PAGE_SHIFT;
- if (oftree < (ulong)_start)
- heap_start = ALIGN_UP(oftree_end, PAGE_SIZE);
-
- heap_start = init_boot_allocator(heap_start);
- if (heap_start > (ulong)_start) {
- panic("space below _start (%p) is not enough memory "
- "for heap (0x%lx)\n", _start, heap_start);
- }
-
- /* we give the first RMA to the hypervisor */
- xenheap_phys_end = rma_size(cpu_rma_order());
-
- /* allow everything else to be allocated */
- init_boot_pages(xenheap_phys_end, eomem);
- init_frametable();
- end_boot_allocator();
-
- /* Add memory between the beginning of the heap and the beginning
- * of out text */
- free_xenheap(heap_start, (ulong)_start);
+ xenheap_phys_end = setup_memory();
+
freemem = ALIGN_UP((ulong)_end, PAGE_SIZE);
for (i = 0; i < mbi->mods_count; i++) {
@@ -355,10 +299,6 @@ static void __init __start_xen(multiboot
/* make sure the OF devtree is good */
ofd_walk((void *)oftree, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
#endif
-
- heap_size = xenheap_phys_end - heap_start;
-
- printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
percpu_init_areas();
./xen/arch/powerpc/memory.c:
#include <xen/sched.h>
#include <xen/mm.h>
#include "of-devtree.h"
#include "oftree.h"
#include "memory.h"
typedef ulong (*walk_mem_fn)(ulong *membuf, int entries, ulong ret, ulong arg);
static ulong ofd_walk_mem(void *m, walk_mem_fn fn, ulong arg);
static ulong end_of_mem(ulong *membuf, int entries, ulong end, ulong unused);
static ulong init_unused_pages(ulong *membuf, int entries, ulong ret, ulong
freemem);
ulong setup_memory(void)
{
ulong eomem, holes;
ulong heap_start, xenheap_phys_end, heap_size;
printk("Physical RAM map:\n");
/* lets find out how much memory there is */
eomem = ofd_walk_mem((void *)oftree, end_of_mem, 0 /*unused*/);
if (eomem == 0){
panic("ofd_walk_mem((void *)oftree, end_of_mem, 0 /*unused*/)
failed\n");
}
printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
/* top of memory */
max_page = PFN_DOWN(ALIGN_DOWN(eomem, PAGE_SIZE));
/* Architecturally the first 4 pages are exception hendlers, we
* will also be copying down some code there */
heap_start = 4 << PAGE_SHIFT;
if (oftree < (ulong)_start)
heap_start = ALIGN_UP(oftree_end, PAGE_SIZE);
heap_start = init_boot_allocator(heap_start);
if (heap_start > (ulong)_start) {
panic("space below _start (%p) is not enough memory "
"for heap (0x%lx)\n", _start, heap_start);
}
/* we give the first RMA to the hypervisor */
xenheap_phys_end = rma_size(cpu_rma_order());
/* allow everything else to be allocated */
holes = ofd_walk_mem((void *)oftree, init_unused_pages, xenheap_phys_end);
printk("Memory holes: %luMB (%lukB)\n", holes >> 20, holes >> 10);
total_pages = max_page - (holes / PAGE_SIZE);
printk("total_pages: 0x%016lx\n", total_pages);
init_frametable();
end_boot_allocator();
/* Add memory between the beginning of the heap and the beginning
* of out text */
free_xenheap(heap_start, (ulong)_start);
heap_size = xenheap_phys_end - heap_start;
printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
return(xenheap_phys_end);
}
ulong ofd_walk_mem(void *m, walk_mem_fn fn, ulong arg)
{
ofdn_t n;
int p_len;
ulong ret = 0;
ulong membuf[16];
static char name[] = "memory";
n = ofd_node_find_by_prop(m, OFD_ROOT, "device_type", name, sizeof(name));
while (n > 0){
p_len = ofd_getprop(m, n, "reg", membuf, sizeof (membuf));
if (p_len <= 0){
printk("ofd_getprop(m, n, 'reg', ... failed\n");
return 0;
}
ret = fn(membuf, p_len / sizeof(ulong), ret, arg);
n = ofd_node_find_next(m, n);
}
return(ret);
}
ulong end_of_mem(ulong *membuf, int entries, ulong end, ulong unused)
{
int i;
for (i = 0; i < entries; i += 2){
if (end < membuf[i] + membuf[i + 1])
end = membuf[i] + membuf[i + 1];
}
return(end);
}
/* mark all memory from modules onward as unused, skipping hole(s),
* and returning size of hole(s) */
ulong init_unused_pages(ulong *membuf, int entries, ulong holes, ulong freemem)
{
int i;
ulong start_blk, end_blk;
for (i = 0; i < entries; i += 2){
start_blk = membuf[i];
if (i > 0){
holes += start_blk - end_blk;
}
end_blk = membuf[i] + membuf[i + 1];
if (start_blk < freemem){
init_boot_pages(freemem, end_blk);
} else {
init_boot_pages(start_blk, end_blk);
}
}
return(holes);
}
./xen/arch/powerpc/memory.h:
#ifndef _ARCH_PPC_MEMORY_H_
#define _ARCH_PPC_MEMORY_H_
ulong setup_memory(void);
ulong free_xenheap(ulong start, ulong end);
#endif /* _ARCH_PPC_MEMORY_H_ */
diff -r 9c72449e4370 xen/arch/powerpc/oftree.h
--- a/xen/arch/powerpc/oftree.h Fri Aug 18 17:52:04 2006 -0500
+++ b/xen/arch/powerpc/oftree.h Tue Aug 22 09:52:23 2006 -0400
@@ -23,6 +23,7 @@
extern ulong oftree;
extern ulong oftree_len;
+extern ulong oftree_end;
extern int ofd_dom0_fixup(
struct domain *d, ulong oftree, start_info_t *si, ulong dst);
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|