On Jan 3, 2007, at 12:32 PM, Hollis Blanchard wrote:

Xen on x86 uses GRUB's "multiboot" capabilities to load an arbitrary
number of images, including Xen, dom0 kernel, dom0 initrd, and ACM
policy. On PowerPC, we've had to build Xen, the dom0 kernel and the dom0
initrd all into the same file to get them loaded.

We also boot from yaboot which allows us to separate dom0 from xen, as does newer PIBS firmware via r3 & r4 and trivial to teach SLOF and other OF how as well. Please do not assume that we are fully linked only and do not remove that logic. Using your new boot loader case should be additive.


Since we currently
boot directly from Open Firmware, early PPC Xen code then fakes up a
multiboot info structure which later PPC Xen code extracts data from.

GRUB2, which supports PowerPC, is defining a new multiboot format
because the original was far too x86-specific. That loader is not yet
committed but is fairly complete, so to test it out I'm adapting PPC Xen
to it.

This is the first step: I've replaced our early multiboot code to fake
up a multiboot2 structure instead. I haven't yet tried to boot this from
GRUB2, but we will likely want to continue supporting directly booting
from firmware so this code needs to work.

Of interest is that I've changed the memory map to simplify some of the early memory allocation code (which unlike x86 tried to handle unordered
discontiguous allocations). With this patch, our memory map now looks
like this:

        exception handlers (0x0 to 0x4000)
        RTAS
        Open Firmware device tree

RTAS and OFD are subject to "avail" properties in from OF and whether or not they can be claimed. I don't think you should write code that assumes they are here.

        boot allocator bitmap (common Xen code)
        Xen heap
                ...
        _start (0x400000; 64MB)
0x400000 is 4MiB
I had a paragraph on how 64MiB was bad and then realized it is still 4MiB :)
                [Xen text/data]
        _end
        modules
                [dom0, dom0 initrd, etc]
        Xen heap
                ...
                [fixed size]
        domain heap
                ...
                [consumes all remaining memory]

Comments and testing are welcome, or I'll probably check this in in a
day or so.

Signed-off-by: Hollis Blanchard <[EMAIL PROTECTED]>

diff -r dbc74db14a4b xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Tue Dec 12 14:35:07 2006 -0600
+++ b/xen/arch/powerpc/boot_of.c        Wed Jan 03 10:50:07 2007 -0600
@@ -22,7 +22,7 @@
 #include <xen/config.h>
 #include <xen/init.h>
 #include <xen/lib.h>
-#include <xen/multiboot.h>
+#include <xen/multiboot2.h>
 #include <xen/version.h>
 #include <xen/spinlock.h>
 #include <xen/serial.h>
@@ -30,6 +30,7 @@
 #include <xen/sched.h>
 #include <asm/page.h>
 #include <asm/io.h>
+#include <asm/boot.h>
 #include "exceptions.h"
 #include "of-devtree.h"
 #include "oftree.h"
@@ -77,6 +78,28 @@ static int bof_chosen;
 static int bof_chosen;

 static struct of_service s;
+
+static unsigned char xentags[512];
+static int xentags_pos;
+
+static int of_printf(const char *fmt, ...)
+    __attribute__ ((format (printf, 1, 2)));
+
+static void *alloc_tag(int key, int len)
+{
+    struct mb2_tag_header *tag;
+

Does len include sizeof(*tag)? it looks like it does, why not make it implicit? Since the the largest member of *tag is a uint32_t then it must be 4 byte aligned, please make sure your allocations are rounded up to 4 bytes, unless you _know_ that len is, but I'd do it anyway.

+    if (xentags_pos + len > sizeof(xentags))
+        of_panic("Couldn't allocate multiboot tag.");
+
+    tag = (struct mb2_tag_header *)(xentags + xentags_pos);
+    tag->key = key;
+    tag->len = len;
+
+    xentags_pos += len;
+
+    return tag;
+}

 static int __init of_call(
     const char *service, u32 nargs, u32 nrets, s32 rets[], ...)
@@ -160,8 +183,6 @@ static int __init of_write(int ih, const
     return sum;
 }

-static int of_printf(const char *fmt, ...)
-    __attribute__ ((format (printf, 1, 2)));
 static int __init of_printf(const char *fmt, ...)
 {
     static char buf[1024];
@@ -609,8 +630,11 @@ static ulong boot_of_mem_init(void)
     return 0;
 }

-static void boot_of_bootargs(multiboot_info_t *mbi)
-{
+static char *boot_of_bootargs(char **dom0_cmdline)
+{
+    static const char *sepr[] = {" -- ", " || "};
+    char *p;
+    int sepr_index;
     int rc;

     if (builtin_cmdline[0] == '\0') {
@@ -620,10 +644,22 @@ static void boot_of_bootargs(multiboot_i
of_panic("bootargs[] not big enough for /chosen/ bootargs\n");
     }

-    mbi->flags |= MBI_CMDLINE;
-    mbi->cmdline = (ulong)builtin_cmdline;
-
     of_printf("bootargs = %s\n", builtin_cmdline);
+
+    /* look for delimiter: "--" or "||" */
+ for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index+ +){
+        p = strstr((char *)builtin_cmdline, sepr[sepr_index]);

Is the cast necessary?

+        if (p != NULL) {
+            /* Xen proper should never know about the dom0 args.  */
+            *(char *)p = '\0';

Why casting here?

+            p += strlen(sepr[sepr_index]);
+            *dom0_cmdline = p;
+ of_printf("%s: dom0 cmdline: %s\n", __func__, *dom0_cmdline);
+            break;
+        }
+    }
+
+    return builtin_cmdline;
 }

 static int save_props(void *m, ofdn_t n, int pkg)
@@ -894,8 +930,8 @@ static void __init boot_of_fix_maple(voi
         }
     }
 }
-
-static int __init boot_of_serial(void *oft)
+
+void __init boot_of_serial(void *oft)
 {
     int n;
     int p;
@@ -975,11 +1011,9 @@ static int __init boot_of_serial(void *o
                   __func__, ns16550.irq);
         ns16550.irq = 0;
     }
-
-    return 1;
-}
-
-static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi)
+}
+
+static int __init boot_of_rtas(void)
 {
     int rtas_node;
     int rtas_instance;
@@ -1026,12 +1060,10 @@ static int __init boot_of_rtas(module_t
     rtas_end = mem + size;
     rtas_msr = of_msr;

-    mod->mod_start = rtas_base;
-    mod->mod_end = rtas_end;
     return 1;

hmm, aren't you going to create a tag so you know where RTAS has been placed and how big it is?

 }

-static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
+void __init *boot_of_devtree(void)
 {
     void *oft;
     ulong oft_sz = 48 * PAGE_SIZE;
@@ -1057,105 +1089,32 @@ static void * __init boot_of_devtree(mod

     ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2);

-    mod->mod_start = (ulong)oft;
-    mod->mod_end = mod->mod_start + oft_sz;
-    of_printf("%s: devtree mod @ 0x%016x - 0x%016x\n", __func__,
-              mod->mod_start, mod->mod_end);
+    oftree = (ulong)oft;
+    oftree_end = (ulong)oft + oft_sz;
+    oftree_len = oft_sz;

     return oft;
 }

-static void * __init boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
-{
-    static module_t mods[4];
-    ulong mod0_start;
-    ulong mod0_size;
-    static const char * sepr[] = {" -- ", " || "};
-    int sepr_index;
+/* Create a module tag for dom0. */
+static void __init boot_of_module(char *dom0_cmdline)
+{
+    struct mb2_tag_module *tag;
     extern char dom0_start[] __attribute__ ((weak));
     extern char dom0_size[] __attribute__ ((weak));
-    const char *p = NULL;
-    int mod;
-    void *oft;
-

A mentioned above, please do not remove the logic below,

-    if ((r3 > 0) && (r4 > 0)) {
-        /* was it handed to us in registers ? */
-        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 = simple_strtoul(p, NULL, 0);
-
-            p = strstr((char *)((ulong)mbi->cmdline), "dom0_size=");
-            p += 10;
-            mod0_size = simple_strtoul(p, NULL, 0);
-            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 = (ulong)dom0_start;
-            mod0_size = (ulong)dom0_size;
-            of_printf("%s: Dom0 is linked in: 0x%lx[size 0x%lx]\n",
-                      __func__, mod0_start, mod0_size);
-        } else {
-            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]);
-    }
-
-    mod = 0;
-    mods[mod].mod_start = mod0_start;
-    mods[mod].mod_end = mod0_start + mod0_size;
-
-    of_printf("%s: dom0 mod @ 0x%016x[0x%x]\n", __func__,
-              mods[mod].mod_start, mods[mod].mod_end);
-
-    /* look for delimiter: "--" or "||" */
- for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index+ +){
-        p = strstr((char *)(ulong)mbi->cmdline, sepr[sepr_index]);
-        if (p != NULL)
-            break;
-    }
-
-    if (p != NULL) {
-        /* Xen proper should never know about the dom0 args.  */
-        *(char *)p = '\0';
-        p += strlen(sepr[sepr_index]);
-        mods[mod].string = (u32)(ulong)p;
-        of_printf("%s: dom0 mod string: %s\n", __func__, p);
-    }
-
-    ++mod;
-    if (boot_of_rtas(&mods[mod], mbi))
-        ++mod;
-
-    oft = boot_of_devtree(&mods[mod], mbi);
-    if (oft == NULL)
-        of_panic("%s: boot_of_devtree failed\n", __func__);
-
-    ++mod;
-
-    mbi->flags |= MBI_MODULES;
-    mbi->mods_count = mod;
-    mbi->mods_addr = (u32)mods;
-
-    return oft;
+    const char *c = (const char *)dom0_start;
+
+    if (dom0_size == 0)
+        return;
+
+ of_printf("%s: dom0 @ %p[%p]\n", __func__, dom0_start, dom0_size);
+    of_printf("dom0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
+
+ tag = alloc_tag(MB2_TAG_MODULE, sizeof(*tag) + strlen (dom0_cmdline));
+    tag->addr = (ulong)dom0_start;
+    tag->size = (ulong)dom0_size;
+    strcpy(tag->type, "dom0");
+    strcpy(tag->cmdline, dom0_cmdline);
 }

 static int __init boot_of_cpus(void)
@@ -1278,15 +1237,19 @@ static int __init boot_of_cpus(void)
     return 1;
 }

-multiboot_info_t __init *boot_of_init(
- ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
-{
-    static multiboot_info_t mbi;
-    void *oft;
+void __init boot_of_init(ulong vec, ulong orig_msr)
+{
     int r;

     of_vec = vec;
     of_msr = orig_msr;
+
+    if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
+ of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
+                "that ranges: %p .. %p.\n",
+                vec, _start, _end);
+    }
+    of_printf("%s: _start %p _end %p\n", __func__, _start, _end);

     bof_chosen = of_finddevice("/chosen");
     of_getprop(bof_chosen, "stdout", &of_out, sizeof (of_out));
@@ -1297,32 +1260,56 @@ multiboot_info_t __init *boot_of_init(
               xen_compile_by(), xen_compile_domain(),
               xen_compiler(), xen_compile_date());

-    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)) {
- of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
-                "that ranges: %p .. %p.\n",
-                vec, _start, _end);
-    }
- of_printf("%s: _start %p _end %p 0x%lx\n", __func__, _start, _end, r6);
-
     boot_of_fix_maple();
     r = boot_of_mem_init();
     if (r == 0)
         of_panic("failure to initialize memory allocator");
-    boot_of_bootargs(&mbi);
-    oft = boot_of_module(r3, r4, &mbi);
+
+    boot_of_rtas();
     boot_of_cpus();
-    boot_of_serial(oft);
-
+}
+
+/* Create a structure as if we were loaded by a multiboot bootloader. */
+struct mb2_tag_header __init *boot_of_multiboot(void)
+{
+    struct mb2_tag_start *start;
+    struct mb2_tag_name *name;
+    struct mb2_tag_module *xenmod;
+    struct mb2_tag_end *end;
+    char *xen_cmdline;
+    char *dom0_cmdline = NULL;
+    static char *namestr = "xen";
+
+    /* create "start" tag. start->size is filled in later. */
+    start = alloc_tag(MB2_TAG_START, sizeof(*start));
+
+    /* create "name" tag. */
+    name = alloc_tag(MB2_TAG_NAME, sizeof(*name) + strlen(namestr));

Are you intentionally skipping the '\0' that in the alloc

+    strcpy(name->name, namestr);

strcpy() will copy the '\0' so you will will be stepping on something here

+
+    /* figure out the command line and create the Xen module tag. */
+    xen_cmdline = boot_of_bootargs(&dom0_cmdline);
+ xenmod = alloc_tag(MB2_TAG_MODULE, sizeof(*xenmod) + strlen (xen_cmdline));
+    xenmod->addr = (ulong)_start;
+    xenmod->size = _end - _start;
+    strcpy(xenmod->type, "xen");
+    strcpy(xenmod->cmdline, xen_cmdline);
+
+    /* create more module tags. */
+    boot_of_module(dom0_cmdline);
+
+    /* create "end" tag and terminate "start" tag. */
+    end = alloc_tag(MB2_TAG_END, sizeof(*end));
+    start->size = xentags_pos;
+
+    return (struct mb2_tag_header *)xentags;
+}
+
+void __init boot_of_finish(void)
+{
     /* end of OF */
     of_printf("Quiescing Open Firmware ...\n");
     of_call("quiesce", 0, 0, NULL);
-
-    return &mbi;
 }

 /*
diff -r dbc74db14a4b xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h     Tue Dec 12 14:35:07 2006 -0600
+++ b/xen/arch/powerpc/exceptions.h     Tue Jan 02 15:49:20 2007 -0600
@@ -33,9 +33,6 @@ extern void ack_APIC_irq(void);
 extern void ack_APIC_irq(void);
extern int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval); extern int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val);
-extern void __start_xen_ppc(
- ulong r3, ulong r4, ulong r5, ulong r6, ulong r7, ulong orig_msr); -extern multiboot_info_t *boot_of_init(ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr);

 extern void do_timer(struct cpu_user_regs *regs);
 extern void do_dec(struct cpu_user_regs *regs);
diff -r dbc74db14a4b xen/arch/powerpc/memory.c
--- a/xen/arch/powerpc/memory.c Tue Dec 12 14:35:07 2006 -0600
+++ b/xen/arch/powerpc/memory.c Tue Jan 02 15:58:29 2007 -0600
@@ -21,6 +21,8 @@
 #include <xen/sched.h>
 #include <xen/mm.h>
 #include <xen/numa.h>
+#include <xen/multiboot2.h>
+#include <asm/boot.h>
 #include "of-devtree.h"
 #include "oftree.h"
 #include "rtas.h"
@@ -141,43 +143,9 @@ static void ofd_walk_mem(void *m, walk_m
     }
 }

-static void setup_xenheap(module_t *mod, int mcount)
-{
-    int i;
-    ulong freemem;
-
-    freemem = ALIGN_UP((ulong)_end, PAGE_SIZE);
-
-    for (i = 0; i < mcount; i++) {
-        u32 s;
-
-        if (mod[i].mod_end == mod[i].mod_start)
-            continue;
-
-        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");
-
-        free_xenheap(freemem, s);
-        freemem = ALIGN_UP(mod[i].mod_end, PAGE_SIZE);
-
-    }
-
-    /* the rest of the xenheap, starting at the end of modules */
-    free_xenheap(freemem, xenheap_phys_end);
-}
-
-void memory_init(module_t *mod, int mcount)

We did a lot of work here so that stuff could be placed anywhere. I admit it was not pretty but I'd expect this patch to replace/improve not remove.

+void memory_init(ulong mod_end)
 {
     ulong eomem;
-    ulong heap_start;
     ulong xh_pages;

     /* lets find out how much memory there is and set max_page */
@@ -185,19 +153,8 @@ void memory_init(module_t *mod, int mcou
     printk("Physical RAM map:\n");
     ofd_walk_mem((void *)oftree, set_max_page);
     eomem = max_page << PAGE_SHIFT;
-
-    if (eomem == 0){
+    if (eomem == 0) {
         panic("ofd_walk_mem() failed\n");
-    }
-
-    /* find the portion of memory we need to keep safe */
-    save_start = oftree;
-    save_end = oftree_end;
-    if (rtas_base) {
-        if (save_start > rtas_base)
-            save_start = rtas_base;
-        if (save_end < rtas_end)
-            save_end = rtas_end;
     }

/* minimum heap has to reach to the end of all Xen required memory */
@@ -214,16 +171,10 @@ void memory_init(module_t *mod, int mcou

printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);

-    /* 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) {
+    freemem_start = init_boot_allocator(freemem_start);
+    if (freemem_start > (ulong)_start) {
         panic("space below _start (%p) is not enough memory "
-              "for heap (0x%lx)\n", _start, heap_start);
+              "for heap (0x%lx)\n", _start, freemem_start);
     }

     /* allow everything else to be allocated */
@@ -242,12 +193,14 @@ void memory_init(module_t *mod, int mcou

     numa_initmem_init(0, max_page);

+    /* domain heap gets all the still-unclaimed memory */
     end_boot_allocator();

-    /* Add memory between the beginning of the heap and the beginning
-     * of our text */
-    free_xenheap(heap_start, (ulong)_start);
-    setup_xenheap(mod, mcount);
+    /* xen heap: memory below _start */
+    free_xenheap(freemem_start, (ulong)_start);
+    /* xen heap: memory after modules */
+    free_xenheap(mod_end, xenheap_phys_end);
+
     printk("Xen Heap: %luMiB (%luKiB)\n",
            xenheap_size >> 20, xenheap_size >> 10);

diff -r dbc74db14a4b xen/arch/powerpc/oftree.h
--- a/xen/arch/powerpc/oftree.h Tue Dec 12 14:35:07 2006 -0600
+++ b/xen/arch/powerpc/oftree.h Tue Jan 02 15:51:54 2007 -0600
@@ -34,6 +34,4 @@ extern int firmware_image_start[0];
 extern int firmware_image_start[0];
 extern int firmware_image_size[0];

-extern void memory_init(module_t *mod, int mcount);
-
 #endif  /* #ifndef _OFTREE_H */
diff -r dbc74db14a4b xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Tue Dec 12 14:35:07 2006 -0600
+++ b/xen/arch/powerpc/setup.c  Wed Jan 03 11:04:10 2007 -0600
@@ -24,8 +24,8 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/cpumask.h>
+#include <xen/multiboot2.h>
 #include <xen/sched.h>
-#include <xen/multiboot.h>
 #include <xen/serial.h>
 #include <xen/softirq.h>
 #include <xen/console.h>
@@ -46,6 +46,7 @@
 #include <asm/delay.h>
 #include <asm/percpu.h>
 #include <asm/io.h>
+#include <asm/boot.h>
 #include "exceptions.h"
 #include "of-devtree.h"
 #include "oftree.h"
@@ -76,6 +77,7 @@ ulong oftree;
 ulong oftree;
 ulong oftree_len;
 ulong oftree_end;
+ulong freemem_start;

 uint cpu_hard_id[NR_CPUS] __initdata;
 cpumask_t cpu_present_map;
@@ -287,21 +289,31 @@ void secondary_cpu_init(int cpuid, unsig
     panic("should never get here\n");
 }

-static void __init __start_xen(multiboot_info_t *mbi)
-{
-    char *cmdline;
-    module_t *mod = (module_t *)((ulong)mbi->mods_addr);
-    ulong dom0_start, dom0_len;
-    ulong initrd_start, initrd_len;
+static void __init __start_xen(struct mb2_tag_header *tags)
+{
+    struct mb2_tag_header *tag;
+    ulong mod_end = (ulong)_end;
+    char *dom0_cmdline;
+    ulong dom0_start = 0;
+    ulong dom0_len = 0;
+    ulong initrd_start = 0;
+    ulong initrd_len = 0;

memcpy(0, exception_vectors, exception_vectors_end - exception_vectors);
     synchronize_caches(0, exception_vectors_end - exception_vectors);

     ticks_per_usec = timebase_freq / 1000000ULL;

-    /* Parse the command-line options. */
-    if ((mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0))
-        cmdline_parse(__va((ulong)mbi->cmdline));
+    /* parse the command-line options. */

Can you make the following a function:
struct mb2_tag_module *find_tag_mod_type(uint32_t key, const char *type)

It will be handy as more tags are created.

+    for_each_tag(tag, tags) {
+        if (tag->key == MB2_TAG_MODULE) {
+ struct mb2_tag_module *module = (struct mb2_tag_module *)tag;
+            if (!strcmp(module->type, "xen")) {
+                cmdline_parse(module->cmdline);
+                break;
+            }
+        }
+    }

     /* we need to be able to identify this CPU early on */
     init_boot_cpu();
@@ -314,32 +326,28 @@ static void __init __start_xen(multiboot
     serial_init_preirq();

     init_console();
-    /* let synchronize until we really get going */
-    console_start_sync();
-
-    /* Check that we have at least one Multiboot module. */
-    if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) {
- panic("FATAL ERROR: Require at least one Multiboot module. \n");
-    }
-
-    /* OF dev tree is the last module */
-    oftree = mod[mbi->mods_count-1].mod_start;
-    oftree_end = mod[mbi->mods_count-1].mod_end;
-    oftree_len = oftree_end - oftree;
-
-    /* remove it from consideration */
-    mod[mbi->mods_count-1].mod_start = 0;
-    mod[mbi->mods_count-1].mod_end = 0;
-    --mbi->mods_count;
-
-    if (rtas_entry) {
-        rtas_init((void *)oftree);
-        /* remove rtas module from consideration */
-        mod[mbi->mods_count-1].mod_start = 0;
-        mod[mbi->mods_count-1].mod_end = 0;
-        --mbi->mods_count;
-    }
-    memory_init(mod, mbi->mods_count);
+    console_start_sync(); /* stay synchronous for early debugging. */
+
+    rtas_init((void *)oftree);
+
+    /* copy modules to a contiguous space immediately after Xen */

We stopped doing this copy because it was unnecessary, I believe it still is what the reason for putting it back?
How do the original pages get released back into the xenheap?

+    for_each_tag(tag, tags) {
+        if (tag->key == MB2_TAG_MODULE) {
+ struct mb2_tag_module *module = (struct mb2_tag_module *)tag; + memmove((void *)mod_end, (void *)(ulong)module->addr, module->size);
+            if (!strcmp(module->type, "dom0")) {
+                dom0_start = mod_end;
+                dom0_len = module->size;
+                dom0_cmdline = module->cmdline;
+            } else if (!strcmp(module->type, "initrd")) {
+                initrd_start = mod_end;
+                initrd_len = module->size;
+            }
+            mod_end += module->size;
+        }
+    }
+
+    memory_init(mod_end);

 #ifdef OF_DEBUG
     key_ofdump(0);
@@ -392,25 +400,17 @@ static void __init __start_xen(multiboot
     /* Post-create hook sets security label. */
     acm_post_domain0_create(dom0->domain_id);

- cmdline = (char *)(mod[0].string ? __va((ulong)mod [0].string) : NULL);
-
/* scrub_heap_pages() requires IRQs enabled, and we're post IRQ setup... */
     local_irq_enable();
/* Scrub RAM that is still free and so may go to an unprivileged domain. */
     scrub_heap_pages();

-    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 ((dom0_start == 0) || (dom0_len == 0))
+        panic("No domain 0 found.\n");
+
     if (construct_dom0(dom0, dom0_start, dom0_len,
                        initrd_start, initrd_len,
-                       cmdline) != 0) {
+                       dom0_cmdline) != 0) {
         panic("Could not set up DOM0 guest OS\n");
     }

@@ -439,22 +439,37 @@ void __init __start_xen_ppc(
 void __init __start_xen_ppc(
     ulong r3, ulong r4, ulong r5, ulong r6, ulong r7, ulong orig_msr)
 {
-    multiboot_info_t *mbi = NULL;
+    struct mb2_tag_header *tags = NULL;
+    void *oft;
+
+    /* Open Firmware required. */
+    if (!r5)
+        return;

     /* clear bss */
     memset(__bss_start, 0, (ulong)_end - (ulong)__bss_start);

-    if (r5 > 0) {
-        /* we were booted by OpenFirmware */
-        mbi = boot_of_init(r3, r4, r5, r6, r7, orig_msr);
-
+    boot_of_init(r5, orig_msr);
+    /* copy device tree from firmware */
+    oft = boot_of_devtree();
+    freemem_start = oftree_end;
+
+    /* detect the Xen console from the device tree */
+    boot_of_serial(oft);
+
+    if (r3 == MB2_BOOTLOADER_MAGIC) {
+        tags = (struct mb2_tag_header *)r4;
+        if (tags->key != MB2_TAG_START)

If this fails, why not just continue with the fake up?

+            return;
     } else {
- /* booted by someone else that hopefully has a trap handler */
-        __builtin_trap();
-    }
-
-    __start_xen(mbi);
-

the fake multiboot stuff should be in its own file and we can keep boot_of.c clean.

+ /* We were booted directly from Open Firmware. Fake up some multiboot
+         * tags. */
+        tags = boot_of_multiboot();
+    }
+
+    boot_of_finish();
+
+    __start_xen(tags);
 }

 extern void arch_get_xen_caps(xen_capabilities_info_t info);
diff -r dbc74db14a4b xen/include/asm-powerpc/boot.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-powerpc/boot.h    Tue Jan 02 15:55:49 2007 -0600
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2005
+ *
+ * Authors: Hollis Blanchard <[EMAIL PROTECTED]>
+ */
+
+#ifndef _ASM_BOOT_H
+#define _ASM_BOOT_H
+
+struct mb2_tag_header;
+
+extern ulong freemem_start;
+
+extern void boot_of_init(ulong, ulong);
+extern void *boot_of_devtree(void);
+extern void boot_of_serial(void *);
+extern struct mb2_tag_header *boot_of_multiboot(void);
+extern void boot_of_finish(void);
+
+extern void __start_xen_ppc(ulong, ulong, ulong, ulong, ulong, ulong);
+
+extern void memory_init(ulong);
+
+#endif
diff -r dbc74db14a4b xen/include/xen/multiboot2.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/multiboot2.h      Tue Jan 02 15:41:42 2007 -0600
@@ -0,0 +1,102 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <[EMAIL PROTECTED]>
+ *
+ */
+
+#ifndef _MULTIBOOT2_H_
+#define _MULTIBOOT2_H_
+
+/* How many bytes from the start of the file we search for the header. */
+#define MB2_HEADER_SEARCH           8192
+
+/* The magic field should contain this.  */
+#define MB2_HEADER_MAGIC            0xe85250d6
+
+/* Passed from the bootloader to the kernel.  */
+#define MB2_BOOTLOADER_MAGIC        0x36d76289
+
+#include <stdint.h>
+
+#define for_each_tag(_tag, _tags) \
+    for ((_tag) = (_tags); \
+            (_tag)->key != MB2_TAG_END; \
+            (_tag) = (void *)(_tag) + (_tag)->len)
+
+typedef uint32_t mb2_word;
+
+struct mb2_header
+{
+  uint32_t magic;
+};
+
+struct mb2_tag_header
+{
+  uint32_t key;
+  uint32_t len;
+};
+
+#define MB2_TAG_RESERVED1 0
+#define MB2_TAG_RESERVED2 (~0)
+
+#define MB2_TAG_START     1
+struct mb2_tag_start
+{
+  struct mb2_tag_header header;
+  mb2_word size; /* Total size of all mb2 tags. */
+};
+
+#define MB2_TAG_NAME      2
+struct mb2_tag_name
+{
+  struct mb2_tag_header header;
+  char name[1];
+};
+
+#define MB2_TAG_MODULE    3
+struct mb2_tag_module
+{
+  struct mb2_tag_header header;
+  mb2_word addr;
+  mb2_word size;
+  unsigned char type[36];
+  unsigned char cmdline[1];
+};
+
+#define MB2_TAG_MEMORY    4
+struct mb2_tag_memory
+{
+  struct mb2_tag_header header;
+  mb2_word addr;
+  mb2_word size;
+  mb2_word type;
+};
+
+#define MB2_TAG_UNUSED    5
+struct mb2_tag_unused
+{
+  struct mb2_tag_header header;
+};
+
+#define MB2_TAG_END       0xffff
+struct mb2_tag_end
+{
+  struct mb2_tag_header header;
+};
+
+#endif


--
Hollis Blanchard
IBM Linux Technology Center


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


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

Reply via email to