WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

Re: [XenPPC] [xenppc-unstable] [POWERPC] memory clean up (phase 3)

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: Re: [XenPPC] [xenppc-unstable] [POWERPC] memory clean up (phase 3)
From: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
Date: Thu, 17 Aug 2006 16:29:54 -0400
Delivery-date: Thu, 17 Aug 2006 13:30:39 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <E1GDoN1-0005SD-OQ@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
References: <E1GDoN1-0005SD-OQ@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
BTW: This has been tested with DOM0_IMAGE=...vmlinux.strip, tho' it would be better to use a zImage anyway.
-JX
On Aug 17, 2006, at 4:21 PM, Xen patchbot-xenppc-unstable wrote:

# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 697bd866535ba6d73de5fc6c988e96bc034bbdd0
# Parent  5e4dcc79f29a9dc5217a86b561e36b8d07c2d7dc
[POWERPC] memory clean up (phase 3)

The following changes are included:
 Open Firmware:
  - use all args for of_claim()
  - handle broken claim methods as best we can
  - describe where the Dom0 image is comming from
  - stop copying the Dom0 image

 Heaps:
  - make sure we do not overwrite the oftree
  - release as much memory as possible to xenheap
  - release Dom0 image after we are done with it
  - Lots of checks and simplifications
---
xen/arch/powerpc/boot_of.c | 127 ++++++++++++++++++++++ +---------------------- xen/arch/powerpc/setup.c | 107 ++++++++++++++++++++++++ +------------
 2 files changed, 137 insertions(+), 97 deletions(-)

diff -r 5e4dcc79f29a -r 697bd866535b xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Thu Aug 17 07:10:57 2006 -0400
+++ b/xen/arch/powerpc/boot_of.c        Thu Aug 17 16:21:34 2006 -0400
@@ -26,6 +26,7 @@
 #include <xen/spinlock.h>
 #include <xen/serial.h>
 #include <xen/time.h>
+#include <xen/sched.h>
 #include <asm/page.h>
 #include <asm/io.h>
 #include "exceptions.h"
@@ -322,17 +323,18 @@ static void __init of_test(const char *o
     }
 }

-static int __init of_claim(void * virt, u32 size)
+static int __init of_claim(u32 virt, u32 size, u32 align)
 {
     int rets[1] = { OF_FAILURE };

-    of_call("claim", 3, 1, rets, virt, size, 0/*align*/);
+    of_call("claim", 3, 1, rets, virt, size, align);
     if (rets[0] == OF_FAILURE) {
-        DBG("%s 0x%p 0x%08x -> FAIL\n", __func__, virt, size);
-        return OF_FAILURE;
-    }
-
-    DBG("%s 0x%p 0x%08x -> 0x%x\n", __func__, virt, size, rets[0]);
+ DBG("%s 0x%08x 0x%08x 0x%08x -> FAIL\n", __func__, virt, size, align);
+        return OF_FAILURE;
+    }
+
+ DBG("%s 0x%08x 0x%08x 0x%08x -> 0x%08x\n", __func__, virt, size, align,
+        rets[0]);
     return rets[0];
 }

@@ -683,32 +685,47 @@ static int boot_of_fixup_chosen(void *me
 }

 static ulong space_base;
-static ulong find_space(u32 size, ulong align, multiboot_info_t *mbi)
+static int broken_claim;
+
+/*
+ * The following function is necessary because we cannot depend on all
+ * FW to actually allocate us any space, so we look for it _hoping_
+ * that at least is will fail if we try to claim something that
+ * belongs to FW.  This hope does not seem to be true on some version
+ * of PIBS.
+ */
+static ulong find_space(u32 size, u32 align, multiboot_info_t *mbi)
 {
     memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr);
ulong eomem = ((u64)map->length_high << 32) | (u64)map- >length_low;
     ulong base;

- of_printf("%s base=0x%016lx eomem=0x%016lx size=0x%08x align=0x%lx\n",
+    if (size == 0) return base;
+
+    if (align == 0)
+        of_panic("cannot call %s() with align of 0\n", __func__);
+
+    if (!broken_claim) {
+        /* just try and claim it to the FW chosen address */
+        base = of_claim(0, size, align);
+        if (base != OF_FAILURE)
+            return base;
+ of_printf("%s: Firmware does not allocate memory for you \n", __func__);
+        broken_claim = 1;
+    }
+
+ of_printf("%s base=0x%016lx eomem=0x%016lx size=0x%08x align=0x%x\n",
                     __func__, space_base, eomem, size, align);
     base = ALIGN_UP(space_base, PAGE_SIZE);
-    if ((base + size) >= 0x4000000) return 0;
-    if (base + size > eomem) of_panic("not enough RAM\n");
-
-    if (size == 0) return base;
-    if (of_claim((void*)base, size) != OF_FAILURE) {
-        space_base = base + size;
-        return base;
-    } else {
- for(base += 0x100000; (base+size) < 0x4000000; base += 0x100000) {
-            of_printf("Trying 0x%016lx\n", base);
-            if (of_claim((void*)base, size) != OF_FAILURE) {
-                space_base = base + size;
-                return base;
-            }
-        }
-        return 0;
-    }
+
+    while ((base + size) < rma_size(cpu_rma_order())) {
+        if (of_claim(base, size, 0) != OF_FAILURE) {
+            space_base = base + size;
+            return base;
+        }
+        base += (PAGE_SIZE >  align) ? PAGE_SIZE : align;
+    }
+    of_panic("Cannot find memory in the RMA\n");
 }

 /* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges
@@ -834,9 +851,8 @@ static void boot_of_module(ulong r3, ulo
     static module_t mods[3];
     void *oftree;
     ulong oftree_sz = 48 * PAGE_SIZE;
-    char *mod0_start;
+    ulong mod0_start;
     ulong mod0_size;
-    ulong mod0;
     static const char sepr[] = " -- ";
     extern char dom0_start[] __attribute__ ((weak));
     extern char dom0_size[] __attribute__ ((weak));
@@ -844,59 +860,48 @@ static void boot_of_module(ulong r3, ulo

     if ((r3 > 0) && (r4 > 0)) {
         /* was it handed to us in registers ? */
-        mod0_start = (void *)r3;
+        mod0_start = r3;
         mod0_size = r4;
+            of_printf("%s: Dom0 was loaded and found using r3/r4:"
+                      "0x%lx[size 0x%lx]\n",
+                      __func__, mod0_start, mod0_size);
     } else {
         /* see if it is in the boot params */
         p = strstr((char *)((ulong)mbi->cmdline), "dom0_start=");
         if ( p != NULL) {
             p += 11;
-            mod0_start = (char *)simple_strtoul(p, NULL, 0);
+            mod0_start = simple_strtoul(p, NULL, 0);

             p = strstr((char *)((ulong)mbi->cmdline), "dom0_size=");
             p += 10;
             mod0_size = simple_strtoul(p, NULL, 0);
-
-            of_printf("mod0: %o %c %c %c\n",
-                      mod0_start[0],
-                      mod0_start[1],
-                      mod0_start[2],
-                      mod0_start[3]);
-
+            of_printf("%s: Dom0 was loaded and found using cmdline:"
+                      "0x%lx[size 0x%lx]\n",
+                      __func__, mod0_start, mod0_size);
} else if ( ((ulong)dom0_start != 0) && ((ulong)dom0_size ! = 0) ) {
             /* was it linked in ? */

-            mod0_start = dom0_start;
+            mod0_start = (ulong)dom0_start;
             mod0_size = (ulong)dom0_size;
-            of_printf("%s: linked in module copied after _end "
-                      "(start 0x%p size 0x%lx)\n",
+            of_printf("%s: Dom0 is linked in: 0x%lx[size 0x%lx]\n",
                       __func__, mod0_start, mod0_size);
         } else {
-            mod0_start = _end;
+            mod0_start = (ulong)_end;
             mod0_size = 0;
-        }
+ of_printf("%s: FYI Dom0 is unknown, will be caught later\n",
+                      __func__);
+        }
+    }
+
+    if (mod0_size > 0) {
+        const char *c = (const char *)mod0_start;
+
+        of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
     }

     space_base = (ulong)_end;
-    mod0 = find_space(mod0_size, PAGE_SIZE, mbi);
-
-    /* three cases
-     * 1) mod0_size is not 0 and the image can be copied
-     * 2) mod0_size is not 0 and the image cannot be copied
-     * 3) mod0_size is 0
-     */
-    if (mod0_size > 0) {
-        if (mod0 != 0) {
-            memcpy((void *)mod0, mod0_start, mod0_size);
-            mods[0].mod_start = mod0;
-            mods[0].mod_end = mod0 + mod0_size;
-        } else {
-            of_panic("No space to copy mod0\n");
-        }
-    } else {
-        mods[0].mod_start = mod0;
-        mods[0].mod_end = mod0;
-    }
+    mods[0].mod_start = mod0_start;
+    mods[0].mod_end = mod0_start + mod0_size;

     of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__,
               mods[0].mod_start, mods[0].mod_end);
diff -r 5e4dcc79f29a -r 697bd866535b xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Thu Aug 17 07:10:57 2006 -0400
+++ b/xen/arch/powerpc/setup.c  Thu Aug 17 16:21:34 2006 -0400
@@ -44,6 +44,8 @@
 #include "exceptions.h"
 #include "of-devtree.h"

+DEFINE_PER_CPU(ulong, pcpu_var);
+
 #define DEBUG
 unsigned long xenheap_phys_end;

@@ -61,6 +63,7 @@ unsigned long wait_init_idle;
 unsigned long wait_init_idle;
 ulong oftree;
 ulong oftree_len;
+ulong oftree_end;

 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
@@ -193,17 +196,37 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }

+static ulong free_xenheap(ulong start, ulong end)
+{
+    start = ALIGN_UP(start, PAGE_SIZE);
+    end = ALIGN_DOWN(end, PAGE_SIZE);
+
+    printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
+
+    if (oftree <= end && oftree >= start) {
+        printk("%s:     Go around the devtree: 0x%lx - 0x%lx\n",
+                  __func__, oftree, oftree_end);
+        init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE));
+        init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end);
+    } else {
+        init_xenheap_pages(start, end);
+    }
+    return ALIGN_UP(end, PAGE_SIZE);
+}
+
 static void __init __start_xen(multiboot_info_t *mbi)
 {
     char *cmdline;
     module_t *mod = (module_t *)((ulong)mbi->mods_addr);
     ulong heap_start;
-    ulong modules_start, modules_size;
     ulong eomem = 0;
     ulong heap_size = 0;
     ulong bytes = 0;
-    ulong freemem = (ulong)_end;
-    ulong oftree_end;
+    ulong freemem;
+    ulong dom0_start, dom0_len;
+    ulong initrd_start, initrd_len;
+
+    int i;

memcpy(0, exception_vectors, exception_vectors_end - exception_vectors);
     synchronize_caches(0, exception_vectors_end - exception_vectors);
@@ -234,10 +257,6 @@ static void __init __start_xen(multiboot
     if (!(mbi->flags & MBI_MEMMAP)) {
panic("FATAL ERROR: Bootloader provided no memory information.\n");
     }
-
-    /* mark the begining of images */
-    modules_start = mod[0].mod_start;
-    modules_size = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;

     /* OF dev tree is the last module */
     oftree = mod[mbi->mods_count-1].mod_start;
@@ -283,7 +302,15 @@ static void __init __start_xen(multiboot

     /* Architecturally the first 4 pages are exception hendlers, we
      * will also be copying down some code there */
-    heap_start = init_boot_allocator(4 << PAGE_SHIFT);
+    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());
@@ -295,24 +322,28 @@ static void __init __start_xen(multiboot

     /* Add memory between the beginning of the heap and the beginning
      * of out text */
-    init_xenheap_pages(heap_start, (ulong)_start);
-
-    /* move the modules to just after _end */
-    if (modules_start) {
-        printk("modules at: %016lx - %016lx\n", modules_start,
-                modules_start + modules_size);
-        freemem = ALIGN_UP(freemem, PAGE_SIZE);
- memmove((void *)freemem, (void *)modules_start, modules_size);
-
-        oftree -= modules_start - freemem;
-        modules_start = freemem;
-        freemem += modules_size;
-        printk("  moved to: %016lx - %016lx\n", modules_start,
-                modules_start + modules_size);
+    free_xenheap(heap_start, (ulong)_start);
+    freemem = ALIGN_UP((ulong)_end, PAGE_SIZE);
+
+    for (i = 0; i < mbi->mods_count; i++) {
+        u32 s;
+
+        s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
+
+        if (mod[i].mod_start > (ulong)_start &&
+            mod[i].mod_start < (ulong)_end) {
+            /* mod was linked in */
+            continue;
+        }
+
+        if (s < freemem)
+            panic("module addresses must assend\n");
+
+        freemem = free_xenheap(freemem, s);
     }

     /* the rest of the xenheap, starting at the end of modules */
-    init_xenheap_pages(freemem, xenheap_phys_end);
+    free_xenheap(freemem, xenheap_phys_end);


 #ifdef OF_DEBUG
@@ -353,22 +384,26 @@ static void __init __start_xen(multiboot
/* Scrub RAM that is still free and so may go to an unprivileged domain. */
     scrub_heap_pages();

-    /*
-     * We're going to setup domain0 using the module(s) that we
-     * stashed safely above our heap. The second module, if present,
-     * is an initrd ramdisk.  The last module is the OF devtree.
-     */
-    if (construct_dom0(dom0,
-                       modules_start,
-                       mod[0].mod_end-mod[0].mod_start,
-                       (mbi->mods_count == 1) ? 0 :
-                       modules_start +
-                       (mod[1].mod_start-mod[0].mod_start),
-                       (mbi->mods_count == 1) ? 0 :
- mod[mbi->mods_count-1].mod_end - mod [1].mod_start,
+    dom0_start = mod[0].mod_start;
+    dom0_len = mod[0].mod_end - mod[0].mod_start;
+    if (mbi->mods_count > 1) {
+        initrd_start = mod[1].mod_start;
+        initrd_len = mod[1].mod_end - mod[1].mod_start;
+    } else {
+        initrd_start = 0;
+        initrd_len = 0;
+    }
+    if (construct_dom0(dom0, dom0_start, dom0_len,
+                       initrd_start, initrd_len,
                        cmdline) != 0) {
         panic("Could not set up DOM0 guest OS\n");
     }
+
+    free_xenheap(ALIGN_UP(dom0_start, PAGE_SIZE),
+                 ALIGN_DOWN(dom0_start + dom0_len, PAGE_SIZE));
+    if (initrd_start)
+        free_xenheap(ALIGN_UP(initrd_start, PAGE_SIZE),
+ ALIGN_DOWN(initrd_start + initrd_len, PAGE_SIZE));

     init_trace_bufs();


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


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

<Prev in Thread] Current Thread [Next in Thread>