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-changelog

[Xen-changelog] [xen-unstable] merge with xen-ia64-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-ia64-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 18 Jan 2007 21:10:21 -0800
Delivery-date: Thu, 18 Jan 2007 21:11:08 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1166207578 25200
# Node ID e17d7438e09e5ead12049b44f5bf9d842a401129
# Parent  1e042dde1a5f2a56ed6517e00ac83d44f324a652
# Parent  41d9f00140c51783ef4030b4f646feb36af7c195
merge with xen-ia64-unstable.hg
---
 tools/libxen/include/xen_boot_type.h                        |   87 -
 tools/libxen/include/xen_boot_type_internal.h               |   37 
 tools/libxen/src/xen_boot_type.c                            |   83 -
 xen/arch/powerpc/boot/boot32.S                              |   75 -
 xen/arch/powerpc/boot/start.S                               |   51 
 xen/arch/powerpc/delay.c                                    |   37 
 xen/arch/powerpc/mambo.S                                    |   64 -
 xen/include/asm-powerpc/misc.h                              |   33 
 xen/include/asm-powerpc/uaccess.h                           |   38 
 .hgignore                                                   |   13 
 config/powerpc64.mk                                         |    2 
 linux-2.6-xen-sparse/arch/i386/kernel/fixup.c               |   10 
 linux-2.6-xen-sparse/arch/ia64/Kconfig                      |    1 
 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c             |   25 
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c            |   28 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c        |    4 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c      |    2 
 linux-2.6-xen-sparse/net/core/skbuff.c                      |   11 
 patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch |   21 
 patches/linux-2.6.16.33/series                              |    1 
 tools/Rules.mk                                              |    4 
 tools/blktap/drivers/blktapctrl.c                           |   49 
 tools/blktap/drivers/block-qcow.c                           |  120 +-
 tools/blktap/drivers/qcow-create.c                          |   71 -
 tools/check/check_crypto_lib                                |   17 
 tools/check/check_openssl_devel                             |   17 
 tools/check/check_python                                    |    5 
 tools/check/check_python_devel                              |   17 
 tools/check/check_python_xml                                |    8 
 tools/check/check_udev                                      |   40 
 tools/check/check_x11_devel                                 |   18 
 tools/examples/external-device-migrate                      |    4 
 tools/ioemu/target-i386-dm/exec-dm.c                        |   11 
 tools/ioemu/vl.c                                            |    7 
 tools/libaio/src/syscall-ppc.h                              |    6 
 tools/libxc/ia64/xc_ia64_hvm_build.c                        |   10 
 tools/libxc/powerpc64/Makefile                              |    4 
 tools/libxc/powerpc64/flatdevtree.c                         |   23 
 tools/libxc/powerpc64/flatdevtree.h                         |    2 
 tools/libxc/powerpc64/utils.c                               |  211 +++
 tools/libxc/powerpc64/utils.h                               |   38 
 tools/libxc/powerpc64/xc_linux_build.c                      |  292 +----
 tools/libxc/powerpc64/xc_prose_build.c                      |  323 +++++
 tools/libxc/xc_linux_build.c                                |   16 
 tools/libxc/xc_load_elf.c                                   |   28 
 tools/libxc/xenctrl.h                                       |    4 
 tools/libxc/xenguest.h                                      |   15 
 tools/libxc/xg_private.h                                    |    1 
 tools/libxen/include/xen_console.h                          |    4 
 tools/libxen/include/xen_host.h                             |    4 
 tools/libxen/include/xen_host_cpu.h                         |    4 
 tools/libxen/include/xen_internal.h                         |    1 
 tools/libxen/include/xen_network.h                          |    4 
 tools/libxen/include/xen_pif.h                              |    4 
 tools/libxen/include/xen_sr.h                               |    4 
 tools/libxen/include/xen_user.h                             |    4 
 tools/libxen/include/xen_vdi.h                              |    4 
 tools/libxen/include/xen_vif.h                              |    4 
 tools/libxen/include/xen_vm.h                               |  289 +++--
 tools/libxen/include/xen_vtpm.h                             |    4 
 tools/libxen/src/xen_console.c                              |    2 
 tools/libxen/src/xen_vif.c                                  |    2 
 tools/libxen/src/xen_vm.c                                   |  550 +++++----
 tools/libxen/src/xen_vtpm.c                                 |    2 
 tools/libxen/test/test_bindings.c                           |   76 +
 tools/python/xen/lowlevel/xc/xc.c                           |   87 +
 tools/python/xen/xend/FlatDeviceTree.py                     |   94 +
 tools/python/xen/xend/XendAPI.py                            |  155 +-
 tools/python/xen/xend/XendBootloader.py                     |   17 
 tools/python/xen/xend/XendConfig.py                         |   83 -
 tools/python/xen/xend/XendDomain.py                         |   10 
 tools/python/xen/xend/XendDomainInfo.py                     |  309 ++---
 tools/python/xen/xend/XendStorageRepository.py              |   16 
 tools/python/xen/xend/image.py                              |   81 +
 tools/python/xen/xend/server/DevController.py               |   41 
 tools/python/xen/xend/server/SrvDomain.py                   |    9 
 tools/python/xen/xend/server/blkif.py                       |    6 
 tools/python/xen/xm/XenAPI.py                               |    4 
 tools/python/xen/xm/main.py                                 |  253 ++--
 tools/xenstore/xenstored_domain.c                           |    2 
 xen/arch/ia64/xen/xensetup.c                                |    6 
 xen/arch/powerpc/Makefile                                   |   69 -
 xen/arch/powerpc/backtrace.c                                |   34 
 xen/arch/powerpc/bitops.c                                   |  124 +-
 xen/arch/powerpc/boot_of.c                                  |  621 +++++++----
 xen/arch/powerpc/cmdline.c                                  |   24 
 xen/arch/powerpc/crash.c                                    |    1 
 xen/arch/powerpc/dart.c                                     |   13 
 xen/arch/powerpc/dart_u4.c                                  |    7 
 xen/arch/powerpc/domain.c                                   |   33 
 xen/arch/powerpc/domain_build.c                             |    3 
 xen/arch/powerpc/domctl.c                                   |    6 
 xen/arch/powerpc/exceptions.c                               |   34 
 xen/arch/powerpc/exceptions.h                               |    7 
 xen/arch/powerpc/external.c                                 |   30 
 xen/arch/powerpc/gdbstub.c                                  |    1 
 xen/arch/powerpc/iommu.c                                    |   34 
 xen/arch/powerpc/machine_kexec.c                            |    6 
 xen/arch/powerpc/memory.c                                   |  104 +
 xen/arch/powerpc/mm.c                                       |  235 +++-
 xen/arch/powerpc/mpic.c                                     |  127 +-
 xen/arch/powerpc/mpic_init.c                                |   54 
 xen/arch/powerpc/numa.c                                     |    1 
 xen/arch/powerpc/of-devtree.h                               |   40 
 xen/arch/powerpc/of-devwalk.c                               |   14 
 xen/arch/powerpc/of_handler/console.c                       |   12 
 xen/arch/powerpc/ofd_fixup.c                                |   12 
 xen/arch/powerpc/ofd_fixup_memory.c                         |   18 
 xen/arch/powerpc/papr/xlate.c                               |  259 ++--
 xen/arch/powerpc/powerpc64/exceptions.S                     |   18 
 xen/arch/powerpc/powerpc64/io.S                             |   65 -
 xen/arch/powerpc/powerpc64/ppc970.c                         |   71 -
 xen/arch/powerpc/powerpc64/ppc970_machinecheck.c            |    7 
 xen/arch/powerpc/powerpc64/ppc970_scom.c                    |  175 ++-
 xen/arch/powerpc/powerpc64/scom.h                           |   39 
 xen/arch/powerpc/powerpc64/traps.c                          |    4 
 xen/arch/powerpc/rtas.c                                     |   84 +
 xen/arch/powerpc/rtas.h                                     |   34 
 xen/arch/powerpc/setup.c                                    |  144 +-
 xen/arch/powerpc/shadow.c                                   |    7 
 xen/arch/powerpc/smp.c                                      |  192 +++
 xen/arch/powerpc/smpboot.c                                  |   29 
 xen/arch/powerpc/start.S                                    |   62 +
 xen/arch/powerpc/systemsim.S                                |   64 +
 xen/arch/powerpc/time.c                                     |    3 
 xen/arch/powerpc/usercopy.c                                 |  248 ----
 xen/arch/powerpc/xen.lds.S                                  |    8 
 xen/arch/x86/crash.c                                        |   23 
 xen/arch/x86/domain.c                                       |    4 
 xen/arch/x86/domain_build.c                                 |    8 
 xen/arch/x86/hvm/hvm.c                                      |    7 
 xen/arch/x86/hvm/i8254.c                                    |   41 
 xen/arch/x86/hvm/svm/svm.c                                  |   12 
 xen/arch/x86/hvm/vmx/vmcs.c                                 |    6 
 xen/arch/x86/hvm/vmx/vmx.c                                  |   30 
 xen/arch/x86/mm.c                                           |   12 
 xen/arch/x86/mm/shadow/common.c                             |    8 
 xen/arch/x86/mm/shadow/multi.c                              |    9 
 xen/arch/x86/numa.c                                         |    2 
 xen/arch/x86/traps.c                                        |   30 
 xen/common/Makefile                                         |    2 
 xen/common/domain.c                                         |   25 
 xen/common/elf.c                                            |   27 
 xen/common/gdbstub.c                                        |    1 
 xen/common/kexec.c                                          |   86 -
 xen/common/page_alloc.c                                     |   50 
 xen/common/sched_credit.c                                   |  663 +++++-------
 xen/common/xencomm.c                                        |  316 +++++
 xen/drivers/char/console.c                                  |    2 
 xen/include/asm-powerpc/acpi.h                              |    2 
 xen/include/asm-powerpc/cache.h                             |    1 
 xen/include/asm-powerpc/config.h                            |    4 
 xen/include/asm-powerpc/debugger.h                          |   70 +
 xen/include/asm-powerpc/delay.h                             |   16 
 xen/include/asm-powerpc/domain.h                            |    5 
 xen/include/asm-powerpc/flushtlb.h                          |    1 
 xen/include/asm-powerpc/grant_table.h                       |   12 
 xen/include/asm-powerpc/guest_access.h                      |   78 -
 xen/include/asm-powerpc/mach-default/irq_vectors.h          |   22 
 xen/include/asm-powerpc/mm.h                                |  100 +
 xen/include/asm-powerpc/msr.h                               |    4 
 xen/include/asm-powerpc/numa.h                              |    2 
 xen/include/asm-powerpc/page.h                              |    5 
 xen/include/asm-powerpc/powerpc64/string.h                  |    3 
 xen/include/asm-powerpc/processor.h                         |  108 +
 xen/include/asm-powerpc/smp.h                               |   22 
 xen/include/asm-powerpc/spinlock.h                          |   33 
 xen/include/asm-powerpc/xenoprof.h                          |   26 
 xen/include/asm-x86/hvm/hvm.h                               |    7 
 xen/include/asm-x86/hvm/vpt.h                               |    2 
 xen/include/asm-x86/numa.h                                  |    2 
 xen/include/asm-x86/page.h                                  |   36 
 xen/include/asm-x86/shadow.h                                |    3 
 xen/include/asm-x86/x86_32/page-2level.h                    |    6 
 xen/include/asm-x86/x86_32/page-3level.h                    |   29 
 xen/include/asm-x86/x86_64/page.h                           |    6 
 xen/include/public/arch-ia64.h                              |    7 
 xen/include/public/arch-powerpc.h                           |    2 
 xen/include/public/domctl.h                                 |    8 
 xen/include/public/io/fbif.h                                |   88 -
 xen/include/public/io/kbdif.h                               |   70 -
 xen/include/public/io/pciif.h                               |   44 
 xen/include/public/io/xenbus.h                              |   12 
 xen/include/public/memory.h                                 |    2 
 xen/include/public/sysctl.h                                 |    2 
 xen/include/public/trace.h                                  |    2 
 xen/include/public/xenoprof.h                               |    2 
 xen/include/xen/elfcore.h                                   |    4 
 xen/include/xen/kexec.h                                     |    8 
 xen/include/xen/list.h                                      |  387 ++++---
 xen/include/xen/sched.h                                     |    2 
 xen/include/xen/xencomm.h                                   |  115 ++
 192 files changed, 6225 insertions(+), 3795 deletions(-)

diff -r 1e042dde1a5f -r e17d7438e09e .hgignore
--- a/.hgignore Fri Dec 15 10:59:33 2006 -0700
+++ b/.hgignore Fri Dec 15 11:32:58 2006 -0700
@@ -53,6 +53,8 @@
 ^docs/user/labels\.pl$
 ^docs/user/user\.css$
 ^docs/user/user\.html$
+^docs/xen-api/vm_lifecycle.eps$
+^docs/xen-api/xenapi-datamodel-graph.eps$
 ^extras/mini-os/h/hypervisor-ifs$
 ^extras/mini-os/h/xen-public$
 ^extras/mini-os/mini-os\..*$
@@ -98,17 +100,15 @@
 ^tools/firmware/.*\.bin$
 ^tools/firmware/.*\.sym$
 ^tools/firmware/.*bios/.*bios.*\.txt$
+^tools/firmware/hvmloader/acpi/acpigen$
 ^tools/firmware/hvmloader/hvmloader$
 ^tools/firmware/hvmloader/roms\.h$
 ^tools/firmware/rombios/BIOS-bochs-[^/]*$
 ^tools/firmware/rombios/_rombios[^/]*_\.c$
 ^tools/firmware/rombios/rombios[^/]*\.s$
-^tools/firmware/vmxassist/acpi\.h$
 ^tools/firmware/vmxassist/gen$
 ^tools/firmware/vmxassist/offsets\.h$
-^tools/firmware/vmxassist/roms\.h$
 ^tools/firmware/vmxassist/vmxassist$
-^tools/firmware/vmxassist/vmxloader$
 ^tools/ioemu/\.pc/.*$
 ^tools/ioemu/config-host\.h$
 ^tools/ioemu/config-host\.mak$
@@ -220,10 +220,11 @@
 ^xen/arch/powerpc/dom0\.bin$
 ^xen/arch/powerpc/asm-offsets\.s$
 ^xen/arch/powerpc/firmware$
-^xen/arch/powerpc/firmware_image$
+^xen/arch/powerpc/firmware_image.bin$
 ^xen/arch/powerpc/xen\.lds$
-^xen/arch/powerpc/.xen-syms$
-^xen/arch/powerpc/xen-syms.S$
+^xen/arch/powerpc/\.xen-syms$
+^xen/arch/powerpc/xen-syms\.S$
+^xen/arch/powerpc/cmdline.dep$
 ^unmodified_drivers/linux-2.6/\.tmp_versions
 ^unmodified_drivers/linux-2.6/.*\.cmd$
 ^unmodified_drivers/linux-2.6/.*\.ko$
diff -r 1e042dde1a5f -r e17d7438e09e config/powerpc64.mk
--- a/config/powerpc64.mk       Fri Dec 15 10:59:33 2006 -0700
+++ b/config/powerpc64.mk       Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,7 @@ CONFIG_POWERPC := y
 CONFIG_POWERPC := y
 CONFIG_POWERPC_$(XEN_OS) := y
 
+CONFIG_XENCOMM := y
+
 CFLAGS += -DELFSIZE=64
 LIBDIR := lib
diff -r 1e042dde1a5f -r e17d7438e09e 
linux-2.6-xen-sparse/arch/i386/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c     Fri Dec 15 10:59:33 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c     Fri Dec 15 11:32:58 
2006 -0700
@@ -43,17 +43,17 @@ fastcall void do_fixup_4gb_segment(struc
        char info[100];
        int i;
 
-       if (test_and_set_bit(0, &printed))
+       /* Ignore statically-linked init. */
+       if (current->tgid == 1)
                return;
-
-        if (current->tgid == 1) /* Ignore statically linked init */
-                return; 
             
        HYPERVISOR_vm_assist(
                VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
 
+       if (test_and_set_bit(0, &printed))
+               return;
+
        sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
-
 
        DP("");
        DP("***************************************************************");
diff -r 1e042dde1a5f -r e17d7438e09e linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Fri Dec 15 10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Fri Dec 15 11:32:58 2006 -0700
@@ -532,6 +532,7 @@ config XEN_BALLOON
 
 config XEN_SKBUFF
        default y
+       depends on NET
 
 config XEN_REBOOT
        default y
diff -r 1e042dde1a5f -r e17d7438e09e 
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Fri Dec 15 10:59:33 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Fri Dec 15 11:32:58 
2006 -0700
@@ -110,6 +110,18 @@ set_cpu_sibling_map(int cpu)
        cpu_data[cpu].booted_cores = 1;
 }
 
+static void
+remove_siblinginfo(int cpu)
+{
+       phys_proc_id[cpu] = BAD_APICID;
+       cpu_core_id[cpu]  = BAD_APICID;
+
+       cpus_clear(cpu_sibling_map[cpu]);
+       cpus_clear(cpu_core_map[cpu]);
+
+       cpu_data[cpu].booted_cores = 0;
+}
+
 static int xen_smp_intr_init(unsigned int cpu)
 {
        int rc;
@@ -358,18 +370,6 @@ static int __init initialize_cpu_present
 }
 core_initcall(initialize_cpu_present_map);
 
-static void
-remove_siblinginfo(int cpu)
-{
-       phys_proc_id[cpu] = BAD_APICID;
-       cpu_core_id[cpu]  = BAD_APICID;
-
-       cpus_clear(cpu_sibling_map[cpu]);
-       cpus_clear(cpu_core_map[cpu]);
-
-       cpu_data[cpu].booted_cores = 0;
-}
-
 int __cpu_disable(void)
 {
        cpumask_t map = cpu_online_map;
@@ -432,7 +432,6 @@ int __devinit __cpu_up(unsigned int cpu)
        /* This must be done before setting cpu_online_map */
        set_cpu_sibling_map(cpu);
        wmb();
-
 
        rc = xen_smp_intr_init(cpu);
        if (rc) {
diff -r 1e042dde1a5f -r e17d7438e09e 
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c  Fri Dec 15 10:59:33 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c  Fri Dec 15 11:32:58 
2006 -0700
@@ -105,7 +105,6 @@ static int xenfb_queue_full(struct xenfb
 
 static void xenfb_update_screen(struct xenfb_info *info)
 {
-       unsigned long flags;
        int y1, y2, x1, x2;
        struct xenfb_mapping *map;
 
@@ -114,7 +113,7 @@ static void xenfb_update_screen(struct x
        if (xenfb_queue_full(info))
                return;
 
-       spin_lock_irqsave(&info->mm_lock, flags);
+       spin_lock(&info->mm_lock);
 
        y1 = info->y1;
        y2 = info->y2;
@@ -131,7 +130,7 @@ static void xenfb_update_screen(struct x
                map->faults = 0;
        }
 
-       spin_unlock_irqrestore(&info->mm_lock, flags);
+       spin_unlock(&info->mm_lock);
 
        xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
 }
@@ -214,11 +213,9 @@ static void xenfb_refresh(struct xenfb_i
 static void xenfb_refresh(struct xenfb_info *info,
                          int x1, int y1, int w, int h)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&info->mm_lock, flags);
+       spin_lock(&info->mm_lock);
        __xenfb_refresh(info, x1, y1, w, h);
-       spin_unlock_irqrestore(&info->mm_lock, flags);
+       spin_unlock(&info->mm_lock);
 }
 
 static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
@@ -255,14 +252,13 @@ static void xenfb_vm_close(struct vm_are
 {
        struct xenfb_mapping *map = vma->vm_private_data;
        struct xenfb_info *info = map->info;
-       unsigned long flags;
-
-       spin_lock_irqsave(&info->mm_lock, flags);
+
+       spin_lock(&info->mm_lock);
        if (atomic_dec_and_test(&map->map_refs)) {
                list_del(&map->link);
                kfree(map);
        }
-       spin_unlock_irqrestore(&info->mm_lock, flags);
+       spin_unlock(&info->mm_lock);
 }
 
 static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
@@ -271,14 +267,13 @@ static struct page *xenfb_vm_nopage(stru
        struct xenfb_mapping *map = vma->vm_private_data;
        struct xenfb_info *info = map->info;
        int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
-       unsigned long flags;
        struct page *page;
        int y1, y2;
 
        if (pgnr >= info->nr_pages)
                return NOPAGE_SIGBUS;
 
-       spin_lock_irqsave(&info->mm_lock, flags);
+       spin_lock(&info->mm_lock);
        page = info->pages[pgnr];
        get_page(page);
        map->faults++;
@@ -288,7 +283,7 @@ static struct page *xenfb_vm_nopage(stru
        if (y2 > info->fb_info->var.yres)
                y2 = info->fb_info->var.yres;
        __xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
-       spin_unlock_irqrestore(&info->mm_lock, flags);
+       spin_unlock(&info->mm_lock);
 
        if (type)
                *type = VM_FAULT_MINOR;
@@ -305,7 +300,6 @@ static int xenfb_mmap(struct fb_info *fb
 static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
 {
        struct xenfb_info *info = fb_info->par;
-       unsigned long flags;
        struct xenfb_mapping *map;
        int map_pages;
 
@@ -329,9 +323,9 @@ static int xenfb_mmap(struct fb_info *fb
        map->info = info;
        atomic_set(&map->map_refs, 1);
 
-       spin_lock_irqsave(&info->mm_lock, flags);
+       spin_lock(&info->mm_lock);
        list_add(&map->link, &info->mappings);
-       spin_unlock_irqrestore(&info->mm_lock, flags);
+       spin_unlock(&info->mm_lock);
 
        vma->vm_ops = &xenfb_vm_ops;
        vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
diff -r 1e042dde1a5f -r e17d7438e09e 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Dec 15 
10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Dec 15 
11:32:58 2006 -0700
@@ -525,6 +525,8 @@ static void backend_changed(struct xenbu
                break;
 
        case XenbusStateInitWait:
+               if (dev->state != XenbusStateInitialising)
+                       break;
                if (network_connect(netdev) != 0)
                        break;
                xenbus_switch_state(dev, XenbusStateConnected);
@@ -532,6 +534,8 @@ static void backend_changed(struct xenbu
                break;
 
        case XenbusStateClosing:
+               if (dev->state == XenbusStateClosed)
+                       break;
                netfront_closing(dev);
                break;
        }
diff -r 1e042dde1a5f -r e17d7438e09e 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Dec 15 
10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Dec 15 
11:32:58 2006 -0700
@@ -487,6 +487,8 @@ int xenbus_probe_node(struct xen_bus_typ
        if (!xendev)
                return -ENOMEM;
 
+       xendev->state = XenbusStateInitialising;
+
        /* Copy the strings into the extra space. */
 
        tmpstring = (char *)(xendev + 1);
diff -r 1e042dde1a5f -r e17d7438e09e linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c    Fri Dec 15 10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c    Fri Dec 15 11:32:58 2006 -0700
@@ -1875,7 +1875,7 @@ struct sk_buff *skb_segment(struct sk_bu
        do {
                struct sk_buff *nskb;
                skb_frag_t *frag;
-               int hsize, nsize;
+               int hsize;
                int k;
                int size;
 
@@ -1886,11 +1886,10 @@ struct sk_buff *skb_segment(struct sk_bu
                hsize = skb_headlen(skb) - offset;
                if (hsize < 0)
                        hsize = 0;
-               nsize = hsize + doffset;
-               if (nsize > len + doffset || !sg)
-                       nsize = len + doffset;
-
-               nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+               if (hsize > len || !sg)
+                       hsize = len;
+
+               nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
                if (unlikely(!nskb))
                        goto err;
 
diff -r 1e042dde1a5f -r e17d7438e09e 
patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch       Fri Dec 
15 11:32:58 2006 -0700
@@ -0,0 +1,26 @@
+diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c
+--- a/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
++++ b/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
+@@ -1946,7 +1946,7 @@
+       do {
+               struct sk_buff *nskb;
+               skb_frag_t *frag;
+-              int hsize, nsize;
++              int hsize;
+               int k;
+               int size;
+ 
+@@ -1957,11 +1957,10 @@
+               hsize = skb_headlen(skb) - offset;
+               if (hsize < 0)
+                       hsize = 0;
+-              nsize = hsize + doffset;
+-              if (nsize > len + doffset || !sg)
+-                      nsize = len + doffset;
++              if (hsize > len || !sg)
++                      hsize = len;
+ 
+-              nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
++              nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
+               if (unlikely(!nskb))
+                       goto err;
diff -r 1e042dde1a5f -r e17d7438e09e patches/linux-2.6.16.33/series
--- a/patches/linux-2.6.16.33/series    Fri Dec 15 10:59:33 2006 -0700
+++ b/patches/linux-2.6.16.33/series    Fri Dec 15 11:32:58 2006 -0700
@@ -17,6 +17,7 @@ net-gso-3-fix-errorcheck.patch
 net-gso-3-fix-errorcheck.patch
 net-gso-4-kill-warnon.patch
 net-gso-5-rcv-mss.patch
+net-gso-6-linear-segmentation.patch
 pci-mmconfig-fix-from-2.6.17.patch
 pmd-shared.patch
 rcu_needs_cpu.patch
diff -r 1e042dde1a5f -r e17d7438e09e tools/Rules.mk
--- a/tools/Rules.mk    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/Rules.mk    Fri Dec 15 11:32:58 2006 -0700
@@ -18,6 +18,10 @@ CFLAGS  += $(shell getconf LFS_CFLAGS)
 CFLAGS  += $(shell getconf LFS_CFLAGS)
 CFLAGS  += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
 LDFLAGS += $(shell getconf LFS_LDFLAGS)
+
+# 32-bit x86 does not perform well with -ve segment accesses on Xen.
+CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
+CFLAGS += $(CFLAGS-y)
 
 %.opic: %.c
        $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/blktapctrl.c Fri Dec 15 11:32:58 2006 -0700
@@ -57,6 +57,8 @@
 #include "blktapctrl.h"
 #include "tapdisk.h"
 
+#define PIDFILE "/var/run/blktapctrl.pid"
+
 #define NUM_POLL_FDS 2
 #define MSG_SIZE 4096
 #define MAX_TIMEOUT 10
@@ -622,6 +624,42 @@ static void print_drivers(void)
                DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
 } 
 
+static void write_pidfile(long pid)
+{
+       char buf[100];
+       int len;
+       int fd;
+       int flags;
+
+       fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);
+       if (fd == -1) {
+               DPRINTF("Opening pid file failed (%d)\n", errno);
+               exit(1);
+       }
+
+       /* We exit silently if daemon already running. */
+       if (lockf(fd, F_TLOCK, 0) == -1)
+               exit(0);
+
+       /* Set FD_CLOEXEC, so that tapdisk doesn't get this file
+          descriptor. */
+       if ((flags = fcntl(fd, F_GETFD)) == -1) {
+               DPRINTF("F_GETFD failed (%d)\n", errno);
+               exit(1);
+       }
+       flags |= FD_CLOEXEC;
+       if (fcntl(fd, F_SETFD, flags) == -1) {
+               DPRINTF("F_SETFD failed (%d)\n", errno);
+               exit(1);
+       }
+
+       len = sprintf(buf, "%ld\n", pid);
+       if (write(fd, buf, len) != len) {
+               DPRINTF("Writing pid file failed (%d)\n", errno);
+               exit(1);
+       }
+}
+
 int main(int argc, char *argv[])
 {
        char *devname;
@@ -681,6 +719,7 @@ int main(int argc, char *argv[])
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
 
        process = getpid();
+       write_pidfile(process);
        ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );
 
        /*Static pollhooks*/
@@ -716,3 +755,13 @@ int main(int argc, char *argv[])
        closelog();
        return -1;
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/block-qcow.c Fri Dec 15 11:32:58 2006 -0700
@@ -74,8 +74,9 @@ struct pending_aio {
 #define XEN_MAGIC  (('X' << 24) | ('E' << 16) | ('N' << 8) | 0xfb)
 #define QCOW_VERSION 1
 
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES  1
+#define QCOW_CRYPT_NONE 0x00
+#define QCOW_CRYPT_AES  0x01
+#define QCOW_SPARSE_FILE 0x02
 
 #define QCOW_OFLAG_COMPRESSED (1LL << 63)
 
@@ -101,6 +102,7 @@ typedef struct QCowHeader_ext {
         uint32_t xmagic;
         uint32_t cksum;
         uint32_t min_cluster_alloc;
+        uint32_t flags;
 } QCowHeader_ext;
 
 #define L2_CACHE_SIZE 16  /*Fixed allocation in Qemu*/
@@ -119,6 +121,7 @@ struct tdqcow_state {
        int cluster_alloc;             /*Blktap fix for allocating full 
                                        *extents*/
        int min_cluster_alloc;         /*Blktap historical extent alloc*/
+       int sparse;                    /*Indicates whether to preserve 
sparseness*/
        int l2_bits;                   /*Size of L2 table entry*/
        int l2_size;                   /*Full table size*/
        int l1_size;                   /*L1 table size*/
@@ -413,6 +416,37 @@ static void encrypt_sectors(struct tdqco
        }
 }
 
+static int qtruncate(int fd, off_t length, int sparse)
+{
+       int current, ret, i; 
+       int sectors = length/DEFAULT_SECTOR_SIZE;
+       struct stat st;
+       char buf[DEFAULT_SECTOR_SIZE];
+
+       /* If length is greater than the current file len
+        * we synchronously write zeroes to the end of the 
+        * file, otherwise we truncate the length down
+        */
+       memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
+       ret = fstat(fd, &st);
+       if((ret == -1) || S_ISBLK(st.st_mode))
+               return -1;
+
+       if(st.st_size < length) {
+               /*We are extending the file*/
+               lseek(fd, 0, SEEK_END);
+               for (i = 0; i < sectors; i++ ) {
+                       ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
+                       if (ret != DEFAULT_SECTOR_SIZE)
+                               return -1;
+               }
+               
+       } else if(sparse && (st.st_size > length))
+               ftruncate(fd, length);
+
+       return 1;
+}
+
 
 /* 'allocate' is:
  *
@@ -463,8 +497,8 @@ static uint64_t get_cluster_offset(struc
                
                /*Truncate file for L2 table 
                 *(initialised to zero in case we crash)*/
-               ftruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)));
-               s->fd_end += (s->l2_size * sizeof(uint64_t));
+               qtruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)), 
s->sparse);
+               s->fd_end = l2_offset + (s->l2_size * sizeof(uint64_t));
 
                /*Update the L1 table entry on disk
                  * (for O_DIRECT we write 4KByte blocks)*/
@@ -483,7 +517,7 @@ static uint64_t get_cluster_offset(struc
                 */
                lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
                if (write(s->fd, tmp_ptr, 4096) != 4096)
-                       return 0;
+                       return 0;
                free(tmp_ptr);
 
                new_l2_table = 1;
@@ -530,8 +564,8 @@ cache_miss:
                                (s->l2_size * sizeof(uint64_t));
                        cluster_offset = (cluster_offset + s->cluster_size - 1)
                                & ~(s->cluster_size - 1);
-                       ftruncate(s->fd, cluster_offset + 
-                                 (s->cluster_size * s->l2_size));
+                       qtruncate(s->fd, cluster_offset + 
+                                 (s->cluster_size * s->l2_size), s->sparse);
                        s->fd_end = cluster_offset + 
                                (s->cluster_size * s->l2_size);
                        for (i = 0; i < s->l2_size; i++) {
@@ -542,7 +576,7 @@ cache_miss:
 
                lseek(s->fd, l2_offset, SEEK_SET);
                if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
-                   s->l2_size * sizeof(uint64_t))
+                  s->l2_size * sizeof(uint64_t))
                        return 0;
        } else {
                lseek(s->fd, l2_offset, SEEK_SET);
@@ -573,7 +607,7 @@ found:
                           overwritten */
                        if (decompress_cluster(s, cluster_offset) < 0)
                                return 0;
-                       cluster_offset = lseek(s->fd, 0, SEEK_END);
+                       cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
                        cluster_offset = (cluster_offset + s->cluster_size - 1)
                                & ~(s->cluster_size - 1);
                        /* write the cluster content - not asynchronous */
@@ -583,14 +617,15 @@ found:
                            return -1;
                } else {
                        /* allocate a new cluster */
-                       cluster_offset = lseek(s->fd, 0, SEEK_END);
+                       cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
                        if (allocate == 1) {
                                /* round to cluster size */
                                cluster_offset = 
                                        (cluster_offset + s->cluster_size - 1) 
                                        & ~(s->cluster_size - 1);
-                               ftruncate(s->fd, cluster_offset + 
-                                         s->cluster_size);
+                               qtruncate(s->fd, cluster_offset + 
+                                         s->cluster_size, s->sparse);
+                               s->fd_end = (cluster_offset + s->cluster_size);
                                /* if encrypted, we must initialize the cluster
                                   content which won't be written */
                                if (s->crypt_method && 
@@ -633,9 +668,9 @@ found:
                        DPRINTF("ERROR allocating memory for L1 table\n");
                }
                memcpy(tmp_ptr2, l2_ptr, 4096);
-               aio_lock(s, offset >> 9);
-               async_write(s, s->fd, 4096, l2_offset + (l2_sector << 12), 
-                           tmp_ptr2, 0, -2, offset >> 9, 0, NULL);
+               lseek(s->fd, l2_offset + (l2_sector << 12), SEEK_SET);
+               write(s->fd, tmp_ptr2, 4096);
+               free(tmp_ptr2);
        }
        return cluster_offset;
 }
@@ -733,6 +768,7 @@ int tdqcow_open (struct td_state *bs, co
        QCowHeader *header;
        QCowHeader_ext *exthdr;
        uint32_t cksum;
+       uint64_t final_cluster = 0;
 
        DPRINTF("QCOW: Opening %s\n",name);
        /* set up a pipe so that we can hand back a poll fd that won't fire.*/
@@ -766,7 +802,7 @@ int tdqcow_open (struct td_state *bs, co
        be64_to_cpus(&header->size);
        be32_to_cpus(&header->crypt_method);
        be64_to_cpus(&header->l1_table_offset);
-   
+
        if (header->magic != QCOW_MAGIC || header->version > QCOW_VERSION)
                goto fail;
        if (header->size <= 1 || header->cluster_bits < 9)
@@ -798,6 +834,7 @@ int tdqcow_open (struct td_state *bs, co
        }
        ret = posix_memalign((void **)&s->l1_table, 4096, l1_table_size);
        if (ret != 0) goto fail;
+
        memset(s->l1_table, 0x00, l1_table_size);
 
        DPRINTF("L1 Table offset detected: %llu, size %d (%d)\n",
@@ -808,10 +845,13 @@ int tdqcow_open (struct td_state *bs, co
        lseek(fd, s->l1_table_offset, SEEK_SET);
        if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
                goto fail;
-/*     for(i = 0;i < s->l1_size; i++) {
+
+       for(i = 0;i < s->l1_size; i++) {
                //be64_to_cpus(&s->l1_table[i]);
-               DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
-               }*/
+               //DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
+               if (s->l1_table[i] > final_cluster)
+                       final_cluster = s->l1_table[i];
+       }
 
        /* alloc L2 cache */
        size = s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t);
@@ -870,10 +910,14 @@ int tdqcow_open (struct td_state *bs, co
                /*Finally check the L1 table cksum*/
                be32_to_cpus(&exthdr->cksum);
                cksum = gen_cksum((char *)s->l1_table, s->l1_size * 
sizeof(uint64_t));
-               if(exthdr->cksum != cksum)
+               if(exthdr->cksum != cksum) {
                        goto end_xenhdr;
+               }
                        
                be32_to_cpus(&exthdr->min_cluster_alloc);
+               be32_to_cpus(&exthdr->flags);
+               if (exthdr->flags & QCOW_SPARSE_FILE)
+                       s->sparse = 1;
                s->min_cluster_alloc = exthdr->min_cluster_alloc; 
        }
 
@@ -882,7 +926,8 @@ int tdqcow_open (struct td_state *bs, co
                DPRINTF("Unable to initialise AIO state\n");
                goto fail;
        }
-       s->fd_end = lseek(s->fd, 0, SEEK_END);
+       s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size) 
: 
+                               (final_cluster + s->cluster_size));
 
        return 0;
        
@@ -1172,7 +1217,7 @@ int qcow_create(const char *filename, ui
        QCowHeader header;
        QCowHeader_ext exthdr;
        char backing_filename[1024], *ptr;
-       uint64_t tmp, size;
+       uint64_t tmp, size, total_length;
        struct stat st;
 
        DPRINTF("Qcow_create: size %llu\n",(long long unsigned)total_size);
@@ -1260,7 +1305,7 @@ int qcow_create(const char *filename, ui
        DPRINTF("L1 Table offset: %d, size %d\n",
                header_size,
                (int)(l1_size * sizeof(uint64_t)));
-       if (flags) {
+       if (flags & QCOW_CRYPT_AES) {
                header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
        } else {
                header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
@@ -1270,8 +1315,26 @@ int qcow_create(const char *filename, ui
        exthdr.cksum = cpu_to_be32(gen_cksum(ptr, l1_size * sizeof(uint64_t)));
        printf("Created cksum: %d\n",exthdr.cksum);
        free(ptr);
+
+       /*adjust file length to 4 KByte boundary*/
+       length = header_size + l1_size * sizeof(uint64_t);
+       if (length % 4096 > 0) {
+               length = ((length >> 12) + 1) << 12;
+               qtruncate(fd, length, 0);
+               DPRINTF("Adjusted filelength to %d for 4 "
+                       "Kbyte alignment\n",length);
+       }
+
+       if (!(flags & QCOW_SPARSE_FILE)) {
+               /*Filesize is length +  l1_size * (1 << s->l2_bits) + 
(size*512)*/
+               total_length = length + (l1_size * (1 << 9)) + (size * 512);
+               qtruncate(fd, total_length, 0);
+               printf("File truncated to length %"PRIu64"\n",total_length);
+       }
+       exthdr.flags = cpu_to_be32(flags);
        
        /* write all the data */
+       lseek(fd, 0, SEEK_SET);
        ret += write(fd, &header, sizeof(header));
        ret += write(fd, &exthdr, sizeof(exthdr));
        if (backing_file) {
@@ -1283,15 +1346,6 @@ int qcow_create(const char *filename, ui
                ret += write(fd, &tmp, sizeof(tmp));
        }
 
-       /*adjust file length to 4 KByte boundary*/
-       length = header_size + l1_size * sizeof(uint64_t);
-       if (length % 4096 > 0) {
-               length = ((length >> 12) + 1) << 12;
-               ftruncate(fd, length);
-               DPRINTF("Adjusted filelength to %d for 4 "
-                       "Kbyte alignment\n",length);
-       }
-
        close(fd);
 
        return 0;
@@ -1306,7 +1360,7 @@ int qcow_make_empty(struct td_state *bs)
        lseek(s->fd, s->l1_table_offset, SEEK_SET);
        if (write(s->fd, s->l1_table, l1_length) < 0)
                return -1;
-       ftruncate(s->fd, s->l1_table_offset + l1_length);
+       qtruncate(s->fd, s->l1_table_offset + l1_length, s->sparse);
 
        memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
        memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/qcow-create.c
--- a/tools/blktap/drivers/qcow-create.c        Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/qcow-create.c        Fri Dec 15 11:32:58 2006 -0700
@@ -47,32 +47,69 @@
 #define DFPRINTF(_f, _a...) ((void)0)
 #endif
 
+#define QCOW_NONSPARSE_FILE 0x00
+#define QCOW_SPARSE_FILE 0x02
+#define MAX_NAME_LEN 1000
+
+void help(void)
+{
+       fprintf(stderr, "Qcow-utils: v1.0.0\n");
+       fprintf(stderr, 
+               "usage: qcow-create [-h help] [-p reserve] <SIZE(MB)> 
<FILENAME> "
+               "[<BACKING_FILENAME>]\n"); 
+       exit(-1);
+}
 
 int main(int argc, char *argv[])
 {
-       int ret = -1;
+       int ret = -1, c, backed = 0;
+       int flags =  QCOW_SPARSE_FILE;
        uint64_t size;
+       char filename[MAX_NAME_LEN], bfilename[MAX_NAME_LEN];
 
-       if ( (argc < 3) || (argc > 4) ) {
-               fprintf(stderr, "Qcow-utils: v1.0.0\n");
-               fprintf(stderr, 
-                       "usage: %s <SIZE(MB)> <FILENAME> "
-                       "[<BACKING_FILENAME>]\n", 
-                       argv[0]);
+        for(;;) {
+                c = getopt(argc, argv, "hp");
+                if (c == -1)
+                        break;
+                switch(c) {
+                case 'h':
+                        help();
+                        exit(0);
+                        break;
+                case 'p':
+                       flags = QCOW_NONSPARSE_FILE;
+                       break;
+               }
+       }
+
+       printf("Optind %d, argc %d\n", optind, argc);
+       if ( !(optind == (argc - 2) || optind == (argc - 3)) )
+               help();
+
+       size = atoi(argv[optind++]);
+       size = size << 20;
+
+       if (snprintf(filename, MAX_NAME_LEN, "%s",argv[optind++]) >=
+               MAX_NAME_LEN) {
+               fprintf(stderr,"Device name too long\n");
                exit(-1);
        }
 
-       size = atoi(argv[1]);
-       size = size << 20;
-       DFPRINTF("Creating file size %llu\n",(long long unsigned)size);
-       switch(argc) {
-       case 3: 
-               ret = qcow_create(argv[2],size,NULL,0);
-               break;
-       case 4:
-               ret = qcow_create(argv[2],size,argv[3],0);
-               break;          
+       if (optind != argc) {
+               backed = 1;
+               if (snprintf(bfilename, MAX_NAME_LEN, "%s",argv[optind++]) >=
+                       MAX_NAME_LEN) {
+                       fprintf(stderr,"Device name too long\n");
+                       exit(-1);
+               }
        }
+
+       DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size, 
filename);
+       if (!backed)
+               ret = qcow_create(filename,size,NULL,flags);
+       else
+               ret = qcow_create(filename,size,bfilename,flags);
+
        if (ret < 0) DPRINTF("Unable to create QCOW file\n");
        else DPRINTF("QCOW file successfully created\n");
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_crypto_lib
--- a/tools/check/check_crypto_lib      Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_crypto_lib      Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,14 @@
-#!/bin/bash
+#!/bin/sh
 # CHECK-BUILD CHECK-INSTALL
 
-function error {
-    echo
-    echo "  *** Check for crypto library FAILED"
-    exit 1
-}
+RC=0
 
 set -e
-ldconfig -p | grep -q libcrypto.so || error
+ldconfig -v 2>&1 | grep -q libcrypto.so || RC=1
+
+if test ${RC} -ne 0; then
+        echo
+        echo " *** Check for crypto library FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_openssl_devel
--- a/tools/check/check_openssl_devel   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_openssl_devel   Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,14 @@
-#!/bin/bash
+#!/bin/sh
 # CHECK-BUILD
 
-function error {
-    echo
-    echo "  *** Check for openssl headers FAILED"
-    exit 1
-}
+RC=0
 
 set -e
-[ -e /usr/include/openssl/md5.h ] || error
+test -r /usr/include/openssl/md5.h || RC=1 
+
+if test ${RC} -ne 0; then
+       echo
+       echo " *** Check for openssl headers FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python
--- a/tools/check/check_python  Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_python  Fri Dec 15 11:32:58 2006 -0700
@@ -3,7 +3,10 @@
 
 RC=0
 
-python -V 2>&1 | cut -d ' ' -f 2 | grep -q '^2.[2345]' || RC=1
+python -c '
+import sys
+sys.exit(sys.version_info[0] < 2 or sys.version_info[1] < 2)
+' || RC=1
 
 if test ${RC} -ne 0; then
        echo
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python_devel
--- a/tools/check/check_python_devel    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_python_devel    Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,7 @@
-#!/bin/bash
+#!/bin/sh
 # CHECK-BUILD
 
-function error {
-    echo
-    echo "  *** Check for python development environment FAILED"
-    exit 1
-}
+RC=0
 
 python -c '
 import os.path, sys
@@ -13,4 +9,11 @@ for p in sys.path:
        if os.path.exists(p + "/config/Makefile"):
                sys.exit(0)
 sys.exit(1)
-' || error
+' || RC=1 
+
+if test ${RC} -ne 0; then
+       echo
+       echo " *** Check for python development environment FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python_xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/check/check_python_xml      Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,8 @@
+#!/bin/sh
+# CHECK-INSTALL
+
+python -c 'import xml.dom.minidom' 2>/dev/null || {
+    echo
+    echo "  *** Check for python-xml package FAILED"
+    exit 1
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_udev
--- a/tools/check/check_udev    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_udev    Fri Dec 15 11:32:58 2006 -0700
@@ -1,16 +1,34 @@
-#!/bin/bash
+#!/bin/sh
 # CHECK-INSTALL
 
-function error {
-   echo
-   echo '  *** Check for udev/hotplug FAILED'
-   exit 1
-}
-[ -x "$(which udevinfo)" ] && \
-  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* 
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
+RC=0
 
-if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
-  exit 0
+case ${OS} in
+OpenBSD|NetBSD|FreeBSD)
+       TOOL="vnconfig"
+       which ${TOOL} 1>/dev/null 2>&1 || RC=1
+       ;;
+Linux)
+       TOOL="udevinfo"
+       UDEV_VERSION="0"
+       test -x "$(which ${TOOL})" && \
+               UDEV_VERSION=$(${TOOL} -V | sed -e 's/^[^0-9]* 
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
+       if test "${UDEV_VERSION}" -ge 059; then
+               RC=0
+       else
+               TOOL="hotplug"
+               which ${TOOL} 1>/dev/null 2>&1 || RC=1
+       fi
+       ;;
+*)
+       TOOL=""
+       echo "Unknown OS" && RC=1
+       ;;
+esac
+
+if test ${RC} -ne 0; then
+       echo
+       echo ' *** Check for ${TOOL} FAILED'
 fi
 
-which hotplug 1>/dev/null 2>&1 || error
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_x11_devel
--- a/tools/check/check_x11_devel       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_x11_devel       Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,15 @@
-#!/bin/bash
+#!/bin/sh
 # CHECK-BUILD
 
-function error {
-    echo
-    echo "  *** Check for x11 headers FAILED"
-    exit 1
-}
+RC=0
 
 set -e
-[ -e /usr/include/X11/keysymdef.h ] || error
+test -r /usr/include/X11/keysymdef.h || \
+test -r /usr/X11R6/include/X11/keysymdef.h || RC=1
+
+if test ${RC} -ne 0; then
+       echo
+       echo " *** Check for x11 headers FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/examples/external-device-migrate    Fri Dec 15 11:32:58 2006 -0700
@@ -60,8 +60,8 @@ function evaluate_params()
                -step)          step=$2; shift 2;;
                -host)          host=$2; shift 2;;
                -domname)       domname=$2; shift 2;;
-               -type)          type=$2; shift 2;;
-               -subtype)       subtype=$2; shift 2;;
+               -type)          typ=$2; shift 2;;
+               -subtype)       stype=$2; shift 2;;
                -recover)       recover=1; shift;;
                -help)          ext_dev_migrate_usage; exit 0;;
                *)              break;;
diff -r 1e042dde1a5f -r e17d7438e09e tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Fri Dec 15 11:32:58 2006 -0700
@@ -439,7 +439,12 @@ void cpu_physical_memory_rw(target_phys_
     int l, io_index;
     uint8_t *ptr;
     uint32_t val;
-    
+
+#if defined(__i386__) || defined(__x86_64__)
+    static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+    pthread_mutex_lock(&mutex);
+#endif
+
     while (len > 0) {
         /* How much can we copy before the next page boundary? */
         l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
@@ -504,6 +509,10 @@ void cpu_physical_memory_rw(target_phys_
         buf += l;
         addr += l;
     }
+
+#if defined(__i386__) || defined(__x86_64__)
+    pthread_mutex_unlock(&mutex);
+#endif
 }
 #endif
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/ioemu/vl.c  Fri Dec 15 11:32:58 2006 -0700
@@ -5820,8 +5820,8 @@ static int qemu_map_cache_init(unsigned 
     if (nr_pages < max_pages)
         max_pages = nr_pages;
 
-    nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT;
-
+    nr_buckets   = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1;
+    nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
     fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
 
     mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
@@ -5857,8 +5857,7 @@ uint8_t *qemu_map_cache(target_phys_addr
 
     entry = &mapcache_entry[address_index % nr_buckets];
 
-    if (entry->vaddr_base == NULL || entry->paddr_index != address_index)
-    { 
+    if (entry->vaddr_base == NULL || entry->paddr_index != address_index) {
         /* We need to remap a bucket. */
         uint8_t *vaddr_base;
         unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
diff -r 1e042dde1a5f -r e17d7438e09e tools/libaio/src/syscall-ppc.h
--- a/tools/libaio/src/syscall-ppc.h    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libaio/src/syscall-ppc.h    Fri Dec 15 11:32:58 2006 -0700
@@ -1,3 +1,6 @@
+#include <asm/unistd.h>
+#include <errno.h>
+
 #define __NR_io_setup          227
 #define __NR_io_destroy                228
 #define __NR_io_getevents      229
@@ -9,7 +12,7 @@
  * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
  * an error return status).
  */
-
+#ifndef __syscall_nr
 #define __syscall_nr(nr, type, name, args...)                          \
        unsigned long __sc_ret, __sc_err;                               \
        {                                                               \
@@ -37,6 +40,7 @@
        }                                                               \
        if (__sc_err & 0x10000000) return -((int)__sc_ret);             \
        return (type) __sc_ret
+#endif
 
 #define __sc_loadargs_0(name, dummy...)                                        
\
        __sc_0 = __NR_##name
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Fri Dec 15 11:32:58 2006 -0700
@@ -660,8 +660,14 @@ setup_guest(int xc_handle, uint32_t dom,
         goto error_out;
     }
 
-    // Get number of vcpus, stored by pyxc_hvm_build()
-    xc_get_hvm_param(xc_handle, dom, HVM_PARAM_VCPUS, &vcpus);
+    domctl.cmd = XEN_DOMCTL_getdomaininfo;
+    domctl.domain = (domid_t)dom;
+    if (xc_domctl(xc_handle, &domctl) < 0) {
+        PERROR("Could not get info on domain");
+        goto error_out;
+    }
+
+    vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1;
 
     // Hand-off state passed to guest firmware 
     if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus) < 0) {
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/Makefile    Fri Dec 15 11:32:58 2006 -0700
@@ -1,4 +1,6 @@ GUEST_SRCS-y += powerpc64/xc_linux_build
+GUEST_SRCS-y += powerpc64/flatdevtree.c
 GUEST_SRCS-y += powerpc64/xc_linux_build.c
-GUEST_SRCS-y += powerpc64/flatdevtree.c
+GUEST_SRCS-y += powerpc64/xc_prose_build.c
+GUEST_SRCS-y += powerpc64/utils.c
 
 CTRL_SRCS-y += powerpc64/xc_memory.c
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/flatdevtree.c
--- a/tools/libxc/powerpc64/flatdevtree.c       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.c       Fri Dec 15 11:32:58 2006 -0700
@@ -220,6 +220,29 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
        cxt->p_anchor = cxt->pres + 16; /* over the terminator */
 }
 
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size)
+{
+       const struct boot_param_header *bph = bphp;
+       u64 *p_rsvmap = (u64 *)
+               ((char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
+       u32 i;
+
+       for (i = 0;; i++) {
+               u64 addr, sz;
+
+               addr = be64_to_cpu(p_rsvmap[i * 2]);
+               sz = be64_to_cpu(p_rsvmap[i * 2 + 1]);
+               if (addr == 0 && size == 0)
+                       break;
+               if (m == i) {
+                       p_rsvmap[i * 2] = cpu_to_be64(physaddr);
+                       p_rsvmap[i * 2 + 1] = cpu_to_be64(size);
+                       return 0;
+               }
+       }
+       return -1;
+}
+
 void ft_begin_tree(struct ft_cxt *cxt)
 {
        cxt->p_begin = cxt->p_anchor;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/flatdevtree.h
--- a/tools/libxc/powerpc64/flatdevtree.h       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.h       Fri Dec 15 11:32:58 2006 -0700
@@ -66,8 +66,10 @@ void ft_prop_int(struct ft_cxt *cxt, con
 void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
 void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
 void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size);
 
 void ft_dump_blob(const void *bphp);
+void ft_backtrack_node(struct ft_cxt *cxt);
 void ft_merge_blob(struct ft_cxt *cxt, void *blob);
 
 void *ft_find_node(const void *bphp, const char *srch_path);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/utils.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/utils.c     Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,211 @@
+/*
+ * 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xc_private.h>
+#include <xg_private.h>
+#include <xenctrl.h>
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+#include "utils.h"
+
+unsigned long get_rma_pages(void *devtree)
+{
+    void *rma;
+    uint64_t rma_reg[2];
+    int rc;
+
+    rma = ft_find_node(devtree, "/memory@0");
+    if (rma == NULL) {
+        DPRINTF("couldn't find /memory@0\n");
+        return 0;
+    }
+    rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
+    if (rc < 0) {
+        DPRINTF("couldn't get /memory@0/reg\n");
+        return 0;
+    }
+    if (rma_reg[0] != 0) {
+        DPRINTF("RMA did not start at 0\n");
+        return 0;
+    }
+    return rma_reg[1] >> PAGE_SHIFT;
+}
+
+int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
+                      unsigned long nr_pages)
+{
+    int rc;
+    int i;
+    xen_pfn_t *p;
+
+    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
+    if (*page_array == NULL) {
+        perror("malloc");
+        return -1;
+    }
+
+    DPRINTF("xc_get_pfn_list\n");
+    /* We know that the RMA is machine contiguous so lets just get the
+     * first MFN and fill the rest in ourselves */
+    rc = xc_get_pfn_list(xc_handle, domid, *page_array, 1);
+    if (rc == -1) {
+        perror("Could not get the page frame list");
+        return -1;
+    }
+    p = *page_array;
+    for (i = 1; i < nr_pages; i++)
+        p[i] = p[i - 1] + 1;
+    return 0;
+}
+
+int install_image(
+        int xc_handle,
+        int domid,
+        xen_pfn_t *page_array,
+        void *image,
+        unsigned long paddr,
+        unsigned long size)
+{
+    uint8_t *img = image;
+    int i;
+    int rc = 0;
+
+    if (paddr & ~PAGE_MASK) {
+        printf("*** unaligned address\n");
+        return -1;
+    }
+
+    for (i = 0; i < size; i += PAGE_SIZE) {
+        void *page = img + i;
+        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
+        xen_pfn_t mfn = page_array[pfn];
+
+        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
+        if (rc < 0) {
+            perror("xc_copy_to_domain_page");
+            break;
+        }
+    }
+    return rc;
+}
+
+void *load_file(const char *path, unsigned long *filesize)
+{
+    void *img;
+    ssize_t size;
+    int fd;
+
+    DPRINTF("load_file(%s)\n", path);
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        perror(path);
+        return NULL;
+    }
+
+    size = lseek(fd, 0, SEEK_END);
+    if (size < 0) {
+        perror(path);
+        close(fd);
+        return NULL;
+    }
+    lseek(fd, 0, SEEK_SET);
+
+    img = malloc(size);
+    if (img == NULL) {
+        perror(path);
+        close(fd);
+        return NULL;
+    }
+
+    size = read(fd, img, size);
+    if (size <= 0) {
+        perror(path);
+        close(fd);
+        free(img);
+        return NULL;
+    }
+
+    if (filesize)
+        *filesize = size;
+    close(fd);
+    return img;
+}
+
+int load_elf_kernel(
+    int xc_handle,
+    int domid,
+    const char *kernel_path,
+    struct domain_setup_info *dsi,
+    xen_pfn_t *page_array)
+{
+    struct load_funcs load_funcs;
+    char *kernel_img;
+    unsigned long kernel_size;
+    int rc;
+
+    /* load the kernel ELF file */
+    kernel_img = load_file(kernel_path, &kernel_size);
+    if (kernel_img == NULL) {
+        rc = -1;
+        goto out;
+    }
+
+    DPRINTF("probe_elf\n");
+    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
+    if (rc < 0) {
+        rc = -1;
+        printf("%s is not an ELF file\n", kernel_path);
+        goto out;
+    }
+
+    DPRINTF("parseimage\n");
+    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
+    if (rc < 0) {
+        rc = -1;
+        goto out;
+    }
+
+    DPRINTF("loadimage\n");
+    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
+            page_array, dsi);
+
+    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
+    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
+    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
+    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
+    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
+
+out:
+    free(kernel_img);
+    return rc;
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/utils.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/utils.h     Fri Dec 15 11:32:58 2006 -0700
@@ -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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+
+extern unsigned long get_rma_pages(void *devtree);
+extern int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
+                             unsigned long nr_pages);
+extern int install_image(int xc_handle, int domid, xen_pfn_t *page_array,
+                        void *image, unsigned long paddr, unsigned long size);
+extern void *load_file(const char *path, unsigned long *filesize);
+extern int load_elf_kernel(int xc_handle, int domid,  const char *kernel_path,
+                          struct domain_setup_info *dsi,
+                          xen_pfn_t *page_array);
+
+#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+
+#define max(x,y) ({ \
+        const typeof(x) _x = (x);       \
+        const typeof(y) _y = (y);       \
+        (void) (&_x == &_y);            \
+        _x > _y ? _x : _y; })
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/xc_linux_build.c    Fri Dec 15 11:32:58 2006 -0700
@@ -35,60 +35,10 @@
 
 #include "flatdevtree_env.h"
 #include "flatdevtree.h"
+#include "utils.h"
 
 #define INITRD_ADDR (24UL << 20)
 #define DEVTREE_ADDR (16UL << 20)
-
-#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
-
-#define max(x,y) ({ \
-        const typeof(x) _x = (x);       \
-        const typeof(y) _y = (y);       \
-        (void) (&_x == &_y);            \
-        _x > _y ? _x : _y; })
-
-static void *load_file(const char *path, unsigned long *filesize)
-{
-    void *img;
-    ssize_t size;
-    int fd;
-
-    DPRINTF("load_file(%s)\n", path);
-
-    fd = open(path, O_RDONLY);
-    if (fd < 0) {
-        perror(path);
-        return NULL;
-    }
-
-    size = lseek(fd, 0, SEEK_END);
-    if (size < 0) {
-        perror(path);
-        close(fd);
-        return NULL;
-    }
-    lseek(fd, 0, SEEK_SET);
-
-    img = malloc(size);
-    if (img == NULL) {
-        perror(path);
-        close(fd);
-        return NULL;
-    }
-
-    size = read(fd, img, size);
-    if (size <= 0) {
-        perror(path);
-        close(fd);
-        free(img);
-        return NULL;
-    }
-
-    if (filesize)
-        *filesize = size;
-    close(fd);
-    return img;
-}
 
 static int init_boot_vcpu(
     int xc_handle,
@@ -128,37 +78,6 @@ static int init_boot_vcpu(
     return rc;
 }
 
-static int install_image(
-        int xc_handle,
-        int domid,
-        xen_pfn_t *page_array,
-        void *image,
-        unsigned long paddr,
-        unsigned long size)
-{
-    uint8_t *img = image;
-    int i;
-    int rc = 0;
-
-    if (paddr & ~PAGE_MASK) {
-        printf("*** unaligned address\n");
-        return -1;
-    }
-
-    for (i = 0; i < size; i += PAGE_SIZE) {
-        void *page = img + i;
-        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
-        xen_pfn_t mfn = page_array[pfn];
-
-        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
-        if (rc < 0) {
-            perror("xc_copy_to_domain_page");
-            break;
-        }
-    }
-    return rc;
-}
-
 static int load_devtree(
     int xc_handle,
     int domid,
@@ -167,10 +86,10 @@ static int load_devtree(
     unsigned long devtree_addr,
     uint64_t initrd_base,
     unsigned long initrd_len,
-    start_info_t *si,
-    unsigned long si_addr)
-{
-    uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
+    start_info_t *start_info __attribute__((unused)),
+    unsigned long start_info_addr)
+{
+    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
     struct boot_param_header *header;
     void *chosen;
     void *xen;
@@ -208,9 +127,14 @@ static int load_devtree(
         return rc;
     }
 
+    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
+    if (rc < 0) {
+        DPRINTF("couldn't set initrd reservation\n");
+        return ~0UL;
+    }
+
     /* start-info (XXX being removed soon) */
-    rc = ft_set_prop(&devtree, xen, "start-info",
-            start_info, sizeof(start_info));
+    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
     if (rc < 0) {
         DPRINTF("couldn't set /xen/start-info\n");
         return rc;
@@ -218,91 +142,19 @@ static int load_devtree(
 
     header = devtree;
     devtree_size = header->totalsize;
+    {
+        static const char dtb[] = "/tmp/xc_domU.dtb";
+        int dfd = creat(dtb, 0666);
+        if (dfd != -1) {
+            write(dfd, devtree, devtree_size);
+            close(dfd);
+        } else
+            DPRINTF("could not open(\"%s\")\n", dtb);
+    }
 
     DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
     return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
                        devtree_size);
-}
-
-unsigned long spin_list[] = {
-#if 0
-    0x100,
-    0x200,
-    0x300,
-    0x380,
-    0x400,
-    0x480,
-    0x500,
-    0x700,
-    0x900,
-    0xc00,
-#endif
-    0
-};
-
-/* XXX yes, this is a hack */
-static void hack_kernel_img(char *img)
-{
-    const off_t file_offset = 0x10000;
-    unsigned long *addr = spin_list;
-
-    while (*addr) {
-        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
-        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
-        *instruction = 0x48000000;
-        addr++;
-    }
-}
-
-static int load_kernel(
-    int xc_handle,
-    int domid,
-    const char *kernel_path,
-    struct domain_setup_info *dsi,
-    xen_pfn_t *page_array)
-{
-    struct load_funcs load_funcs;
-    char *kernel_img;
-    unsigned long kernel_size;
-    int rc;
-
-    /* load the kernel ELF file */
-    kernel_img = load_file(kernel_path, &kernel_size);
-    if (kernel_img == NULL) {
-        rc = -1;
-        goto out;
-    }
-
-    hack_kernel_img(kernel_img);
-
-    DPRINTF("probe_elf\n");
-    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
-    if (rc < 0) {
-        rc = -1;
-        printf("%s is not an ELF file\n", kernel_path);
-        goto out;
-    }
-
-    DPRINTF("parseimage\n");
-    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
-    if (rc < 0) {
-        rc = -1;
-        goto out;
-    }
-
-    DPRINTF("loadimage\n");
-    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
-            page_array, dsi);
-
-    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
-    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
-    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
-    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
-    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
-
-out:
-    free(kernel_img);
-    return rc;
 }
 
 static int load_initrd(
@@ -334,49 +186,38 @@ out:
     return rc;
 }
 
-static unsigned long create_start_info(start_info_t *si,
+static unsigned long create_start_info(
+       void *devtree, start_info_t *start_info,
         unsigned int console_evtchn, unsigned int store_evtchn,
-        unsigned long nr_pages)
-{
-    unsigned long si_addr;
-
-    memset(si, 0, sizeof(*si));
-    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
-
-    si->nr_pages = nr_pages;
-    si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
-    si->store_mfn = si->nr_pages - 2;
-    si->store_evtchn = store_evtchn;
-    si->console.domU.mfn = si->nr_pages - 3;
-    si->console.domU.evtchn = console_evtchn;
-    si_addr = (si->nr_pages - 4) << PAGE_SHIFT;
-
-    return si_addr;
-}
-
-static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
-                          unsigned long *nr_pages)
-{
+       unsigned long nr_pages, unsigned long rma_pages)
+{
+    unsigned long start_info_addr;
+    uint64_t rma_top;
     int rc;
 
-    DPRINTF("xc_get_tot_pages\n");
-    *nr_pages = xc_get_tot_pages(xc_handle, domid);
-    DPRINTF("  0x%lx\n", *nr_pages);
-
-    *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
-    if (*page_array == NULL) {
-        perror("malloc");
-        return -1;
-    }
-
-    DPRINTF("xc_get_pfn_list\n");
-    rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
-    if (rc != *nr_pages) {
-        perror("Could not get the page frame list");
-        return -1;
-    }
-
-    return 0;
+    memset(start_info, 0, sizeof(*start_info));
+    snprintf(start_info->magic, sizeof(start_info->magic),
+             "xen-%d.%d-powerpc64HV", 3, 0);
+
+    rma_top = rma_pages << PAGE_SHIFT;
+    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
+
+    start_info->nr_pages = nr_pages;
+    start_info->shared_info = rma_top - PAGE_SIZE;
+    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
+    start_info->store_evtchn = store_evtchn;
+    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
+    start_info->console.domU.evtchn = console_evtchn;
+    start_info_addr = rma_top - 4*PAGE_SIZE;
+
+    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
+    if (rc < 0) {
+        DPRINTF("couldn't set start_info reservation\n");
+        return ~0UL;
+    }
+
+
+    return start_info_addr;
 }
 
 static void free_page_array(xen_pfn_t *page_array)
@@ -388,6 +229,7 @@ static void free_page_array(xen_pfn_t *p
 
 int xc_linux_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *initrd_name,
                    const char *cmdline,
@@ -399,7 +241,7 @@ int xc_linux_build(int xc_handle,
                    unsigned long *console_mfn,
                    void *devtree)
 {
-    start_info_t si;
+    start_info_t start_info;
     struct domain_setup_info dsi;
     xen_pfn_t *page_array = NULL;
     unsigned long nr_pages;
@@ -407,18 +249,28 @@ int xc_linux_build(int xc_handle,
     unsigned long kern_addr;
     unsigned long initrd_base = 0;
     unsigned long initrd_len = 0;
-    unsigned long si_addr;
+    unsigned long start_info_addr;
+    unsigned long rma_pages;
     int rc = 0;
 
     DPRINTF("%s\n", __func__);
 
-    if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
+    nr_pages = mem_mb << (20 - PAGE_SHIFT);
+    DPRINTF("nr_pages 0x%lx\n", nr_pages);
+
+    rma_pages = get_rma_pages(devtree);
+    if (rma_pages == 0) {
+           rc = -1;
+           goto out;
+    }
+
+    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
         rc = -1;
         goto out;
     }
 
     DPRINTF("loading image '%s'\n", image_name);
-    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
+    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
         rc = -1;
         goto out;
     }
@@ -434,11 +286,12 @@ int xc_linux_build(int xc_handle,
     }
 
     /* start_info stuff: about to be removed  */
-    si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
-    *console_mfn = page_array[si.console.domU.mfn];
-    *store_mfn = page_array[si.store_mfn];
-    if (install_image(xc_handle, domid, page_array, &si, si_addr,
-                sizeof(start_info_t))) {
+    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+                                        store_evtchn, nr_pages, rma_pages);
+    *console_mfn = page_array[start_info.console.domU.mfn];
+    *store_mfn = page_array[start_info.store_mfn];
+    if (install_image(xc_handle, domid, page_array, &start_info,
+                      start_info_addr, sizeof(start_info_t))) {
         rc = -1;
         goto out;
     }
@@ -447,7 +300,8 @@ int xc_linux_build(int xc_handle,
         DPRINTF("loading flattened device tree\n");
         devtree_addr = DEVTREE_ADDR;
         if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
-                     initrd_base, initrd_len, &si, si_addr)) {
+                         initrd_base, initrd_len, &start_info,
+                         start_info_addr)) {
             DPRINTF("couldn't load flattened device tree.\n");
             rc = -1;
             goto out;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/xc_prose_build.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/xc_prose_build.c    Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,323 @@
+/*
+ * 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Jonathan Appavoo <jappavoo@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xc_private.h>
+#include <xg_private.h>
+#include <xenctrl.h>
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+#include "utils.h"
+
+#define INITRD_ADDR (24UL << 20)
+#define DEVTREE_ADDR (16UL << 20)
+
+static int init_boot_vcpu(
+    int xc_handle,
+    int domid,
+    struct domain_setup_info *dsi,
+    unsigned long devtree_addr,
+    unsigned long kern_addr)
+{
+    vcpu_guest_context_t ctxt;
+    int rc;
+
+    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
+    ctxt.user_regs.pc = dsi->v_kernentry;
+    ctxt.user_regs.msr = 0;
+    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
+    ctxt.user_regs.gprs[3] = devtree_addr;
+    ctxt.user_regs.gprs[4] = kern_addr;
+    ctxt.user_regs.gprs[5] = 0; /* reserved for specifying OF handler */
+    /* There is a buggy kernel that does not zero the "local_paca", so
+     * we must make sure this register is 0 */
+    ctxt.user_regs.gprs[13] = 0;
+
+    DPRINTF("xc_vcpu_setvcpucontext:\n"
+                 "  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
+                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
+                 " %016"PRIx64"\n",
+                 ctxt.user_regs.pc, ctxt.user_regs.msr,
+                 ctxt.user_regs.gprs[1],
+                 ctxt.user_regs.gprs[2],
+                 ctxt.user_regs.gprs[3],
+                 ctxt.user_regs.gprs[4],
+                 ctxt.user_regs.gprs[5]);
+    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
+    if (rc < 0)
+        perror("setdomaininfo");
+
+    return rc;
+}
+
+static int load_devtree(
+    int xc_handle,
+    int domid,
+    xen_pfn_t *page_array,
+    void *devtree,
+    unsigned long devtree_addr,
+    uint64_t initrd_base,
+    unsigned long initrd_len,
+    start_info_t *start_info __attribute__((unused)),
+    unsigned long start_info_addr)
+{
+    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
+    struct boot_param_header *header;
+    void *chosen;
+    void *xen;
+    uint64_t initrd_end = initrd_base + initrd_len;
+    unsigned int devtree_size;
+    int rc = 0;
+
+    DPRINTF("adding initrd props\n");
+
+    chosen = ft_find_node(devtree, "/chosen");
+    if (chosen == NULL) {
+        DPRINTF("couldn't find /chosen\n");
+        return -1;
+    }
+
+    xen = ft_find_node(devtree, "/xen");
+    if (xen == NULL) {
+        DPRINTF("couldn't find /xen\n");
+        return -1;
+    }
+
+    /* initrd-start */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
+            &initrd_base, sizeof(initrd_base));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
+        return rc;
+    }
+
+    /* initrd-end */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
+            &initrd_end, sizeof(initrd_end));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
+        return rc;
+    }
+
+    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
+    if (rc < 0) {
+        DPRINTF("couldn't set initrd reservation\n");
+        return ~0UL;
+    }
+
+    /* start-info (XXX being removed soon) */
+    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
+    if (rc < 0) {
+        DPRINTF("couldn't set /xen/start-info\n");
+        return rc;
+    }
+
+    header = devtree;
+    devtree_size = header->totalsize;
+    {
+        static const char dtb[] = "/tmp/xc_domU.dtb";
+        int dfd = creat(dtb, 0666);
+        if (dfd != -1) {
+            write(dfd, devtree, devtree_size);
+            close(dfd);
+        } else
+            DPRINTF("could not open(\"%s\")\n", dtb);
+    }
+
+    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
+    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
+                       devtree_size);
+}
+
+static int load_initrd(
+    int xc_handle,
+    int domid,
+    xen_pfn_t *page_array,
+    const char *initrd_path,
+    unsigned long *base,
+    unsigned long *len)
+{
+    uint8_t *initrd_img;
+    int rc = -1;
+
+    /* load the initrd file */
+    initrd_img = load_file(initrd_path, len);
+    if (initrd_img == NULL)
+        return -1;
+
+    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
+    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
+                *len))
+        goto out;
+
+    *base = INITRD_ADDR;
+    rc = 0;
+
+out:
+    free(initrd_img);
+    return rc;
+}
+
+static unsigned long create_start_info(
+       void *devtree, start_info_t *start_info,
+        unsigned int console_evtchn, unsigned int store_evtchn,
+       unsigned long nr_pages, unsigned long rma_pages, const char *cmdline)
+{
+    unsigned long start_info_addr;
+    uint64_t rma_top;
+    int rc;
+
+    memset(start_info, 0, sizeof(*start_info));
+    snprintf(start_info->magic, sizeof(start_info->magic),
+             "xen-%d.%d-powerpc64HV", 3, 0);
+
+    rma_top = rma_pages << PAGE_SHIFT;
+    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
+
+    start_info->nr_pages = nr_pages;
+    start_info->shared_info = rma_top - PAGE_SIZE;
+    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
+    start_info->store_evtchn = store_evtchn;
+    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
+    start_info->console.domU.evtchn = console_evtchn;
+    strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
+    /* just in case we truncated cmdline with strncpy add 0 at the end */
+    start_info->cmd_line[MAX_GUEST_CMDLINE-1]=0;
+    start_info_addr = rma_top - 4*PAGE_SIZE;
+
+    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
+    if (rc < 0) {
+        DPRINTF("couldn't set start_info reservation\n");
+        return ~0UL;
+    }
+
+    return start_info_addr;
+}
+
+static void free_page_array(xen_pfn_t *page_array)
+{
+    free(page_array);
+}
+
+int xc_prose_build(int xc_handle,
+                   uint32_t domid,
+                   unsigned int mem_mb,
+                   const char *image_name,
+                   const char *initrd_name,
+                   const char *cmdline,
+                   const char *features,
+                   unsigned long flags,
+                   unsigned int store_evtchn,
+                   unsigned long *store_mfn,
+                   unsigned int console_evtchn,
+                   unsigned long *console_mfn,
+                   void *devtree)
+{
+    start_info_t start_info;
+    struct domain_setup_info dsi;
+    xen_pfn_t *page_array = NULL;
+    unsigned long nr_pages;
+    unsigned long devtree_addr = 0;
+    unsigned long kern_addr;
+    unsigned long initrd_base = 0;
+    unsigned long initrd_len = 0;
+    unsigned long start_info_addr;
+    unsigned long rma_pages;
+    int rc = 0;
+
+    DPRINTF("%s\n", __func__);
+
+    DPRINTF("cmdline=%s\n", cmdline);
+
+    nr_pages = mem_mb << (20 - PAGE_SHIFT);
+    DPRINTF("nr_pages 0x%lx\n", nr_pages);
+
+    rma_pages = get_rma_pages(devtree);
+    if (rma_pages == 0) {
+           rc = -1;
+           goto out;
+    }
+
+    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
+        rc = -1;
+        goto out;
+    }
+
+    DPRINTF("loading image '%s'\n", image_name);
+    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
+        rc = -1;
+        goto out;
+    }
+    kern_addr = 0;
+
+    if (initrd_name && initrd_name[0] != '\0') {
+        DPRINTF("loading initrd '%s'\n", initrd_name);
+        if (load_initrd(xc_handle, domid, page_array, initrd_name,
+                &initrd_base, &initrd_len)) {
+            rc = -1;
+            goto out;
+        }
+    }
+
+    /* start_info stuff: about to be removed  */
+    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+                                        store_evtchn, nr_pages,
+                                       rma_pages, cmdline);
+    *console_mfn = page_array[start_info.console.domU.mfn];
+    *store_mfn = page_array[start_info.store_mfn];
+    if (install_image(xc_handle, domid, page_array, &start_info,
+                      start_info_addr, sizeof(start_info_t))) {
+        rc = -1;
+        goto out;
+    }
+
+    if (devtree) {
+        DPRINTF("loading flattened device tree\n");
+        devtree_addr = DEVTREE_ADDR;
+        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
+                         initrd_base, initrd_len, &start_info,
+                         start_info_addr)) {
+            DPRINTF("couldn't load flattened device tree.\n");
+            rc = -1;
+            goto out;
+        }
+    }
+
+    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
+        rc = -1;
+        goto out;
+    }
+
+out:
+    free_page_array(page_array);
+    return rc;
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xc_linux_build.c      Fri Dec 15 11:32:58 2006 -0700
@@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
     }
 
     if (strstr(xen_caps, "xen-3.0-x86_32p")) {
-        if (dsi->pae_kernel == PAEKERN_no) {
+        if (dsi->pae_kernel == PAEKERN_bimodal) {
+            dsi->pae_kernel = PAEKERN_extended_cr3;
+        } else if (dsi->pae_kernel == PAEKERN_no) {
             xc_set_error(XC_INVALID_KERNEL,
                          "Non PAE-kernel on PAE host.");
             return 0;
         }
-    } else if (dsi->pae_kernel != PAEKERN_no) {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "PAE-kernel on non-PAE host.");
-        return 0;
+    } else {
+        if (dsi->pae_kernel == PAEKERN_bimodal) {
+            dsi->pae_kernel = PAEKERN_no;
+        } else if (dsi->pae_kernel != PAEKERN_no) {
+            xc_set_error(XC_INVALID_KERNEL,
+                         "PAE-kernel on non-PAE host.");
+            return 0;
+        }
     }
 
     return 1;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xc_load_elf.c Fri Dec 15 11:32:58 2006 -0700
@@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
         return -EINVAL;
     }
 
-    /* Find the section-header strings table. */
-    if ( ehdr->e_shstrndx == SHN_UNDEF )
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "ELF image has no section-header strings table 
(shstrtab).");
-        return -EINVAL;
-    }
-    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
-                        (ehdr->e_shstrndx*ehdr->e_shentsize));
-    shstrtab = image + shdr->sh_offset;
-
     dsi->__elfnote_section = NULL;
     dsi->__xen_guest_string = NULL;
 
@@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
     /* Fall back to looking for the special '__xen_guest' section. */
     if ( dsi->__elfnote_section == NULL )
     {
+        /* Find the section-header strings table. */
+        if ( ehdr->e_shstrndx == SHN_UNDEF )
+        {
+            xc_set_error(XC_INVALID_KERNEL,
+                         "ELF image has no section-header strings table.");
+            return -EINVAL;
+        }
+        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+                            (ehdr->e_shstrndx*ehdr->e_shentsize));
+        shstrtab = image + shdr->sh_offset;
+
         for ( h = 0; h < ehdr->e_shnum; h++ )
         {
             shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
@@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
     }
 
     /*
+     * A "bimodal" ELF note indicates the kernel will adjust to the
+     * current paging mode, including handling extended cr3 syntax.
      * If we have ELF notes then PAE=yes implies that we must support
      * the extended cr3 syntax. Otherwise we need to find the
      * [extended-cr3] syntax in the __xen_guest string.
@@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
     if ( dsi->__elfnote_section )
     {
         p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
-        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+            dsi->pae_kernel = PAEKERN_bimodal;
+        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
             dsi->pae_kernel = PAEKERN_extended_cr3;
 
     }
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xenctrl.h     Fri Dec 15 11:32:58 2006 -0700
@@ -728,4 +728,8 @@ const char *xc_error_code_to_desc(int co
  */
 xc_error_handler xc_set_error_handler(xc_error_handler handler);
 
+/* PowerPC specific. */
+int xc_alloc_real_mode_area(int xc_handle,
+                            uint32_t domid,
+                            unsigned int log);
 #endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xenguest.h    Fri Dec 15 11:32:58 2006 -0700
@@ -122,4 +122,19 @@ int xc_get_hvm_param(
 int xc_get_hvm_param(
     int handle, domid_t dom, int param, unsigned long *value);
 
+/* PowerPC specific. */
+int xc_prose_build(int xc_handle,
+                   uint32_t domid,
+                   unsigned int mem_mb,
+                   const char *image_name,
+                   const char *ramdisk_name,
+                   const char *cmdline,
+                   const char *features,
+                   unsigned long flags,
+                   unsigned int store_evtchn,
+                   unsigned long *store_mfn,
+                   unsigned int console_evtchn,
+                   unsigned long *console_mfn,
+                   void *arch_args);
+
 #endif /* XENGUEST_H */
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xg_private.h  Fri Dec 15 11:32:58 2006 -0700
@@ -132,6 +132,7 @@ struct domain_setup_info
 #define PAEKERN_no           0
 #define PAEKERN_yes          1
 #define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal      3
     unsigned int  pae_kernel;
 
     unsigned int  load_symtab;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_boot_type.h
--- a/tools/libxen/include/xen_boot_type.h      Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- */
-
-#ifndef XEN_BOOT_TYPE_H
-#define XEN_BOOT_TYPE_H
-
-
-#include "xen_common.h"
-
-
-enum xen_boot_type
-{
-    /**
-     * boot an HVM guest using an emulated BIOS
-     */
-    XEN_BOOT_TYPE_BIOS,
-
-    /**
-     * boot from inside the machine using grub
-     */
-    XEN_BOOT_TYPE_GRUB,
-
-    /**
-     * boot from an external kernel
-     */
-    XEN_BOOT_TYPE_KERNEL_EXTERNAL,
-
-    /**
-     * boot from a kernel inside the guest filesystem
-     */
-    XEN_BOOT_TYPE_KERNEL_INTERNAL
-};
-
-
-typedef struct xen_boot_type_set
-{
-    size_t size;
-    enum xen_boot_type contents[];
-} xen_boot_type_set;
-
-/**
- * Allocate a xen_boot_type_set of the given size.
- */
-extern xen_boot_type_set *
-xen_boot_type_set_alloc(size_t size);
-
-/**
- * Free the given xen_boot_type_set.  The given set must have been
- * allocated by this library.
- */
-extern void
-xen_boot_type_set_free(xen_boot_type_set *set);
-
-
-/**
- * Return the name corresponding to the given code.  This string must
- * not be modified or freed.
- */
-extern const char *
-xen_boot_type_to_string(enum xen_boot_type val);
-
-
-/**
- * Return the correct code for the given string, or set the session
- * object to failure and return an undefined value if the given string does
- * not match a known code.
- */
-extern enum xen_boot_type
-xen_boot_type_from_string(xen_session *session, const char *str);
-
-
-#endif
diff -r 1e042dde1a5f -r e17d7438e09e 
tools/libxen/include/xen_boot_type_internal.h
--- a/tools/libxen/include/xen_boot_type_internal.h     Fri Dec 15 10:59:33 
2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- */
-
-
-/*
- * Declarations of the abstract types used during demarshalling of enum
- * xen_boot_type.  Internal to this library -- do not use from outside.
- */
-
-
-#ifndef XEN_BOOT_TYPE_INTERNAL_H
-#define XEN_BOOT_TYPE_INTERNAL_H
-
-
-#include "xen_internal.h"
-
-
-extern const abstract_type xen_boot_type_abstract_type_;
-extern const abstract_type xen_boot_type_set_abstract_type_;
-
-
-#endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_console.h
--- a/tools/libxen/include/xen_console.h        Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_console.h        Fri Dec 15 11:32:58 2006 -0700
@@ -149,14 +149,14 @@ xen_console_record_opt_set_free(xen_cons
 
 
 /**
- * Get the current state of the given console.
+ * Get a record containing the current state of the given console.
  */
 extern bool
 xen_console_get_record(xen_session *session, xen_console_record **result, 
xen_console console);
 
 
 /**
- * Get a reference to the object with the specified UUID.
+ * Get a reference to the console instance with the specified UUID.
  */
 extern bool
 xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_host.h
--- a/tools/libxen/include/xen_host.h   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_host.h   Fri Dec 15 11:32:58 2006 -0700
@@ -154,14 +154,14 @@ xen_host_record_opt_set_free(xen_host_re
 
 
 /**
- * Get the current state of the given host.  !!!
+ * Get a record containing the current state of the given host.
  */
 extern bool
 xen_host_get_record(xen_session *session, xen_host_record **result, xen_host 
host);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the host instance with the specified UUID.
  */
 extern bool
 xen_host_get_by_uuid(xen_session *session, xen_host *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_host_cpu.h
--- a/tools/libxen/include/xen_host_cpu.h       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_host_cpu.h       Fri Dec 15 11:32:58 2006 -0700
@@ -153,14 +153,14 @@ xen_host_cpu_record_opt_set_free(xen_hos
 
 
 /**
- * Get the current state of the given host_cpu.  !!!
+ * Get a record containing the current state of the given host_cpu.
  */
 extern bool
 xen_host_cpu_get_record(xen_session *session, xen_host_cpu_record **result, 
xen_host_cpu host_cpu);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the host_cpu instance with the specified UUID.
  */
 extern bool
 xen_host_cpu_get_by_uuid(xen_session *session, xen_host_cpu *result, char 
*uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_internal.h
--- a/tools/libxen/include/xen_internal.h       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_internal.h       Fri Dec 15 11:32:58 2006 -0700
@@ -128,7 +128,6 @@ xen_enum_lookup_(xen_session *session, c
     xen_enum_lookup_(session__, str__, lookup_table__,  \
                      sizeof(lookup_table__) /           \
                      sizeof(lookup_table__[0]))         \
-                                                        \
 
 #define XEN_ALLOC(type__)                       \
 type__ *                                        \
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_network.h
--- a/tools/libxen/include/xen_network.h        Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_network.h        Fri Dec 15 11:32:58 2006 -0700
@@ -152,14 +152,14 @@ xen_network_record_opt_set_free(xen_netw
 
 
 /**
- * Get the current state of the given network.  !!!
+ * Get a record containing the current state of the given network.
  */
 extern bool
 xen_network_get_record(xen_session *session, xen_network_record **result, 
xen_network network);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the network instance with the specified UUID.
  */
 extern bool
 xen_network_get_by_uuid(xen_session *session, xen_network *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_pif.h
--- a/tools/libxen/include/xen_pif.h    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_pif.h    Fri Dec 15 11:32:58 2006 -0700
@@ -155,14 +155,14 @@ xen_pif_record_opt_set_free(xen_pif_reco
 
 
 /**
- * Get the current state of the given PIF.  !!!
+ * Get a record containing the current state of the given PIF.
  */
 extern bool
 xen_pif_get_record(xen_session *session, xen_pif_record **result, xen_pif pif);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the PIF instance with the specified UUID.
  */
 extern bool
 xen_pif_get_by_uuid(xen_session *session, xen_pif *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_sr.h
--- a/tools/libxen/include/xen_sr.h     Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_sr.h     Fri Dec 15 11:32:58 2006 -0700
@@ -153,14 +153,14 @@ xen_sr_record_opt_set_free(xen_sr_record
 
 
 /**
- * Get the current state of the given SR.  !!!
+ * Get a record containing the current state of the given SR.
  */
 extern bool
 xen_sr_get_record(xen_session *session, xen_sr_record **result, xen_sr sr);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the SR instance with the specified UUID.
  */
 extern bool
 xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_user.h
--- a/tools/libxen/include/xen_user.h   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_user.h   Fri Dec 15 11:32:58 2006 -0700
@@ -146,14 +146,14 @@ xen_user_record_opt_set_free(xen_user_re
 
 
 /**
- * Get the current state of the given user.  !!!
+ * Get a record containing the current state of the given user.
  */
 extern bool
 xen_user_get_record(xen_session *session, xen_user_record **result, xen_user 
user);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the user instance with the specified UUID.
  */
 extern bool
 xen_user_get_by_uuid(xen_session *session, xen_user *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vdi.h
--- a/tools/libxen/include/xen_vdi.h    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vdi.h    Fri Dec 15 11:32:58 2006 -0700
@@ -159,14 +159,14 @@ xen_vdi_record_opt_set_free(xen_vdi_reco
 
 
 /**
- * Get the current state of the given VDI.  !!!
+ * Get a record containing the current state of the given VDI.
  */
 extern bool
 xen_vdi_get_record(xen_session *session, xen_vdi_record **result, xen_vdi vdi);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the VDI instance with the specified UUID.
  */
 extern bool
 xen_vdi_get_by_uuid(xen_session *session, xen_vdi *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vif.h
--- a/tools/libxen/include/xen_vif.h    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vif.h    Fri Dec 15 11:32:58 2006 -0700
@@ -156,14 +156,14 @@ xen_vif_record_opt_set_free(xen_vif_reco
 
 
 /**
- * Get the current state of the given VIF.  !!!
+ * Get a record containing the current state of the given VIF.
  */
 extern bool
 xen_vif_get_record(xen_session *session, xen_vif_record **result, xen_vif vif);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the VIF instance with the specified UUID.
  */
 extern bool
 xen_vif_get_by_uuid(xen_session *session, xen_vif *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h     Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vm.h     Fri Dec 15 11:32:58 2006 -0700
@@ -19,7 +19,6 @@
 #ifndef XEN_VM_H
 #define XEN_VM_H
 
-#include "xen_boot_type.h"
 #include "xen_common.h"
 #include "xen_console_decl.h"
 #include "xen_cpu_feature.h"
@@ -36,9 +35,36 @@
 
 
 /*
- * The VM class. 
- *  
+ * The VM class.
+ * 
  * A virtual machine (or 'guest').
+ * 
+ * VM booting is controlled by setting one of the two mutually exclusive
+ * groups: "PV", and "HVM".  If HVM.boot is the empty string, then paravirtual
+ * domain building and booting will be used; otherwise the VM will be loaded
+ * as an HVM domain, and booted using an emulated BIOS.
+ * 
+ * When paravirtual booting is in use, the PV/bootloader field indicates the
+ * bootloader to use.  It may be "pygrub", in which case the platform's
+ * default installation of pygrub will be used, or a full path within the
+ * control domain to some other bootloader.  The other fields, PV/kernel,
+ * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader
+ * unmodified, and interpretation of those fields is then specific to the
+ * bootloader itself, including the possibility that the bootloader will
+ * ignore some or all of those given values.
+ * 
+ * If the bootloader is pygrub, then the menu.lst is parsed if present in the
+ * guest's filesystem, otherwise the specified kernel and ramdisk are used, or
+ * an autodetected kernel is used if nothing is specified and autodetection is
+ * possible.  PV/args is appended to the kernel command line, no matter which
+ * mechanism is used for finding the kernel.
+ * 
+ * If PV/bootloader is empty but PV/kernel is specified, then the kernel and
+ * ramdisk values will be treated as paths within the control domain.  If both
+ * PV/bootloader and PV/kernel are empty, then the behaviour is as if
+ * PV/bootloader was specified as "pygrub".
+ * 
+ * When using HVM booting, HVM/boot specifies the order of the boot devices.
  */
 
 
@@ -79,6 +105,7 @@ typedef struct xen_vm_record
     char *name_description;
     int64_t user_version;
     bool is_a_template;
+    bool auto_power_on;
     struct xen_host_record_opt *resident_on;
     int64_t memory_static_max;
     int64_t memory_dynamic_max;
@@ -101,18 +128,17 @@ typedef struct xen_vm_record
     struct xen_vif_record_opt_set *vifs;
     struct xen_vbd_record_opt_set *vbds;
     struct xen_vtpm_record_opt_set *vtpms;
-    char *bios_boot;
+    char *pv_bootloader;
+    char *pv_kernel;
+    char *pv_ramdisk;
+    char *pv_args;
+    char *pv_bootloader_args;
+    char *hvm_boot;
     bool platform_std_vga;
     char *platform_serial;
     bool platform_localtime;
     bool platform_clock_offset;
     bool platform_enable_audio;
-    char *builder;
-    enum xen_boot_type boot_method;
-    char *kernel_kernel;
-    char *kernel_initrd;
-    char *kernel_args;
-    char *grub_cmdline;
     char *pci_bus;
     xen_string_string_map *tools_version;
     xen_string_string_map *otherconfig;
@@ -198,14 +224,14 @@ xen_vm_record_opt_set_free(xen_vm_record
 
 
 /**
- * Get the current state of the given VM.  !!!
+ * Get a record containing the current state of the given VM.
  */
 extern bool
 xen_vm_get_record(xen_session *session, xen_vm_record **result, xen_vm vm);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the VM instance with the specified UUID.
  */
 extern bool
 xen_vm_get_by_uuid(xen_session *session, xen_vm *result, char *uuid);
@@ -277,6 +303,13 @@ xen_vm_get_is_a_template(xen_session *se
 
 
 /**
+ * Get the auto_power_on field of the given VM.
+ */
+extern bool
+xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm);
+
+
+/**
  * Get the resident_on field of the given VM.
  */
 extern bool
@@ -431,10 +464,45 @@ xen_vm_get_vtpms(xen_session *session, s
 
 
 /**
- * Get the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm);
+ * Get the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
 
 
 /**
@@ -473,48 +541,6 @@ xen_vm_get_platform_enable_audio(xen_ses
 
 
 /**
- * Get the builder field of the given VM.
- */
-extern bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the boot_method field of the given VM.
- */
-extern bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, 
xen_vm vm);
-
-
-/**
- * Get the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm);
-
-
-/**
  * Get the PCI_bus field of the given VM.
  */
 extern bool
@@ -564,6 +590,13 @@ xen_vm_set_is_a_template(xen_session *se
 
 
 /**
+ * Set the auto_power_on field of the given VM.
+ */
+extern bool
+xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on);
+
+
+/**
  * Set the memory/dynamic_max field of the given VM.
  */
 extern bool
@@ -592,6 +625,13 @@ xen_vm_set_vcpus_params(xen_session *ses
 
 
 /**
+ * Set the VCPUs/number field of the given VM.
+ */
+extern bool
+xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number);
+
+
+/**
  * Set the VCPUs/features/force_on field of the given VM.
  */
 extern bool
@@ -599,6 +639,22 @@ xen_vm_set_vcpus_features_force_on(xen_s
 
 
 /**
+ * Add the given value to the VCPUs/features/force_on field of the
+ * given VM.  If the value is already in that Set, then do nothing.
+ */
+extern bool
+xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value);
+
+
+/**
+ * Remove the given value from the VCPUs/features/force_on field of the
+ * given VM.  If the value is not in that Set, then do nothing.
+ */
+extern bool
+xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value);
+
+
+/**
  * Set the VCPUs/features/force_off field of the given VM.
  */
 extern bool
@@ -606,6 +662,22 @@ xen_vm_set_vcpus_features_force_off(xen_
 
 
 /**
+ * Add the given value to the VCPUs/features/force_off field of the
+ * given VM.  If the value is already in that Set, then do nothing.
+ */
+extern bool
+xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value);
+
+
+/**
+ * Remove the given value from the VCPUs/features/force_off field of
+ * the given VM.  If the value is not in that Set, then do nothing.
+ */
+extern bool
+xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value);
+
+
+/**
  * Set the actions/after_shutdown field of the given VM.
  */
 extern bool
@@ -634,10 +706,45 @@ xen_vm_set_actions_after_crash(xen_sessi
 
 
 /**
- * Set the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot);
+ * Set the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader);
+
+
+/**
+ * Set the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel);
+
+
+/**
+ * Set the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk);
+
+
+/**
+ * Set the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args);
+
+
+/**
+ * Set the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char 
*bootloader_args);
+
+
+/**
+ * Set the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
 
 
 /**
@@ -673,48 +780,6 @@ xen_vm_set_platform_clock_offset(xen_ses
  */
 extern bool
 xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool 
enable_audio);
-
-
-/**
- * Set the builder field of the given VM.
- */
-extern bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder);
-
-
-/**
- * Set the boot_method field of the given VM.
- */
-extern bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type 
boot_method);
-
-
-/**
- * Set the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel);
-
-
-/**
- * Set the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd);
-
-
-/**
- * Set the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args);
-
-
-/**
- * Set the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline);
 
 
 /**
@@ -760,8 +825,8 @@ xen_vm_unpause(xen_session *session, xen
 
 /**
  * Attempt to cleanly shutdown the specified VM. (Note: this may not be
- * supported---e.g. if a guest agent is not installed). 
- *  
+ * supported---e.g. if a guest agent is not installed).
+ * 
  * Once shutdown has been completed perform poweroff action specified in guest
  * configuration.
  */
@@ -771,8 +836,8 @@ xen_vm_clean_shutdown(xen_session *sessi
 
 /**
  * Attempt to cleanly shutdown the specified VM (Note: this may not be
- * supported---e.g. if a guest agent is not installed). 
- *  
+ * supported---e.g. if a guest agent is not installed).
+ * 
  * Once shutdown has been completed perform reboot action specified in guest
  * configuration.
  */
@@ -817,12 +882,4 @@ xen_vm_get_all(xen_session *session, str
 xen_vm_get_all(xen_session *session, struct xen_vm_set **result);
 
 
-/**
- * Destroy the specified VM.  The VM is completely removed from the system.
- * This function can only be called when the VM is in the Halted State.
- */
-extern bool
-xen_vm_destroy(xen_session *session, xen_vm vm);
-
-
 #endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vtpm.h
--- a/tools/libxen/include/xen_vtpm.h   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vtpm.h   Fri Dec 15 11:32:58 2006 -0700
@@ -151,14 +151,14 @@ xen_vtpm_record_opt_set_free(xen_vtpm_re
 
 
 /**
- * Get the current state of the given VTPM.  !!!
+ * Get a record containing the current state of the given VTPM.
  */
 extern bool
 xen_vtpm_get_record(xen_session *session, xen_vtpm_record **result, xen_vtpm 
vtpm);
 
 
 /**
- * Get a reference to the object with the specified UUID.  !!!
+ * Get a reference to the VTPM instance with the specified UUID.
  */
 extern bool
 xen_vtpm_get_by_uuid(xen_session *session, xen_vtpm *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_boot_type.c
--- a/tools/libxen/src/xen_boot_type.c  Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- */
-
-#include <string.h>
-
-#include "xen_internal.h"
-#include "xen_boot_type.h"
-#include "xen_boot_type_internal.h"
-
-
-/*
- * Maintain this in the same order as the enum declaration!
- */
-static const char *lookup_table[] =
-{
-    "bios",
-    "grub",
-    "kernel_external",
-    "kernel_internal"
-};
-
-
-extern xen_boot_type_set *
-xen_boot_type_set_alloc(size_t size)
-{
-    return calloc(1, sizeof(xen_boot_type_set) +
-                  size * sizeof(enum xen_boot_type));
-}
-
-
-extern void
-xen_boot_type_set_free(xen_boot_type_set *set)
-{
-    free(set);
-}
-
-
-const char *
-xen_boot_type_to_string(enum xen_boot_type val)
-{
-    return lookup_table[val];
-}
-
-
-extern enum xen_boot_type
-xen_boot_type_from_string(xen_session *session, const char *str)
-{
-    return ENUM_LOOKUP(session, str, lookup_table);
-}
-
-
-const abstract_type xen_boot_type_abstract_type_ =
-    {
-        .typename = ENUM,
-        .enum_marshaller =
-             (const char *(*)(int))&xen_boot_type_to_string,
-        .enum_demarshaller =
-             (int (*)(xen_session *, const char *))&xen_boot_type_from_string
-    };
-
-
-const abstract_type xen_boot_type_set_abstract_type_ =
-    {
-        .typename = SET,
-        .child = &xen_boot_type_abstract_type_
-    };
-
-
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_console.c
--- a/tools/libxen/src/xen_console.c    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_console.c    Fri Dec 15 11:32:58 2006 -0700
@@ -158,9 +158,7 @@ xen_console_get_protocol(xen_session *se
         };
 
     abstract_type result_type = xen_console_protocol_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("console.get_protocol");
-    *result = xen_console_protocol_from_string(session, result_str);
     return session->ok;
 }
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vif.c
--- a/tools/libxen/src/xen_vif.c        Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vif.c        Fri Dec 15 11:32:58 2006 -0700
@@ -197,9 +197,7 @@ xen_vif_get_type(xen_session *session, e
         };
 
     abstract_type result_type = xen_driver_type_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VIF.get_type");
-    *result = xen_driver_type_from_string(session, result_str);
     return session->ok;
 }
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vm.c Fri Dec 15 11:32:58 2006 -0700
@@ -20,7 +20,6 @@
 #include <stddef.h>
 #include <stdlib.h>
 
-#include "xen_boot_type_internal.h"
 #include "xen_common.h"
 #include "xen_console.h"
 #include "xen_cpu_feature.h"
@@ -67,6 +66,9 @@ static const struct_member xen_vm_record
         { .key = "is_a_template",
           .type = &abstract_type_bool,
           .offset = offsetof(xen_vm_record, is_a_template) },
+        { .key = "auto_power_on",
+          .type = &abstract_type_bool,
+          .offset = offsetof(xen_vm_record, auto_power_on) },
         { .key = "resident_on",
           .type = &abstract_type_ref,
           .offset = offsetof(xen_vm_record, resident_on) },
@@ -133,9 +135,24 @@ static const struct_member xen_vm_record
         { .key = "VTPMs",
           .type = &abstract_type_ref_set,
           .offset = offsetof(xen_vm_record, vtpms) },
-        { .key = "bios_boot",
+        { .key = "PV_bootloader",
           .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, bios_boot) },
+          .offset = offsetof(xen_vm_record, pv_bootloader) },
+        { .key = "PV_kernel",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_kernel) },
+        { .key = "PV_ramdisk",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_ramdisk) },
+        { .key = "PV_args",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_args) },
+        { .key = "PV_bootloader_args",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_bootloader_args) },
+        { .key = "HVM_boot",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, hvm_boot) },
         { .key = "platform_std_VGA",
           .type = &abstract_type_bool,
           .offset = offsetof(xen_vm_record, platform_std_vga) },
@@ -151,24 +168,6 @@ static const struct_member xen_vm_record
         { .key = "platform_enable_audio",
           .type = &abstract_type_bool,
           .offset = offsetof(xen_vm_record, platform_enable_audio) },
-        { .key = "builder",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, builder) },
-        { .key = "boot_method",
-          .type = &xen_boot_type_abstract_type_,
-          .offset = offsetof(xen_vm_record, boot_method) },
-        { .key = "kernel_kernel",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_kernel) },
-        { .key = "kernel_initrd",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_initrd) },
-        { .key = "kernel_args",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_args) },
-        { .key = "grub_cmdline",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, grub_cmdline) },
         { .key = "PCI_bus",
           .type = &abstract_type_string,
           .offset = offsetof(xen_vm_record, pci_bus) },
@@ -213,13 +212,13 @@ xen_vm_record_free(xen_vm_record *record
     xen_vif_record_opt_set_free(record->vifs);
     xen_vbd_record_opt_set_free(record->vbds);
     xen_vtpm_record_opt_set_free(record->vtpms);
-    free(record->bios_boot);
+    free(record->pv_bootloader);
+    free(record->pv_kernel);
+    free(record->pv_ramdisk);
+    free(record->pv_args);
+    free(record->pv_bootloader_args);
+    free(record->hvm_boot);
     free(record->platform_serial);
-    free(record->builder);
-    free(record->kernel_kernel);
-    free(record->kernel_initrd);
-    free(record->kernel_args);
-    free(record->grub_cmdline);
     free(record->pci_bus);
     xen_string_string_map_free(record->tools_version);
     xen_string_string_map_free(record->otherconfig);
@@ -325,9 +324,7 @@ xen_vm_get_power_state(xen_session *sess
         };
 
     abstract_type result_type = xen_vm_power_state_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VM.get_power_state");
-    *result = xen_vm_power_state_from_string(session, result_str);
     return session->ok;
 }
 
@@ -399,6 +396,22 @@ xen_vm_get_is_a_template(xen_session *se
 
 
 bool
+xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_bool;
+
+    XEN_CALL_("VM.get_auto_power_on");
+    return session->ok;
+}
+
+
+bool
 xen_vm_get_resident_on(xen_session *session, xen_host *result, xen_vm vm)
 {
     abstract_value param_values[] =
@@ -640,9 +653,7 @@ xen_vm_get_actions_after_shutdown(xen_se
         };
 
     abstract_type result_type = xen_on_normal_exit_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VM.get_actions_after_shutdown");
-    *result = xen_on_normal_exit_from_string(session, result_str);
     return session->ok;
 }
 
@@ -657,9 +668,7 @@ xen_vm_get_actions_after_reboot(xen_sess
         };
 
     abstract_type result_type = xen_on_normal_exit_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VM.get_actions_after_reboot");
-    *result = xen_on_normal_exit_from_string(session, result_str);
     return session->ok;
 }
 
@@ -674,9 +683,7 @@ xen_vm_get_actions_after_suspend(xen_ses
         };
 
     abstract_type result_type = xen_on_normal_exit_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VM.get_actions_after_suspend");
-    *result = xen_on_normal_exit_from_string(session, result_str);
     return session->ok;
 }
 
@@ -691,9 +698,7 @@ xen_vm_get_actions_after_crash(xen_sessi
         };
 
     abstract_type result_type = xen_on_crash_behaviour_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VM.get_actions_after_crash");
-    *result = xen_on_crash_behaviour_from_string(session, result_str);
     return session->ok;
 }
 
@@ -767,7 +772,7 @@ xen_vm_get_vtpms(xen_session *session, s
 
 
 bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm)
 {
     abstract_value param_values[] =
         {
@@ -778,7 +783,92 @@ xen_vm_get_bios_boot(xen_session *sessio
     abstract_type result_type = abstract_type_string;
 
     *result = NULL;
-    XEN_CALL_("VM.get_bios_boot");
+    XEN_CALL_("VM.get_PV_bootloader");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_kernel");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_ramdisk");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_args");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_bootloader_args");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_HVM_boot");
     return session->ok;
 }
 
@@ -860,108 +950,6 @@ xen_vm_get_platform_enable_audio(xen_ses
     abstract_type result_type = abstract_type_bool;
 
     XEN_CALL_("VM.get_platform_enable_audio");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_builder");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, 
xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = xen_boot_type_abstract_type_;
-    char *result_str = NULL;
-    XEN_CALL_("VM.get_boot_method");
-    *result = xen_boot_type_from_string(session, result_str);
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_kernel");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_initrd");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_args");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_grub_cmdline");
     return session->ok;
 }
 
@@ -1082,6 +1070,22 @@ xen_vm_set_is_a_template(xen_session *se
 
 
 bool
+xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_bool,
+              .u.bool_val = auto_power_on }
+        };
+
+    xen_call_(session, "VM.set_auto_power_on", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_vm_set_memory_dynamic_max(xen_session *session, xen_vm vm, int64_t 
dynamic_max)
 {
     abstract_value param_values[] =
@@ -1146,6 +1150,22 @@ xen_vm_set_vcpus_params(xen_session *ses
 
 
 bool
+xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_int,
+              .u.int_val = number }
+        };
+
+    xen_call_(session, "VM.set_VCPUs_number", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_vm_set_vcpus_features_force_on(xen_session *session, xen_vm vm, struct 
xen_cpu_feature_set *force_on)
 {
     abstract_value param_values[] =
@@ -1162,6 +1182,38 @@ xen_vm_set_vcpus_features_force_on(xen_s
 
 
 bool
+xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &xen_cpu_feature_abstract_type_,
+              .u.string_val = xen_cpu_feature_to_string(value) }
+        };
+
+    xen_call_(session, "VM.add_VCPUs_features_force_on", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &xen_cpu_feature_abstract_type_,
+              .u.string_val = xen_cpu_feature_to_string(value) }
+        };
+
+    xen_call_(session, "VM.remove_VCPUs_features_force_on", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_vm_set_vcpus_features_force_off(xen_session *session, xen_vm vm, struct 
xen_cpu_feature_set *force_off)
 {
     abstract_value param_values[] =
@@ -1178,6 +1230,38 @@ xen_vm_set_vcpus_features_force_off(xen_
 
 
 bool
+xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &xen_cpu_feature_abstract_type_,
+              .u.string_val = xen_cpu_feature_to_string(value) }
+        };
+
+    xen_call_(session, "VM.add_VCPUs_features_force_off", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum 
xen_cpu_feature value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &xen_cpu_feature_abstract_type_,
+              .u.string_val = xen_cpu_feature_to_string(value) }
+        };
+
+    xen_call_(session, "VM.remove_VCPUs_features_force_off", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_vm_set_actions_after_shutdown(xen_session *session, xen_vm vm, enum 
xen_on_normal_exit after_shutdown)
 {
     abstract_value param_values[] =
@@ -1242,7 +1326,87 @@ xen_vm_set_actions_after_crash(xen_sessi
 
 
 bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot)
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = bootloader }
+        };
+
+    xen_call_(session, "VM.set_PV_bootloader", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = kernel }
+        };
+
+    xen_call_(session, "VM.set_PV_kernel", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = ramdisk }
+        };
+
+    xen_call_(session, "VM.set_PV_ramdisk", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = args }
+        };
+
+    xen_call_(session, "VM.set_PV_args", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char 
*bootloader_args)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = bootloader_args }
+        };
+
+    xen_call_(session, "VM.set_PV_bootloader_args", param_values, 2, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
 {
     abstract_value param_values[] =
         {
@@ -1252,7 +1416,7 @@ xen_vm_set_bios_boot(xen_session *sessio
               .u.string_val = boot }
         };
 
-    xen_call_(session, "VM.set_bios_boot", param_values, 2, NULL, NULL);
+    xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
     return session->ok;
 }
 
@@ -1268,7 +1432,7 @@ xen_vm_set_platform_std_vga(xen_session 
               .u.bool_val = std_vga }
         };
 
-    xen_call_(session, "VM.set_platform_std_vga", param_values, 2, NULL, NULL);
+    xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
     return session->ok;
 }
 
@@ -1338,102 +1502,6 @@ xen_vm_set_platform_enable_audio(xen_ses
 
 
 bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = builder }
-        };
-
-    xen_call_(session, "VM.set_builder", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type 
boot_method)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &xen_boot_type_abstract_type_,
-              .u.string_val = xen_boot_type_to_string(boot_method) }
-        };
-
-    xen_call_(session, "VM.set_boot_method", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = kernel }
-        };
-
-    xen_call_(session, "VM.set_kernel_kernel", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = initrd }
-        };
-
-    xen_call_(session, "VM.set_kernel_initrd", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = args }
-        };
-
-    xen_call_(session, "VM.set_kernel_args", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = cmdline }
-        };
-
-    xen_call_(session, "VM.set_grub_cmdline", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
 xen_vm_set_otherconfig(xen_session *session, xen_vm vm, xen_string_string_map 
*otherconfig)
 {
     abstract_value param_values[] =
@@ -1444,7 +1512,7 @@ xen_vm_set_otherconfig(xen_session *sess
               .u.set_val = (arbitrary_set *)otherconfig }
         };
 
-    xen_call_(session, "VM.set_otherconfig", param_values, 2, NULL, NULL);
+    xen_call_(session, "VM.set_otherConfig", param_values, 2, NULL, NULL);
     return session->ok;
 }
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vtpm.c
--- a/tools/libxen/src/xen_vtpm.c       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vtpm.c       Fri Dec 15 11:32:58 2006 -0700
@@ -196,9 +196,7 @@ xen_vtpm_get_driver(xen_session *session
         };
 
     abstract_type result_type = xen_driver_type_abstract_type_;
-    char *result_str = NULL;
     XEN_CALL_("VTPM.get_driver");
-    *result = xen_driver_type_from_string(session, result_str);
     return session->ok;
 }
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/test/test_bindings.c
--- a/tools/libxen/test/test_bindings.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/test/test_bindings.c Fri Dec 15 11:32:58 2006 -0700
@@ -58,7 +58,8 @@ typedef struct
 } xen_comms;
 
 
-static void create_new_vm(xen_session *session);
+static xen_vm create_new_vm(xen_session *session);
+static void print_vm_power_state(xen_session *session, xen_vm vm);
 
 
 static size_t
@@ -244,7 +245,7 @@ int main(int argc, char **argv)
     xen_string_string_map_free(versions);
 
 
-    create_new_vm(session);
+    xen_vm new_vm = create_new_vm(session);
     if (!session->ok)
     {
         /* Error has been logged, just clean up. */
@@ -252,6 +253,16 @@ int main(int argc, char **argv)
         return 1;
     }
 
+    print_vm_power_state(session, new_vm);
+    if (!session->ok)
+    {
+        /* Error has been logged, just clean up. */
+        xen_vm_free(new_vm);
+        CLEANUP;
+        return 1;
+    }
+
+    xen_vm_free(new_vm);
     CLEANUP;
 
     return 0;
@@ -264,7 +275,7 @@ int main(int argc, char **argv)
  * allocation patterns can be used, as long as the allocation and free are
  * paired correctly.
  */
-static void create_new_vm(xen_session *session)
+static xen_vm create_new_vm(xen_session *session)
 {
     xen_cpu_feature_set *empty_cpu_feature_set =
         xen_cpu_feature_set_alloc(0);
@@ -294,12 +305,12 @@ static void create_new_vm(xen_session *s
             .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
             .actions_after_suspend = XEN_ON_NORMAL_EXIT_DESTROY,
             .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
-            .bios_boot = "hd(0,0)",
-            .builder = "Linux",
-            .boot_method = XEN_BOOT_TYPE_KERNEL_EXTERNAL,
-            .kernel_kernel = "vmlinuz",
-            .kernel_initrd = "initrd.img",
-            .kernel_args = ""
+            .hvm_boot = "",
+            .pv_bootloader = "pygrub",
+            .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
+            .pv_ramdisk = "",
+            .pv_args = "",
+            .pv_bootloader_args = ""
         };
 
 
@@ -313,7 +324,7 @@ static void create_new_vm(xen_session *s
     {
         fprintf(stderr, "VM creation failed.\n");
         print_error(session);
-        return;
+        return NULL;
     }
 
 
@@ -327,7 +338,7 @@ static void create_new_vm(xen_session *s
         fprintf(stderr, "SR lookup failed.\n");
         print_error(session);
         xen_vm_free(vm);
-        return;
+        return NULL;
     }
 
     xen_sr_record_opt sr_record =
@@ -339,7 +350,7 @@ static void create_new_vm(xen_session *s
             .name_label = "MyRootFS",
             .name_description = "MyRootFS description",
             .sr = &sr_record,
-            .virtual_size = (1 << 20) / 512,
+            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
             .sector_size = 512,
             .type = XEN_VDI_TYPE_SYSTEM,
             .sharable = false,
@@ -354,7 +365,7 @@ static void create_new_vm(xen_session *s
 
         xen_sr_set_free(srs);
         xen_vm_free(vm);
-        return;
+        return NULL;
     }
 
 
@@ -370,7 +381,7 @@ static void create_new_vm(xen_session *s
         {
             .vm = &vm_record_opt,
             .vdi = &vdi0_record_opt,
-            .device = "sda1",
+            .device = "xvda1",
             .mode = XEN_VBD_MODE_RW,
             .driver = XEN_DRIVER_TYPE_PARAVIRTUALISED
         };
@@ -384,7 +395,7 @@ static void create_new_vm(xen_session *s
         xen_vdi_free(vdi0);
         xen_sr_set_free(srs);
         xen_vm_free(vm);
-        return;
+        return NULL;
     }
 
     char *vm_uuid;
@@ -407,7 +418,7 @@ static void create_new_vm(xen_session *s
         xen_vdi_free(vdi0);
         xen_sr_set_free(srs);
         xen_vm_free(vm);
-        return;
+        return NULL;
     }
 
     fprintf(stderr,
@@ -420,5 +431,34 @@ static void create_new_vm(xen_session *s
     xen_vbd_free(vbd0);
     xen_vdi_free(vdi0);
     xen_sr_set_free(srs);
-    xen_vm_free(vm);
-}
+
+    return vm;
+}
+
+
+/**
+ * Print the power state for the given VM.
+ */
+static void print_vm_power_state(xen_session *session, xen_vm vm)
+{
+    char *vm_uuid;
+    enum xen_vm_power_state power_state;
+
+    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+    {
+        print_error(session);
+        return;
+    }
+
+    if (!xen_vm_get_power_state(session, &power_state, vm))
+    {
+        xen_uuid_free(vm_uuid);
+        print_error(session);
+        return;
+    }
+
+    printf("VM %s power state is %s.\n", vm_uuid,
+           xen_vm_power_state_to_string(power_state));
+
+    xen_uuid_free(vm_uuid);
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Dec 15 11:32:58 2006 -0700
@@ -408,10 +408,6 @@ static PyObject *pyxc_hvm_build(XcObject
                                       &image, &vcpus, &pae, &acpi, &apic) )
         return NULL;
 
-#if defined(__ia64__)
-    /* Set vcpus to later be retrieved in setup_guest() */
-    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_VCPUS, vcpus);
-#endif
     if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
         return pyxc_error_to_exception();
 
@@ -919,6 +915,68 @@ static PyObject *dom_op(XcObject *self, 
     return zero;
 }
 
+#ifdef __powerpc__
+static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
+                                           PyObject *args,
+                                           PyObject *kwds)
+{
+    uint32_t dom;
+    unsigned int log;
+
+    static char *kwd_list[] = { "dom", "log", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
+                                      &dom, &log) )
+        return NULL;
+
+    if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
+        return PyErr_SetFromErrno(xc_error);
+
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_prose_build(XcObject *self,
+                                  PyObject *args,
+                                  PyObject *kwds)
+{
+    uint32_t dom;
+    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
+    int flags = 0;
+    int store_evtchn, console_evtchn;
+    unsigned long store_mfn = 0;
+    unsigned long console_mfn = 0;
+    void *arch_args = NULL;
+    int unused;
+
+    static char *kwd_list[] = { "dom", "store_evtchn",
+                                "console_evtchn", "image",
+                                /* optional */
+                                "ramdisk", "cmdline", "flags",
+                                "features", "arch_args", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
+                                      &dom, &store_evtchn,
+                                      &console_evtchn, &image,
+                                      /* optional */
+                                      &ramdisk, &cmdline, &flags,
+                                      &features, &arch_args, &unused) )
+        return NULL;
+
+    if ( xc_prose_build(self->xc_handle, dom, image,
+                        ramdisk, cmdline, features, flags,
+                        store_evtchn, &store_mfn,
+                        console_evtchn, &console_mfn,
+                        arch_args) != 0 ) {
+        if (!errno)
+             errno = EINVAL;
+        return PyErr_SetFromErrno(xc_error);
+    }
+    return Py_BuildValue("{s:i,s:i}", 
+                         "store_mfn", store_mfn,
+                         "console_mfn", console_mfn);
+}
+#endif /* powerpc */
 
 static PyMethodDef pyxc_methods[] = {
     { "handle",
@@ -1224,6 +1282,27 @@ static PyMethodDef pyxc_methods[] = {
       "Set a domain's time offset to Dom0's localtime\n"
       " dom        [int]: Domain whose time offset is being set.\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
+
+#ifdef __powerpc__
+    { "arch_alloc_real_mode_area", 
+      (PyCFunction)pyxc_alloc_real_mode_area, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Allocate a domain's real mode area.\n"
+      " dom [int]: Identifier of domain.\n"
+      " log [int]: Specifies the area's size.\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "arch_prose_build", 
+      (PyCFunction)pyxc_prose_build, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Build a new Linux guest OS.\n"
+      " dom     [int]:      Identifier of domain to build into.\n"
+      " image   [str]:      Name of kernel image file. May be gzipped.\n"
+      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
+      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
+      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+#endif /* __powerpc */
 
     { NULL, NULL, 0, NULL }
 };
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/FlatDeviceTree.py
--- a/tools/python/xen/xend/FlatDeviceTree.py   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/FlatDeviceTree.py   Fri Dec 15 11:32:58 2006 -0700
@@ -22,6 +22,10 @@ import struct
 import struct
 import stat
 import re
+import glob
+import math
+
+_host_devtree_root = '/proc/device-tree'
 
 _OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
 _OF_DT_BEGIN_NODE = 0x1
@@ -33,8 +37,10 @@ def _bincat(seq, separator=''):
     '''Concatenate the contents of seq into a bytestream.'''
     strs = []
     for item in seq:
-        if type(item) == type(0):
+        if isinstance(item, int):
             strs.append(struct.pack(">I", item))
+        elif isinstance(item, long):
+            strs.append(struct.pack(">Q", item))
         else:
             try:
                 strs.append(item.to_bin())
@@ -231,37 +237,50 @@ class Tree(_Node):
         header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
         return _pad(header.to_bin(), 8) + payload
 
-_host_devtree_root = '/proc/device-tree'
-def _getprop(propname):
-    '''Extract a property from the system's device tree.'''
-    f = file(os.path.join(_host_devtree_root, propname), 'r')
+def _readfile(fullpath):
+    '''Return full contents of a file.'''
+    f = file(fullpath, 'r')
     data = f.read()
     f.close()
     return data
 
+def _find_first_cpu(dirpath):
+    '''Find the first node of type 'cpu' in a directory tree.'''
+    cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
+    for node in cpulist:
+        try:
+            data = _readfile(os.path.join(node, 'device_type'))
+        except IOError:
+            continue
+        if 'cpu' in data:
+            return node
+    raise IOError("couldn't find any CPU nodes under " + dirpath)
+
 def _copynode(node, dirpath, propfilter):
-    '''Extract all properties from a node in the system's device tree.'''
+    '''Copy all properties and children nodes from a directory tree.'''
     dirents = os.listdir(dirpath)
     for dirent in dirents:
         fullpath = os.path.join(dirpath, dirent)
         st = os.lstat(fullpath)
         if stat.S_ISDIR(st.st_mode):
             child = node.addnode(dirent)
-            _copytree(child, fullpath, propfilter)
+            _copynode(child, fullpath, propfilter)
         elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
-            node.addprop(dirent, _getprop(fullpath))
-
-def _copytree(node, dirpath, propfilter):
-    path = os.path.join(_host_devtree_root, dirpath)
-    _copynode(node, path, propfilter)
+            node.addprop(dirent, _readfile(fullpath))
 
 def build(imghandler):
     '''Construct a device tree by combining the domain's configuration and
     the host's device tree.'''
     root = Tree()
 
-    # 4 pages: start_info, console, store, shared_info
+    # 1st reseravtion entry used for start_info, console, store, shared_info
     root.reserve(0x3ffc000, 0x4000)
+
+    # 2nd reservation enrty used for initrd, later on when we load the
+    # initrd we may fill this in with zeroes which signifies the end
+    # of the reservation map.  So as to avoid adding a zero map now we
+    # put some bogus yet sensible numbers here.
+    root.reserve(0x1000000, 0x1000)
 
     root.addprop('device_type', 'chrp-but-not-really\0')
     root.addprop('#size-cells', 2)
@@ -270,35 +289,52 @@ def build(imghandler):
     root.addprop('compatible', 'Momentum,Maple\0')
 
     xen = root.addnode('xen')
-    xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
+    xen.addprop('start-info', long(0x3ffc000), long(0x1000))
     xen.addprop('version', 'Xen-3.0-unstable\0')
-    xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
+    xen.addprop('reg', long(imghandler.vm.domid), long(0))
     xen.addprop('domain-name', imghandler.vm.getName() + '\0')
     xencons = xen.addnode('console')
     xencons.addprop('interrupts', 1, 0)
 
-    # XXX split out RMA node
-    mem = root.addnode('memory@0')
+    # add memory nodes
     totalmem = imghandler.vm.getMemoryTarget() * 1024
-    mem.addprop('reg', 0, 0, 0, totalmem)
-    mem.addprop('device_type', 'memory\0')
-
+    rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
+    rma_bytes = 1 << rma_log
+
+    # RMA node
+    rma = root.addnode('memory@0')
+    rma.addprop('reg', long(0), long(rma_bytes))
+    rma.addprop('device_type', 'memory\0')
+
+    # all the rest in a single node
+    remaining = totalmem - rma_bytes
+    if remaining > 0:
+        mem = root.addnode('memory@1')
+        mem.addprop('reg', long(rma_bytes), long(remaining))
+        mem.addprop('device_type', 'memory\0')
+
+    # add CPU nodes
     cpus = root.addnode('cpus')
     cpus.addprop('smp-enabled')
     cpus.addprop('#size-cells', 0)
     cpus.addprop('#address-cells', 1)
 
     # Copy all properties the system firmware gave us, except for 'linux,'
-    # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are
-    # identical...
+    # properties, from the first CPU node in the device tree. Do this once for
+    # every vcpu. Hopefully all cpus are identical...
     cpu0 = None
+    cpu0path = _find_first_cpu(_host_devtree_root)
     def _nolinuxprops(fullpath):
         return not os.path.basename(fullpath).startswith('linux,')
     for i in range(imghandler.vm.getVCpuCount()):
-        cpu = cpus.addnode('PowerPC,970@0')
-        _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops)
-        # and then overwrite what we need to
-        pft_size = imghandler.vm.info.get('pft-size', 0x14)
+        # create new node and copy all properties
+        cpu = cpus.addnode('PowerPC,970@%d' % i)
+        _copynode(cpu, cpu0path, _nolinuxprops)
+
+        # overwrite what we need to
+        shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
+        shadow_mb_log = int(math.log(shadow_mb, 2))
+        pft_size = shadow_mb_log + 20
         cpu.setprop('ibm,pft-size', 0, pft_size)
 
         # set default CPU
@@ -307,13 +343,13 @@ def build(imghandler):
 
     chosen = root.addnode('chosen')
     chosen.addprop('cpu', cpu0.get_phandle())
-    chosen.addprop('memory', mem.get_phandle())
+    chosen.addprop('memory', rma.get_phandle())
     chosen.addprop('linux,stdout-path', '/xen/console\0')
     chosen.addprop('interrupt-controller', xen.get_phandle())
     chosen.addprop('bootargs', imghandler.cmdline + '\0')
     # xc_linux_load.c will overwrite these 64-bit properties later
-    chosen.addprop('linux,initrd-start', 0, 0)
-    chosen.addprop('linux,initrd-end', 0, 0)
+    chosen.addprop('linux,initrd-start', long(0))
+    chosen.addprop('linux,initrd-end', long(0))
 
     if 1:
         f = file('/tmp/domU.dtb', 'w')
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendAPI.py  Fri Dec 15 11:32:58 2006 -0700
@@ -118,11 +118,16 @@ def valid_vm(func):
     @param func: function with params: (self, session, vm_ref)
     @rtype: callable object
     """    
-    def check_vm_ref(self, session, vm_ref, *args, **kwargs):
+    def check_vm_ref(self, session, *args, **kwargs):
+        if len(args) == 0:
+            return {'Status': 'Failure',
+                    'ErrorDescription': XEND_ERROR_VM_INVALID}
+
+        vm_ref = args[0]
         xendom = XendDomain.instance()
         if type(vm_ref) == type(str()) and \
                xendom.is_valid_vm(vm_ref):
-            return func(self, session, vm_ref, *args, **kwargs)
+            return func(self, session, *args, **kwargs)
         else:
             return {'Status': 'Failure',
                     'ErrorDescription': XEND_ERROR_VM_INVALID}
@@ -567,6 +572,7 @@ class XendAPI:
                   'VCPUs_utilisation',
                   'VCPUs_features_required',
                   'VCPUs_can_use',
+                  'consoles',
                   'VIFs',
                   'VBDs',
                   'VTPMs',
@@ -578,6 +584,7 @@ class XendAPI:
                   'name_description',
                   'user_version',
                   'is_a_template',
+                  'auto_power_on',
                   'memory_dynamic_max',
                   'memory_dynamic_min',
                   'VCPUs_policy',
@@ -588,19 +595,18 @@ class XendAPI:
                   'actions_after_reboot',
                   'actions_after_suspend',
                   'actions_after_crash',
-                  'bios_boot',
+                  'PV_bootloader',
+                  'PV_kernel',
+                  'PV_ramdisk',
+                  'PV_args',
+                  'PV_bootloader_args',
+                  'HVM_boot',
                   'platform_std_VGA',
                   'platform_serial',
                   'platform_localtime',
                   'platform_clock_offset',
                   'platform_enable_audio',
                   'platform_keymap',
-                  'builder',
-                  'boot_method',
-                  'kernel_kernel',
-                  'kernel_initrd',
-                  'kernel_args',
-                  'grub_cmdline',
                   'otherConfig']
 
     VM_methods = ['clone',
@@ -636,26 +642,34 @@ class XendAPI:
         'actions_after_reboot',
         'actions_after_suspend',
         'actions_after_crash',
-        'bios_boot',
+        'PV_bootloader',
+        'PV_kernel',
+        'PV_ramdisk',
+        'PV_args',
+        'PV_bootloader_args',
+        'HVM_boot',
         'platform_std_VGA',
         'platform_serial',
         'platform_localtime',
         'platform_clock_offset',
         'platform_enable_audio',
         'platform_keymap',
-        'builder',
-        'boot_method',
-        'kernel_kernel',
-        'kernel_initrd',
-        'kernel_args',
         'grub_cmdline',
         'PCI_bus',
         'otherConfig']
         
+    def VM_get(self, name, session, vm_ref):
+        return xen_api_success(
+            XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
+
+    def VM_set(self, name, session, vm_ref, value):
+        XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
+        return xen_api_success_void()
+
     # attributes (ro)
     def VM_get_power_state(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.state)
+        return xen_api_success(dom.get_power_state())
     
     def VM_get_resident_on(self, session, vm_ref):
         return xen_api_success(XendNode.instance().uuid)
@@ -765,9 +779,23 @@ class XendAPI:
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_crash())
     
-    def VM_get_bios_boot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_bios_boot())
+    def VM_get_PV_bootloader(self, session, vm_ref):
+        return self.VM_get('PV_bootloader', session, vm_ref)
+    
+    def VM_get_PV_kernel(self, session, vm_ref):
+        return self.VM_get('PV_kernel', session, vm_ref)
+    
+    def VM_get_PV_ramdisk(self, session, vm_ref):
+        return self.VM_get('PV_ramdisk', session, vm_ref)
+    
+    def VM_get_PV_args(self, session, vm_ref):
+        return self.VM_get('PV_args', session, vm_ref)
+
+    def VM_get_PV_bootloader_args(self, session, vm_ref):
+        return self.VM_get('PV_bootloader_args', session, vm_ref)
+
+    def VM_get_HVM_boot(self, session, vm_ref):
+        return self.VM_get('HVM_boot', session, vm_ref)
     
     def VM_get_platform_std_VGA(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -793,34 +821,10 @@ class XendAPI:
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
     
-    def VM_get_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_builder())
-    
-    def VM_get_boot_method(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_boot_method())
-    
-    def VM_get_kernel_kernel(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_kernel_initrd(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_kernel_args(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_grub_cmdline(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
     def VM_get_otherConfig(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
-    
+
     def VM_set_name_label(self, session, vm_ref, label):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         dom.setName(label)
@@ -877,11 +881,25 @@ class XendAPI:
     def VM_set_actions_after_crash(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
-    
-    def VM_set_bios_boot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
+
+    def VM_set_HVM_boot(self, session, vm_ref, value):
+        return self.VM_set('HVM_boot', session, vm_ref, value)
+
+    def VM_set_PV_bootloader(self, session, vm_ref, value):
+        return self.VM_set('PV_bootloader', session, vm_ref, value)
+
+    def VM_set_PV_kernel(self, session, vm_ref, value):
+        return self.VM_set('PV_kernel', session, vm_ref, value)
+
+    def VM_set_PV_ramdisk(self, session, vm_ref, value):
+        return self.VM_set('PV_ramdisk', session, vm_ref, value)
+
+    def VM_set_PV_args(self, session, vm_ref, value):
+        return self.VM_set('PV_args', session, vm_ref, value)
+
+    def VM_set_PV_bootloader_args(self, session, vm_ref, value):
+        return self.VM_set('PV_bootloader_args', session, vm_ref, value)
+
     def VM_set_platform_std_VGA(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
@@ -899,30 +917,6 @@ class XendAPI:
         return xen_api_success_void()
     
     def VM_set_platform_enable_audio(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_boot_method(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_kernel(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_initrd(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_args(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_grub_cmdline(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
     
@@ -961,6 +955,7 @@ class XendAPI:
             'name_description': xeninfo.getName(),
             'user_version': 1,
             'is_a_template': False,
+            'auto_power_on': False,
             'resident_on': XendNode.instance().uuid,
             'memory_static_min': xeninfo.get_memory_static_min(),
             'memory_static_max': xeninfo.get_memory_static_max(),
@@ -979,22 +974,22 @@ class XendAPI:
             'actions_after_reboot': xeninfo.get_on_reboot(),
             'actions_after_suspend': xeninfo.get_on_suspend(),
             'actions_after_crash': xeninfo.get_on_crash(),
+            'consoles': xeninfo.get_consoles(),
             'VIFs': xeninfo.get_vifs(),
             'VBDs': xeninfo.get_vbds(),
             'VTPMs': xeninfo.get_vtpms(),
-            'bios_boot': xeninfo.get_bios_boot(),
+            'PV_bootloader': xeninfo.info.get('PV_bootloader'),
+            'PV_kernel': xeninfo.info.get('PV_kernel'),
+            'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
+            'PV_args': xeninfo.info.get('PV_args'),
+            'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
+            'HVM_boot': xeninfo.info.get('HVM_boot'),
             'platform_std_VGA': xeninfo.get_platform_std_vga(),
             'platform_serial': xeninfo.get_platform_serial(),
             'platform_localtime': xeninfo.get_platform_localtime(),
             'platform_clock_offset': xeninfo.get_platform_clock_offset(),
             'platform_enable_audio': xeninfo.get_platform_enable_audio(),
             'platform_keymap': xeninfo.get_platform_keymap(),
-            'builder': xeninfo.get_builder(),
-            'boot_method': xeninfo.get_boot_method(),
-            'kernel_kernel': xeninfo.get_kernel_image(),
-            'kernel_initrd': xeninfo.get_kernel_initrd(),
-            'kernel_args': xeninfo.get_kernel_args(),
-            'grub_cmdline': xeninfo.get_grub_cmdline(),
             'PCI_bus': xeninfo.get_pci_bus(),
             'tools_version': xeninfo.get_tools_version(),
             'otherConfig': xeninfo.get_other_config()
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendBootloader.py   Fri Dec 15 11:32:58 2006 -0700
@@ -21,7 +21,8 @@ from XendLogging import log
 from XendLogging import log
 from XendError import VmError
 
-def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
+def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
+               ramdisk = '', kernel_args = ''):
     """Run the boot loader executable on the given disk and return a
     config image.
     @param blexec  Binary to use as the boot loader
@@ -55,18 +56,19 @@ def bootloader(blexec, disk, quiet = 0, 
         if quiet:
             args.append("-q")
         args.append("--output=%s" % fifo)
-        if blargs is not None:
+        if blargs:
             args.extend(shlex.split(blargs))
         args.append(disk)
 
         try:
+            log.debug("Launching bootloader as %s." % str(args))
             os.execvp(args[0], args)
         except OSError, e:
             print e
             pass
         os._exit(1)
 
-    while 1:
+    while True:
         try:
             r = os.open(fifo, os.O_RDONLY)
         except OSError, e:
@@ -74,7 +76,7 @@ def bootloader(blexec, disk, quiet = 0, 
                 continue
         break
     ret = ""
-    while 1:
+    while True:
         select.select([r], [], [])
         s = os.read(r, 1024)
         ret = ret + s
@@ -94,9 +96,4 @@ def bootloader(blexec, disk, quiet = 0, 
     pin.input(ret)
     pin.input_eof()
     blcfg = pin.val
-
-    if imgcfg is None:
-        return blcfg
-    else:
-        c = sxp.merge(blcfg, imgcfg)
-        return c
+    return blcfg
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py       Fri Dec 15 11:32:58 2006 -0700
@@ -103,7 +103,7 @@ XENAPI_HVM_CFG = {
     'platform_keymap' : 'keymap',
 }    
 
-# List of XendConfig configuration keys that have no equivalent
+# List of XendConfig configuration keys that have no direct equivalent
 # in the old world.
 
 XENAPI_CFG_TYPES = {
@@ -132,19 +132,18 @@ XENAPI_CFG_TYPES = {
     'actions_after_crash': str,
     'tpm_instance': int,
     'tpm_backend': int,    
-    'bios_boot': str,
+    'PV_bootloader': str,
+    'PV_kernel': str,
+    'PV_initrd': str,
+    'PV_args': str,
+    'PV_bootloader_args': str,
+    'HVM_boot': str,
     'platform_std_vga': bool0,
     'platform_serial': str,
     'platform_localtime': bool0,
     'platform_clock_offset': bool0,
     'platform_enable_audio': bool0,
     'platform_keymap': str,
-    'boot_method': str,
-    'builder': str,
-    'kernel_kernel': str,
-    'kernel_initrd': str,
-    'kernel_args': str,
-    'grub_cmdline': str,
     'pci_bus': str,
     'tools_version': dict,
     'otherconfig': dict,
@@ -160,8 +159,6 @@ LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
     'vcpu_avail',
     'cpu_weight',
     'cpu_cap',
-    'bootloader',
-    'bootloader_args',
     'features',
     # read/write
     'on_xend_start',
@@ -188,8 +185,6 @@ LEGACY_CFG_TYPES = {
     'cpu_cap':         int,
     'cpu_weight':      int,
     'cpu_time':      float,
-    'bootloader':      str,
-    'bootloader_args': str,
     'features':        str,
     'localtime':       int,
     'name':        str,
@@ -331,16 +326,18 @@ class XendConfig(dict):
             'actions_after_crash': 'restart',
             'actions_after_suspend': '',
             'features': '',
-            'builder': 'linux',
+            'PV_bootloader': '',
+            'PV_kernel': '',
+            'PV_ramdisk': '',
+            'PV_args': '',
+            'PV_bootloader_args': '',
+            'HVM_boot': '',
             'memory_static_min': 0,
             'memory_dynamic_min': 0,
             'shadow_memory': 0,
             'memory_static_max': 0,
             'memory_dynamic_max': 0,
             'memory_actual': 0,
-            'boot_method': None,
-            'bootloader': None,
-            'bootloader_args': None,
             'devices': {},
             'image': {},
             'security': None,
@@ -353,6 +350,7 @@ class XendConfig(dict):
             'online_vcpus': 1,
             'max_vcpu_id': 0,
             'vcpu_avail': 1,
+            'console_refs': [],
             'vif_refs': [],
             'vbd_refs': [],
             'vtpm_refs': [],
@@ -382,10 +380,6 @@ class XendConfig(dict):
                 raise XendConfigError('Invalid event handling mode: ' +
                                       event)
 
-    def _builder_sanity_check(self):
-        if self['builder'] not in ('hvm', 'linux'):
-            raise XendConfigError('Invalid builder configuration')
-
     def _vcpus_sanity_check(self):
         if self.get('vcpus_number') != None:
             self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
@@ -397,7 +391,6 @@ class XendConfig(dict):
     def validate(self):
         self._memory_sanity_check()
         self._actions_sanity_check()
-        self._builder_sanity_check()
         self._vcpus_sanity_check()
         self._uuid_sanity_check()
 
@@ -597,38 +590,18 @@ class XendConfig(dict):
             except KeyError:
                 pass
 
-        # Convert Legacy "image" config to Xen API kernel_*
-        # configuration
+        self['PV_bootloader']      = cfg.get('bootloader',      '')
+        self['PV_bootloader_args'] = cfg.get('bootloader_args', '')
+        
         image_sxp = sxp.child_value(sxp_cfg, 'image', [])
         if image_sxp:
-            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
-            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
-            kernel_args = sxp.child_value(image_sxp, 'args', '')
-
-            # attempt to extract extra arguments from SXP config
-            arg_ip = sxp.child_value(image_sxp, 'ip')
-            if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
-                kernel_args += ' ip=%s' % arg_ip
-            arg_root = sxp.child_value(image_sxp, 'root')
-            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
-                kernel_args += ' root=%s' % arg_root
-            
-            self['kernel_args'] = kernel_args
+            self.update_with_image_sxp(image_sxp)
 
         # Convert Legacy HVM parameters to Xen API configuration
         self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
         self['platform_serial'] = str(cfg.get('serial', ''))
         self['platform_localtime'] = bool0(cfg.get('localtime', 0))
         self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
-
-        # Convert path to bootloader to boot_method
-        if not cfg.get('bootloader'):
-            if self.get('kernel_kernel','').endswith('hvmloader'):
-                self['boot_method'] = 'bios'
-            else:
-                self['boot_method'] = 'kernel_external'
-        else:
-            self['boot_method'] = 'grub'
 
         # make sure a sane maximum is set
         if self['memory_static_max'] <= 0:
@@ -643,6 +616,7 @@ class XendConfig(dict):
         # set device references in the configuration
         self['devices'] = cfg.get('devices', {})
         
+        self['console_refs'] = []
         self['vif_refs'] = []
         self['vbd_refs'] = []
         self['vtpm_refs'] = []
@@ -703,9 +677,6 @@ class XendConfig(dict):
         if backend:
             self['backend'] = backend
 
-        if self['image'].has_key('hvm'):
-            self['builder'] = 'hvm'
-            
         # Parse and convert other Non Xen API parameters.
         def _set_cfg_if_exists(sxp_arg):
             val = sxp.child_value(sxp_cfg, sxp_arg)
@@ -715,7 +686,6 @@ class XendConfig(dict):
                 else:
                     self[sxp_arg] = val
 
-        _set_cfg_if_exists('bootloader')
         _set_cfg_if_exists('shadow_memory')
         _set_cfg_if_exists('security')
         _set_cfg_if_exists('features')
@@ -739,8 +709,9 @@ class XendConfig(dict):
         """
 
         # populate image
-        self['image']['type'] = self['builder']
-        if self['builder'] == 'hvm':
+        hvm = self['HVM_boot'] != ''
+        self['image']['type'] = hvm and 'hvm' or 'linux'
+        if hvm:
             self['image']['hvm'] = {}
             for xapi, cfgapi in XENAPI_HVM_CFG.items():
                 self['image']['hvm'][cfgapi] = self[xapi]
@@ -778,8 +749,10 @@ class XendConfig(dict):
         @type xapi: dict
         """
         for key, val in xapi.items():
-            key = key.lower()
             type_conv = XENAPI_CFG_TYPES.get(key)
+            if type_conv is None:
+                key = key.lower()
+                type_conv = XENAPI_CFG_TYPES.get(key)
             if callable(type_conv):
                 self[key] = type_conv(val)
             else:
@@ -1098,8 +1071,8 @@ class XendConfig(dict):
     def update_with_image_sxp(self, image_sxp):
         # Convert Legacy "image" config to Xen API kernel_*
         # configuration
-        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
-        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+        self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+        self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
         kernel_args = sxp.child_value(image_sxp, 'args', '')
         
         # attempt to extract extra arguments from SXP config
@@ -1109,7 +1082,7 @@ class XendConfig(dict):
         arg_root = sxp.child_value(image_sxp, 'root')
         if arg_root and not re.search(r'root=', kernel_args):
             kernel_args += ' root=%s' % arg_root
-        self['kernel_args'] = kernel_args
+        self['PV_args'] = kernel_args
 
         # Store image SXP in python dictionary format
         image = {}
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Fri Dec 15 11:32:58 2006 -0700
@@ -591,7 +591,9 @@ class XendDomain:
         try:
             self.domains_lock.acquire()
             result = [d.get_uuid() for d in self.domains.values()]
-            result += self.managed_domains.keys()
+            for d in self.managed_domains.keys():
+                if d not in result:
+                    result.append(d)
             return result
         finally:
             self.domains_lock.release()
@@ -1337,11 +1339,7 @@ class XendDomain:
         dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
-        maxmem = int(mem) * 1024
-        try:
-            return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
-        except Exception, ex:
-            raise XendError(str(ex))
+        dominfo.setMemoryMaximum(mem)
 
     def domain_ioport_range_enable(self, domid, first, last):
         """Enable access to a range of IO ports for a domain
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Dec 15 11:32:58 2006 -0700
@@ -51,71 +51,13 @@ from xen.xend.XendAPIConstants import *
 from xen.xend.XendAPIConstants import *
 
 MIGRATE_TIMEOUT = 30.0
+BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
 
 xc = xen.lowlevel.xc.xc()
 xroot = XendRoot.instance()
 
 log = logging.getLogger("xend.XendDomainInfo")
 #log.setLevel(logging.TRACE)
-
-
-def bool0(v):
-    return v != "0" and bool(v)
-
-
-##
-# All parameters of VMs that may be configured on-the-fly, or at start-up.
-# 
-VM_CONFIG_PARAMS = [
-    ('name',        str),
-    ('on_poweroff', str),
-    ('on_reboot',   str),
-    ('on_crash',    str),
-    ]
-
-
-##
-# Configuration entries that we expect to round-trip -- be read from the
-# config file or xc, written to save-files (i.e. through sxpr), and reused as
-# config on restart or restore, all without munging.  Some configuration
-# entries are munged for backwards compatibility reasons, or because they
-# don't come out of xc in the same form as they are specified in the config
-# file, so those are handled separately.
-ROUNDTRIPPING_CONFIG_ENTRIES = [
-    ('uuid',            str),
-    ('vcpus',           int),
-    ('vcpu_avail',      int),
-    ('cpu_cap',         int),
-    ('cpu_weight',      int),
-    ('memory',          int),
-    ('shadow_memory',   int),
-    ('maxmem',          int),
-    ('bootloader',      str),
-    ('bootloader_args', str),
-    ('features',        str),
-    ('localtime',       bool0),
-    ]
-
-ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
-
-
-##
-# All entries written to the store.  This is VM_CONFIG_PARAMS, plus those
-# entries written to the store that cannot be reconfigured on-the-fly.
-#
-VM_STORE_ENTRIES = [
-    ('uuid',          str),
-    ('vcpus',         int),
-    ('vcpu_avail',    int),
-    ('memory',        int),
-    ('shadow_memory', int),
-    ('maxmem',        int),
-    ('start_time',    float),
-    ('on_xend_start', str),
-    ('on_xend_stop', str),
-    ]
-
-VM_STORE_ENTRIES += VM_CONFIG_PARAMS
 
 
 #
@@ -167,7 +109,7 @@ def recreate(info, priv):
 
     @param xeninfo: Parsed configuration
     @type  xeninfo: Dictionary
-    @param priv: TODO, unknown, something to do with memory
+    @param priv: Is a privileged domain (Dom 0)
     @type  priv: bool
 
     @rtype:  XendDomainInfo
@@ -381,7 +323,7 @@ class XendDomainInfo:
         @type    dompath: string
         @keyword augment: Augment given info with xenstored VM info
         @type    augment: bool
-        @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
+        @keyword priv: Is a privileged domain (Dom 0)
         @type    priv: bool
         @keyword resume: Is this domain being resumed?
         @type    resume: bool
@@ -497,6 +439,7 @@ class XendDomainInfo:
             xc.domain_pause(self.domid)
             self._stateSet(DOM_STATE_PAUSED)
         except Exception, ex:
+            log.exception(ex)
             raise XendError("Domain unable to be paused: %s" % str(ex))
 
     def unpause(self):
@@ -508,6 +451,7 @@ class XendDomainInfo:
             xc.domain_unpause(self.domid)
             self._stateSet(DOM_STATE_RUNNING)
         except Exception, ex:
+            log.exception(ex)
             raise XendError("Domain unable to be unpaused: %s" % str(ex))
 
     def send_sysrq(self, key):
@@ -526,7 +470,8 @@ class XendDomainInfo:
         dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
         dev_config_dict = self.info['devices'][dev_uuid][1]
         log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config_dict))
-        devid = self._createDevice(dev_type, dev_config_dict)
+        dev_config_dict['devid'] = devid = \
+             self._createDevice(dev_type, dev_config_dict)
         self._waitForDevice(dev_type, devid)
         return self.getDeviceController(dev_type).sxpr(devid)
 
@@ -563,7 +508,7 @@ class XendDomainInfo:
         for devclass in XendDevices.valid_devices():
             self.getDeviceController(devclass).waitForDevices()
 
-    def destroyDevice(self, deviceClass, devid):
+    def destroyDevice(self, deviceClass, devid, force = False):
         try:
             devid = int(devid)
         except ValueError:
@@ -578,7 +523,7 @@ class XendDomainInfo:
                     devid = entry
                     break
                 
-        return self.getDeviceController(deviceClass).destroyDevice(devid)
+        return self.getDeviceController(deviceClass).destroyDevice(devid, 
force)
 
 
 
@@ -606,8 +551,34 @@ class XendDomainInfo:
             raise XendError('Invalid memory size')
         
         self.info['memory_static_min'] = target
-        self.storeVm("memory", target)
-        self.storeDom("memory/target", target << 10)
+        if self.domid >= 0:
+            self.storeVm("memory", target)
+            self.storeDom("memory/target", target << 10)
+        else:
+            self.info['memory_dynamic_min'] = target
+            xen.xend.XendDomain.instance().managed_config_save(self)
+
+    def setMemoryMaximum(self, limit):
+        """Set the maximum memory limit of this domain
+        @param limit: In MiB.
+        """
+        log.debug("Setting memory maximum of domain %s (%d) to %d MiB.",
+                  self.info['name_label'], self.domid, limit)
+
+        if limit <= 0:
+            raise XendError('Invalid memory size')
+
+        self.info['memory_static_max'] = limit
+        if self.domid >= 0:
+            maxmem = int(limit) * 1024
+            try:
+                return xc.domain_setmaxmem(self.domid, maxmem)
+            except Exception, ex:
+                raise XendError(str(ex))
+        else:
+            self.info['memory_dynamic_max'] = limit
+            xen.xend.XendDomain.instance().managed_config_save(self)
+
 
     def getVCPUInfo(self):
         try:
@@ -647,6 +618,8 @@ class XendDomainInfo:
         if priv:
             augment_entries.remove('memory')
             augment_entries.remove('maxmem')
+            augment_entries.remove('vcpus')
+            augment_entries.remove('vcpu_avail')
 
         vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
                                          for k in augment_entries])
@@ -663,6 +636,14 @@ class XendDomainInfo:
                     self.info[xapiarg] = val
                 else:
                     self.info[arg] = val
+
+        # For dom0, we ignore any stored value for the vcpus fields, and
+        # read the current value from Xen instead.  This allows boot-time
+        # settings to take precedence over any entries in the store.
+        if priv:
+            xeninfo = dom_get(self.domid)
+            self.info['vcpus_number'] = xeninfo['online_vcpus']
+            self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
 
         # read image value
         image_sxp = self._readVm('image')
@@ -876,18 +857,23 @@ class XendDomainInfo:
 
     def setVCpuCount(self, vcpus):
         self.info['vcpu_avail'] = (1 << vcpus) - 1
-        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
-        # update dom differently depending on whether we are adjusting
-        # vcpu number up or down, otherwise _vcpuDomDetails does not
-        # disable the vcpus
-        if self.info['vcpus_number'] > vcpus:
-            # decreasing
-            self._writeDom(self._vcpuDomDetails())
+        if self.domid >= 0:
+            self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+            # update dom differently depending on whether we are adjusting
+            # vcpu number up or down, otherwise _vcpuDomDetails does not
+            # disable the vcpus
+            if self.info['vcpus_number'] > vcpus:
+                # decreasing
+                self._writeDom(self._vcpuDomDetails())
+                self.info['vcpus_number'] = vcpus
+            else:
+                # same or increasing
+                self.info['vcpus_number'] = vcpus
+                self._writeDom(self._vcpuDomDetails())
+        else:
             self.info['vcpus_number'] = vcpus
-        else:
-            # same or increasing
-            self.info['vcpus_number'] = vcpus
-            self._writeDom(self._vcpuDomDetails())
+            self.info['online_vcpus'] = vcpus
+            xen.xend.XendDomain.instance().managed_config_save(self)
 
     def getLabel(self):
         return security.get_security_info(self.info, 'label')
@@ -895,6 +881,10 @@ class XendDomainInfo:
     def getMemoryTarget(self):
         """Get this domain's target memory size, in KB."""
         return self.info['memory_static_min'] * 1024
+
+    def getMemoryMaximum(self):
+        """Get this domain's maximum memory size, in KB."""
+        return self.info['memory_static_max'] * 1024
 
     def getResume(self):
         return str(self._resume)
@@ -1017,7 +1007,8 @@ class XendDomainInfo:
             self.refresh_shutdown_lock.release()
 
         if restart_reason:
-            self._maybeRestart(restart_reason)
+            threading.Thread(target = self._maybeRestart,
+                             args = (restart_reason,)).start()
 
 
     #
@@ -1060,7 +1051,6 @@ class XendDomainInfo:
         """
         from xen.xend import XendDomain
         
-        self._configureBootloader()
         config = self.sxpr()
 
         if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
@@ -1186,6 +1176,10 @@ class XendDomainInfo:
     def _waitForDevice(self, deviceClass, devid):
         return self.getDeviceController(deviceClass).waitForDevice(devid)
 
+    def _waitForDeviceUUID(self, dev_uuid):
+        deviceClass, config = self.info['devices'].get(dev_uuid)
+        self._waitForDevice(deviceClass, config['devid'])
+
     def _reconfigureDevice(self, deviceClass, devid, devconfig):
         return self.getDeviceController(deviceClass).reconfigureDevice(
             devid, devconfig)
@@ -1289,6 +1283,8 @@ class XendDomainInfo:
 
         log.debug('XendDomainInfo.constructDomain')
 
+        self.shutdownStartTime = None
+
         image_cfg = self.info.get('image', {})
         hvm = image_cfg.has_key('hvm')
 
@@ -1333,10 +1329,7 @@ class XendDomainInfo:
                   self.domid,
                   self.info['cpu_weight'])
 
-        # if we have a boot loader but no image, then we need to set things
-        # up by running the boot loader non-interactively
-        if self.info.get('bootloader'):
-            self._configureBootloader()
+        self._configureBootloader()
 
         if not self._infoIsSet('image'):
             raise VmError('Missing image in configuration')
@@ -1363,9 +1356,9 @@ class XendDomainInfo:
             # Use architecture- and image-specific calculations to determine
             # the various headrooms necessary, given the raw configured
             # values. maxmem, memory, and shadow are all in KiB.
+            memory = self.image.getRequiredAvailableMemory(
+                self.info['memory_static_min'] * 1024)
             maxmem = self.image.getRequiredAvailableMemory(
-                self.info['memory_static_min'] * 1024)
-            memory = self.image.getRequiredAvailableMemory(
                 self.info['memory_static_max'] * 1024)
             shadow = self.image.getRequiredShadowMemory(
                 self.info['shadow_memory'] * 1024,
@@ -1397,17 +1390,14 @@ class XendDomainInfo:
 
             self._createDevices()
 
-            if self.info['bootloader']:
-                self.image.cleanupBootloading()
+            self.image.cleanupBootloading()
 
             self.info['start_time'] = time.time()
 
             self._stateSet(DOM_STATE_RUNNING)
         except RuntimeError, exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
-            if self.info['bootloader'] not in (None, 'kernel_external') \
-                   and self.image is not None:
-                self.image.cleanupBootloading()
+            self.image.cleanupBootloading()
             raise VmError(str(exn))
 
 
@@ -1538,33 +1528,78 @@ class XendDomainInfo:
 
     def _configureBootloader(self):
         """Run the bootloader if we're configured to do so."""
-        if not self.info.get('bootloader'):
-            return
-        blcfg = None
-
-        # FIXME: this assumes that we want to use the first disk device
-        for (devtype, devinfo) in self.info.all_devices_sxpr():
-            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
-                continue
-            disk = None
-            for param in devinfo:
-                if param[0] == 'uname':
-                    disk = param[1]
-                    break
-
-            if disk is None:
-                continue
-            fn = blkdev_uname_to_file(disk)
-            blcfg = bootloader(self.info['bootloader'], fn, 1,
-                               self.info['bootloader_args'],
-                               self.info['image'])
-            break
-        if blcfg is None:
-            msg = "Had a bootloader specified, but can't find disk"
-            log.error(msg)
-            raise VmError(msg)
-        
-        self.info.update_with_image_sxp(blcfg)
+
+        blexec          = self.info['PV_bootloader']
+        bootloader_args = self.info['PV_bootloader_args']
+        kernel          = self.info['PV_kernel']
+        ramdisk         = self.info['PV_ramdisk']
+        args            = self.info['PV_args']
+        boot            = self.info['HVM_boot']
+
+        if boot:
+            # HVM booting.
+            self.info['image']['type'] = 'hvm'
+            self.info['image']['devices']['boot'] = boot
+        elif not blexec and kernel:
+            # Boot from dom0.  Nothing left to do -- the kernel and ramdisk
+            # will be picked up by image.py.
+            pass
+        else:
+            # Boot using bootloader
+            if not blexec or blexec == 'pygrub':
+                blexec = '/usr/bin/pygrub'
+
+            blcfg = None
+            for (devtype, devinfo) in self.info.all_devices_sxpr():
+                if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
+                    continue
+                disk = None
+                for param in devinfo:
+                    if param[0] == 'uname':
+                        disk = param[1]
+                        break
+
+                if disk is None:
+                    continue
+                fn = blkdev_uname_to_file(disk)
+                mounted = devtype == 'tap' and not os.stat(fn).st_rdev
+                if mounted:
+                    # This is a file, not a device.  pygrub can cope with a
+                    # file if it's raw, but if it's QCOW or other such formats
+                    # used through blktap, then we need to mount it first.
+
+                    log.info("Mounting %s on %s." %
+                             (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+                    vbd = {
+                        'mode': 'RO',
+                        'device': BOOTLOADER_LOOPBACK_DEVICE,
+                        }
+
+                    from xen.xend import XendDomain
+                    dom0 = XendDomain.instance().privilegedDomain()
+                    dom0._waitForDeviceUUID(dom0.create_vbd_with_vdi(vbd, fn))
+                    fn = BOOTLOADER_LOOPBACK_DEVICE
+
+                try:
+                    blcfg = bootloader(blexec, fn, True,
+                                       bootloader_args, kernel, ramdisk, args)
+                finally:
+                    if mounted:
+                        log.info("Unmounting %s from %s." %
+                                 (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+                        dom0.destroyDevice('tap', '/dev/xvdp')
+
+                break
+
+            if blcfg is None:
+                msg = "Had a bootloader specified, but can't find disk"
+                log.error(msg)
+                raise VmError(msg)
+        
+            self.info.update_with_image_sxp(blcfg)
+
 
     # 
     # VM Functions
@@ -1727,7 +1762,7 @@ class XendDomainInfo:
             raise VmError("VM name '%s' already exists%s" %
                           (name,
                            dom.domid is not None and
-                           ("as domain %s" % str(dom.domid)) or ""))
+                           (" as domain %s" % str(dom.domid)) or ""))
         
 
     def update(self, info = None, refresh = True):
@@ -1809,8 +1844,6 @@ class XendDomainInfo:
         return '' # TODO
     def get_power_state(self):
         return XEN_API_VM_POWER_STATE[self.state]
-    def get_bios_boot(self):
-        return '' # TODO
     def get_platform_std_vga(self):
         return self.info.get('platform_std_vga', False)    
     def get_platform_keymap(self):
@@ -1825,18 +1858,6 @@ class XendDomainInfo:
         return self.info.get('platform_enable_audio', False)
     def get_platform_keymap(self):
         return self.info.get('platform_keymap', '')
-    def get_builder(self):
-        return self.info.get('builder', 0)
-    def get_boot_method(self):
-        return self.info.get('boot_method', XEN_API_BOOT_TYPE[2])
-    def get_kernel_image(self):
-        return self.info.get('kernel_kernel', '')
-    def get_kernel_initrd(self):
-        return self.info.get('kernel_initrd', '')
-    def get_kernel_args(self):
-        return self.info.get('kernel_args', '')
-    def get_grub_cmdline(self):
-        return '' # TODO
     def get_pci_bus(self):
         return '' # TODO
     def get_tools_version(self):
@@ -1972,6 +1993,9 @@ class XendDomainInfo:
                 
         return vcpu_util
 
+    def get_consoles(self):
+        return self.info.get('console_refs', [])
+
     def get_vifs(self):
         return self.info.get('vif_refs', [])
 
@@ -1992,10 +2016,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('vbd').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('vbd').createDevice(config)
 
         return dev_uuid
 
@@ -2013,10 +2036,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
 
-        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('tap').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('tap').createDevice(config)
 
         return dev_uuid
 
@@ -2031,10 +2053,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state in (DOM_STATE_HALTED,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('vif').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('vif').createDevice(config)
 
         return dev_uuid
 
diff -r 1e042dde1a5f -r e17d7438e09e 
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py    Fri Dec 15 10:59:33 
2006 -0700
+++ b/tools/python/xen/xend/XendStorageRepository.py    Fri Dec 15 11:32:58 
2006 -0700
@@ -20,6 +20,7 @@
 #
 
 import commands
+import logging
 import os
 import stat
 import threading
@@ -33,9 +34,12 @@ XEND_STORAGE_DIR = "/var/lib/xend/storag
 XEND_STORAGE_DIR = "/var/lib/xend/storage/"
 XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
 XEND_STORAGE_VDICFG_FILENAME = "%s.vdi.xml"
-QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s"
-
-MB = 1024 *1024
+QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create -p %d %s"
+
+MB = 1024 * 1024
+
+log = logging.getLogger("xend.XendStorageRepository")
+
 
 class DeviceInvalidError(Exception):
     pass
@@ -89,8 +93,7 @@ class XendStorageRepository:
                 open(uuid_file, 'w').write(new_uuid + '\n')
                 return new_uuid
         except IOError:
-            # TODO: log warning
-            pass
+            log.exception("Failed to determine SR UUID")
 
         return uuid.createString()
 
@@ -229,8 +232,7 @@ class XendStorageRepository:
                     if cfg_path and os.path.exists(cfg_path):
                         os.unlink(cfg_path)
                 except OSError:
-                    # TODO: log warning
-                    pass
+                    log.exception("Failed to destroy image")
                 del self.images[image_uuid]
                 return True
         finally:
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/image.py    Fri Dec 15 11:32:58 2006 -0700
@@ -68,6 +68,7 @@ class ImageHandler:
     def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
         self.vm = vm
 
+        self.bootloader = None
         self.kernel = None
         self.ramdisk = None
         self.cmdline = None
@@ -76,9 +77,10 @@ class ImageHandler:
 
     def configure(self, vmConfig, imageConfig, _):
         """Config actions common to all unix-like domains."""
-        self.kernel = vmConfig['kernel_kernel']
-        self.cmdline = vmConfig['kernel_args']
-        self.ramdisk = vmConfig['kernel_initrd']
+        self.bootloader = vmConfig['PV_bootloader']
+        self.kernel = vmConfig['PV_kernel']
+        self.cmdline = vmConfig['PV_args']
+        self.ramdisk = vmConfig['PV_ramdisk']
         self.vm.storeVm(("image/ostype", self.ostype),
                         ("image/kernel", self.kernel),
                         ("image/cmdline", self.cmdline),
@@ -86,8 +88,9 @@ class ImageHandler:
 
 
     def cleanupBootloading(self):
-        self.unlink(self.kernel)
-        self.unlink(self.ramdisk)
+        if self.bootloader:
+            self.unlink(self.kernel)
+            self.unlink(self.ramdisk)
 
 
     def unlink(self, f):
@@ -145,6 +148,14 @@ class ImageHandler:
         add headroom where necessary."""
         return self.getRequiredAvailableMemory(self.vm.getMemoryTarget())
 
+    def getRequiredMaximumReservation(self):
+        """@param mem_kb The maximum possible memory, in KiB.
+        @return The corresponding required amount of memory to be free, also
+        in KiB. This is normally the same as getRequiredAvailableMemory, but
+        architecture- or image-specific code may override this to
+        add headroom where necessary."""
+        return self.getRequiredAvailableMemory(self.vm.getMemoryMaximum())
+
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         """@param shadow_mem_kb The configured shadow memory, in KiB.
         @param maxmem_kb The configured maxmem, in KiB.
@@ -234,6 +245,60 @@ class PPC_LinuxImageHandler(LinuxImageHa
                               ramdisk        = self.ramdisk,
                               features       = self.vm.getFeatures(),
                               arch_args      = devtree.to_bin())
+
+    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+        """@param shadow_mem_kb The configured shadow memory, in KiB.
+        @param maxmem_kb The configured maxmem, in KiB.
+        @return The corresponding required amount of shadow memory, also in
+        KiB.
+        PowerPC currently uses "shadow memory" to refer to the hash table."""
+        return max(maxmem_kb / 64, shadow_mem_kb)
+
+
+class PPC_ProseImageHandler(LinuxImageHandler):
+
+    ostype = "prose"
+
+    def configure(self, imageConfig, deviceConfig):
+        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
+        self.imageConfig = imageConfig
+
+    def buildDomain(self):
+        store_evtchn = self.vm.getStorePort()
+        console_evtchn = self.vm.getConsolePort()
+
+        mem_mb = self.getRequiredInitialReservation() / 1024
+
+        log.debug("dom            = %d", self.vm.getDomid())
+        log.debug("memsize        = %d", mem_mb)
+        log.debug("image          = %s", self.kernel)
+        log.debug("store_evtchn   = %d", store_evtchn)
+        log.debug("console_evtchn = %d", console_evtchn)
+        log.debug("cmdline        = %s", self.cmdline)
+        log.debug("ramdisk        = %s", self.ramdisk)
+        log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("features       = %s", self.vm.getFeatures())
+
+        devtree = FlatDeviceTree.build(self)
+
+        return xc.arch_prose_build(dom            = self.vm.getDomid(),
+                                   memsize        = mem_mb,
+                                   image          = self.kernel,
+                                   store_evtchn   = store_evtchn,
+                                   console_evtchn = console_evtchn,
+                                   cmdline        = self.cmdline,
+                                   ramdisk        = self.ramdisk,
+                                   features       = self.vm.getFeatures(),
+                                   arch_args      = devtree.to_bin())
+
+    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+        """@param shadow_mem_kb The configured shadow memory, in KiB.
+        @param maxmem_kb The configured maxmem, in KiB.
+        @return The corresponding required amount of shadow memory, also in
+        KiB.
+        PowerPC currently uses "shadow memory" to refer to the hash table."""
+        return max(maxmem_kb / 64, shadow_mem_kb)
+
 
 class HVMImageHandler(ImageHandler):
 
@@ -539,6 +604,9 @@ class X86_HVM_ImageHandler(HVMImageHandl
     def getRequiredInitialReservation(self):
         return self.vm.getMemoryTarget()
 
+    def getRequiredMaximumReservation(self):
+        return self.vm.getMemoryMaximum()
+
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         # 256 pages (1MB) per vcpu,
         # plus 1 page per MiB of RAM for the P2M map,
@@ -553,13 +621,14 @@ class X86_Linux_ImageHandler(LinuxImageH
     def buildDomain(self):
         # set physical mapping limit
         # add an 8MB slack to balance backend allocations.
-        mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
+        mem_kb = self.getRequiredMaximumReservation() + (8 * 1024)
         xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
         return LinuxImageHandler.buildDomain(self)
 
 _handlers = {
     "powerpc": {
         "linux": PPC_LinuxImageHandler,
+        "prose": PPC_ProseImageHandler,
     },
     "ia64": {
         "linux": LinuxImageHandler,
diff -r 1e042dde1a5f -r e17d7438e09e 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Fri Dec 15 10:59:33 
2006 -0700
+++ b/tools/python/xen/xend/server/DevController.py     Fri Dec 15 11:32:58 
2006 -0700
@@ -19,12 +19,14 @@ from threading import Event
 from threading import Event
 import types
 
-from xen.xend import sxp
+from xen.xend import sxp, XendRoot
 from xen.xend.XendError import VmError
 from xen.xend.XendLogging import log
 
 from xen.xend.xenstore.xstransact import xstransact, complete
 from xen.xend.xenstore.xswatch import xswatch
+
+import os
 
 DEVICE_CREATE_TIMEOUT = 100
 HOTPLUG_STATUS_NODE = "hotplug-status"
@@ -47,6 +49,8 @@ xenbusState = {
     'Closing'      : 5,
     'Closed'       : 6,
     }
+
+xroot = XendRoot.instance()
 
 xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys())))
 
@@ -151,13 +155,13 @@ class DevController:
         status = self.waitForBackend(devid)
 
         if status == Timeout:
-            self.destroyDevice(devid)
+            self.destroyDevice(devid, False)
             raise VmError("Device %s (%s) could not be connected. "
                           "Hotplug scripts not working." %
                           (devid, self.deviceClass))
 
         elif status == Error:
-            self.destroyDevice(devid)
+            self.destroyDevice(devid, False)
             raise VmError("Device %s (%s) could not be connected. "
                           "Backend device not found." %
                           (devid, self.deviceClass))
@@ -176,7 +180,7 @@ class DevController:
             if not err:
                 err = "Busy."
                 
-            self.destroyDevice(devid)
+            self.destroyDevice(devid, False)
             raise VmError("Device %s (%s) could not be connected.\n%s" %
                           (devid, self.deviceClass, err))
 
@@ -191,7 +195,7 @@ class DevController:
         raise VmError('%s devices may not be reconfigured' % self.deviceClass)
 
 
-    def destroyDevice(self, devid):
+    def destroyDevice(self, devid, force):
         """Destroy the specified device.
 
         @param devid The device ID, or something device-specific from which
@@ -211,6 +215,13 @@ class DevController:
         # drivers, so this ordering avoids a race).
         self.writeBackend(devid, 'online', "0")
         self.writeBackend(devid, 'state', str(xenbusState['Closing']))
+
+        if force:
+            frontpath = self.frontendPath(devid)
+            backpath = xstransact.Read(frontpath, "backend")
+            if backpath:
+                xstransact.Remove(backpath)
+            xstransact.Remove(frontpath)
 
 
     def configurations(self):
@@ -313,6 +324,16 @@ class DevController:
                       Make sure that the migration has finished and only
                       then return from the call.
         """
+        tool = xroot.get_external_migration_tool()
+        if tool:
+            log.info("Calling external migration tool for step %d" % step)
+            fd = os.popen("%s -type %s -step %d -host %s -domname %s" %
+                          (tool, self.deviceClass, step, dst, domName))
+            for line in fd:
+                log.info(line.rstrip())
+            rc = fd.close()
+            if rc:
+                raise VmError('Migration tool returned %d' % (rc >> 8))
         return 0
 
 
@@ -320,6 +341,16 @@ class DevController:
         """ Recover from device migration. The given step was the
             last one that was successfully executed.
         """
+        tool = xroot.get_external_migration_tool()
+        if tool:
+            log.info("Calling external migration tool")
+            fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" 
%
+                          (tool, self.deviceClass, step, dst, domName))
+            for line in fd:
+                log.info(line.rstrip())
+            rc = fd.close()
+            if rc:
+                raise VmError('Migration tool returned %d' % (rc >> 8))
         return 0
 
 
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/server/SrvDomain.py Fri Dec 15 11:32:58 2006 -0700
@@ -160,12 +160,9 @@ class SrvDomain(SrvDir):
         return val
 
     def op_maxmem_set(self, _, req):
-        fn = FormFn(self.xd.domain_maxmem_set,
-                    [['dom',    'int'],
-                     ['memory', 'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
-
+        return self.call(self.dom.setMemoryMaximum,
+                         [['memory', 'int']],
+                         req)
     
     def call(self, fn, args, req):
         return FormFn(fn, args)(req.args)
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/server/blkif.py     Fri Dec 15 11:32:58 2006 -0700
@@ -133,7 +133,7 @@ class BlkifController(DevController):
 
         return config
 
-    def destroyDevice(self, devid):
+    def destroyDevice(self, devid, force):
         """@see DevController.destroyDevice"""
 
         # If we are given a device name, then look up the device ID from it,
@@ -142,13 +142,13 @@ class BlkifController(DevController):
         # superclass's method.
 
         try:
-            DevController.destroyDevice(self, int(devid))
+            DevController.destroyDevice(self, int(devid), force)
         except ValueError:
             devid_end = type(devid) is str and devid.split('/')[-1] or None
 
             for i in self.deviceIDs():
                 d = self.readBackend(i, 'dev')
                 if d == devid or (devid_end and d == devid_end):
-                    DevController.destroyDevice(self, i)
+                    DevController.destroyDevice(self, i, force)
                     return
             raise VmError("Device %s not connected" % devid)
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py     Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xm/XenAPI.py     Fri Dec 15 11:32:58 2006 -0700
@@ -82,7 +82,7 @@ class Session(xen.util.xmlrpclib2.Server
         self._session = None
 
 
-    def _xen_request(self, methodname, params):
+    def xenapi_request(self, methodname, params):
         full_params = (self._session,) + params
         return _parse_result(getattr(self, methodname)(*full_params))
 
@@ -94,7 +94,7 @@ class Session(xen.util.xmlrpclib2.Server
 
     def __getattr__(self, name):
         if name == 'xenapi':
-            return _Dispatcher(self._xen_request, None)
+            return _Dispatcher(self.xenapi_request, None)
         elif name.startswith('login'):
             return lambda u, p: self._login(name, u, p)
         else:
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xm/main.py       Fri Dec 15 11:32:58 2006 -0700
@@ -22,7 +22,10 @@
 """Grand unified management application for Xen.
 """
 import atexit
+import cmd
 import os
+import pprint
+import shlex
 import sys
 import re
 import getopt
@@ -77,6 +80,8 @@ USAGE_FOOTER = '<Domain> can either be t
 
 SUBCOMMAND_HELP = {
     # common commands
+
+    'shell'       : ('', 'Launch an interactive shell.'),
     
     'console'     : ('[-q|--quiet] <Domain>',
                      'Attach to <Domain>\'s console.'),
@@ -142,14 +147,15 @@ SUBCOMMAND_HELP = {
                         'Create a new virtual block device.'),
     'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
                         'Change block device configuration'),
-    'block-detach'  :  ('<Domain> <DevId>',
+    'block-detach'  :  ('<Domain> <DevId> [-f|--force]',
                         'Destroy a domain\'s virtual block device.'),
     'block-list'    :  ('<Domain> [--long]',
                         'List virtual block devices for a domain.'),
-    'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
-                        '[--mac=<mac>]',
+    'network-attach':  ('<Domain> [type=<type>] [mac=<mac>] [bridge=<bridge>] '
+                        '[ip=<ip>] [script=<script>] [backend=<BackDomain>] '
+                        '[vifname=<name>]',
                         'Create a new virtual network device.'),
-    'network-detach':  ('<Domain> <DevId>',
+    'network-detach':  ('<Domain> <DevId> [-f|--force]',
                         'Destroy a domain\'s virtual network device.'),
     'network-list'  :  ('<Domain> [--long]',
                         'List virtual network interfaces for a domain.'),
@@ -245,6 +251,7 @@ common_commands = [
     "restore",
     "resume",
     "save",
+    "shell",
     "shutdown",
     "start",
     "suspend",
@@ -328,7 +335,7 @@ acm_commands = [
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
-                device_commands + vnet_commands + acm_commands)
+                device_commands + vnet_commands + acm_commands + ['shell'])
 
 
 ##
@@ -362,6 +369,7 @@ def parseAuthentication():
             server.getAttribute('password'))
 
 serverType, serverURI = parseServer()
+server = None
 
 
 ####################################################################
@@ -455,12 +463,16 @@ def longHelp():
     print
     print USAGE_FOOTER        
 
+def _usage(cmd):
+    """ Print help usage information """
+    if cmd:
+        cmdHelp(cmd)
+    else:
+        shortHelp()
+
 def usage(cmd = None):
     """ Print help usage information and exits """
-    if cmd:
-        cmdHelp(cmd)
-    else:
-        shortHelp()
+    _usage(cmd)
     sys.exit(1)
 
 
@@ -523,6 +535,49 @@ def get_single_vm(dom):
         dominfo = server.xend.domain(dom, False)
         return dominfo['uuid']
 
+##
+#
+# Xen-API Shell
+#
+##
+
+class Shell(cmd.Cmd):
+    def __init__(self):
+        cmd.Cmd.__init__(self)
+        self.prompt = "xm> "
+
+    def default(self, line):
+        words = shlex.split(line)
+        if len(words) > 0 and words[0] == 'xm':
+            words = words[1:]
+        if len(words) > 0:
+            cmd = xm_lookup_cmd(words[0])
+            if cmd:
+                _run_cmd(cmd, words[0], words[1:])
+            elif serverType == SERVER_XEN_API:
+                ok, res = _run_cmd(lambda x: server.xenapi_request(words[0],
+                                                                   tuple(x)),
+                                   words[0], words[1:])
+                if ok and res != '':
+                    pprint.pprint(res)
+            else:
+                print '*** Unknown command: %s' % words[0]
+        return False
+
+    def emptyline(self):
+        pass
+
+    def do_EOF(self, line):
+        print
+        sys.exit(0)
+
+    def do_help(self, line):
+        _usage(line)
+
+
+def xm_shell(args):
+    Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
+
 
 #########################################################################
 #
@@ -554,7 +609,7 @@ def xm_restore(args):
         (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('restore')
 
     paused = False
     for (k, v) in options:
@@ -564,7 +619,6 @@ def xm_restore(args):
     if len(params) != 1:
         err("Wrong number of parameters")
         usage('restore')
-        sys.exit(1)
 
     savefile = os.path.abspath(params[0])
 
@@ -594,7 +648,6 @@ def xm_list(args):
     except getopt.GetoptError, opterr:
         err(opterr)
         usage('list')
-        sys.exit(1)
     
     for (k, v) in options:
         if k in ['-l', '--long']:
@@ -709,7 +762,7 @@ def xm_vcpu_list(args):
         dominfo = map(server.xend.domain.getVCPUInfo, doms)
 
     print '%-32s %3s %5s %5s %5s %9s %s' % \
-          ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
+          ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
 
     format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
              ' %(cpu_time)8.1f %(cpumap)s'
@@ -815,7 +868,7 @@ def xm_start(args):
         (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('start')
 
     paused = False
     for (k, v) in options:
@@ -825,7 +878,6 @@ def xm_start(args):
     if len(params) != 1:
         err("Wrong number of parameters")
         usage('start')
-        sys.exit(1)
 
     dom = params[0]
     if serverType == SERVER_XEN_API:
@@ -856,7 +908,7 @@ def xm_resume(args):
         (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('resume')
 
     paused = False
     for (k, v) in options:
@@ -866,7 +918,6 @@ def xm_resume(args):
     if len(params) != 1:
         err("Wrong number of parameters")
         usage('resume')
-        sys.exit(1)
 
     dom = params[0]
     if serverType == SERVER_XEN_API:
@@ -1061,7 +1112,7 @@ def xm_sched_sedf(args):
             ['period=', 'slice=', 'latency=', 'extratime=', 'weight='])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('sched-sedf')
     
     # convert to nanoseconds if needed 
     for (k, v) in options:
@@ -1122,7 +1173,6 @@ def xm_sched_credit(args):
     except getopt.GetoptError, opterr:
         err(opterr)
         usage('sched-credit')
-        sys.exit(1)
 
     domain = None
     weight = None
@@ -1140,7 +1190,6 @@ def xm_sched_credit(args):
         # place holder for system-wide scheduler parameters
         err("No domain given.")
         usage('sched-credit')
-        sys.exit(1)
 
     if weight is None and cap is None:
         print server.xend.domain.sched_credit_get(domain)
@@ -1169,7 +1218,7 @@ def xm_console(args):
         (options, params) = getopt.gnu_getopt(args, 'q', ['quiet'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('console')
 
     for (k, v) in options:
         if k in ['-q', '--quiet']:
@@ -1180,7 +1229,6 @@ def xm_console(args):
     if len(params) != 1:
         err('No domain given')
         usage('console')
-        sys.exit(1)
 
     dom = params[0]
 
@@ -1208,7 +1256,7 @@ def xm_uptime(args):
         (options, params) = getopt.gnu_getopt(args, 's', ['short'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('uptime')
 
     for (k, v) in options:
         if k in ['-s', '--short']:
@@ -1273,7 +1321,7 @@ def xm_dmesg(args):
         (options, params) = getopt.gnu_getopt(args, 'c', ['clear'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('dmesg')
     
     use_clear = 0
     for (k, v) in options:
@@ -1283,7 +1331,6 @@ def xm_dmesg(args):
     if len(params) :
         err("No parameter required")
         usage('dmesg')
-        sys.exit(1)
 
     if not use_clear:
         print server.xend.node.dmesg.info()
@@ -1493,16 +1540,24 @@ def xm_network_attach(args):
 
 
 def detach(args, command, deviceClass):
-    arg_check(args, command, 2)
+    arg_check(args, command, 2, 3)
 
     dom = args[0]
     dev = args[1]
-
-    server.xend.domain.destroyDevice(dom, deviceClass, dev)
+    try:
+        force = args[2]
+        if (force != "--force") and (force != "-f"):
+            print "Ignoring option %s"%(force)
+            force = None
+    except IndexError:
+        force = None
+
+    server.xend.domain.destroyDevice(dom, deviceClass, dev, force)
 
 
 def xm_block_detach(args):
     detach(args, 'block-detach', 'vbd')
+    detach(args, 'block-detach', 'tap')
 
 
 def xm_network_detach(args):
@@ -1514,7 +1569,7 @@ def xm_vnet_list(args):
         (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
     except getopt.GetoptError, opterr:
         err(opterr)
-        sys.exit(1)
+        usage('vnet-list')
     
     use_long = 0
     for (k, v) in options:
@@ -1552,6 +1607,7 @@ def xm_vnet_delete(args):
     server.xend_vnet_delete(vnet)
 
 commands = {
+    "shell": xm_shell,
     # console commands
     "console": xm_console,
     # xenstat commands
@@ -1655,17 +1711,13 @@ def xm_lookup_cmd(cmd):
             # only execute if there is only 1 match
             if len(same_prefix_cmds) == 1:
                 return same_prefix_cmds[0]
-            
-        err('Sub Command %s not found!' % cmd)
-        usage()
+        return None
 
 def deprecated(old,new):
     print >>sys.stderr, (
         "Command %s is deprecated.  Please use xm %s instead." % (old, new))
 
 def main(argv=sys.argv):
-    global server
-
     if len(argv) < 2:
         usage()
 
@@ -1674,16 +1726,26 @@ def main(argv=sys.argv):
         if help in argv[1:]:
             if help == argv[1]:
                 longHelp()
+                sys.exit(0)
             else:
                 usage(argv[1])
-            sys.exit(0)
-
-    cmd = xm_lookup_cmd(argv[1])
-
-    # strip off prog name and subcmd
-    args = argv[2:]
+
+    cmd_name = argv[1]
+    cmd = xm_lookup_cmd(cmd_name)
     if cmd:
-        try:
+        # strip off prog name and subcmd
+        args = argv[2:]
+        _, rc = _run_cmd(cmd, cmd_name, args)
+        sys.exit(rc)
+    else:
+        err('Subcommand %s not found!' % cmd_name)
+        usage()
+
+def _run_cmd(cmd, cmd_name, args):
+    global server
+
+    try:
+        if server is None:
             if serverType == SERVER_XEN_API:
                 server = XenAPI.Session(serverURI)
                 username, password = parseAuthentication()
@@ -1697,66 +1759,55 @@ def main(argv=sys.argv):
             else:
                 server = ServerProxy(serverURI)
 
-            rc = cmd(args)
-            if rc:
-                usage()
-        except socket.error, ex:
-            if os.geteuid() != 0:
-                err("Most commands need root access. Please try again as 
root.")
-            else:
-                err("Unable to connect to xend: %s. Is xend running?" % ex[1])
-            sys.exit(1)
-        except KeyboardInterrupt:
-            print "Interrupted."
-            sys.exit(1)
-        except IOError, ex:
-            if os.geteuid() != 0:
-                err("Most commands need root access.  Please try again as 
root.")
-            else:
-                err("Unable to connect to xend: %s." % ex[1])
-            sys.exit(1)
-        except SystemExit:
-            sys.exit(1)
-        except XenAPI.Failure, exn:
-            err(str(exn))
-            sys.exit(1)
-        except xmlrpclib.Fault, ex:
-            if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
-                err("Domain '%s' does not exist." % ex.faultString)
-            else:
-                err(ex.faultString)
-            usage(argv[1])
-            sys.exit(1)
-        except xmlrpclib.ProtocolError, ex:
-            if ex.errcode == -1:
-                print  >>sys.stderr, (
-                    "Xend has probably crashed!  Invalid or missing HTTP "
-                    "status code.")
-            else:
-                print  >>sys.stderr, (
-                    "Xend has probably crashed!  ProtocolError(%d, %s)." %
-                    (ex.errcode, ex.errmsg))
-            sys.exit(1)
-        except (ValueError, OverflowError):
-            err("Invalid argument.")
-            usage(argv[1])
-            sys.exit(1)
-        except OptionError, e:
-            err(str(e))
-            usage(argv[1])
-            print e.usage()
-            sys.exit(1)
-        except security.ACMError, e:
-            err(str(e))
-            sys.exit(1)
-        except:
-            print "Unexpected error:", sys.exc_info()[0]
-            print
-            print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-            raise
-                
-    else:
-        usage()
+        return True, cmd(args)
+    except socket.error, ex:
+        if os.geteuid() != 0:
+            err("Most commands need root access. Please try again as root.")
+        else:
+            err("Unable to connect to xend: %s. Is xend running?" % ex[1])
+    except KeyboardInterrupt:
+        print "Interrupted."
+        return True, ''
+    except IOError, ex:
+        if os.geteuid() != 0:
+            err("Most commands need root access.  Please try again as root.")
+        else:
+            err("Unable to connect to xend: %s." % ex[1])
+    except SystemExit, code:
+        return code == 0, code
+    except XenAPI.Failure, exn:
+        err(str(exn))
+    except xmlrpclib.Fault, ex:
+        if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
+            err("Domain '%s' does not exist." % ex.faultString)
+        else:
+            err(ex.faultString)
+        _usage(cmd_name)
+    except xmlrpclib.ProtocolError, ex:
+        if ex.errcode == -1:
+            print  >>sys.stderr, (
+                "Xend has probably crashed!  Invalid or missing HTTP "
+                "status code.")
+        else:
+            print  >>sys.stderr, (
+                "Xend has probably crashed!  ProtocolError(%d, %s)." %
+                (ex.errcode, ex.errmsg))
+    except (ValueError, OverflowError):
+        err("Invalid argument.")
+        _usage(cmd_name)
+    except OptionError, e:
+        err(str(e))
+        _usage(cmd_name)
+        print e.usage()
+    except security.ACMError, e:
+        err(str(e))
+    except:
+        print "Unexpected error:", sys.exc_info()[0]
+        print
+        print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
+        raise
+
+    return False, 1
 
 if __name__ == "__main__":
     main()
diff -r 1e042dde1a5f -r e17d7438e09e tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/xenstore/xenstored_domain.c Fri Dec 15 11:32:58 2006 -0700
@@ -459,6 +459,8 @@ static int dom0_init(void)
                return -1;
 
        dom0 = new_domain(NULL, 0, port); 
+       if (dom0 == NULL)
+               return -1;
 
        dom0->interface = xenbus_map();
        if (dom0->interface == NULL)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/ia64/xen/xensetup.c      Fri Dec 15 11:32:58 2006 -0700
@@ -51,7 +51,7 @@ extern void xen_patch_kernel(void);
 extern void xen_patch_kernel(void);
 
 /* opt_nosmp: If true, secondary processors are ignored. */
-static int opt_nosmp = 0;
+static int opt_nosmp;
 boolean_param("nosmp", opt_nosmp);
 
 /* maxcpus: maximum number of CPUs to activate. */
@@ -65,7 +65,7 @@ integer_param("xencons", opt_xencons);
 integer_param("xencons", opt_xencons);
 
 /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
-static int opt_xencons_poll = 0;
+static int opt_xencons_poll;
 boolean_param("xencons_poll", opt_xencons_poll);
 
 /*
@@ -163,7 +163,7 @@ struct ns16550_defaults ns16550_com2 = {
 };
 
 /* efi_print: print efi table at boot */
-static int opt_efi_print = 0;
+static int opt_efi_print;
 boolean_param("efi_print", opt_efi_print);
 
 /* print EFI memory map: */
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/Makefile Fri Dec 15 11:32:58 2006 -0700
@@ -9,10 +9,10 @@ obj-y += backtrace.o
 obj-y += backtrace.o
 obj-y += bitops.o
 obj-y += boot_of.o
+obj-y += cmdline.o
 obj-y += dart.o
 obj-y += dart_u3.o
 obj-y += dart_u4.o
-obj-y += delay.o
 obj-y += domctl.o
 obj-y += domain_build.o
 obj-y += domain.o
@@ -22,11 +22,12 @@ obj-y += hcalls.o
 obj-y += hcalls.o
 obj-y += iommu.o
 obj-y += irq.o
-obj-y += mambo.o
+obj-y += systemsim.o
 obj-y += memory.o
 obj-y += mm.o
 obj-y += mpic.o
 obj-y += mpic_init.o
+obj-y += numa.o
 obj-y += of-devtree.o
 obj-y += of-devwalk.o
 obj-y += ofd_fixup.o
@@ -36,6 +37,7 @@ obj-y += setup.o
 obj-y += setup.o
 obj-y += shadow.o
 obj-y += smp.o
+obj-y += smpboot.o
 obj-y += smp-tbsync.o
 obj-y += sysctl.o
 obj-y += time.o
@@ -57,11 +59,6 @@ PPC_C_WARNINGS += -Wshadow
 PPC_C_WARNINGS += -Wshadow
 CFLAGS += $(PPC_C_WARNINGS)
 
-LINK=0x400000
-boot32_link_base = $(LINK)
-xen_link_offset  = 100
-xen_link_base    = $(patsubst %000,%$(xen_link_offset),$(LINK))
-
 #
 # The following flags are fed to gcc in order to link several
 # objects into a single ELF segment and to not link in any additional
@@ -72,34 +69,39 @@ firmware: of_handler/built_in.o $(TARGET
 firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
        $(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
 
-firmware_image: firmware
+firmware_image.bin: firmware
        $(CROSS_COMPILE)objcopy --output-target=binary $< $@
-
-firmware_image.o: firmware_image
-       $(CROSS_COMPILE)objcopy --input-target=binary \
-               --output-target=elf64-powerpc \
-               --binary-architecture=powerpc \
-               --redefine-sym _binary_$<_start=$(@:%.o=%)_start \
-               --redefine-sym _binary_$<_end=$(@:%.o=%)_end \
-               --redefine-sym _binary_$<_size=$(@:%.o=%)_size  $< $@
 
 #
 # Hacks for included C files
 #
 irq.o: ../x86/irq.c
 physdev.o: ../x86/physdev.c
+numa.o: ../x86/numa.c
 
 HDRS += $(wildcard *.h)
 
+ifneq ($(CMDLINE),)
 # The first token in the arguments will be silently dropped.
-IMAGENAME = xen
-CMDLINE = ""
-boot_of.o: CFLAGS += -DCMDLINE="\"$(IMAGENAME) $(CMDLINE)\""
+FULL_CMDLINE := xen $(CMDLINE)
+endif
 
-start.o: boot/start.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
+ifeq ($(wildcard cmdline.dep),)
+cmdline.dep:
+       echo $(FULL_CMDLINE) > cmdline.dep
+else
+ifneq ($(FULL_CMDLINE),$(shell cat cmdline.dep))
+cmdline.dep::
+       echo $(FULL_CMDLINE) > cmdline.dep
+else
+cmdline.dep:
+endif
+endif
 
-TARGET_OPTS = $(OMAGIC) -Wl,-Ttext,$(xen_link_base),-T,xen.lds
+cmdline.o: cmdline.dep
+cmdline.o: CFLAGS += -DCMDLINE="\"$(FULL_CMDLINE)\""
+
+TARGET_OPTS = $(OMAGIC) -Wl,-T,xen.lds
 TARGET_OPTS += start.o $(ALL_OBJS)
 
 .xen-syms: start.o $(ALL_OBJS) xen.lds
@@ -122,22 +124,10 @@ xen-syms.o: xen-syms.S
 $(TARGET)-syms: start.o $(ALL_OBJS) xen-syms.o xen.lds
        $(CC) $(CFLAGS) $(TARGET_OPTS) xen-syms.o -o $@
 
-$(TARGET).bin: $(TARGET)-syms
-       $(CROSS_COMPILE)objcopy --output-target=binary $< $@
-
-$(TARGET).bin.o: $(TARGET).bin
-       $(CROSS_COMPILE)objcopy --input-target=binary \
-               --output-target=elf32-powerpc \
-               --binary-architecture=powerpc  $< $@
-
-boot32.o: boot/boot32.S
-       $(CC) -m32 -Wa,-a32,-mppc64bridge \
-               -D__ASSEMBLY__ -D__BRIDGE64__ $(CFLAGS) -c $< -o $@
-
-$(TARGET): boot32.o $(TARGET).bin.o
-       $(CC) -m32 -N -Wl,-melf32ppclinux -static -nostdlib \
-               -Wl,-Ttext,$(boot32_link_base)  -Wl,-Tdata,$(xen_link_base) \
-               $(CFLAGS) $^ -o $@
+# our firmware only loads 32-bit ELF files
+OCPYFLAGS := --input-target=elf64-powerpc --output-target=elf32-powerpc
+$(TARGET): $(TARGET)-syms
+       $(CROSS_COMPILE)objcopy $(OCPYFLAGS) $^ $@
 
 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
        $(CC) $(CFLAGS) -S -o $@ $<
@@ -150,4 +140,5 @@ dom0.bin: $(DOM0_IMAGE)
 
 clean::
        $(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean
-       rm -f firmware firmware_image dom0.bin .xen-syms
+       rm -f firmware firmware_image.bin dom0.bin .xen-syms xen-syms.S \
+               xen.lds asm-offsets.s cmdline.dep
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/backtrace.c      Fri Dec 15 11:32:58 2006 -0700
@@ -14,6 +14,7 @@
 #include <xen/console.h>
 #include <xen/sched.h>
 #include <xen/symbols.h>
+#include <asm/debugger.h>
 
 static char namebuf[KSYM_NAME_LEN+1];
 
@@ -192,6 +193,19 @@ void show_backtrace(ulong sp, ulong lr, 
     console_end_sync();
 }
 
+void show_backtrace_regs(struct cpu_user_regs *regs)
+{
+    console_start_sync();
+    
+    show_registers(regs);
+    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
+    printk("hid4 0x%016lx\n", regs->hid4);
+    printk("---[ backtrace ]---\n");
+    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
+
+    console_end_sync();
+}
+
 void __warn(char *file, int line)
 {
     ulong sp;
@@ -202,9 +216,19 @@ void __warn(char *file, int line)
 
     sp = (ulong)__builtin_frame_address(0);
     lr = (ulong)__builtin_return_address(0);
-
     backtrace(sp, lr, lr);
-    console_end_sync();
-}
-
-    
+
+    console_end_sync();
+}
+
+void dump_execution_state(void)
+{
+    struct vcpu *v = current;
+    struct cpu_user_regs *regs = &v->arch.ctxt;
+
+    show_registers(regs);
+    if (regs->msr & MSR_HV) {
+        printk("In Xen:\n");
+        show_backtrace(regs->gprs[1], regs->pc, regs->lr);
+    }
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/bitops.c
--- a/xen/arch/powerpc/bitops.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/bitops.c Fri Dec 15 11:32:58 2006 -0700
@@ -12,42 +12,42 @@
  * @size: The maximum size to search
  */
 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
-                           unsigned long offset)
+                            unsigned long offset)
 {
-       const unsigned long *p = addr + BITOP_WORD(offset);
-       unsigned long result = offset & ~(BITS_PER_LONG-1);
-       unsigned long tmp;
+    const unsigned long *p = addr + BITOP_WORD(offset);
+    unsigned long result = offset & ~(BITS_PER_LONG-1);
+    unsigned long tmp;
 
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset %= BITS_PER_LONG;
-       if (offset) {
-               tmp = *(p++);
-               tmp &= (~0UL << offset);
-               if (size < BITS_PER_LONG)
-                       goto found_first;
-               if (tmp)
-                       goto found_middle;
-               size -= BITS_PER_LONG;
-               result += BITS_PER_LONG;
-       }
-       while (size & ~(BITS_PER_LONG-1)) {
-               if ((tmp = *(p++)))
-                       goto found_middle;
-               result += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
+    if (offset >= size)
+        return size;
+    size -= result;
+    offset %= BITS_PER_LONG;
+    if (offset) {
+        tmp = *(p++);
+        tmp &= (~0UL << offset);
+        if (size < BITS_PER_LONG)
+            goto found_first;
+        if (tmp)
+            goto found_middle;
+        size -= BITS_PER_LONG;
+        result += BITS_PER_LONG;
+    }
+    while (size & ~(BITS_PER_LONG-1)) {
+        if ((tmp = *(p++)))
+            goto found_middle;
+        result += BITS_PER_LONG;
+        size -= BITS_PER_LONG;
+    }
+    if (!size)
+        return result;
+    tmp = *p;
 
 found_first:
-       tmp &= (~0UL >> (BITS_PER_LONG - size));
-       if (tmp == 0UL)         /* Are any bits set? */
-               return result + size;   /* Nope. */
+    tmp &= (~0UL >> (BITS_PER_LONG - size));
+    if (tmp == 0UL)        /* Are any bits set? */
+        return result + size;    /* Nope. */
 found_middle:
-       return result + __ffs(tmp);
+    return result + __ffs(tmp);
 }
 
 /*
@@ -55,40 +55,40 @@ found_middle:
  * Linus' asm-alpha/bitops.h.
  */
 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
-                                unsigned long offset)
+                                 unsigned long offset)
 {
-       const unsigned long *p = addr + BITOP_WORD(offset);
-       unsigned long result = offset & ~(BITS_PER_LONG-1);
-       unsigned long tmp;
+    const unsigned long *p = addr + BITOP_WORD(offset);
+    unsigned long result = offset & ~(BITS_PER_LONG-1);
+    unsigned long tmp;
 
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset %= BITS_PER_LONG;
-       if (offset) {
-               tmp = *(p++);
-               tmp |= ~0UL >> (BITS_PER_LONG - offset);
-               if (size < BITS_PER_LONG)
-                       goto found_first;
-               if (~tmp)
-                       goto found_middle;
-               size -= BITS_PER_LONG;
-               result += BITS_PER_LONG;
-       }
-       while (size & ~(BITS_PER_LONG-1)) {
-               if (~(tmp = *(p++)))
-                       goto found_middle;
-               result += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
+    if (offset >= size)
+        return size;
+    size -= result;
+    offset %= BITS_PER_LONG;
+    if (offset) {
+        tmp = *(p++);
+        tmp |= ~0UL >> (BITS_PER_LONG - offset);
+        if (size < BITS_PER_LONG)
+            goto found_first;
+        if (~tmp)
+            goto found_middle;
+        size -= BITS_PER_LONG;
+        result += BITS_PER_LONG;
+    }
+    while (size & ~(BITS_PER_LONG-1)) {
+        if (~(tmp = *(p++)))
+            goto found_middle;
+        result += BITS_PER_LONG;
+        size -= BITS_PER_LONG;
+    }
+    if (!size)
+        return result;
+    tmp = *p;
 
 found_first:
-       tmp |= ~0UL << size;
-       if (tmp == ~0UL)        /* Are any bits zero? */
-               return result + size;   /* Nope. */
+    tmp |= ~0UL << size;
+    if (tmp == ~0UL)    /* Are any bits zero? */
+        return result + size;    /* Nope. */
 found_middle:
-       return result + ffz(tmp);
+    return result + ffz(tmp);
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot/boot32.S
--- a/xen/arch/powerpc/boot/boot32.S    Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-       
-### 32 bit strapping code so Of will like us
-       .section        ".text"
-       .align 3
-       .globl _start
-               
-_start:
-       ## Double word align the MSR value below
-       nop
-       bl _real_start
-       ## static value for MSR
-       .llong 0x9000000000001000
-
-       ## see also docs/reference/ppc/msr.txt
-##bit C  Hex               Name Desc
-##  0 63 80000000 00000000 SF   64-bit Mode
-##  3 60 10000000 00000000 HV   Hypervisor State iff PR = 0 in hypervisor 
state.
-## 51 12 00000000 00001000 ME   Machine Check Enable
-
-_real_start:           
-       # pass the original msr as argument to hype_init
-       mfmsr   8
-
-       ## Set PC
-       li      21, 0
-       oris    21, 21, _hype64@h
-       ori     21, 21, _hype64@l
-#ifdef __BRIDGE64__
-       ## In 64bit we use rfid to switch from 32bit to 64 bit
-       mtsrr0  21
-
-       ## Set MSR
-       mflr    21
-       ld      22, 0(21)
-       mtsrr1  22
-       bl __leap
-       /* should never return */
-       trap
-__leap:                
-       rfid
-#else
-       mtctr 21
-       bctrl
-       /* should never return */
-       trap
-#endif
-
-       
-_real_end:
-       .data
-       .align 3
-       ## Hypervisor starts here, at the first data address
-       ## linker magic positions _hype64 0x100 after _start
-       ## hype/ppc64/Makefile.isa 
-_hype64:               
-
-
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot/start.S
--- a/xen/arch/powerpc/boot/start.S     Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include <asm/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
-    .globl _start
-_start:
-    /* load up the stack */
-    SET_REG_TO_LABEL(r1, cpu0_stack)
-
-    /* call the init function */
-    LOADADDR(r21,__start_xen_ppc)
-
-#ifdef __PPC64__
-    ld r2, 8(r21)
-    ld r21, 0(r21)
-#endif
-    mtctr r21
-    bctrl
-    /* should never return */
-    trap
-
-    /* Note! GDB 6.3 makes the very stupid assumption that PC > SP means we are
-     * in a Linux signal trampoline, and it begins groping for a struct
-     * rt_sigframe on the stack. Naturally, this fails miserably for our
-     * backtrace. To work around this behavior, we must make certain that our
-     * stack is always above our text, e.g. in the data section. */
-    .data /* DO NOT REMOVE; see GDB note above */
-    .align 4
-cpu0_stack_bottom:
-    .space STACK_SIZE
-cpu0_stack:
-    .space STACK_FRAME_OVERHEAD
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/boot_of.c        Fri Dec 15 11:32:58 2006 -0700
@@ -16,6 +16,7 @@
  * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
 
 #include <xen/config.h>
@@ -32,6 +33,7 @@
 #include "exceptions.h"
 #include "of-devtree.h"
 #include "oftree.h"
+#include "rtas.h"
 
 /* Secondary processors use this for handshaking with main processor.  */
 volatile unsigned int __spin_ack;
@@ -39,20 +41,27 @@ static ulong of_vec;
 static ulong of_vec;
 static ulong of_msr;
 static int of_out;
-static char bootargs[256];
-
-#define COMMAND_LINE_SIZE 512
-static char builtin_cmdline[COMMAND_LINE_SIZE]
-    __attribute__((section("__builtin_cmdline"))) = CMDLINE;
-
+static ulong eomem;
+
+#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)
+static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);
+
+extern char builtin_cmdline[];
 extern struct ns16550_defaults ns16550;
 
 #undef OF_DEBUG
+#undef OF_DEBUG_LOW
 
 #ifdef OF_DEBUG
 #define DBG(args...) of_printf(args)
 #else
 #define DBG(args...)
+#endif
+
+#ifdef OF_DEBUG_LOW
+#define DBG_LOW(args...) of_printf(args)
+#else
+#define DBG_LOW(args...)
 #endif
 
 #define of_panic(MSG...) \
@@ -68,7 +77,6 @@ static int bof_chosen;
 static int bof_chosen;
 
 static struct of_service s;
-extern s32 prom_call(void *arg, ulong rtas_base, ulong func, ulong msr);
 
 static int __init of_call(
     const char *service, u32 nargs, u32 nrets, s32 rets[], ...)
@@ -78,7 +86,6 @@ static int __init of_call(
     if (of_vec != 0) {
         va_list args;
         int i;
-
         memset(&s, 0, sizeof (s));
         s.ofs_service = (ulong)service;
         s.ofs_nargs = nargs;
@@ -189,7 +196,7 @@ static int __init of_finddevice(const ch
         DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]);
         return OF_FAILURE;
     }
-    DBG("finddevice %s -> %d\n",devspec, rets[0]);
+    DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]);
     return rets[0];
 }
 
@@ -200,11 +207,11 @@ static int __init of_getprop(int ph, con
     of_call("getprop", 4, 1, rets, ph, name, buf, buflen);
 
     if (rets[0] == OF_FAILURE) {
-        DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
+        DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name);
         return OF_FAILURE;
     }
 
-    DBG("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
+    DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
     return rets[0];
 }
 
@@ -220,7 +227,7 @@ static int __init of_setprop(
         return OF_FAILURE;
     }
 
-    DBG("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
+    DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
     return rets[0];
 }
 
@@ -232,7 +239,7 @@ static int __init of_getchild(int ph)
     int rets[1] = { OF_FAILURE };
 
     of_call("child", 1, 1, rets, ph);
-    DBG("getchild 0x%x -> 0x%x\n", ph, rets[0]);
+    DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]);
 
     return rets[0];
 }
@@ -245,7 +252,7 @@ static int __init of_getpeer(int ph)
     int rets[1] = { OF_FAILURE };
 
     of_call("peer", 1, 1, rets, ph);
-    DBG("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
+    DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
 
     return rets[0];
 }
@@ -259,7 +266,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 -> 0x%x\n", ph, name, rets[0]);
+    DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
     return rets[0];
 }
 
@@ -272,7 +279,7 @@ static int __init of_package_to_path(int
         DBG("%s 0x%x -> FAILURE\n", __func__, ph);
         return OF_FAILURE;
     }
-    DBG("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
+    DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
     if (rets[0] <= buflen)
         buffer[rets[0]] = '\0';
     return rets[0];
@@ -289,7 +296,7 @@ static int __init of_nextprop(int ph, co
         return OF_FAILURE;
     }
 
-    DBG("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
+    DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
     return rets[0];
 }
 
@@ -336,7 +343,7 @@ static int __init of_claim(u32 virt, u32
         return OF_FAILURE;
     }
 
-    DBG("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,
+    DBG_LOW("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, 
align,
         rets[0]);
     return rets[0];
 }
@@ -358,29 +365,194 @@ static int __init of_getparent(int ph)
 
     of_call("parent", 1, 1, rets, ph);
 
-    DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
-    return rets[0];
-}
-
-static void boot_of_probemem(multiboot_info_t *mbi)
+    DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]);
+    return rets[0];
+}
+
+static int __init of_open(const char *devspec)
+{
+    int rets[1] = { OF_FAILURE };
+
+    of_call("open", 1, 1, rets, devspec);
+    return rets[0];
+}
+
+static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells)
+{
+    int rc;
+    uint pg;
+    uint a[64];
+    int tst;
+    u64 start;
+    u64 size;
+
+    rc = of_getprop(m, "available", a, sizeof (a));
+    if (rc > 0) {
+        int l =  rc / sizeof(a[0]);
+        int r = 0;
+
+#ifdef OF_DEBUG
+        { 
+            int i;
+            of_printf("avail:\n");
+            for (i = 0; i < l; i += 4)
+                of_printf("  0x%x%x, 0x%x%x\n",
+                          a[i], a[i + 1],
+                          a[i + 2] ,a[i + 3]);
+        }
+#endif
+            
+        pg = 0;
+        while (pg < MEM_AVAILABLE_PAGES && r < l) {
+            ulong end;
+
+            start = a[r++];
+            if (addr_cells == 2 && (r < l) )
+                start = (start << 32) | a[r++];
+            
+            size = a[r++];
+            if (size_cells == 2 && (r < l) )
+                size = (size << 32) | a[r++];
+                
+            end = ALIGN_DOWN(start + size, PAGE_SIZE);
+
+            start = ALIGN_UP(start, PAGE_SIZE);
+
+            DBG("%s: marking 0x%x - 0x%lx\n", __func__,
+                pg << PAGE_SHIFT, start);
+
+            start >>= PAGE_SHIFT;
+            while (pg < MEM_AVAILABLE_PAGES && pg < start) {
+                set_bit(pg, mem_available_pages);
+                pg++;
+            }
+
+            pg = end  >> PAGE_SHIFT;
+        }
+    }
+
+    /* Now make sure we mark our own memory */
+    pg =  (ulong)_start >> PAGE_SHIFT;
+    start = (ulong)_end >> PAGE_SHIFT;
+
+    DBG("%s: marking 0x%x - 0x%lx\n", __func__,
+        pg << PAGE_SHIFT, start << PAGE_SHIFT);
+
+    /* Lets try and detect if our image has stepped on something. It
+     * is possible that FW has already subtracted our image from
+     * available memory so we must make sure that the previous bits
+     * are the same for the whole image */
+    tst = test_and_set_bit(pg, mem_available_pages);
+    ++pg;
+    while (pg <= start) {
+        if (test_and_set_bit(pg, mem_available_pages) != tst)
+            of_panic("%s: pg :0x%x of our image is different\n",
+                     __func__, pg);
+        ++pg;
+    }
+
+    DBG("%s: marking 0x%x - 0x%x\n", __func__,
+        0 << PAGE_SHIFT, 3 << PAGE_SHIFT);
+    /* First for pages (where the vectors are) should be left alone as well */
+    set_bit(0, mem_available_pages);
+    set_bit(1, mem_available_pages);
+    set_bit(2, mem_available_pages);
+    set_bit(3, mem_available_pages);
+}
+
+#ifdef BOOT_OF_FREE
+/* this is here in case we ever need a free call at a later date */
+static void boot_of_free(ulong addr, ulong size)
+{
+    ulong bits;
+    ulong pos;
+    ulong i;
+
+    size = ALIGN_UP(size, PAGE_SIZE);
+    bits = size >> PAGE_SHIFT;
+    pos = addr >> PAGE_SHIFT;
+
+    for (i = 0; i < bits; i++) {
+        if (!test_and_clear_bit(pos + i, mem_available_pages))
+            of_panic("%s: pg :0x%lx was never allocated\n",
+                     __func__, pos + i);
+    }
+}
+#endif
+
+static ulong boot_of_alloc(ulong size)
+{
+    ulong bits;
+    ulong pos;
+
+    if (size == 0)
+        return 0;
+
+    DBG("%s(0x%lx)\n", __func__, size);
+
+    size = ALIGN_UP(size, PAGE_SIZE);
+    bits = size >> PAGE_SHIFT;
+    pos = 0;
+    for (;;) {
+        ulong i;
+
+        pos = find_next_zero_bit(mem_available_pages,
+                                 MEM_AVAILABLE_PAGES, pos);
+        DBG("%s: found start bit at: 0x%lx\n", __func__, pos);
+
+        /* found nothing */
+        if ((pos + bits) > MEM_AVAILABLE_PAGES) {
+            of_printf("%s: allocation of size: 0x%lx failed\n",
+                     __func__, size);
+            return 0;
+        }
+
+        /* find a set that fits */
+        DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos);
+
+        i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);  
+        if (i - pos >= bits) {
+            uint addr = pos << PAGE_SHIFT;
+
+            /* make sure OF is happy with our choice */
+            if (of_claim(addr, size, 0) != OF_FAILURE) {
+                for (i = 0; i < bits; i++)
+                    set_bit(pos + i, mem_available_pages);
+
+                DBG("%s: 0x%lx is good returning 0x%x\n",
+                    __func__, pos, addr);
+                return addr;
+            }
+            /* if OF did not like the address then simply start from
+             * the next bit */
+            i = 1;
+        }
+
+        pos = pos + i;
+    }
+}
+
+static ulong boot_of_mem_init(void)
 {
     int root;
     int p;
-    u32 addr_cells = 1;
-    u32 size_cells = 1;
     int rc;
-    int mcount = 0;
-    static memory_map_t mmap[16];
+    uint addr_cells;
+    uint size_cells;
 
     root = of_finddevice("/");
     p = of_getchild(root);
 
     /* 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));
+    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);
-    
+
+    /* We do ream memory discovery later, for now we only want to find
+     * the first LMB */
     do {
         const char memory[] = "memory";
         char type[32];
@@ -389,82 +561,69 @@ static void boot_of_probemem(multiboot_i
 
         of_getprop(p, "device_type", type, sizeof (type));
         if (strncmp(type, memory, sizeof (memory)) == 0) {
-            u32 reg[48];  
-            u32 al, ah, ll, lh;
+            uint reg[48];  
+            u64 start;
+            u64 size;
             int r;
+            int l;
 
             rc = of_getprop(p, "reg", reg, sizeof (reg));
             if (rc == OF_FAILURE) {
                 of_panic("no reg property for memory node: 0x%x.\n", p);
             }
-            int l = rc/sizeof(u32); /* number reg element */
+
+            l = rc / sizeof(reg[0]); /* number reg element */
             DBG("%s: number of bytes in property 'reg' %d\n",
                             __func__, rc);
             
             r = 0;
             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 */
+                start = reg[r++];
+                if (addr_cells == 2 && (r < l) )
+                    start = (start << 32) | reg[r++];
+
+                if (r >= l)
+                    break;  /* partial line.  Skip */
+
+                if (start > 0) {
+                    /* this is not the first LMB so we skip it */
+                    break;
                 }
-                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;
-                }
+
+                size = reg[r++];
+                if (size_cells == 2 && (r < l) )
+                    size = (size << 32) | reg[r++];
+                
+                if (r > l)
+                    break;  /* partial line.  Skip */
+
+                boot_of_alloc_init(p, addr_cells, size_cells);
+                
+                eomem = size;
+                return size;
             }
         }
         p = of_getpeer(p);
     } while (p != OF_FAILURE && p != 0);
 
-    if (mcount > 0) {
-        mbi->flags |= MBI_MEMMAP;
-        mbi->mmap_length = sizeof (mmap[0]) * mcount;
-        mbi->mmap_addr = (ulong)mmap;
-    }
+    return 0;
 }
 
 static void boot_of_bootargs(multiboot_info_t *mbi)
 {
     int rc;
 
-    rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
-    if (rc == OF_FAILURE || bootargs[0] == '\0') {
-        strlcpy(bootargs, builtin_cmdline, sizeof(bootargs));
+    if (builtin_cmdline[0] == '\0') {
+        rc = of_getprop(bof_chosen, "bootargs", builtin_cmdline,
+                CONFIG_CMDLINE_SIZE);
+        if (rc > CONFIG_CMDLINE_SIZE)
+            of_panic("bootargs[] not big enough for /chosen/bootargs\n");
     }
 
     mbi->flags |= MBI_CMDLINE;
-    mbi->cmdline = (u32)bootargs;
-
-    of_printf("bootargs = %s\n", bootargs);
+    mbi->cmdline = (ulong)builtin_cmdline;
+
+    of_printf("bootargs = %s\n", builtin_cmdline);
 }
 
 static int save_props(void *m, ofdn_t n, int pkg)
@@ -500,7 +659,8 @@ static int save_props(void *m, ofdn_t n,
                     of_panic("obj array not big enough for 0x%x\n", sz);
                 }
                 actual = of_getprop(pkg, name, obj, sz);
-                if (actual > sz) of_panic("obj too small");
+                if (actual > sz)
+                    of_panic("obj too small");
             }
 
             if (strncmp(name, name_str, sizeof(name_str)) == 0) {
@@ -512,7 +672,8 @@ static int save_props(void *m, ofdn_t n,
             }
 
             pos = ofd_prop_add(m, n, name, obj, actual);
-            if (pos == 0) of_panic("prop_create");
+            if (pos == 0)
+                of_panic("prop_create");
         }
 
         result = of_nextprop(pkg, name, name);
@@ -536,10 +697,12 @@ retry:
 
     if (pnext != 0) {
         sz = of_package_to_path(pnext, path, psz);
-        if (sz == OF_FAILURE) 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");
+        if (nnext == 0)
+            of_panic("out of mem\n");
 
         do_pkg(m, nnext, pnext, path, psz);
     }
@@ -551,7 +714,8 @@ 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 space in OFD tree.\n");
+        if (nnext <= 0)
+            of_panic("out of space in OFD tree.\n");
 
         n = nnext;
         p = pnext;
@@ -559,7 +723,7 @@ retry:
     }
 }
 
-static int pkg_save(void *mem)
+static long pkg_save(void *mem)
 {
     int root;
     char path[256];
@@ -570,11 +734,12 @@ static int pkg_save(void *mem)
 
     /* get root */
     root = of_getpeer(0);
-    if (root == OF_FAILURE) 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));
 
-    r = (((ofdn_t *)mem)[1] + 1) * sizeof (u64);
+    r = ofd_size(mem);
 
     of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r);
 
@@ -604,7 +769,8 @@ static int boot_of_fixup_refs(void *mem)
             char ofpath[256];
 
             path = ofd_node_path(mem, c);
-            if (path == NULL) of_panic("no path to found prop: %s\n", name);
+            if (path == NULL)
+                of_panic("no path to found prop: %s\n", name);
 
             rp = of_finddevice(path);
             if (rp == OF_FAILURE)
@@ -629,13 +795,15 @@ static int boot_of_fixup_refs(void *mem)
                          "ref 0x%x\n", name, path, rp, ref);
 
             dp = ofd_node_find(mem, ofpath);
-            if (dp <= 0) of_panic("no ofd node for OF node[0x%x]: %s\n",
-                                  ref, ofpath);
+            if (dp <= 0)
+                of_panic("no ofd node for OF node[0x%x]: %s\n",
+                         ref, ofpath);
 
             ref = dp;
 
             upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref));
-            if (upd <= 0) of_panic("update failed: %s\n", name);
+            if (upd <= 0)
+                of_panic("update failed: %s\n", name);
 
 #ifdef DEBUG
             of_printf("%s: %s/%s -> %s\n", __func__,
@@ -658,7 +826,8 @@ static int boot_of_fixup_chosen(void *me
     char ofpath[256];
 
     ch = of_finddevice("/chosen");
-    if (ch == OF_FAILURE) of_panic("/chosen not found\n");
+    if (ch == OF_FAILURE)
+        of_panic("/chosen not found\n");
 
     rc = of_getprop(ch, "cpu", &val, sizeof (val));
 
@@ -667,16 +836,19 @@ static int boot_of_fixup_chosen(void *me
 
         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);
 
             ofd_boot_cpu = dn;
             val = dn;
 
             dn = ofd_node_find(mem, "/chosen");
-            if (dn <= 0) of_panic("no /chosen node\n");
+            if (dn <= 0)
+                of_panic("no /chosen node\n");
 
             dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val));
-            if (dc <= 0) of_panic("could not fix /chosen/cpu\n");
+            if (dc <= 0)
+                of_panic("could not fix /chosen/cpu\n");
             rc = 1;
         } else {
             of_printf("*** can't find path to booting cpu, "
@@ -685,56 +857,6 @@ static int boot_of_fixup_chosen(void *me
         }
     }
     return rc;
-}
-
-static ulong space_base;
-
-/*
- * 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;
-
-    if (size == 0)
-        return 0;
-
-    if (align == 0)
-        of_panic("cannot call %s() with align of 0\n", __func__);
-
-#ifdef BROKEN_CLAIM_WORKAROUND
-    {
-        static int broken_claim;
-        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;
-        }
-    }
-#endif
-
-    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);
-
-    while ((base + size) < rma_size(cpu_default_rma_order_pages())) {
-        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
@@ -798,8 +920,10 @@ static int __init boot_of_serial(void *o
             of_panic("package-to-path failed\n");
 
         rc = of_getprop(p, "device_type", type, sizeof (type));
-        if (rc == OF_FAILURE)
-            of_panic("fetching device type failed\n");
+        if (rc == OF_FAILURE) {
+            of_printf("%s: fetching type of `%s' failed\n", __func__, buf);
+            continue;
+        }
 
         if (strcmp(type, "serial") != 0)
             continue;
@@ -855,17 +979,104 @@ static int __init boot_of_serial(void *o
     return 1;
 }
 
-static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
-{
-    static module_t mods[3];
+static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi)
+{
+    int rtas_node;
+    int rtas_instance;
+    uint size = 0;
+    int res[2];
+    int mem;
+    int ret;
+
+    rtas_node = of_finddevice("/rtas");
+
+    if (rtas_node <= 0) {
+        of_printf("No RTAS, Xen has no power control\n");
+        return 0;
+    }
+    of_getprop(rtas_node, "rtas-size", &size, sizeof (size));
+    if (size == 0) {
+        of_printf("RTAS, has no size\n");
+        return 0;
+    }
+
+    rtas_instance = of_open("/rtas");
+    if (rtas_instance == OF_FAILURE) {
+        of_printf("RTAS, could not open\n");
+        return 0;
+    }
+
+    size = ALIGN_UP(size, PAGE_SIZE);
+    
+    mem = boot_of_alloc(size);
+    if (mem == 0)
+        of_panic("Could not allocate RTAS tree\n");
+
+    of_printf("instantiating RTAS at: 0x%x\n", mem);
+
+    ret = of_call("call-method", 3, 2, res,
+                  "instantiate-rtas", rtas_instance, mem);
+    if (ret == OF_FAILURE) {
+        of_printf("RTAS, could not open\n");
+        return 0;
+    }
+    
+    rtas_entry = res[1];
+    rtas_base = mem;
+    rtas_end = mem + size;
+    rtas_msr = of_msr;
+
+    mod->mod_start = rtas_base;
+    mod->mod_end = rtas_end;
+    return 1;
+}
+
+static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
+{
     void *oft;
     ulong oft_sz = 48 * PAGE_SIZE;
+
+    /* snapshot the tree */
+    oft = (void *)boot_of_alloc(oft_sz);
+    if (oft == NULL)
+        of_panic("Could not allocate OFD tree\n");
+
+    of_printf("creating oftree at: 0x%p\n", oft);
+    of_test("package-to-path");
+    oft = ofd_create(oft, oft_sz);
+    pkg_save(oft);
+
+    if (ofd_size(oft) > oft_sz)
+         of_panic("Could not fit all of native devtree\n");
+
+    boot_of_fixup_refs(oft);
+    boot_of_fixup_chosen(oft);
+
+    if (ofd_size(oft) > oft_sz)
+         of_panic("Could not fit all devtree fixups\n");
+
+    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);
+
+    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[] = " -- ";
+    static const char * sepr[] = {" -- ", " || "};
+    int sepr_index;
     extern char dom0_start[] __attribute__ ((weak));
     extern char dom0_size[] __attribute__ ((weak));
-    const char *p;
+    const char *p = NULL;
+    int mod;
+    void *oft;
 
     if ((r3 > 0) && (r4 > 0)) {
         /* was it handed to us in registers ? */
@@ -908,57 +1119,50 @@ static void boot_of_module(ulong r3, ulo
         of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
     }
 
-    space_base = (ulong)_end;
-    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);
-    p = strstr((char *)(ulong)mbi->cmdline, sepr);
+    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) {
-        p += sizeof (sepr) - 1;
-        mods[0].string = (u32)(ulong)p;
-        of_printf("%s: mod[0].string: %s\n", __func__, p);
-    }
-
-    /* snapshot the tree */
-    oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
-    if (oft == 0)
-        of_panic("Could not allocate OFD tree\n");
-
-    of_printf("creating oft\n");
-    of_test("package-to-path");
-    oft = ofd_create(oft, oft_sz);
-    pkg_save(oft);
-
-    if (ofd_size(oft) > oft_sz)
-         of_panic("Could not fit all of native devtree\n");
-
-    boot_of_fixup_refs(oft);
-    boot_of_fixup_chosen(oft);
-
-    if (ofd_size(oft) > oft_sz)
-         of_panic("Could not fit all devtree fixups\n");
-
-    ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
-
-    mods[1].mod_start = (ulong)oft;
-    mods[1].mod_end = mods[1].mod_start + oft_sz;
-    of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
-              mods[1].mod_start, mods[1].mod_end);
-
+        /* 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 = 2;
+    mbi->mods_count = mod;
     mbi->mods_addr = (u32)mods;
 
-    boot_of_serial(oft);
+    return oft;
 }
 
 static int __init boot_of_cpus(void)
 {
-    int cpus_node;
-    int cpu_node, bootcpu_node, logical;
+    int cpus_node, cpu_node;
+    int bootcpu_instance, bootcpu_node;
+    int logical;
     int result;
     s32 cpuid;
     u32 cpu_clock[2];
@@ -967,9 +1171,13 @@ static int __init boot_of_cpus(void)
     /* Look up which CPU we are running on right now and get all info
      * from there */
     result = of_getprop(bof_chosen, "cpu",
-                        &bootcpu_node, sizeof (bootcpu_node));
+                        &bootcpu_instance, sizeof (bootcpu_instance));
     if (result == OF_FAILURE)
-        of_panic("Failed to look up boot cpu\n");
+        of_panic("Failed to look up boot cpu instance\n");
+
+    bootcpu_node = of_instance_to_package(bootcpu_instance);
+    if (result == OF_FAILURE)
+        of_panic("Failed to look up boot cpu package\n");
 
     cpu_node = bootcpu_node;
 
@@ -1070,15 +1278,12 @@ static int __init boot_of_cpus(void)
     return 1;
 }
 
-static int __init boot_of_rtas(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;
+    int r;
 
     of_vec = vec;
     of_msr = orig_msr;
@@ -1098,18 +1303,20 @@ multiboot_info_t __init *boot_of_init(
             r3, r4, vec, r6, r7, orig_msr);
 
     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",
+        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();
-    boot_of_probemem(&mbi);
+    r = boot_of_mem_init();
+    if (r == 0)
+        of_panic("failure to initialize memory allocator");
     boot_of_bootargs(&mbi);
-    boot_of_module(r3, r4, &mbi);
+    oft = boot_of_module(r3, r4, &mbi);
     boot_of_cpus();
-    boot_of_rtas();
+    boot_of_serial(oft);
 
     /* end of OF */
     of_printf("Quiescing Open Firmware ...\n");
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/cmdline.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/cmdline.c        Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,24 @@
+/*
+ * 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 <hollisb@xxxxxxxxxx>
+ */
+
+#include <asm/config.h>
+
+char builtin_cmdline[CONFIG_CMDLINE_SIZE] 
+        __attribute__((section("__builtin_cmdline"))) = CMDLINE;
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/crash.c
--- a/xen/arch/powerpc/crash.c  Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/crash.c  Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,6 @@
 #include <xen/lib.h>       /* for printk() used in stub */
 #include <xen/types.h>
+#include <xen/kexec.h>
 #include <public/kexec.h>
 
 void machine_crash_shutdown(void)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/dart.c
--- a/xen/arch/powerpc/dart.c   Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/dart.c   Fri Dec 15 11:32:58 2006 -0700
@@ -60,8 +60,8 @@ union dart_entry {
     u32 de_word;
     struct {
         u32 de_v:1;             /* valid */
-        u32 de_rp:1;             /* read protected*/
-        u32 de_wp:1;             /* write protected*/
+        u32 de_rp:1;             /* read protected */
+        u32 de_wp:1;             /* write protected */
         u32 _de_res:5;
         u32 de_ppn:24;         /* 24 bit Physical Page Number
                                  * representing address [28:51] */
@@ -98,7 +98,6 @@ static u32 dart_encode(int perm, ulong r
     if (perm & DART_WRITE) {
         e.de_bits.de_wp = 0;
     }
-
     return e.de_word;
 }
 
@@ -190,10 +189,8 @@ static int find_dart(struct dart_info *d
     ofdn_t n;
     char compat[128];
 
-
-    if (on_mambo()) {
-        /* mambo has no dart */
-        DBG("%s: Mambo does not support a dart\n", __func__);
+    if (on_systemsim()) {
+        DBG("%s: systemsim does not support a dart\n", __func__);
         return -1;
     }
 
@@ -263,7 +260,7 @@ static int init_dart(void)
 
     /* Linux uses a dummy page, filling "empty" DART entries with a
        reference to this page to capture stray DMA's */
-    dummy_page = (ulong)alloc_xenheap_pages(1);
+    dummy_page = (ulong)alloc_xenheap_pages(0);
     clear_page((void *)dummy_page);
     dummy_page >>= PAGE_SHIFT;
 
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/dart_u4.c
--- a/xen/arch/powerpc/dart_u4.c        Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/dart_u4.c        Fri Dec 15 11:32:58 2006 -0700
@@ -19,6 +19,7 @@
  */
 
 #undef DEBUG
+#define INVALIDATE_ALL
 
 #include <xen/config.h>
 #include <xen/types.h>
@@ -123,8 +124,13 @@ static void u4_inv_all(void)
 
 static void u4_inv_entry(ulong pgn)
 {
+#ifdef INVALIDATE_ALL
+    return u4_inv_all();
+#else
     union dart_ctl dc;
     ulong retries = 0;
+
+    return u4_inv_all();
 
     dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
     dc.dc_bits.dc_ilpn = pgn;
@@ -139,6 +145,7 @@ static void u4_inv_entry(ulong pgn)
         if (retries > 1000000)
             panic("WAY! too long\n");
     } while (dc.dc_bits.dc_ione != 0);
+#endif
 }
 
 static struct dart_ops u4_ops = {
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/delay.c
--- a/xen/arch/powerpc/delay.c  Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * 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: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
- */
-
-#include <xen/config.h>
-#include <xen/delay.h>
-#include <xen/time.h>
-#include <asm/processor.h>
-
-void udelay(unsigned long usecs)
-{
-    ulong ticks = usecs * ticks_per_usec;
-    ulong s;
-    ulong e;
-
-    s = get_timebase();
-    do {
-        asm volatile("or 1,1,1"); /* also puts the thread to low priority */
-        e = get_timebase();
-    } while ((e-s) < ticks);
-}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domain.c Fri Dec 15 11:32:58 2006 -0700
@@ -33,6 +33,8 @@
 #include <asm/htab.h>
 #include <asm/current.h>
 #include <asm/hcalls.h>
+#include "rtas.h"
+#include "exceptions.h"
 
 #define next_arg(fmt, args) ({                                              \
     unsigned long __arg;                                                    \
@@ -46,7 +48,6 @@
     }                                                                       \
     __arg;                                                                  \
 })
-extern void idle_loop(void);
 
 unsigned long hypercall_create_continuation(unsigned int op,
         const char *format, ...)
@@ -87,26 +88,44 @@ int arch_domain_create(struct domain *d)
 
     INIT_LIST_HEAD(&d->arch.extent_list);
 
+    d->arch.foreign_mfn_count = 1024;
+    d->arch.foreign_mfns = xmalloc_array(uint, d->arch.foreign_mfn_count);
+    BUG_ON(d->arch.foreign_mfns == NULL);
+
+    memset(d->arch.foreign_mfns, -1, d->arch.foreign_mfn_count * sizeof(uint));
+
     return 0;
 }
 
 void arch_domain_destroy(struct domain *d)
 {
     shadow_teardown(d);
-}
-
+    /* shared_info is part of the RMA so no need to release it */
+}
+
+static void machine_fail(const char *s)
+{
+    printk("%s failed, manual powercycle required!\n", s);
+    for (;;)
+        sleep();
+}
 void machine_halt(void)
 {
     printk("machine_halt called: spinning....\n");
     console_start_sync();
-    while(1);
+    printk("%s called\n", __func__);
+    rtas_halt();
+
+    machine_fail(__func__);
 }
 
 void machine_restart(char * __unused)
 {
     printk("machine_restart called: spinning....\n");
     console_start_sync();
-    while(1);
+    printk("%s called\n", __func__);
+    rtas_reboot();
+    machine_fail(__func__);
 }
 
 struct vcpu *alloc_vcpu_struct(void)
@@ -222,6 +241,7 @@ void context_switch(struct vcpu *prev, s
 
     mtsdr1(next->domain->arch.htab.sdr1);
     local_flush_tlb(); /* XXX maybe flush_tlb_mask? */
+    cpu_flush_icache();
 
     if (is_idle_vcpu(next)) {
         reset_stack_and_jump(idle_loop);
@@ -278,8 +298,10 @@ static void relinquish_memory(struct dom
 
 void domain_relinquish_resources(struct domain *d)
 {
+    relinquish_memory(d, &d->xenpage_list);
     relinquish_memory(d, &d->page_list);
     free_extents(d);
+    xfree(d->arch.foreign_mfns);
     return;
 }
 
@@ -291,7 +313,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
 {
 }
 
-extern void sleep(void);
 static void safe_halt(void)
 {
     int cpu = smp_processor_id();
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c   Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domain_build.c   Fri Dec 15 11:32:58 2006 -0700
@@ -178,8 +178,7 @@ int construct_dom0(struct domain *d,
         shadow_set_allocation(d, opt_dom0_shadow, &preempt);
     } while (preempt);
     if (shadow_get_allocation(d) == 0)
-        panic("shadow allocation failed 0x%x < 0x%x\n",
-              shadow_get_allocation(d), opt_dom0_shadow);
+        panic("shadow allocation failed: %dMib\n", opt_dom0_shadow);
 
     ASSERT( image_len < rma_sz );
 
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domctl.c
--- a/xen/arch/powerpc/domctl.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domctl.c Fri Dec 15 11:32:58 2006 -0700
@@ -96,14 +96,14 @@ long arch_do_domctl(struct xen_domctl *d
     case XEN_DOMCTL_real_mode_area:
     {
         struct domain *d;
-        unsigned int log = domctl->u.real_mode_area.log;
+        unsigned int order = domctl->u.real_mode_area.log - PAGE_SHIFT;
 
         ret = -ESRCH;
         d = find_domain_by_id(domctl->domain);
         if (d != NULL) {
             ret = -EINVAL;
-            if (cpu_rma_valid(log))
-                ret = allocate_rma(d, log - PAGE_SHIFT);
+            if (cpu_rma_valid(order))
+                ret = allocate_rma(d, order);
             put_domain(d);
         }
     }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/exceptions.c     Fri Dec 15 11:32:58 2006 -0700
@@ -25,8 +25,10 @@
 #include <xen/serial.h>
 #include <xen/gdbstub.h>
 #include <xen/console.h>
+#include <xen/shutdown.h>
 #include <asm/time.h>
 #include <asm/processor.h>
+#include <asm/debugger.h>
 
 #undef DEBUG
 
@@ -56,25 +58,19 @@ void do_dec(struct cpu_user_regs *regs)
 
 void program_exception(struct cpu_user_regs *regs, unsigned long cookie)
 {
+    if (cookie == 0x200) {
+        if (cpu_machinecheck(regs))
+            return;
+
+        printk("%s: machine check\n", __func__);
+    } else {
 #ifdef CRASH_DEBUG
-    __trap_to_gdb(regs, cookie);
-#else /* CRASH_DEBUG */
-    int recover = 0;
+        if (__trap_to_gdb(regs, cookie) == 0)
+            return;
+#endif /* CRASH_DEBUG */
 
-    console_start_sync();
-
-    show_registers(regs);
-    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
-    printk("hid4 0x%016lx\n", regs->hid4);
-    printk("---[ backtrace ]---\n");
-    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
-
-    if (cookie == 0x200)
-        recover = cpu_machinecheck(regs);
-
-    if (!recover)
-        panic("%s: 0x%lx\n", __func__, cookie);
-
-    console_end_sync();
-#endif /* CRASH_DEBUG */
+        printk("%s: type: 0x%lx\n", __func__, cookie);
+        show_backtrace_regs(regs);
+    }
+    machine_halt();
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/exceptions.h     Fri Dec 15 11:32:58 2006 -0700
@@ -43,13 +43,14 @@ extern void program_exception(
     struct cpu_user_regs *regs, unsigned long cookie);
 
 extern long xen_hvcall_jump(struct cpu_user_regs *regs, ulong address);
-extern void *mambo_memset(void *, int, ulong);
-extern void *mambo_memcpy(void *, const void *, ulong);
+
+extern void sleep(void);
+extern void idle_loop(void);
 
 extern ulong *__hypercall_table[];
 
 extern char exception_vectors[];
 extern char exception_vectors_end[];
 extern int spin_start[];
-extern int secondary_cpu_init(int cpuid, unsigned long r4);
+extern void secondary_cpu_init(int cpuid, unsigned long r4);
 #endif
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c       Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/external.c       Fri Dec 15 11:32:58 2006 -0700
@@ -82,7 +82,14 @@ void do_external(struct cpu_user_regs *r
 
     vec = xen_mpic_get_irq(regs);
 
-    if (vec != -1) {
+    if (irq_desc[vec].status & IRQ_PER_CPU) {
+        /* x86 do_IRQ does not respect the per cpu flag.  */
+        irq_desc_t *desc = &irq_desc[vec];
+        regs->entry_vector = vec;
+        desc->handler->ack(vec);
+        desc->action->handler(vector_to_irq(vec), desc->action->dev_id, regs);
+        desc->handler->end(vec);
+    } else if (vec != -1) {
         DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
         regs->entry_vector = vec;
         do_IRQ(regs);
@@ -253,3 +260,24 @@ int ioapic_guest_write(unsigned long phy
     BUG_ON(val != val);
     return 0;
 }
+
+void send_IPI_mask(cpumask_t mask, int vector)
+{
+    unsigned int cpus;
+    int const bits = 8 * sizeof(cpus);
+
+    switch(vector) {
+    case CALL_FUNCTION_VECTOR:
+    case EVENT_CHECK_VECTOR:
+        break;
+    default:
+        BUG();
+        return;
+    }
+
+    BUG_ON(NR_CPUS > bits);
+    BUG_ON(fls(mask.bits[0]) > bits);
+
+    cpus = mask.bits[0];
+    mpic_send_ipi(vector, cpus);
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/gdbstub.c
--- a/xen/arch/powerpc/gdbstub.c        Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/gdbstub.c        Fri Dec 15 11:32:58 2006 -0700
@@ -25,6 +25,7 @@
 #include <asm/msr.h>
 #include <asm/bitops.h>
 #include <asm/cache.h>
+#include <asm/debugger.h>
 #include <asm/processor.h>
 
 asm(".globl trap_instruction\n"
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/iommu.c
--- a/xen/arch/powerpc/iommu.c  Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/iommu.c  Fri Dec 15 11:32:58 2006 -0700
@@ -32,6 +32,12 @@
 #include "tce.h"
 #include "iommu.h"
 
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
 struct iommu_funcs {
     int (*iommu_put)(ulong, union tce);
 };
@@ -46,17 +52,31 @@ int iommu_put(u32 buid, ulong ioba, unio
     struct domain *d = v->domain;
 
     if (buid < iommu_phbs_num && iommu_phbs[buid].iommu_put != NULL) {
-        ulong pfn;
+        ulong gmfn;
         ulong mfn;
         int mtype;
 
-        pfn = tce.tce_bits.tce_rpn;
-        mfn = pfn2mfn(d, pfn, &mtype);
+        gmfn = tce.tce_bits.tce_rpn;
+
+        
+        mfn = pfn2mfn(d, gmfn, &mtype);
         if (mfn != INVALID_MFN) {
-#ifdef DEBUG
-            printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
-                   ioba, pfn, mfn);
-#endif
+            switch (mtype) {
+            case PFN_TYPE_RMA:
+            case PFN_TYPE_LOGICAL:
+                break;
+            case PFN_TYPE_FOREIGN:
+                DBG("%s: assigning to Foriegn page: "
+                    "gmfn: 0x%lx mfn: 0x%lx\n",  __func__, gmfn, mfn);
+                break;
+            default:
+                printk("%s: unsupported type[%d]: gmfn: 0x%lx mfn: 0x%lx\n",
+                       __func__, mtype, gmfn, mfn);
+                return -1;
+            break;
+            }
+            DBG("%s: ioba=0x%lx gmfn=0x%lx mfn=0x%lx\n", __func__,
+                ioba, gmfn, mfn);
             tce.tce_bits.tce_rpn = mfn;
             return iommu_phbs[buid].iommu_put(ioba, tce);
         }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/machine_kexec.c
--- a/xen/arch/powerpc/machine_kexec.c  Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/machine_kexec.c  Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,6 @@
 #include <xen/lib.h>       /* for printk() used in stubs */
 #include <xen/types.h>
+#include <xen/kexec.h>
 #include <public/kexec.h>
 
 int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
@@ -9,11 +10,6 @@ int machine_kexec_load(int type, int slo
 }
 
 void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
-{
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
-
-void machine_kexec(xen_kexec_image_t *image)
 {
     printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mambo.S
--- a/xen/arch/powerpc/mambo.S  Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include <asm/config.h>
-#include <asm/processor.h>
-
-_GLOBAL(mambo_callthru)
-       .long 0x000eaeb0
-       blr
-
-_GLOBAL(mambo_write)
-       mr      r5, r4
-       mr      r4, r3
-       li      r3, 0           # Write console code
-       
-       li      r6, 0
-       /* need to fix return value */
-       mflr    r7
-       bl      _ENTRY(mambo_callthru)
-       mtlr    r7
-       mr      r3, r5
-       blr
-
-_GLOBAL(mambo_memset)
-       mr      r6, r5
-       mr      r5, r4
-       mr      r4, r3
-       li      r3, 0x47        # memset
-       /* need to fix return value */
-       mflr    r7
-       bl      _ENTRY(mambo_callthru)
-       mtlr    r7
-       mr      r3, r4
-       blr
-
-_GLOBAL(mambo_memcpy)
-       mr      r6, r5
-       mr      r5, r4
-       mr      r4, r3
-       li      r3, 0x45 # memcpy
-       /* need to fix return value */
-       mflr    r7
-       bl      _ENTRY(mambo_callthru)
-       mtlr    r7
-       mr      r3, r4
-       blr
-
-       
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/memory.c
--- a/xen/arch/powerpc/memory.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/memory.c Fri Dec 15 11:32:58 2006 -0700
@@ -20,10 +20,31 @@
  */
 #include <xen/sched.h>
 #include <xen/mm.h>
+#include <xen/numa.h>
 #include "of-devtree.h"
 #include "oftree.h"
+#include "rtas.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * page_info table and allocation bitmap.
+ */
+static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 
 unsigned long xenheap_phys_end;
+static uint nr_pages;
+static ulong xenheap_size;
+static ulong save_start;
+static ulong save_end;
+
 struct membuf {
     ulong start;
     ulong size;
@@ -36,15 +57,20 @@ static ulong free_xenheap(ulong start, u
     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);
+    DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
+
+    /* need to do this better */
+    if (save_start <= end && save_start >= start) {
+        DBG("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
+               __func__, save_start, save_end);
+        init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
+        xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
+
+        init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
+        xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
     } else {
         init_xenheap_pages(start, end);
+        xenheap_size += end - start;
     }
 
     return ALIGN_UP(end, PAGE_SIZE);
@@ -57,8 +83,10 @@ static void set_max_page(struct membuf *
     for (i = 0; i < entries; i++) {
         ulong end_page;
 
+        printk("  %016lx: %016lx\n", mb[i].start, mb[i].size);
+        nr_pages += mb[i].size >> PAGE_SHIFT;
+
         end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
-
         if (end_page > max_page)
             max_page = end_page;
     }
@@ -71,11 +99,11 @@ static void heap_init(struct membuf *mb,
     ulong start_blk;
     ulong end_blk = 0;
 
-       for (i = 0; i < entries; i++) {
-           start_blk = mb[i].start;
-           end_blk = start_blk + mb[i].size;
-
-           if (start_blk < xenheap_phys_end) {
+    for (i = 0; i < entries; i++) {
+        start_blk = mb[i].start;
+        end_blk = start_blk + mb[i].size;
+
+        if (start_blk < xenheap_phys_end) {
             if (xenheap_phys_end > end_blk) {
                 panic("xenheap spans LMB\n");
             }
@@ -87,7 +115,7 @@ static void heap_init(struct membuf *mb,
 
         init_boot_pages(start_blk, end_blk);
         total_pages += (end_blk - start_blk) >> PAGE_SHIFT;
-       }
+    }
 }
 
 static void ofd_walk_mem(void *m, walk_mem_fn fn)
@@ -123,7 +151,7 @@ static void setup_xenheap(module_t *mod,
     for (i = 0; i < mcount; i++) {
         u32 s;
 
-        if(mod[i].mod_end == mod[i].mod_start)
+        if (mod[i].mod_end == mod[i].mod_start)
             continue;
 
         s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
@@ -149,19 +177,42 @@ void memory_init(module_t *mod, int mcou
 void memory_init(module_t *mod, int mcount)
 {
     ulong eomem;
-    ulong heap_start, heap_size;
-
-    printk("Physical RAM map:\n");
+    ulong heap_start;
+    ulong xh_pages;
 
     /* lets find out how much memory there is and set max_page */
     max_page = 0;
+    printk("Physical RAM map:\n");
     ofd_walk_mem((void *)oftree, set_max_page);
     eomem = max_page << PAGE_SHIFT;
 
     if (eomem == 0){
         panic("ofd_walk_mem() failed\n");
     }
-    printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
+
+    /* 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 */
+    xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
+    xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
+
+    /* While we are allocating HTABS from The Xen Heap we need it to
+     * be larger */
+    xh_pages  += nr_pages >> 5;
+
+    xenheap_phys_end = xh_pages << PAGE_SHIFT;
+    printk("End of Xen Area: %luMiB (%luKiB)\n",
+           xenheap_phys_end >> 20, xenheap_phys_end >> 10);
+
+    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 */
@@ -185,22 +236,23 @@ void memory_init(module_t *mod, int mcou
         panic("total_pages > max_page: 0x%lx > 0x%lx\n",
               total_pages, max_page);
 
-    printk("total_pages: 0x%016lx\n", total_pages);
+    DBG("total_pages: 0x%016lx\n", total_pages);
 
     init_frametable();
+
+    numa_initmem_init(0, max_page);
+
     end_boot_allocator();
 
     /* Add memory between the beginning of the heap and the beginning
-     * of out text */
+     * of our text */
     free_xenheap(heap_start, (ulong)_start);
-
-    heap_size = xenheap_phys_end - heap_start;
-    printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
-
     setup_xenheap(mod, mcount);
+    printk("Xen Heap: %luMiB (%luKiB)\n",
+           xenheap_size >> 20, xenheap_size >> 10);
 
     eomem = avail_domheap_pages();
-    printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
+    printk("Dom Heap: %luMiB (%luKiB)\n",
            (eomem << PAGE_SHIFT) >> 20,
            (eomem << PAGE_SHIFT) >> 10);
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mm.c     Fri Dec 15 11:32:58 2006 -0700
@@ -25,9 +25,9 @@
 #include <xen/kernel.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
-#include <asm/misc.h>
 #include <asm/init.h>
 #include <asm/page.h>
+#include <asm/string.h>
 
 #ifdef VERBOSE
 #define MEM_LOG(_f, _a...)                                  \
@@ -42,18 +42,129 @@ unsigned long max_page;
 unsigned long max_page;
 unsigned long total_pages;
 
+void __init init_frametable(void)
+{
+    unsigned long p;
+    unsigned long nr_pages;
+    int i;
+
+    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
+
+    p = alloc_boot_pages(nr_pages, 1);
+    if (p == 0)
+        panic("Not enough memory for frame table\n");
+
+    frame_table = (struct page_info *)(p << PAGE_SHIFT);
+    for (i = 0; i < nr_pages; i += 1)
+        clear_page((void *)((p + i) << PAGE_SHIFT));
+}
+
+void share_xen_page_with_guest(
+    struct page_info *page, struct domain *d, int readonly)
+{
+    if ( page_get_owner(page) == d )
+        return;
+
+    /* this causes us to leak pages in the Domain and reuslts in
+     * Zombie domains, I think we are missing a piece, until we find
+     * it we disable the following code */
+    set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
+
+    spin_lock(&d->page_alloc_lock);
+
+    /* The incremented type count pins as writable or read-only. */
+    page->u.inuse.type_info  = (readonly ? PGT_none : PGT_writable_page);
+    page->u.inuse.type_info |= PGT_validated | 1;
+
+    page_set_owner(page, d);
+    wmb(); /* install valid domain ptr before updating refcnt. */
+    ASSERT(page->count_info == 0);
+    page->count_info |= PGC_allocated | 1;
+
+    if ( unlikely(d->xenheap_pages++ == 0) )
+        get_knownalive_domain(d);
+    list_add_tail(&page->list, &d->xenpage_list);
+
+    spin_unlock(&d->page_alloc_lock);
+}
+
+void share_xen_page_with_privileged_guests(
+    struct page_info *page, int readonly)
+{
+        unimplemented();
+}
+
+static ulong foreign_to_mfn(struct domain *d, ulong pfn)
+{
+
+    pfn -= 1UL << cpu_foreign_map_order();
+
+    BUG_ON(pfn >= d->arch.foreign_mfn_count);
+
+    return d->arch.foreign_mfns[pfn];
+}
+
+static int set_foreign(struct domain *d, ulong pfn, ulong mfn)
+{
+    pfn -= 1UL << cpu_foreign_map_order();
+
+    BUG_ON(pfn >= d->arch.foreign_mfn_count);
+    d->arch.foreign_mfns[pfn] = mfn;
+
+    return 0;
+}
+
+static int create_grant_va_mapping(
+    unsigned long va, unsigned long frame, struct vcpu *v)
+{
+    if (v->domain->domain_id != 0) {
+        printk("only Dom0 can map a grant entry\n");
+        BUG();
+        return GNTST_permission_denied;
+    }
+    set_foreign(v->domain, va >> PAGE_SHIFT, frame);
+    return GNTST_okay;
+}
+
+static int destroy_grant_va_mapping(
+    unsigned long addr, unsigned long frame, struct domain *d)
+{
+    if (d->domain_id != 0) {
+        printk("only Dom0 can map a grant entry\n");
+        BUG();
+        return GNTST_permission_denied;
+    }
+    set_foreign(d, addr >> PAGE_SHIFT, ~0UL);
+    return GNTST_okay;
+}
+
 int create_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned int flags)
 {
-    panic("%s called\n", __func__);
-    return 1;
+    if (flags & GNTMAP_application_map) {
+        printk("%s: GNTMAP_application_map not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+    if (flags & GNTMAP_contains_pte) {
+        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+    return create_grant_va_mapping(addr, frame, current);
 }
 
 int destroy_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned int flags)
 {
-    panic("%s called\n", __func__);
-    return 1;
+    if (flags & GNTMAP_contains_pte) {
+        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+
+    /* may have force the remove here */
+    return destroy_grant_va_mapping(addr, frame, current->domain);
 }
 
 int steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
@@ -139,7 +250,7 @@ int get_page_type(struct page_info *page
         {
             return 0;
         }
-        if ( unlikely(!(x & PGT_validated)) )
+        else if ( unlikely(!(x & PGT_validated)) )
         {
             /* Someone else is updating validation of this page. Wait... */
             while ( (y = page->u.inuse.type_info) == x )
@@ -158,25 +269,6 @@ int get_page_type(struct page_info *page
     return 1;
 }
 
-void __init init_frametable(void)
-{
-    unsigned long p;
-    unsigned long nr_pages;
-    int i;
-
-    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
-    nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT)));
-    
-
-    p = alloc_boot_pages(nr_pages, 1);
-    if (p == 0)
-        panic("Not enough memory for frame table\n");
-
-    frame_table = (struct page_info *)(p << PAGE_SHIFT);
-    for (i = 0; i < nr_pages; i += 1)
-        clear_page((void *)((p + i) << PAGE_SHIFT));
-}
-
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 {
     printk("%s: no PPC specific memory ops\n", __func__);
@@ -185,29 +277,28 @@ long arch_memory_op(int op, XEN_GUEST_HA
 
 extern void copy_page(void *dp, void *sp)
 {
-    if (on_mambo()) {
-        extern void *mambo_memcpy(void *,const void *,__kernel_size_t);
-        mambo_memcpy(dp, sp, PAGE_SIZE);
+    if (on_systemsim()) {
+        systemsim_memcpy(dp, sp, PAGE_SIZE);
     } else {
         memcpy(dp, sp, PAGE_SIZE);
     }
 }
 
+/* XXX should probably replace with faster data structure */
 static uint add_extent(struct domain *d, struct page_info *pg, uint order)
 {
     struct page_extents *pe;
 
     pe = xmalloc(struct page_extents);
     if (pe == NULL)
-        return 0;
+        return -ENOMEM;
 
     pe->pg = pg;
     pe->order = order;
-    pe->pfn = page_to_mfn(pg);
 
     list_add_tail(&pe->pe_list, &d->arch.extent_list);
 
-    return pe->pfn;
+    return 0;
 }
 
 void free_extents(struct domain *d)
@@ -246,7 +337,7 @@ uint allocate_extents(struct domain *d, 
         if (pg == NULL)
             return total_nrpages;
 
-        if (add_extent(d, pg, ext_order) == 0) {
+        if (add_extent(d, pg, ext_order) < 0) {
             free_domheap_pages(pg, ext_order);
             return total_nrpages;
         }
@@ -299,13 +390,13 @@ int allocate_rma(struct domain *d, unsig
 
     return 0;
 }
+
 void free_rma_check(struct page_info *page)
 {
     if (test_bit(_PGC_page_RMA, &page->count_info) &&
         !test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags))
         panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
 }
-
 
 ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
 {
@@ -314,9 +405,17 @@ ulong pfn2mfn(struct domain *d, ulong pf
     struct page_extents *pe;
     ulong mfn = INVALID_MFN;
     int t = PFN_TYPE_NONE;
+    ulong foreign_map_pfn = 1UL << cpu_foreign_map_order();
 
     /* quick tests first */
-    if (d->is_privileged && cpu_io_mfn(pfn)) {
+    if (pfn & foreign_map_pfn) {
+        t = PFN_TYPE_FOREIGN;
+        mfn = foreign_to_mfn(d, pfn);
+    } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) {
+        /* Its a grant table access */
+        t = PFN_TYPE_GNTTAB;
+        mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
+    } else if (d->is_privileged && cpu_io_mfn(pfn)) {
         t = PFN_TYPE_IO;
         mfn = pfn;
     } else {
@@ -324,17 +423,32 @@ ulong pfn2mfn(struct domain *d, ulong pf
             t = PFN_TYPE_RMA;
             mfn = pfn + rma_base_mfn;
         } else {
+            ulong cur_pfn = rma_size_mfn;
+
             list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
-                uint end_pfn = pe->pfn + (1 << pe->order);
-
-                if (pfn >= pe->pfn && pfn < end_pfn) {
+                uint pe_pages = 1UL << pe->order;
+                uint end_pfn = cur_pfn + pe_pages;
+
+                if (pfn >= cur_pfn && pfn < end_pfn) {
                     t = PFN_TYPE_LOGICAL;
-                    mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
+                    mfn = page_to_mfn(pe->pg) + (pfn - cur_pfn);
                     break;
                 }
+                cur_pfn += pe_pages;
             }
         }
-        BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d);
+#ifdef DEBUG
+        if (t != PFN_TYPE_NONE &&
+            (d->domain_flags & DOMF_dying) &&
+            page_get_owner(mfn_to_page(mfn)) != d) {
+            printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
+                   __func__, t,
+                   page_get_owner(mfn_to_page(mfn))->domain_id,
+                   page_get_owner(mfn_to_page(mfn)),
+                   d->domain_id, d);
+            BUG();
+        }
+#endif
     }
 
     if (t == PFN_TYPE_NONE) {
@@ -368,6 +482,42 @@ ulong pfn2mfn(struct domain *d, ulong pf
     return mfn;
 }
 
+unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
+{
+    struct page_extents *pe;
+    ulong cur_pfn;
+    ulong gnttab_mfn;
+    ulong rma_mfn;
+
+    /* grant? */
+    gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0);
+    if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES))
+        return max_page + (mfn - gnttab_mfn);
+
+    /* IO? */
+    if (d->is_privileged && cpu_io_mfn(mfn))
+        return mfn;
+
+    rma_mfn = page_to_mfn(d->arch.rma_page);
+    if (mfn >= rma_mfn &&
+        mfn < (rma_mfn + (1 << d->arch.rma_order)))
+        return mfn - rma_mfn;
+
+    /* Extent? */
+    cur_pfn = 1UL << d->arch.rma_order;
+    list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
+        uint pe_pages = 1UL << pe->order;
+        uint b_mfn = page_to_mfn(pe->pg);
+        uint e_mfn = b_mfn + pe_pages;
+
+        if (mfn >= b_mfn && mfn < e_mfn) {
+            return cur_pfn + (mfn - b_mfn);
+        }
+        cur_pfn += pe_pages;
+    }
+    return INVALID_M2P_ENTRY;
+}
+
 void guest_physmap_add_page(
     struct domain *d, unsigned long gpfn, unsigned long mfn)
 {
@@ -382,3 +532,10 @@ void shadow_drop_references(
     struct domain *d, struct page_info *page)
 {
 }
+
+int arch_domain_add_extent(struct domain *d, struct page_info *page, int order)
+{
+    if (add_extent(d, page, order) < 0)
+        return -ENOMEM;
+    return 0;
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mpic.c
--- a/xen/arch/powerpc/mpic.c   Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mpic.c   Fri Dec 15 11:32:58 2006 -0700
@@ -15,22 +15,18 @@
 /* XXX Xen hacks ... */
 /* make this generic */
 
-#define le32_to_cpu(x) \
-({ \
-       __u32 __x = (x); \
-       ((__u32)( \
-               (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
-               (((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) | \
-               (((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) | \
-               (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-})
+#define le32_to_cpu(x)                                          \
+    ({                                                          \
+        __u32 __x = (x);                                        \
+        ((__u32)(                                               \
+             (((__u32)(__x) & (__u32)0x000000ffUL) << 24) |     \
+             (((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) |     \
+             (((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) |     \
+             (((__u32)(__x) & (__u32)0xff000000UL) >> 24) ));   \
+    })
 
 
 #define alloc_bootmem(x) xmalloc_bytes(x)
-#define request_irq(irq, handler, f, devname, dev_id) \
-    panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
-
-typedef int irqreturn_t;
 
 #define IRQ_NONE       (0)
 #define IRQ_HANDLED    (1)
@@ -97,11 +93,6 @@ typedef int irqreturn_t;
 #include <asm/mpic.h>
 #include <asm/smp.h>
 
-static inline void smp_message_recv(int msg, struct pt_regs *regs)
-{
-    return;
-}
-
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
 #else
@@ -126,7 +117,7 @@ static DEFINE_SPINLOCK(mpic_lock);
 
 
 static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
-                           unsigned int reg)
+                             unsigned int reg)
 {
        if (be)
                return in_be32(base + (reg >> 2));
@@ -135,7 +126,7 @@ static inline u32 _mpic_read(unsigned in
 }
 
 static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
-                             unsigned int reg, u32 value)
+                               unsigned int reg, u32 value)
 {
        if (be)
                out_be32(base + (reg >> 2), value);
@@ -186,17 +177,17 @@ static inline u32 _mpic_irq_read(struct 
        unsigned int    idx = src_no & mpic->isu_mask;
 
        return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
-                         reg + (idx * MPIC_IRQ_STRIDE));
+                      reg + (idx * MPIC_IRQ_STRIDE));
 }
 
 static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
-                                  unsigned int reg, u32 value)
+                                   unsigned int reg, u32 value)
 {
        unsigned int    isu = src_no >> mpic->isu_shift;
        unsigned int    idx = src_no & mpic->isu_mask;
 
        _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
-                   reg + (idx * MPIC_IRQ_STRIDE), value);
+                reg + (idx * MPIC_IRQ_STRIDE), value);
 }
 
 #define mpic_read(b,r)         _mpic_read(mpic->flags & 
MPIC_BIG_ENDIAN,(b),(r))
@@ -261,7 +252,7 @@ static inline void mpic_ht_end_irq(struc
 }
 
 static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
-                                     unsigned int irqflags)
+                                      unsigned int irqflags)
 {
        struct mpic_irq_fixup *fixup = &mpic->fixups[source];
        unsigned long flags;
@@ -284,7 +275,7 @@ static void mpic_startup_ht_interrupt(st
 }
 
 static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
-                                      unsigned int irqflags)
+                                       unsigned int irqflags)
 {
        struct mpic_irq_fixup *fixup = &mpic->fixups[source];
        unsigned long flags;
@@ -305,7 +296,7 @@ static void mpic_shutdown_ht_interrupt(s
 }
 
 static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
-                                   unsigned int devfn, u32 vdid)
+                                    unsigned int devfn, u32 vdid)
 {
        int i, irq, n;
        u8 __iomem *base;
@@ -485,8 +476,8 @@ static void mpic_enable_irq(unsigned int
        DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
        mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
-                      ~MPIC_VECPRI_MASK);
+                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+                   ~MPIC_VECPRI_MASK);
 
        /* make sure mask gets to controller before we return to user */
        do {
@@ -532,8 +523,8 @@ static void mpic_disable_irq(unsigned in
        DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
        mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
-                      MPIC_VECPRI_MASK);
+                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+                   MPIC_VECPRI_MASK);
 
        /* make sure mask gets to controller before we return to user */
        do {
@@ -623,7 +614,7 @@ static void mpic_set_affinity(unsigned i
        cpus_and(tmp, cpumask, cpu_online_map);
 
        mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
-                      mpic_physmask(cpus_addr(tmp)[0]));       
+                   mpic_physmask(cpus_addr(tmp)[0]));  
 }
 
 
@@ -633,14 +624,14 @@ static void mpic_set_affinity(unsigned i
 
 
 struct mpic * __init mpic_alloc(unsigned long phys_addr,
-                               unsigned int flags,
-                               unsigned int isu_size,
-                               unsigned int irq_offset,
-                               unsigned int irq_count,
-                               unsigned int ipi_offset,
-                               unsigned char *senses,
-                               unsigned int senses_count,
-                               const char *name)
+                                unsigned int flags,
+                                unsigned int isu_size,
+                                unsigned int irq_offset,
+                                unsigned int irq_count,
+                                unsigned int ipi_offset,
+                                unsigned char *senses,
+                                unsigned int senses_count,
+                                const char *name)
 {
        struct mpic     *mpic;
        u32             reg;
@@ -687,8 +678,8 @@ struct mpic * __init mpic_alloc(unsigned
        /* Reset */
        if (flags & MPIC_WANTS_RESET) {
                mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
-                          mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
-                          | MPIC_GREG_GCONF_RESET);
+                   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+                   | MPIC_GREG_GCONF_RESET);
                while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
                       & MPIC_GREG_GCONF_RESET)
                        mb();
@@ -700,15 +691,15 @@ struct mpic * __init mpic_alloc(unsigned
         */
        reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
        mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
-                         >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
+                      >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
        if (isu_size == 0)
                mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
-                                    >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
+                             >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
 
        /* Map the per-CPU registers */
        for (i = 0; i < mpic->num_cpus; i++) {
                mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
-                                          i * MPIC_CPU_STRIDE, 0x1000);
+                                   i * MPIC_CPU_STRIDE, 0x1000);
                BUG_ON(mpic->cpuregs[i] == NULL);
        }
 
@@ -716,7 +707,7 @@ struct mpic * __init mpic_alloc(unsigned
        if (mpic->isu_size == 0) {
                mpic->isu_size = mpic->num_sources;
                mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
-                                       MPIC_IRQ_STRIDE * mpic->isu_size);
+                                MPIC_IRQ_STRIDE * mpic->isu_size);
                BUG_ON(mpic->isus[0] == NULL);
        }
        mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -752,7 +743,7 @@ struct mpic * __init mpic_alloc(unsigned
 }
 
 void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
-                           unsigned long phys_addr)
+                            unsigned long phys_addr)
 {
        unsigned int isu_first = isu_num * mpic->isu_size;
 
@@ -764,7 +755,7 @@ void __init mpic_assign_isu(struct mpic 
 }
 
 void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
-                              void *data)
+                               void *data)
 {
        struct mpic *mpic = mpic_find(irq, NULL);
        unsigned long flags;
@@ -799,20 +790,20 @@ void __init mpic_init(struct mpic *mpic)
        /* Initialize timers: just disable them all */
        for (i = 0; i < 4; i++) {
                mpic_write(mpic->tmregs,
-                          i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
                mpic_write(mpic->tmregs,
-                          i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
-                          MPIC_VECPRI_MASK |
-                          (MPIC_VEC_TIMER_0 + i));
+                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+                   MPIC_VECPRI_MASK |
+                   (MPIC_VEC_TIMER_0 + i));
        }
 
        /* Initialize IPIs to our reserved vectors and mark them disabled for 
now */
        mpic_test_broken_ipi(mpic);
        for (i = 0; i < 4; i++) {
                mpic_ipi_write(i,
-                              MPIC_VECPRI_MASK |
-                              (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
-                              (MPIC_VEC_IPI_0 + i));
+                       MPIC_VECPRI_MASK |
+                       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
+                       (MPIC_VEC_IPI_0 + i));
 #ifdef CONFIG_SMP
                if (!(mpic->flags & MPIC_PRIMARY))
                        continue;
@@ -859,7 +850,7 @@ void __init mpic_init(struct mpic *mpic)
 #ifdef CONFIG_MPIC_BROKEN_U3
                        if (mpic_is_ht_interrupt(mpic, i)) {
                                vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
-                                           MPIC_VECPRI_POLARITY_MASK);
+                            MPIC_VECPRI_POLARITY_MASK);
                                vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
                        }
 #else
@@ -873,7 +864,7 @@ void __init mpic_init(struct mpic *mpic)
                /* init hw */
                mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
                mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-                              1 << hard_smp_processor_id());
+                       1 << hard_smp_processor_id());
 
                /* init linux descriptors */
                if (i < mpic->irq_count) {
@@ -887,8 +878,8 @@ void __init mpic_init(struct mpic *mpic)
 
        /* Disable 8259 passthrough */
        mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
-                  mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
-                  | MPIC_GREG_GCONF_8259_PTHROU_DIS);
+               mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+               | MPIC_GREG_GCONF_8259_PTHROU_DIS);
 
        /* Set current processor priority to 0 */
        mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
@@ -908,12 +899,12 @@ void mpic_irq_set_priority(unsigned int 
                reg = mpic_ipi_read(irq - mpic->ipi_offset) &
                        ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_ipi_write(irq - mpic->ipi_offset,
-                              reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
        } else {
                reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
                        & ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
-                              reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
        }
        spin_unlock_irqrestore(&mpic_lock, flags);
 }
@@ -956,7 +947,7 @@ void mpic_setup_this_cpu(void)
        if (distribute_irqs) {
                for (i = 0; i < mpic->num_sources ; i++)
                        mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-                               mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+                           mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
        }
 
        /* Set current processor priority to 0 */
@@ -1001,7 +992,7 @@ void mpic_teardown_this_cpu(int secondar
        /* let the mpic know we don't want intrs.  */
        for (i = 0; i < mpic->num_sources ; i++)
                mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-                       mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+                       mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
 
        /* Set current processor priority to max */
        mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
@@ -1021,7 +1012,7 @@ void mpic_send_ipi(unsigned int ipi_no, 
 #endif
 
        mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
-                      mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+                   mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
 }
 
 int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
@@ -1049,7 +1040,7 @@ int mpic_get_one_irq(struct mpic *mpic, 
                return irq + mpic->irq_offset;
        }
 #ifdef DEBUG_IPI
-               DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
+    DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
 #endif
        return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
 }
@@ -1075,13 +1066,13 @@ void mpic_request_ipis(void)
 
        /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
        request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
-                   "IPI0 (call function)", mpic);
+                "IPI0 (call function)", mpic);
        request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
-                  "IPI1 (reschedule)", mpic);
+                "IPI1 (reschedule)", mpic);
        request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
-                  "IPI2 (unused)", mpic);
+                "IPI2 (unused)", mpic);
        request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
-                  "IPI3 (debugger break)", mpic);
+                "IPI3 (debugger break)", mpic);
 
        printk("IPIs requested... \n");
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mpic_init.c
--- a/xen/arch/powerpc/mpic_init.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mpic_init.c      Fri Dec 15 11:32:58 2006 -0700
@@ -22,6 +22,7 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <asm/mpic.h>
+#include <errno.h>
 #include "mpic_init.h"
 #include "oftree.h"
 #include "of-devtree.h"
@@ -74,7 +75,7 @@ static unsigned long reg2(void *oft_p, o
     rc = ofd_getprop(oft_p, c, "reg", &isa_reg, sizeof(isa_reg));
 
     DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
-                    isa_reg.address, isa_reg.size);
+        isa_reg.address, isa_reg.size);
     return isa_reg.address;
 }
 
@@ -92,7 +93,7 @@ static unsigned long reg1(void *oft_p, o
     rc = ofd_getprop(oft_p, c, "reg", &reg, sizeof(reg));
 
     DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
-                        reg.address, reg.size);
+        reg.address, reg.size);
     return reg.address;
 }
 
@@ -173,15 +174,15 @@ static unsigned long find_ranges_addr_fr
         break;
     case 2:
         ranges_addr = (((u64)ranges[ranges_i]) << 32) |
-                      ranges[ranges_i + 1];
+            ranges[ranges_i + 1];
         break;
     case 3:  /* the G5 case, how to squeeze 96 bits into 64 */
         ranges_addr = (((u64)ranges[ranges_i+1]) << 32) |
-                      ranges[ranges_i + 2];
+            ranges[ranges_i + 2];
         break;
     case 4:
         ranges_addr = (((u64)ranges[ranges_i+2]) << 32) |
-                      ranges[ranges_i + 4];
+            ranges[ranges_i + 4];
         break;
     default:
         PANIC("#address-cells out of range\n");
@@ -266,7 +267,7 @@ static int find_mpic_canonical_probe(voi
      * We select the one without an 'interrupt' property.
      */
     c = ofd_node_find_by_prop(oft_p, OFD_ROOT, "device_type", mpic_type,
-                                        sizeof(mpic_type));
+                              sizeof(mpic_type));
     while (c > 0) {
         int int_len;
         int good_mpic;
@@ -357,6 +358,42 @@ static struct hw_interrupt_type *share_m
 #define share_mpic(M,X) (M)
 
 #endif
+
+static unsigned int mpic_startup_ipi(unsigned int irq)
+{
+    mpic->hc_ipi.enable(irq);
+    return 0;
+}
+
+int request_irq(unsigned int irq,
+                irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
+                unsigned long irqflags, const char * devname, void *dev_id)
+{
+    int retval;
+    struct irqaction *action;
+    void (*func)(int, void *, struct cpu_user_regs *);
+
+    action = xmalloc(struct irqaction);
+    if (!action) {
+        BUG();
+        return -ENOMEM;
+    }
+
+    /* Xen's handler prototype is slightly different than Linux's.  */
+    func = (void (*)(int, void *, struct cpu_user_regs *))handler;
+
+    action->handler = func;
+    action->name = devname;
+    action->dev_id = dev_id;
+
+    retval = setup_irq(irq, action);
+    if (retval) {
+        BUG();
+        xfree(action);
+    }
+
+    return retval;
+}
 
 struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
 {
@@ -397,6 +434,11 @@ struct hw_interrupt_type *xen_mpic_init(
     hit = share_mpic(&mpic->hc_irq, xen_irq);
 
     printk("%s: success\n", __func__);
+
+    mpic->hc_ipi.ack = xen_irq->ack;
+    mpic->hc_ipi.startup = mpic_startup_ipi;
+    mpic_request_ipis();
+
     return hit;
 }
 
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/numa.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/numa.c   Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,1 @@
+#include "../x86/numa.c"
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of-devtree.h
--- a/xen/arch/powerpc/of-devtree.h     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of-devtree.h     Fri Dec 15 11:32:58 2006 -0700
@@ -33,15 +33,15 @@ union of_pci_hi {
 union of_pci_hi {
     u32 word;
     struct {
-        u32    opa_n: 1; /* relocatable */
-        u32    opa_p: 1; /* prefetchable */
-        u32    opa_t: 1; /* aliased */
+        u32 opa_n: 1; /* relocatable */
+        u32 opa_p: 1; /* prefetchable */
+        u32 opa_t: 1; /* aliased */
         u32 _opa_res: 3;
-        u32    opa: 2; /* space code */
+        u32 opa: 2; /* space code */
         u32  opa_b: 8; /* bus number */
-        u32    opa_d: 5; /* device number */
-        u32    opa_f: 3; /* function number */
-        u32    opa_r: 8; /* register number */
+        u32 opa_d: 5; /* device number */
+        u32 opa_f: 3; /* function number */
+        u32 opa_r: 8; /* register number */
     } bits;
 };
 
@@ -79,9 +79,9 @@ typedef s32 ofdn_t;
 typedef s32 ofdn_t;
 
 #define OFD_ROOT 1
-#define OFD_DUMP_NAMES 0x1
-#define OFD_DUMP_VALUES        0x2
-#define OFD_DUMP_ALL   (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
+#define OFD_DUMP_NAMES 0x1
+#define OFD_DUMP_VALUES 0x2
+#define OFD_DUMP_ALL (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
 
 extern void *ofd_create(void *mem, size_t sz);
 extern ofdn_t ofd_node_parent(void *mem, ofdn_t n);
@@ -90,9 +90,9 @@ extern const char *ofd_node_path(void *m
 extern const char *ofd_node_path(void *mem, ofdn_t p);
 extern int ofd_node_to_path(void *mem, ofdn_t p, void *buf, size_t sz);
 extern ofdn_t ofd_node_child_create(void *mem, ofdn_t parent,
-                                   const char *path, size_t pathlen);
+                                    const char *path, size_t pathlen);
 extern ofdn_t ofd_node_peer_create(void *mem, ofdn_t sibling,
-                                  const char *path, size_t pathlen);
+                                   const char *path, size_t pathlen);
 extern ofdn_t ofd_node_find(void *mem, const char *devspec);
 extern ofdn_t ofd_node_add(void *m, ofdn_t n, const char *path, size_t sz);
 extern int ofd_node_prune(void *m, ofdn_t n);
@@ -102,23 +102,23 @@ extern ofdn_t ofd_nextprop(void *mem, of
 extern ofdn_t ofd_nextprop(void *mem, ofdn_t n, const char *prev, char *name);
 extern ofdn_t ofd_prop_find(void *mem, ofdn_t n, const char *name);
 extern int ofd_getprop(void *mem, ofdn_t n, const char *name,
-                       void *buf, size_t sz);
+                       void *buf, size_t sz);
 extern int ofd_getproplen(void *mem, ofdn_t n, const char *name);
 
 extern int ofd_setprop(void *mem, ofdn_t n, const char *name,
-                       const void *buf, size_t sz);
+                       const void *buf, size_t sz);
 extern void ofd_prop_remove(void *mem, ofdn_t node, ofdn_t prop);
 extern ofdn_t ofd_prop_add(void *mem, ofdn_t n, const char *name,
-                          const void *buf, size_t sz);
+                           const void *buf, size_t sz);
 extern ofdn_t ofd_io_create(void *m, ofdn_t node, u64 open);
 extern u32 ofd_io_open(void *mem, ofdn_t n);
 extern void ofd_io_close(void *mem, ofdn_t n);
 
 
-typedef void (*walk_fn)(void *m, ofdn_t p, int arg);
-extern void ofd_dump_props(void *m, ofdn_t p, int dump);
+typedef void (*walk_fn)(void *m, const char *pre, ofdn_t p, int arg);
+extern void ofd_dump_props(void *m, const char *pre, ofdn_t p, int dump);
 
-extern void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg);
+extern void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg);
 
 
 /* Recursively look up #address_cells and #size_cells properties */
@@ -129,10 +129,10 @@ extern size_t ofd_space(void *mem);
 extern size_t ofd_space(void *mem);
 
 extern void ofd_prop_print(const char *head, const char *path,
-                          const char *name, const char *prop, size_t sz);
+                           const char *name, const char *prop, size_t sz);
 
 extern ofdn_t ofd_node_find_by_prop(void *mem, ofdn_t n, const char *name,
-                                   const void *val, size_t sz);
+                                    const void *val, size_t sz);
 extern ofdn_t ofd_node_find_next(void *mem, ofdn_t n);
 extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n);
 extern void ofd_init(int (*write)(const char *, size_t len));
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of-devwalk.c
--- a/xen/arch/powerpc/of-devwalk.c     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of-devwalk.c     Fri Dec 15 11:32:58 2006 -0700
@@ -80,7 +80,7 @@ void ofd_prop_print(
 #endif
 }
 
-void ofd_dump_props(void *mem, ofdn_t n, int dump)
+void ofd_dump_props(void *mem, const char *pre, ofdn_t n, int dump)
 {
     ofdn_t p;
     char name[128];
@@ -95,7 +95,7 @@ void ofd_dump_props(void *mem, ofdn_t n,
     }
 
     if (dump & OFD_DUMP_NAMES) {
-        printk("of_walk: %s: phandle 0x%x\n", path, n);
+        printk("%s: %s: phandle 0x%x\n", pre, path, n);
     }
 
     p = ofd_nextprop(mem, n, NULL, name);
@@ -106,30 +106,30 @@ void ofd_dump_props(void *mem, ofdn_t n,
         }
 
         if ( dump & OFD_DUMP_VALUES ) {
-            ofd_prop_print("of_walk", path, name, prop, sz);
+            ofd_prop_print(pre, path, name, prop, sz);
         }
 
         p = ofd_nextprop(mem, n, name, name);
     }
 }
 
-void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg)
+void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg)
 {
     ofdn_t n;
 
     if ( fn != NULL ) {
-        (*fn)(m, p, arg);
+        (*fn)(m, pre, p, arg);
     }
 
     /* child */
     n = ofd_node_child(m, p);
     if ( n != 0 ) {
-        ofd_walk(m, n, fn, arg);
+        ofd_walk(m, pre, n, fn, arg);
     }
 
     /* peer */
     n = ofd_node_peer(m, p);
     if ( n != 0 ) {
-        ofd_walk(m, n, fn, arg);
+        ofd_walk(m, pre, n, fn, arg);
     }
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of_handler/console.c
--- a/xen/arch/powerpc/of_handler/console.c     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of_handler/console.c     Fri Dec 15 11:32:58 2006 -0700
@@ -113,7 +113,7 @@ static s32 ofh_xen_dom0_read(s32 chan, v
             return ret;
 
         rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_read,
-                count, desc);
+                        count, desc);
         if (rc <= 0) {
             return ret;
         }
@@ -139,7 +139,7 @@ static s32 ofh_xen_dom0_write(s32 chan, 
             return ret;
 
         rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_write,
-                count, desc);
+                        count, desc);
         if (rc <= 0) {
             return ret;
         }
@@ -157,8 +157,8 @@ static s32 ofh_xen_domu_read(s32 chan, v
 static s32 ofh_xen_domu_read(s32 chan, void *buf, u32 count, s32 *actual,
                              ulong b)
 {
-       struct xencons_interface *intf;
-       XENCONS_RING_IDX cons, prod;
+    struct xencons_interface *intf;
+    XENCONS_RING_IDX cons, prod;
     s32 ret;
 
     intf = DRELA(ofh_ihp, b)->ofi_intf;
@@ -180,8 +180,8 @@ static s32 ofh_xen_domu_write(s32 chan, 
 static s32 ofh_xen_domu_write(s32 chan, const void *buf, u32 count,
                               s32 *actual, ulong b)
 {
-       struct xencons_interface *intf;
-       XENCONS_RING_IDX cons, prod;
+    struct xencons_interface *intf;
+    XENCONS_RING_IDX cons, prod;
     s32 ret;
 
     intf = DRELA(ofh_ihp, b)->ofi_intf;
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c      Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/ofd_fixup.c      Fri Dec 15 11:32:58 2006 -0700
@@ -25,6 +25,7 @@
 #include <public/xen.h>
 #include "of-devtree.h"
 #include "oftree.h"
+#include "rtas.h"
 
 #undef RTAS
 
@@ -347,6 +348,15 @@ static ofdn_t ofd_xen_props(void *m, str
         val[0] =  rma_size(d->arch.rma_order) - val[1];
         ofd_prop_add(m, n, "reserved", val, sizeof (val));
 
+        /* tell dom0 that Xen depends on it to have power control */
+        if (!rtas_entry)
+            ofd_prop_add(m, n, "power-control", NULL, 0);
+
+        /* tell dom0 where ranted pages go in the linear map */
+        val[0] = cpu_foreign_map_order();
+        val[1] = d->arch.foreign_mfn_count;
+        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
+
         n = ofd_node_add(m, n, console, sizeof (console));
         if (n > 0) {
             val[0] = 0;
@@ -417,7 +427,7 @@ int ofd_dom0_fixup(struct domain *d, ulo
 
 
 #ifdef DEBUG
-    ofd_walk(m, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
+    ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
 #endif
     return 1;
 }
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/ofd_fixup_memory.c
--- a/xen/arch/powerpc/ofd_fixup_memory.c       Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/ofd_fixup_memory.c       Fri Dec 15 11:32:58 2006 -0700
@@ -68,6 +68,8 @@ static ofdn_t ofd_memory_node_create(
     reg.sz = size;
     ofd_prop_add(m, n, "reg", &reg, sizeof (reg));
 
+    printk("Dom0: %s: %016lx, %016lx\n", path, start, size);
+
     return n;
 }
 
@@ -86,17 +88,19 @@ static void ofd_memory_extent_nodes(void
     ulong size;
     ofdn_t n;
     struct page_extents *pe;
+    ulong cur_pfn = 1UL << d->arch.rma_order;
 
+    start = cur_pfn << PAGE_SHIFT;
+    size = 0;
     list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
 
-        start = pe->pfn << PAGE_SHIFT;
-        size = 1UL << (pe->order + PAGE_SHIFT);
-
-        n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
-                                    start, size);
-
-        BUG_ON(n <= 0);
+        size += 1UL << (pe->order + PAGE_SHIFT);
+        if (pe->order != cpu_extent_order())
+            panic("we don't handle this yet\n");
     }
+    n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
+                               start, size);
+    BUG_ON(n <= 0);
 }
 
 void ofd_memory_props(void *m, struct domain *d)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/papr/xlate.c
--- a/xen/arch/powerpc/papr/xlate.c     Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/papr/xlate.c     Fri Dec 15 11:32:58 2006 -0700
@@ -19,7 +19,7 @@
  */
 
 #undef DEBUG
-#undef DEBUG_FAIL
+#undef DEBUG_LOW
 
 #include <xen/config.h>
 #include <xen/types.h>
@@ -30,6 +30,17 @@
 #include <asm/papr.h>
 #include <asm/hcalls.h>
 
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) printk(fmt)
+#else
+#define DBG_LOW(fmt...)
+#endif
+
 #ifdef USE_PTE_INSERT
 static inline void pte_insert(union pte volatile *pte,
         ulong vsid, ulong rpn, ulong lrpn)
@@ -106,11 +117,8 @@ static void pte_tlbie(union pte volatile
 
 }
 
-static void h_enter(struct cpu_user_regs *regs)
-{
-    ulong flags = regs->gprs[4];
-    ulong ptex = regs->gprs[5];
-
+long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
+{
     union pte pte;
     union pte volatile *ppte;
     struct domain_htab *htab;
@@ -129,14 +137,13 @@ static void h_enter(struct cpu_user_regs
 
     htab = &d->arch.htab;
     if (ptex > (1UL << htab->log_num_ptes)) {
-        regs->gprs[3] = H_Parameter;
-        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
-        return;
+        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
+        return H_Parameter;
     }
 
     /* use local HPTE to avoid manual shifting & masking */
-    pte.words.vsid = regs->gprs[6];
-    pte.words.rpn = regs->gprs[7];
+    pte.words.vsid = vsid;
+    pte.words.rpn = rpn;
 
     if ( pte.bits.l ) {        /* large page? */
         /* figure out the page size for the selected large page */
@@ -150,10 +157,9 @@ static void h_enter(struct cpu_user_regs
         }
 
         if ( lp_size >= d->arch.large_page_sizes ) {
-            printk("%s: attempt to use unsupported lp_size %d\n",
-                   __func__, lp_size);
-            regs->gprs[3] = H_Parameter;
-            return;
+            DBG("%s: attempt to use unsupported lp_size %d\n",
+                __func__, lp_size);
+            return H_Parameter;
         }
 
         /* get correct pgshift value */
@@ -168,31 +174,32 @@ static void h_enter(struct cpu_user_regs
 
     mfn = pfn2mfn(d, pfn, &mtype);
     if (mfn == INVALID_MFN) {
-        regs->gprs[3] =  H_Parameter;
-        return;
-    }
-
+        DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn);
+        return H_Parameter;
+    }
+
+    if (mtype == PFN_TYPE_IO && !d->is_privileged) {
+        /* only a privilaged dom can access outside IO space */
+        DBG("%s: unprivileged access to physical page: 0x%lx\n",
+            __func__, pfn);
+        return H_Privilege;
+    }
     if (mtype == PFN_TYPE_IO) {
-        /* only a privilaged dom can access outside IO space */
-        if ( !d->is_privileged ) {
-            regs->gprs[3] =  H_Privilege;
-            printk("%s: unprivileged access to physical page: 0x%lx\n",
-                   __func__, pfn);
-            return;
-        }
-
         if ( !((pte.bits.w == 0)
              && (pte.bits.i == 1)
              && (pte.bits.g == 1)) ) {
-#ifdef DEBUG_FAIL
-            printk("%s: expecting an IO WIMG "
-                   "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
-                   pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
-                   pte.words.rpn);
-#endif
-            regs->gprs[3] =  H_Parameter;
-            return;
-        }
+            DBG("%s: expecting an IO WIMG "
+                "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
+                pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
+                pte.words.rpn);
+            return H_Parameter;
+        }
+    }
+    if (mtype == PFN_TYPE_GNTTAB) {
+        DBG("%s: Dom[%d] mapping grant table: 0x%lx\n",
+            __func__, d->domain_id, pfn << PAGE_SHIFT);
+        pte.bits.i = 0;
+        pte.bits.g = 0;
     }
     /* fixup the RPN field of our local PTE copy */
     pte.bits.rpn = mfn | lp_bits;
@@ -213,13 +220,13 @@ static void h_enter(struct cpu_user_regs
         BUG_ON(f == d);
 
         if (unlikely(!get_domain(f))) {
-            regs->gprs[3] = H_Rescinded;
-            return;
+            DBG("%s: Rescinded, no domain: 0x%lx\n",  __func__, pfn);
+            return H_Rescinded;
         }
         if (unlikely(!get_page(pg, f))) {
             put_domain(f);
-            regs->gprs[3] = H_Rescinded;
-            return;
+            DBG("%s: Rescinded, no page: 0x%lx\n",  __func__, pfn);
+            return H_Rescinded;
         }
     }
 
@@ -276,17 +283,12 @@ static void h_enter(struct cpu_user_regs
                 : "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid)
                 : "memory");
 
-            regs->gprs[3] = H_Success;
-            regs->gprs[4] = idx;
-
-            return;
-        }
-    }
-
-#ifdef DEBUG
+            return idx;
+        }
+    }
+
     /* If the PTEG is full then no additional values are returned. */
-    printk("%s: PTEG FULL\n", __func__);
-#endif
+    DBG("%s: PTEG FULL\n", __func__);
 
     if (pg != NULL)
         put_page(pg);
@@ -294,7 +296,24 @@ static void h_enter(struct cpu_user_regs
     if (f != NULL)
         put_domain(f);
 
-    regs->gprs[3] = H_PTEG_Full;
+    return H_PTEG_Full;
+}
+
+static void h_enter(struct cpu_user_regs *regs)
+{
+    ulong flags = regs->gprs[4];
+    ulong ptex = regs->gprs[5];
+    ulong vsid = regs->gprs[6];
+    ulong rpn = regs->gprs[7];
+    long ret;
+
+    ret = pte_enter(flags, ptex, vsid, rpn);
+
+    if (ret >= 0) {
+        regs->gprs[3] = H_Success;
+        regs->gprs[4] = ret;
+    } else
+        regs->gprs[3] = ret;
 }
 
 static void h_protect(struct cpu_user_regs *regs)
@@ -308,13 +327,11 @@ static void h_protect(struct cpu_user_re
     union pte volatile *ppte;

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

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