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
|