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

[XenPPC] [PATCH] changes for g5 hardware

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [PATCH] changes for g5 hardware
From: Maria Butrico <butrico@xxxxxxxxxxxxxx>
Date: Thu, 30 Mar 2006 13:47:55 -0500
Delivery-date: Thu, 30 Mar 2006 19:53:31 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
Signed-off-by: Maria Butrico <butrico@xxxxxxxxxxxxxx>

summary:     OF changes for g5 hardware.

Fixed way in which space is found for dom0 and the ofd tree
by starting to look at the end of the loaded image and at the
next aligned address and asking open firmware for memory of
the required size.  On failure, we try again at a megabyte
interval.  We do this up to 64M, then we give up.

Fixed way in which we find memory bank in open firmware.
We supply a sufficiently large array 32-bits words, and look
through all the entries returned.  Those containing all 0's
are ignored.  Also partial entries are ignored.  (Partial
entries are caused by having too small an array for the
size of the open firmware property).

Fixed a number of minor bugs with return code checking from
open firmware functions.  An of function fails when it returns
-1 (OF_FAILURE), but 0 can sometimes be a valid return code.


diff -r f2d116c693c6 xen/arch/ppc/boot_of.c
--- a/xen/arch/ppc/boot_of.c    Thu Mar 30 12:06:33 2006 -0500
+++ b/xen/arch/ppc/boot_of.c    Thu Mar 30 12:04:11 2006 -0500
@@ -155,7 +155,7 @@ static int __init of_getprop(int ph, con
         return OF_FAILURE;
     }
 
-    DBG("getprop 0x%x %s -> %s\n", ph, name, (char *)buf);
+    DBG("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
     return rets[0];
 }
 
@@ -176,6 +176,9 @@ static int __init of_setprop(int ph, con
 }
 #endif
 
+/*
+ * returns 0 if there are no children (of spec)
+ */
 static int __init of_getchild(int ph)
 {
     int rets[1] = { OF_FAILURE };
@@ -205,7 +208,7 @@ static int __init of_getproplen(int ph, 
         DBG("getproplen 0x%x %s -> FAILURE\n", ph, name);
         return OF_FAILURE;
     }
-    DBG("getproplen 0x%x %s -> 0x0x%x\n", ph, name, rets[0]);
+    DBG("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
     return rets[0];
 }
 
@@ -214,9 +217,11 @@ static int __init of_package_to_path(int
     int rets[1] = { OF_FAILURE };
 
     of_call("package-to-path", 3, 1, rets, ph, buffer, buflen);
-    if (rets[0] == OF_FAILURE)
-        return OF_FAILURE;
-
+    if (rets[0] == OF_FAILURE) {
+        DBG("%s 0x%x -> FAILURE\n", __func__, ph);
+        return OF_FAILURE;
+    }
+    DBG("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
     return rets[0];
 }
 
@@ -256,6 +261,30 @@ static int __init of_start_cpu(int cpu, 
     return rets[0];
 }
 
+static void __init of_test(char * of_method_name)
+{
+    int rets[1] = { OF_FAILURE };
+    
+    of_call("test", 1, 1, rets, of_method_name);
+    if (rets[0] == OF_FAILURE ) {
+        of_printf("Warning: possibly no OF method %s.\n"
+                  "(Ignore this warning on PIBS.)\n", of_method_name);
+    }
+}
+
+static int __init of_claim(void * virt, u32 size)
+{
+    int rets[1] = { OF_FAILURE };
+    
+    of_call("claim", 3, 1, rets, virt, size, 0/*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]);
+    return rets[0];
+}
 
 #if unused_but_will_be
 
@@ -302,6 +331,8 @@ static void boot_of_probemem(multiboot_i
     /* code is writen to assume sizes of 1 */
     of_getprop(root, "#address-cells", &addr_cells, sizeof (addr_cells));
     of_getprop(root, "#size-cells", &size_cells, sizeof (size_cells));
+    DBG("%s: address_cells=%d  size_cells=%d\n",
+                    __func__, addr_cells, size_cells);
     
     do {
         const char memory[] = "memory";
@@ -311,41 +342,54 @@ static void boot_of_probemem(multiboot_i
 
         of_getprop(p, "device_type", type, sizeof (type));
         if (strncmp(type, memory, sizeof (memory)) == 0) {
-            u32 reg[16];
+            u32 reg[48];  
+            u32 al, ah, ll, lh;
             int r;
 
             rc = of_getprop(p, "reg", reg, sizeof (reg));
-            if (rc <= 0) {
-                of_printf("no reg property for memory node: 0x%x\n", p);
-                for (;;);
+            if (rc == OF_FAILURE) {
+                of_panic("no reg property for memory node: 0x%x.\n", p);
             }
-
-            mmap[mcount].size = 20; /* - size field */
-            mmap[mcount].type = 1; /* Regular ram */
-
+            int l = rc/sizeof(u32); /* number reg element */
+            DBG("%s: number of bytes in property 'reg' %d\n",
+                            __func__, rc);
+            
             r = 0;
-            if (addr_cells == 2) {
-                mmap[mcount].base_addr_high = reg[r++];
-                mmap[mcount].base_addr_low = reg[r++];
-            } else {
-                mmap[mcount].base_addr_high = 0;
-                mmap[mcount].base_addr_low = reg[r++];
-            }
-            if (size_cells == 2) {
-                mmap[mcount].length_high = reg[r++];
-                mmap[mcount].length_low = reg[r];
-            } else {
-                mmap[mcount].length_high = 0;
-                mmap[mcount].length_low = reg[r];
-            }
-
-            of_printf("%s: memory 0x%lx[0x%lx]\n",
+            while (r < l) {
+                al = ah = ll = lh = 0;
+                if (addr_cells == 2) {
+                    ah = reg[r++];
+                    if (r >= l) break;  // partial line.  Skip
+                    al = reg[r++];
+                    if (r >= l) break;  // partial line.  Skip
+                } else {
+                    al = reg[r++];
+                    if (r >= l) break;  // partial line.  Skip
+                }
+                if (size_cells == 2) {
+                    lh = reg[r++];
+                    if (r >= l) break;  // partial line.  Skip
+                    ll = reg[r++];
+                } else {
+                    ll = reg[r++];
+                }
+
+                if ((ll != 0) || (lh != 0)) {
+                    mmap[mcount].size = 20; /* - size field */
+                    mmap[mcount].type = 1; /* Regular ram */
+                    mmap[mcount].length_high = lh;
+                    mmap[mcount].length_low = ll;
+                    mmap[mcount].base_addr_high = ah;
+                    mmap[mcount].base_addr_low = al;
+                    of_printf("%s: memory 0x%016lx[0x%08lx]\n",
                       __func__,
                       (u64)(((u64)mmap[mcount].base_addr_high << 32)
                             | mmap[mcount].base_addr_low),
                       (u64)(((u64)mmap[mcount].length_high << 32)
                             | mmap[mcount].length_low));
-            ++mcount;
+                    ++mcount;
+                }
+            }
         }
         p = of_getpeer(p);
     } while (p != OF_FAILURE && p != 0);
@@ -365,7 +409,7 @@ static void boot_of_bootargs(multiboot_i
     const char sepr[] = " -- ";
 
     rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
-    if (rc <= 0) {
+    if (rc == OF_FAILURE) {
         strcpy(bootargs, "xen");
     }
 
@@ -404,7 +448,7 @@ static int save_props(void *m, ofdn_t n,
 
     while (result > 0) {
         int sz;
-        u64 obj[128];
+        u64 obj[1024];
 
         sz = of_getproplen(pkg, name);
         if (sz >= 0) {
@@ -432,6 +476,7 @@ static int save_props(void *m, ofdn_t n,
             if (strncmp(name, devtype_str, sizeof(devtype_str)) == 0) {
                 found_device_type = 1;
             }
+
             pos = ofd_prop_add(m, n, name, obj, actual);
             if (pos == 0) of_panic("prop_create");
         }
@@ -457,7 +502,7 @@ retry:
 
     if (pnext != 0) {
         sz = of_package_to_path(pnext, path, psz);
-        if (sz <= 0) of_panic("bad path\n");
+        if (sz == OF_FAILURE) of_panic("bad path\n");
 
         nnext = ofd_node_child_create(m, n, path, sz);
         if (nnext == 0) of_panic("out of mem\n");
@@ -472,7 +517,7 @@ retry:
         sz = of_package_to_path(pnext, path, psz);
 
         nnext = ofd_node_peer_create(m, n, path, sz);
-        if (nnext <= 0) of_panic("out of mem\n");
+        if (nnext <= 0) of_panic("out of space in OFD tree.\n");
 
         n = nnext;
         p = pnext;
@@ -491,7 +536,7 @@ static int pkg_save(void *mem)
 
     /* get root */
     root = of_getpeer(0);
-    if (root < 0) of_panic("no root package\n");
+    if (root == OF_FAILURE) of_panic("no root package\n");
 
     do_pkg(mem, OFD_ROOT, root, path, sizeof(path));
 
@@ -528,16 +573,29 @@ static int boot_of_fixup_refs(void *mem)
             if (path == NULL) of_panic("no path to found prop: %s\n", name);
 
             rp = of_finddevice(path);
-            if (rp <= 0) of_panic("no real device for: %s\n", path);
+            if (rp == OF_FAILURE)
+                of_panic("no real device for: name %s, path %s\n",
+                          name, path);
+            /* Note: In theory 0 is a valid node handle but it is highly
+             * unlikely.
+             */
+            if (rp == 0) {
+                of_panic("%s: of_finddevice returns 0 for path %s\n",
+                                    __func__, path);
+            } 
 
             rc = of_getprop(rp, name, &ref, sizeof(ref));
-            if (rc <= 0) of_panic("no prop: %s\n", name);
+            if ((rc == OF_FAILURE) || (rc == 0))
+                of_panic("no prop: name %s, path %s, device 0x%x\n",
+                         name, path, rp);
 
             rc = of_package_to_path(ref, ofpath, sizeof (ofpath));
-            if (rc <= 0) of_panic("no package: %s\n", name);
+            if (rc == OF_FAILURE)
+                of_panic("no package: name %s, path %s, device 0x%x,\n"
+                         "ref 0x%x\n", name, path, rp, ref);
 
             dp = ofd_node_find(mem, ofpath);
-            if (dp < 0) of_panic("no node for: %s\n", ofpath);
+            if (dp <= 0) of_panic("no node for: %s\n", ofpath);
 
             ref = dp;
 
@@ -565,16 +623,16 @@ static int boot_of_fixup_chosen(void *me
     char ofpath[256];
 
     ch = of_finddevice("/chosen");
-    if (ch <= 0) of_panic("/chosen not found\n");
+    if (ch == OF_FAILURE) of_panic("/chosen not found\n");
 
     rc = of_getprop(ch, "cpu", &val, sizeof (val));
 
-    if (rc > 0) {
+    if (rc != OF_FAILURE) {
         rc = of_instance_to_path(val, ofpath, sizeof (ofpath));
 
         if (rc > 0) {
             dn = ofd_node_find(mem, ofpath);
-            if (dn < 0) of_panic("no node for: %s\n", ofpath);
+            if (dn <= 0) of_panic("no node for: %s\n", ofpath);
 
             boot_cpu = dn;
             val = dn;
@@ -594,22 +652,48 @@ static int boot_of_fixup_chosen(void *me
     return rc;
 }
 
-static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
-{
-    static module_t mods[3];
+static ulong space_base;
+static ulong find_space(u32 size, ulong 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",
+                    __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;
+    }
+}
+
+static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
+{
+    static module_t mods[3];
     void *oftree;
     ulong oftree_sz = 48 * PAGE_SIZE;
-    ulong ofstart;
     char *mod0_start;
     ulong mod0_size;
-    ulong mod0 =  ALIGN_UP((ulong)_end, PAGE_SIZE);
+    ulong mod0;
     extern char dom0_start[] __attribute__ ((weak));
     extern char dom0_size[] __attribute__ ((weak));
     char *p;
 
-    if (r3 > 0 && r4 > 0) {
+    if ((r3 > 0) && (r4 > 0)) {
         /* was it handed to us in registers ? */
         mod0_start = (void *)r3;
         mod0_size = r4;
@@ -630,37 +714,54 @@ static void boot_of_module(ulong r3, ulo
                       mod0_start[2],
                       mod0_start[3]);
 
-        } else if ( (ulong)dom0_start != 0 && (ulong)dom0_size != 0 ) {
+        } else if ( ((ulong)dom0_start != 0) && ((ulong)dom0_size != 0) ) {
             /* was it linked in ? */
-            of_printf("%s: linked in module copied after _end\n", __func__);
         
             mod0_start = dom0_start;
             mod0_size = (ulong)dom0_size;
+            of_printf("%s: linked in module copied after _end "
+                      "(start 0x%p size 0x%lx)\n",
+                      __func__, mod0_start, mod0_size);
         } else {
             mod0_start = _end;
             mod0_size = 0;
         }
     }
 
-    memcpy((void *)mod0, mod0_start, mod0_size);
-    mods[0].mod_start = mod0;
-    mods[0].mod_end = mod0 + mod0_size;
+    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;
+    }
+
     if (dom0args[0] != '\0') {
         mods[0].string = (ulong)dom0args;
     }
         
-    of_printf("%s: mod[0] @ 0x%x[0x%x]\n", __func__,
+    of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__,
               mods[0].mod_start, mods[0].mod_end);
 
-    ofstart = mods[0].mod_end;
-
     /* snapshot the tree */
-    oftree = (void *)ALIGN_UP(ofstart, PAGE_SIZE);
-
-    if ((ulong)oftree + oftree_sz >  eomem)
-        of_panic("not enough RAM for OF image\n");
+    oftree = (void*)find_space(oftree_sz, PAGE_SIZE, mbi);
+    if (oftree == 0) of_panic("Could not allocate OFD tree\n");
 
     of_printf("creating oftree\n");
+    of_test("package-to-path");
     ofd_create(oftree, oftree_sz);
     pkg_save(oftree);
 
@@ -671,10 +772,14 @@ static void boot_of_module(ulong r3, ulo
 
     mods[1].mod_start = (ulong)oftree;
     mods[1].mod_end = mods[1].mod_start + oftree_sz;
+    of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
+              mods[1].mod_start, mods[1].mod_end);
+
 
     mbi->flags |= MBI_MODULES;
     mbi->mods_count = 2;
     mbi->mods_addr = (u32)mods;
+
 }
 
 
@@ -698,14 +803,13 @@ int __init boot_of_cpus(void)
     result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
             sizeof(timebase_freq));
     if (result == OF_FAILURE) {
-        of_printf("Couldn't get timebase frequency!\n");
-        for (;;);
+        of_panic("Couldn't get timebase frequency!\n");
     }
     of_printf("OF: timebase-frequency = 0x%x\n", timebase_freq);
 
     /* FIXME: should not depend on the boot CPU bring the first child */
     cpu = of_getpeer(cpu);
-    while (cpu > 0) {
+    while (cpu == OF_FAILURE) {
         of_start_cpu(cpu, (ulong)spin_start, 0);
         cpu = of_getpeer(cpu);
     }
@@ -736,15 +840,17 @@ multiboot_info_t __init *boot_of_init(
               XEN_COMPILE_BY, XEN_COMPILE_DOMAIN,
               XEN_COMPILER, XEN_COMPILE_DATE);
 
-    of_printf("boot args: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n"
+    of_printf("%s args: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n"
             "boot msr: 0x%lx\n",
+            __func__,
             r3, r4, vec, r6, r7, orig_msr);
 
-    if (vec >= (ulong)_start && vec <= (ulong)_end) {
+    if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
         of_printf("Hmm.. OF[0x%lx] seems to have stepped on our image "
                 "that ranges: %p .. %p.\n HANG!\n",
                 vec, _start, _end);
     }
+    of_printf("%s: _start %p _end %p 0x%lx\n", __func__, _start, _end, r6);
 
     boot_of_probemem(&mbi);
     boot_of_bootargs(&mbi);

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