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] [pushed] [ppc] Boot OF cleanup for G5s

changeset:   9756:1056a40f301eb9d21c612b30f2e5d22f0ffecf1b
tag:         tip
user:        jimix@xxxxxxxxxxxxxxxxxxxxx
date:        Tue Apr  4 15:10:43 2006 -0400
files:       xen/arch/ppc/boot_of.c
description:
[ppc] Boot OF cleanup for G5s

Signed-off-by: Maria Butrico <butrico@xxxxxxxxxxxxxx>
  - Comment some functions.
  - more DBG() statements
  - Add an OF test method to see if the OF supports other methods.
  - Use OF Claim method rather than guess the memory we can use for the OFD.
    Call claim() sucessively until we find a good spot.
  - use of_panic() instead of for(;;);
  - cleanup and consistant failure checking


diff -r 49cd3529cf17a44ca458f2c46a34684a2248b09f -r 
1056a40f301eb9d21c612b30f2e5d22f0ffecf1b xen/arch/ppc/boot_of.c
--- a/xen/arch/ppc/boot_of.c    Tue Apr  4 08:24:09 2006 -0400
+++ b/xen/arch/ppc/boot_of.c    Tue Apr  4 15:10:43 2006 -0400
@@ -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 };
@@ -186,6 +189,9 @@ static int __init of_getchild(int ph)
     return rets[0];
 }
 
+/*
+ * returns 0 is there are no peers
+ */
 static int __init of_getpeer(int ph)
 {
     int rets[1] = { OF_FAILURE };
@@ -205,7 +211,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 +220,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 +264,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 +334,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 +345,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 +412,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 +451,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 +479,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 +505,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 +520,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 +539,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 +576,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 +626,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 +655,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 +717,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 +775,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,8 +806,7 @@ 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);
 
@@ -736,15 +843,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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [pushed] [ppc] Boot OF cleanup for G5s, jimix <=