ia64/xen-unstable

changeset 13104:e17d7438e09e

merge with xen-ia64-unstable.hg
author awilliam@xenbuild2.aw
date Fri Dec 15 11:32:58 2006 -0700 (2006-12-15)
parents 1e042dde1a5f 41d9f00140c5
children baa07859f24f
files tools/libxen/include/xen_boot_type.h tools/libxen/include/xen_boot_type_internal.h tools/libxen/src/xen_boot_type.c xen/arch/powerpc/boot/boot32.S xen/arch/powerpc/boot/start.S xen/arch/powerpc/delay.c xen/arch/powerpc/mambo.S xen/include/asm-powerpc/misc.h xen/include/asm-powerpc/uaccess.h
line diff
     1.1 --- a/.hgignore	Fri Dec 15 10:59:33 2006 -0700
     1.2 +++ b/.hgignore	Fri Dec 15 11:32:58 2006 -0700
     1.3 @@ -53,6 +53,8 @@
     1.4  ^docs/user/labels\.pl$
     1.5  ^docs/user/user\.css$
     1.6  ^docs/user/user\.html$
     1.7 +^docs/xen-api/vm_lifecycle.eps$
     1.8 +^docs/xen-api/xenapi-datamodel-graph.eps$
     1.9  ^extras/mini-os/h/hypervisor-ifs$
    1.10  ^extras/mini-os/h/xen-public$
    1.11  ^extras/mini-os/mini-os\..*$
    1.12 @@ -98,17 +100,15 @@
    1.13  ^tools/firmware/.*\.bin$
    1.14  ^tools/firmware/.*\.sym$
    1.15  ^tools/firmware/.*bios/.*bios.*\.txt$
    1.16 +^tools/firmware/hvmloader/acpi/acpigen$
    1.17  ^tools/firmware/hvmloader/hvmloader$
    1.18  ^tools/firmware/hvmloader/roms\.h$
    1.19  ^tools/firmware/rombios/BIOS-bochs-[^/]*$
    1.20  ^tools/firmware/rombios/_rombios[^/]*_\.c$
    1.21  ^tools/firmware/rombios/rombios[^/]*\.s$
    1.22 -^tools/firmware/vmxassist/acpi\.h$
    1.23  ^tools/firmware/vmxassist/gen$
    1.24  ^tools/firmware/vmxassist/offsets\.h$
    1.25 -^tools/firmware/vmxassist/roms\.h$
    1.26  ^tools/firmware/vmxassist/vmxassist$
    1.27 -^tools/firmware/vmxassist/vmxloader$
    1.28  ^tools/ioemu/\.pc/.*$
    1.29  ^tools/ioemu/config-host\.h$
    1.30  ^tools/ioemu/config-host\.mak$
    1.31 @@ -220,10 +220,11 @@
    1.32  ^xen/arch/powerpc/dom0\.bin$
    1.33  ^xen/arch/powerpc/asm-offsets\.s$
    1.34  ^xen/arch/powerpc/firmware$
    1.35 -^xen/arch/powerpc/firmware_image$
    1.36 +^xen/arch/powerpc/firmware_image.bin$
    1.37  ^xen/arch/powerpc/xen\.lds$
    1.38 -^xen/arch/powerpc/.xen-syms$
    1.39 -^xen/arch/powerpc/xen-syms.S$
    1.40 +^xen/arch/powerpc/\.xen-syms$
    1.41 +^xen/arch/powerpc/xen-syms\.S$
    1.42 +^xen/arch/powerpc/cmdline.dep$
    1.43  ^unmodified_drivers/linux-2.6/\.tmp_versions
    1.44  ^unmodified_drivers/linux-2.6/.*\.cmd$
    1.45  ^unmodified_drivers/linux-2.6/.*\.ko$
     2.1 --- a/config/powerpc64.mk	Fri Dec 15 10:59:33 2006 -0700
     2.2 +++ b/config/powerpc64.mk	Fri Dec 15 11:32:58 2006 -0700
     2.3 @@ -1,5 +1,7 @@
     2.4  CONFIG_POWERPC := y
     2.5  CONFIG_POWERPC_$(XEN_OS) := y
     2.6  
     2.7 +CONFIG_XENCOMM := y
     2.8 +
     2.9  CFLAGS += -DELFSIZE=64
    2.10  LIBDIR := lib
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c	Fri Dec 15 10:59:33 2006 -0700
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c	Fri Dec 15 11:32:58 2006 -0700
     3.3 @@ -43,18 +43,18 @@ fastcall void do_fixup_4gb_segment(struc
     3.4  	char info[100];
     3.5  	int i;
     3.6  
     3.7 -	if (test_and_set_bit(0, &printed))
     3.8 +	/* Ignore statically-linked init. */
     3.9 +	if (current->tgid == 1)
    3.10  		return;
    3.11 -
    3.12 -        if (current->tgid == 1) /* Ignore statically linked init */
    3.13 -                return; 
    3.14              
    3.15  	HYPERVISOR_vm_assist(
    3.16  		VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
    3.17  
    3.18 +	if (test_and_set_bit(0, &printed))
    3.19 +		return;
    3.20 +
    3.21  	sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
    3.22  
    3.23 -
    3.24  	DP("");
    3.25  	DP("***************************************************************");
    3.26  	DP("***************************************************************");
     4.1 --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig	Fri Dec 15 10:59:33 2006 -0700
     4.2 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig	Fri Dec 15 11:32:58 2006 -0700
     4.3 @@ -532,6 +532,7 @@ config XEN_BALLOON
     4.4  
     4.5  config XEN_SKBUFF
     4.6  	default y
     4.7 +	depends on NET
     4.8  
     4.9  config XEN_REBOOT
    4.10  	default y
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Fri Dec 15 10:59:33 2006 -0700
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Fri Dec 15 11:32:58 2006 -0700
     5.3 @@ -110,6 +110,18 @@ set_cpu_sibling_map(int cpu)
     5.4  	cpu_data[cpu].booted_cores = 1;
     5.5  }
     5.6  
     5.7 +static void
     5.8 +remove_siblinginfo(int cpu)
     5.9 +{
    5.10 +	phys_proc_id[cpu] = BAD_APICID;
    5.11 +	cpu_core_id[cpu]  = BAD_APICID;
    5.12 +
    5.13 +	cpus_clear(cpu_sibling_map[cpu]);
    5.14 +	cpus_clear(cpu_core_map[cpu]);
    5.15 +
    5.16 +	cpu_data[cpu].booted_cores = 0;
    5.17 +}
    5.18 +
    5.19  static int xen_smp_intr_init(unsigned int cpu)
    5.20  {
    5.21  	int rc;
    5.22 @@ -358,18 +370,6 @@ static int __init initialize_cpu_present
    5.23  }
    5.24  core_initcall(initialize_cpu_present_map);
    5.25  
    5.26 -static void
    5.27 -remove_siblinginfo(int cpu)
    5.28 -{
    5.29 -	phys_proc_id[cpu] = BAD_APICID;
    5.30 -	cpu_core_id[cpu]  = BAD_APICID;
    5.31 -
    5.32 -	cpus_clear(cpu_sibling_map[cpu]);
    5.33 -	cpus_clear(cpu_core_map[cpu]);
    5.34 -
    5.35 -	cpu_data[cpu].booted_cores = 0;
    5.36 -}
    5.37 -
    5.38  int __cpu_disable(void)
    5.39  {
    5.40  	cpumask_t map = cpu_online_map;
    5.41 @@ -433,7 +433,6 @@ int __devinit __cpu_up(unsigned int cpu)
    5.42  	set_cpu_sibling_map(cpu);
    5.43  	wmb();
    5.44  
    5.45 -
    5.46  	rc = xen_smp_intr_init(cpu);
    5.47  	if (rc) {
    5.48  		remove_siblinginfo(cpu);
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c	Fri Dec 15 10:59:33 2006 -0700
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c	Fri Dec 15 11:32:58 2006 -0700
     6.3 @@ -105,7 +105,6 @@ static int xenfb_queue_full(struct xenfb
     6.4  
     6.5  static void xenfb_update_screen(struct xenfb_info *info)
     6.6  {
     6.7 -	unsigned long flags;
     6.8  	int y1, y2, x1, x2;
     6.9  	struct xenfb_mapping *map;
    6.10  
    6.11 @@ -114,7 +113,7 @@ static void xenfb_update_screen(struct x
    6.12  	if (xenfb_queue_full(info))
    6.13  		return;
    6.14  
    6.15 -	spin_lock_irqsave(&info->mm_lock, flags);
    6.16 +	spin_lock(&info->mm_lock);
    6.17  
    6.18  	y1 = info->y1;
    6.19  	y2 = info->y2;
    6.20 @@ -131,7 +130,7 @@ static void xenfb_update_screen(struct x
    6.21  		map->faults = 0;
    6.22  	}
    6.23  
    6.24 -	spin_unlock_irqrestore(&info->mm_lock, flags);
    6.25 +	spin_unlock(&info->mm_lock);
    6.26  
    6.27  	xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
    6.28  }
    6.29 @@ -214,11 +213,9 @@ static void __xenfb_refresh(struct xenfb
    6.30  static void xenfb_refresh(struct xenfb_info *info,
    6.31  			  int x1, int y1, int w, int h)
    6.32  {
    6.33 -	unsigned long flags;
    6.34 -
    6.35 -	spin_lock_irqsave(&info->mm_lock, flags);
    6.36 +	spin_lock(&info->mm_lock);
    6.37  	__xenfb_refresh(info, x1, y1, w, h);
    6.38 -	spin_unlock_irqrestore(&info->mm_lock, flags);
    6.39 +	spin_unlock(&info->mm_lock);
    6.40  }
    6.41  
    6.42  static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
    6.43 @@ -255,14 +252,13 @@ static void xenfb_vm_close(struct vm_are
    6.44  {
    6.45  	struct xenfb_mapping *map = vma->vm_private_data;
    6.46  	struct xenfb_info *info = map->info;
    6.47 -	unsigned long flags;
    6.48  
    6.49 -	spin_lock_irqsave(&info->mm_lock, flags);
    6.50 +	spin_lock(&info->mm_lock);
    6.51  	if (atomic_dec_and_test(&map->map_refs)) {
    6.52  		list_del(&map->link);
    6.53  		kfree(map);
    6.54  	}
    6.55 -	spin_unlock_irqrestore(&info->mm_lock, flags);
    6.56 +	spin_unlock(&info->mm_lock);
    6.57  }
    6.58  
    6.59  static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
    6.60 @@ -271,14 +267,13 @@ static struct page *xenfb_vm_nopage(stru
    6.61  	struct xenfb_mapping *map = vma->vm_private_data;
    6.62  	struct xenfb_info *info = map->info;
    6.63  	int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
    6.64 -	unsigned long flags;
    6.65  	struct page *page;
    6.66  	int y1, y2;
    6.67  
    6.68  	if (pgnr >= info->nr_pages)
    6.69  		return NOPAGE_SIGBUS;
    6.70  
    6.71 -	spin_lock_irqsave(&info->mm_lock, flags);
    6.72 +	spin_lock(&info->mm_lock);
    6.73  	page = info->pages[pgnr];
    6.74  	get_page(page);
    6.75  	map->faults++;
    6.76 @@ -288,7 +283,7 @@ static struct page *xenfb_vm_nopage(stru
    6.77  	if (y2 > info->fb_info->var.yres)
    6.78  		y2 = info->fb_info->var.yres;
    6.79  	__xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
    6.80 -	spin_unlock_irqrestore(&info->mm_lock, flags);
    6.81 +	spin_unlock(&info->mm_lock);
    6.82  
    6.83  	if (type)
    6.84  		*type = VM_FAULT_MINOR;
    6.85 @@ -305,7 +300,6 @@ static struct vm_operations_struct xenfb
    6.86  static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
    6.87  {
    6.88  	struct xenfb_info *info = fb_info->par;
    6.89 -	unsigned long flags;
    6.90  	struct xenfb_mapping *map;
    6.91  	int map_pages;
    6.92  
    6.93 @@ -329,9 +323,9 @@ static int xenfb_mmap(struct fb_info *fb
    6.94  	map->info = info;
    6.95  	atomic_set(&map->map_refs, 1);
    6.96  
    6.97 -	spin_lock_irqsave(&info->mm_lock, flags);
    6.98 +	spin_lock(&info->mm_lock);
    6.99  	list_add(&map->link, &info->mappings);
   6.100 -	spin_unlock_irqrestore(&info->mm_lock, flags);
   6.101 +	spin_unlock(&info->mm_lock);
   6.102  
   6.103  	vma->vm_ops = &xenfb_vm_ops;
   6.104  	vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Dec 15 10:59:33 2006 -0700
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Dec 15 11:32:58 2006 -0700
     7.3 @@ -525,6 +525,8 @@ static void backend_changed(struct xenbu
     7.4  		break;
     7.5  
     7.6  	case XenbusStateInitWait:
     7.7 +		if (dev->state != XenbusStateInitialising)
     7.8 +			break;
     7.9  		if (network_connect(netdev) != 0)
    7.10  			break;
    7.11  		xenbus_switch_state(dev, XenbusStateConnected);
    7.12 @@ -532,6 +534,8 @@ static void backend_changed(struct xenbu
    7.13  		break;
    7.14  
    7.15  	case XenbusStateClosing:
    7.16 +		if (dev->state == XenbusStateClosed)
    7.17 +			break;
    7.18  		netfront_closing(dev);
    7.19  		break;
    7.20  	}
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Dec 15 10:59:33 2006 -0700
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Dec 15 11:32:58 2006 -0700
     8.3 @@ -487,6 +487,8 @@ int xenbus_probe_node(struct xen_bus_typ
     8.4  	if (!xendev)
     8.5  		return -ENOMEM;
     8.6  
     8.7 +	xendev->state = XenbusStateInitialising;
     8.8 +
     8.9  	/* Copy the strings into the extra space. */
    8.10  
    8.11  	tmpstring = (char *)(xendev + 1);
     9.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c	Fri Dec 15 10:59:33 2006 -0700
     9.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c	Fri Dec 15 11:32:58 2006 -0700
     9.3 @@ -1875,7 +1875,7 @@ struct sk_buff *skb_segment(struct sk_bu
     9.4  	do {
     9.5  		struct sk_buff *nskb;
     9.6  		skb_frag_t *frag;
     9.7 -		int hsize, nsize;
     9.8 +		int hsize;
     9.9  		int k;
    9.10  		int size;
    9.11  
    9.12 @@ -1886,11 +1886,10 @@ struct sk_buff *skb_segment(struct sk_bu
    9.13  		hsize = skb_headlen(skb) - offset;
    9.14  		if (hsize < 0)
    9.15  			hsize = 0;
    9.16 -		nsize = hsize + doffset;
    9.17 -		if (nsize > len + doffset || !sg)
    9.18 -			nsize = len + doffset;
    9.19 +		if (hsize > len || !sg)
    9.20 +			hsize = len;
    9.21  
    9.22 -		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
    9.23 +		nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
    9.24  		if (unlikely(!nskb))
    9.25  			goto err;
    9.26  
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch	Fri Dec 15 11:32:58 2006 -0700
    10.3 @@ -0,0 +1,26 @@
    10.4 +diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c
    10.5 +--- a/net/core/skbuff.c	2006-12-14 09:32:04 -08:00
    10.6 ++++ b/net/core/skbuff.c	2006-12-14 09:32:04 -08:00
    10.7 +@@ -1946,7 +1946,7 @@
    10.8 + 	do {
    10.9 + 		struct sk_buff *nskb;
   10.10 + 		skb_frag_t *frag;
   10.11 +-		int hsize, nsize;
   10.12 ++		int hsize;
   10.13 + 		int k;
   10.14 + 		int size;
   10.15 + 
   10.16 +@@ -1957,11 +1957,10 @@
   10.17 + 		hsize = skb_headlen(skb) - offset;
   10.18 + 		if (hsize < 0)
   10.19 + 			hsize = 0;
   10.20 +-		nsize = hsize + doffset;
   10.21 +-		if (nsize > len + doffset || !sg)
   10.22 +-			nsize = len + doffset;
   10.23 ++		if (hsize > len || !sg)
   10.24 ++			hsize = len;
   10.25 + 
   10.26 +-		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
   10.27 ++		nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
   10.28 + 		if (unlikely(!nskb))
   10.29 + 			goto err;
    11.1 --- a/patches/linux-2.6.16.33/series	Fri Dec 15 10:59:33 2006 -0700
    11.2 +++ b/patches/linux-2.6.16.33/series	Fri Dec 15 11:32:58 2006 -0700
    11.3 @@ -17,6 +17,7 @@ net-gso-2-checksum-fix.patch
    11.4  net-gso-3-fix-errorcheck.patch
    11.5  net-gso-4-kill-warnon.patch
    11.6  net-gso-5-rcv-mss.patch
    11.7 +net-gso-6-linear-segmentation.patch
    11.8  pci-mmconfig-fix-from-2.6.17.patch
    11.9  pmd-shared.patch
   11.10  rcu_needs_cpu.patch
    12.1 --- a/tools/Rules.mk	Fri Dec 15 10:59:33 2006 -0700
    12.2 +++ b/tools/Rules.mk	Fri Dec 15 11:32:58 2006 -0700
    12.3 @@ -19,6 +19,10 @@ CFLAGS  += $(shell getconf LFS_CFLAGS)
    12.4  CFLAGS  += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
    12.5  LDFLAGS += $(shell getconf LFS_LDFLAGS)
    12.6  
    12.7 +# 32-bit x86 does not perform well with -ve segment accesses on Xen.
    12.8 +CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
    12.9 +CFLAGS += $(CFLAGS-y)
   12.10 +
   12.11  %.opic: %.c
   12.12  	$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
   12.13  
    13.1 --- a/tools/blktap/drivers/blktapctrl.c	Fri Dec 15 10:59:33 2006 -0700
    13.2 +++ b/tools/blktap/drivers/blktapctrl.c	Fri Dec 15 11:32:58 2006 -0700
    13.3 @@ -57,6 +57,8 @@
    13.4  #include "blktapctrl.h"
    13.5  #include "tapdisk.h"
    13.6  
    13.7 +#define PIDFILE "/var/run/blktapctrl.pid"
    13.8 +
    13.9  #define NUM_POLL_FDS 2
   13.10  #define MSG_SIZE 4096
   13.11  #define MAX_TIMEOUT 10
   13.12 @@ -622,6 +624,42 @@ static void print_drivers(void)
   13.13  		DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
   13.14  } 
   13.15  
   13.16 +static void write_pidfile(long pid)
   13.17 +{
   13.18 +	char buf[100];
   13.19 +	int len;
   13.20 +	int fd;
   13.21 +	int flags;
   13.22 +
   13.23 +	fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);
   13.24 +	if (fd == -1) {
   13.25 +		DPRINTF("Opening pid file failed (%d)\n", errno);
   13.26 +		exit(1);
   13.27 +	}
   13.28 +
   13.29 +	/* We exit silently if daemon already running. */
   13.30 +	if (lockf(fd, F_TLOCK, 0) == -1)
   13.31 +		exit(0);
   13.32 +
   13.33 +	/* Set FD_CLOEXEC, so that tapdisk doesn't get this file
   13.34 +	   descriptor. */
   13.35 +	if ((flags = fcntl(fd, F_GETFD)) == -1) {
   13.36 +		DPRINTF("F_GETFD failed (%d)\n", errno);
   13.37 +		exit(1);
   13.38 +	}
   13.39 +	flags |= FD_CLOEXEC;
   13.40 +	if (fcntl(fd, F_SETFD, flags) == -1) {
   13.41 +		DPRINTF("F_SETFD failed (%d)\n", errno);
   13.42 +		exit(1);
   13.43 +	}
   13.44 +
   13.45 +	len = sprintf(buf, "%ld\n", pid);
   13.46 +	if (write(fd, buf, len) != len) {
   13.47 +		DPRINTF("Writing pid file failed (%d)\n", errno);
   13.48 +		exit(1);
   13.49 +	}
   13.50 +}
   13.51 +
   13.52  int main(int argc, char *argv[])
   13.53  {
   13.54  	char *devname;
   13.55 @@ -681,6 +719,7 @@ int main(int argc, char *argv[])
   13.56  	ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
   13.57  
   13.58  	process = getpid();
   13.59 +	write_pidfile(process);
   13.60  	ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );
   13.61  
   13.62  	/*Static pollhooks*/
   13.63 @@ -716,3 +755,13 @@ int main(int argc, char *argv[])
   13.64  	closelog();
   13.65  	return -1;
   13.66  }
   13.67 +
   13.68 +/*
   13.69 + * Local variables:
   13.70 + *  c-file-style: "linux"
   13.71 + *  indent-tabs-mode: t
   13.72 + *  c-indent-level: 8
   13.73 + *  c-basic-offset: 8
   13.74 + *  tab-width: 8
   13.75 + * End:
   13.76 + */
    14.1 --- a/tools/blktap/drivers/block-qcow.c	Fri Dec 15 10:59:33 2006 -0700
    14.2 +++ b/tools/blktap/drivers/block-qcow.c	Fri Dec 15 11:32:58 2006 -0700
    14.3 @@ -74,8 +74,9 @@ struct pending_aio {
    14.4  #define XEN_MAGIC  (('X' << 24) | ('E' << 16) | ('N' << 8) | 0xfb)
    14.5  #define QCOW_VERSION 1
    14.6  
    14.7 -#define QCOW_CRYPT_NONE 0
    14.8 -#define QCOW_CRYPT_AES  1
    14.9 +#define QCOW_CRYPT_NONE 0x00
   14.10 +#define QCOW_CRYPT_AES  0x01
   14.11 +#define QCOW_SPARSE_FILE 0x02
   14.12  
   14.13  #define QCOW_OFLAG_COMPRESSED (1LL << 63)
   14.14  
   14.15 @@ -101,6 +102,7 @@ typedef struct QCowHeader_ext {
   14.16          uint32_t xmagic;
   14.17          uint32_t cksum;
   14.18          uint32_t min_cluster_alloc;
   14.19 +        uint32_t flags;
   14.20  } QCowHeader_ext;
   14.21  
   14.22  #define L2_CACHE_SIZE 16  /*Fixed allocation in Qemu*/
   14.23 @@ -119,6 +121,7 @@ struct tdqcow_state {
   14.24  	int cluster_alloc;             /*Blktap fix for allocating full 
   14.25  					*extents*/
   14.26  	int min_cluster_alloc;         /*Blktap historical extent alloc*/
   14.27 +	int sparse;                    /*Indicates whether to preserve sparseness*/
   14.28  	int l2_bits;                   /*Size of L2 table entry*/
   14.29  	int l2_size;                   /*Full table size*/
   14.30  	int l1_size;                   /*L1 table size*/
   14.31 @@ -413,6 +416,37 @@ static void encrypt_sectors(struct tdqco
   14.32  	}
   14.33  }
   14.34  
   14.35 +static int qtruncate(int fd, off_t length, int sparse)
   14.36 +{
   14.37 +	int current, ret, i; 
   14.38 +	int sectors = length/DEFAULT_SECTOR_SIZE;
   14.39 +	struct stat st;
   14.40 +	char buf[DEFAULT_SECTOR_SIZE];
   14.41 +
   14.42 +	/* If length is greater than the current file len
   14.43 +	 * we synchronously write zeroes to the end of the 
   14.44 +	 * file, otherwise we truncate the length down
   14.45 +	 */
   14.46 +	memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
   14.47 +	ret = fstat(fd, &st);
   14.48 +	if((ret == -1) || S_ISBLK(st.st_mode))
   14.49 +		return -1;
   14.50 +
   14.51 +	if(st.st_size < length) {
   14.52 +		/*We are extending the file*/
   14.53 +		lseek(fd, 0, SEEK_END);
   14.54 +		for (i = 0; i < sectors; i++ ) {
   14.55 +			ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
   14.56 +			if (ret != DEFAULT_SECTOR_SIZE)
   14.57 +				return -1;
   14.58 +		}
   14.59 +		
   14.60 +	} else if(sparse && (st.st_size > length))
   14.61 +		ftruncate(fd, length);
   14.62 +
   14.63 +	return 1;
   14.64 +}
   14.65 +
   14.66  
   14.67  /* 'allocate' is:
   14.68   *
   14.69 @@ -463,8 +497,8 @@ static uint64_t get_cluster_offset(struc
   14.70  		
   14.71  		/*Truncate file for L2 table 
   14.72  		 *(initialised to zero in case we crash)*/
   14.73 -		ftruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)));
   14.74 -		s->fd_end += (s->l2_size * sizeof(uint64_t));
   14.75 +		qtruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)), s->sparse);
   14.76 +		s->fd_end = l2_offset + (s->l2_size * sizeof(uint64_t));
   14.77  
   14.78  		/*Update the L1 table entry on disk
   14.79                   * (for O_DIRECT we write 4KByte blocks)*/
   14.80 @@ -483,7 +517,7 @@ static uint64_t get_cluster_offset(struc
   14.81  		 */
   14.82  		lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
   14.83  		if (write(s->fd, tmp_ptr, 4096) != 4096)
   14.84 -			return 0;
   14.85 +		 	return 0;
   14.86  		free(tmp_ptr);
   14.87  
   14.88  		new_l2_table = 1;
   14.89 @@ -530,8 +564,8 @@ cache_miss:
   14.90  				(s->l2_size * sizeof(uint64_t));
   14.91  			cluster_offset = (cluster_offset + s->cluster_size - 1)
   14.92  				& ~(s->cluster_size - 1);
   14.93 -			ftruncate(s->fd, cluster_offset + 
   14.94 -				  (s->cluster_size * s->l2_size));
   14.95 +			qtruncate(s->fd, cluster_offset + 
   14.96 +				  (s->cluster_size * s->l2_size), s->sparse);
   14.97  			s->fd_end = cluster_offset + 
   14.98  				(s->cluster_size * s->l2_size);
   14.99  			for (i = 0; i < s->l2_size; i++) {
  14.100 @@ -542,7 +576,7 @@ cache_miss:
  14.101  
  14.102  		lseek(s->fd, l2_offset, SEEK_SET);
  14.103  		if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
  14.104 -		    s->l2_size * sizeof(uint64_t))
  14.105 +		   s->l2_size * sizeof(uint64_t))
  14.106  			return 0;
  14.107  	} else {
  14.108  		lseek(s->fd, l2_offset, SEEK_SET);
  14.109 @@ -573,7 +607,7 @@ found:
  14.110  			   overwritten */
  14.111  			if (decompress_cluster(s, cluster_offset) < 0)
  14.112  				return 0;
  14.113 -			cluster_offset = lseek(s->fd, 0, SEEK_END);
  14.114 +			cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
  14.115  			cluster_offset = (cluster_offset + s->cluster_size - 1)
  14.116  				& ~(s->cluster_size - 1);
  14.117  			/* write the cluster content - not asynchronous */
  14.118 @@ -583,14 +617,15 @@ found:
  14.119  			    return -1;
  14.120  		} else {
  14.121  			/* allocate a new cluster */
  14.122 -			cluster_offset = lseek(s->fd, 0, SEEK_END);
  14.123 +			cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
  14.124  			if (allocate == 1) {
  14.125  				/* round to cluster size */
  14.126  				cluster_offset = 
  14.127  					(cluster_offset + s->cluster_size - 1) 
  14.128  					& ~(s->cluster_size - 1);
  14.129 -				ftruncate(s->fd, cluster_offset + 
  14.130 -					  s->cluster_size);
  14.131 +				qtruncate(s->fd, cluster_offset + 
  14.132 +					  s->cluster_size, s->sparse);
  14.133 +				s->fd_end = (cluster_offset + s->cluster_size);
  14.134  				/* if encrypted, we must initialize the cluster
  14.135  				   content which won't be written */
  14.136  				if (s->crypt_method && 
  14.137 @@ -633,9 +668,9 @@ found:
  14.138  			DPRINTF("ERROR allocating memory for L1 table\n");
  14.139  		}
  14.140  		memcpy(tmp_ptr2, l2_ptr, 4096);
  14.141 -		aio_lock(s, offset >> 9);
  14.142 -		async_write(s, s->fd, 4096, l2_offset + (l2_sector << 12), 
  14.143 -			    tmp_ptr2, 0, -2, offset >> 9, 0, NULL);
  14.144 +		lseek(s->fd, l2_offset + (l2_sector << 12), SEEK_SET);
  14.145 +		write(s->fd, tmp_ptr2, 4096);
  14.146 +		free(tmp_ptr2);
  14.147  	}
  14.148  	return cluster_offset;
  14.149  }
  14.150 @@ -733,6 +768,7 @@ int tdqcow_open (struct td_state *bs, co
  14.151  	QCowHeader *header;
  14.152  	QCowHeader_ext *exthdr;
  14.153  	uint32_t cksum;
  14.154 +	uint64_t final_cluster = 0;
  14.155  
  14.156   	DPRINTF("QCOW: Opening %s\n",name);
  14.157  	/* set up a pipe so that we can hand back a poll fd that won't fire.*/
  14.158 @@ -766,7 +802,7 @@ int tdqcow_open (struct td_state *bs, co
  14.159  	be64_to_cpus(&header->size);
  14.160  	be32_to_cpus(&header->crypt_method);
  14.161  	be64_to_cpus(&header->l1_table_offset);
  14.162 -   
  14.163 +
  14.164  	if (header->magic != QCOW_MAGIC || header->version > QCOW_VERSION)
  14.165  		goto fail;
  14.166  	if (header->size <= 1 || header->cluster_bits < 9)
  14.167 @@ -798,6 +834,7 @@ int tdqcow_open (struct td_state *bs, co
  14.168  	}
  14.169  	ret = posix_memalign((void **)&s->l1_table, 4096, l1_table_size);
  14.170  	if (ret != 0) goto fail;
  14.171 +
  14.172  	memset(s->l1_table, 0x00, l1_table_size);
  14.173  
  14.174  	DPRINTF("L1 Table offset detected: %llu, size %d (%d)\n",
  14.175 @@ -808,10 +845,13 @@ int tdqcow_open (struct td_state *bs, co
  14.176  	lseek(fd, s->l1_table_offset, SEEK_SET);
  14.177  	if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
  14.178  		goto fail;
  14.179 -/*	for(i = 0;i < s->l1_size; i++) {
  14.180 +
  14.181 +	for(i = 0;i < s->l1_size; i++) {
  14.182  		//be64_to_cpus(&s->l1_table[i]);
  14.183 -		DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
  14.184 -		}*/
  14.185 +		//DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
  14.186 +		if (s->l1_table[i] > final_cluster)
  14.187 +			final_cluster = s->l1_table[i];
  14.188 +	}
  14.189  
  14.190  	/* alloc L2 cache */
  14.191  	size = s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t);
  14.192 @@ -870,10 +910,14 @@ int tdqcow_open (struct td_state *bs, co
  14.193  		/*Finally check the L1 table cksum*/
  14.194  		be32_to_cpus(&exthdr->cksum);
  14.195  		cksum = gen_cksum((char *)s->l1_table, s->l1_size * sizeof(uint64_t));
  14.196 -		if(exthdr->cksum != cksum)
  14.197 +		if(exthdr->cksum != cksum) {
  14.198  			goto end_xenhdr;
  14.199 +		}
  14.200  			
  14.201  		be32_to_cpus(&exthdr->min_cluster_alloc);
  14.202 +		be32_to_cpus(&exthdr->flags);
  14.203 +		if (exthdr->flags & QCOW_SPARSE_FILE)
  14.204 +			s->sparse = 1;
  14.205  		s->min_cluster_alloc = exthdr->min_cluster_alloc; 
  14.206  	}
  14.207  
  14.208 @@ -882,7 +926,8 @@ int tdqcow_open (struct td_state *bs, co
  14.209  		DPRINTF("Unable to initialise AIO state\n");
  14.210  		goto fail;
  14.211  	}
  14.212 -	s->fd_end = lseek(s->fd, 0, SEEK_END);
  14.213 +	s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size) : 
  14.214 +				(final_cluster + s->cluster_size));
  14.215  
  14.216  	return 0;
  14.217  	
  14.218 @@ -1172,7 +1217,7 @@ int qcow_create(const char *filename, ui
  14.219  	QCowHeader header;
  14.220  	QCowHeader_ext exthdr;
  14.221  	char backing_filename[1024], *ptr;
  14.222 -	uint64_t tmp, size;
  14.223 +	uint64_t tmp, size, total_length;
  14.224  	struct stat st;
  14.225  
  14.226  	DPRINTF("Qcow_create: size %llu\n",(long long unsigned)total_size);
  14.227 @@ -1260,7 +1305,7 @@ int qcow_create(const char *filename, ui
  14.228  	DPRINTF("L1 Table offset: %d, size %d\n",
  14.229  		header_size,
  14.230  		(int)(l1_size * sizeof(uint64_t)));
  14.231 -	if (flags) {
  14.232 +	if (flags & QCOW_CRYPT_AES) {
  14.233  		header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
  14.234  	} else {
  14.235  		header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
  14.236 @@ -1270,8 +1315,26 @@ int qcow_create(const char *filename, ui
  14.237  	exthdr.cksum = cpu_to_be32(gen_cksum(ptr, l1_size * sizeof(uint64_t)));
  14.238  	printf("Created cksum: %d\n",exthdr.cksum);
  14.239  	free(ptr);
  14.240 +
  14.241 +	/*adjust file length to 4 KByte boundary*/
  14.242 +	length = header_size + l1_size * sizeof(uint64_t);
  14.243 +	if (length % 4096 > 0) {
  14.244 +		length = ((length >> 12) + 1) << 12;
  14.245 +		qtruncate(fd, length, 0);
  14.246 +		DPRINTF("Adjusted filelength to %d for 4 "
  14.247 +			"Kbyte alignment\n",length);
  14.248 +	}
  14.249 +
  14.250 +	if (!(flags & QCOW_SPARSE_FILE)) {
  14.251 +		/*Filesize is length + 	l1_size * (1 << s->l2_bits) + (size*512)*/
  14.252 +		total_length = length + (l1_size * (1 << 9)) + (size * 512);
  14.253 +		qtruncate(fd, total_length, 0);
  14.254 +		printf("File truncated to length %"PRIu64"\n",total_length);
  14.255 +	}
  14.256 +	exthdr.flags = cpu_to_be32(flags);
  14.257  	
  14.258  	/* write all the data */
  14.259 +	lseek(fd, 0, SEEK_SET);
  14.260  	ret += write(fd, &header, sizeof(header));
  14.261  	ret += write(fd, &exthdr, sizeof(exthdr));
  14.262  	if (backing_file) {
  14.263 @@ -1283,15 +1346,6 @@ int qcow_create(const char *filename, ui
  14.264  		ret += write(fd, &tmp, sizeof(tmp));
  14.265  	}
  14.266  
  14.267 -	/*adjust file length to 4 KByte boundary*/
  14.268 -	length = header_size + l1_size * sizeof(uint64_t);
  14.269 -	if (length % 4096 > 0) {
  14.270 -		length = ((length >> 12) + 1) << 12;
  14.271 -		ftruncate(fd, length);
  14.272 -		DPRINTF("Adjusted filelength to %d for 4 "
  14.273 -			"Kbyte alignment\n",length);
  14.274 -	}
  14.275 -
  14.276  	close(fd);
  14.277  
  14.278  	return 0;
  14.279 @@ -1306,7 +1360,7 @@ int qcow_make_empty(struct td_state *bs)
  14.280  	lseek(s->fd, s->l1_table_offset, SEEK_SET);
  14.281  	if (write(s->fd, s->l1_table, l1_length) < 0)
  14.282  		return -1;
  14.283 -	ftruncate(s->fd, s->l1_table_offset + l1_length);
  14.284 +	qtruncate(s->fd, s->l1_table_offset + l1_length, s->sparse);
  14.285  
  14.286  	memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
  14.287  	memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
    15.1 --- a/tools/blktap/drivers/qcow-create.c	Fri Dec 15 10:59:33 2006 -0700
    15.2 +++ b/tools/blktap/drivers/qcow-create.c	Fri Dec 15 11:32:58 2006 -0700
    15.3 @@ -47,32 +47,69 @@
    15.4  #define DFPRINTF(_f, _a...) ((void)0)
    15.5  #endif
    15.6  
    15.7 +#define QCOW_NONSPARSE_FILE 0x00
    15.8 +#define QCOW_SPARSE_FILE 0x02
    15.9 +#define MAX_NAME_LEN 1000
   15.10 +
   15.11 +void help(void)
   15.12 +{
   15.13 +	fprintf(stderr, "Qcow-utils: v1.0.0\n");
   15.14 +	fprintf(stderr, 
   15.15 +		"usage: qcow-create [-h help] [-p reserve] <SIZE(MB)> <FILENAME> "
   15.16 +		"[<BACKING_FILENAME>]\n"); 
   15.17 +	exit(-1);
   15.18 +}
   15.19  
   15.20  int main(int argc, char *argv[])
   15.21  {
   15.22 -	int ret = -1;
   15.23 +	int ret = -1, c, backed = 0;
   15.24 +	int flags =  QCOW_SPARSE_FILE;
   15.25  	uint64_t size;
   15.26 +	char filename[MAX_NAME_LEN], bfilename[MAX_NAME_LEN];
   15.27  
   15.28 -	if ( (argc < 3) || (argc > 4) ) {
   15.29 -		fprintf(stderr, "Qcow-utils: v1.0.0\n");
   15.30 -		fprintf(stderr, 
   15.31 -			"usage: %s <SIZE(MB)> <FILENAME> "
   15.32 -			"[<BACKING_FILENAME>]\n", 
   15.33 -			argv[0]);
   15.34 +        for(;;) {
   15.35 +                c = getopt(argc, argv, "hp");
   15.36 +                if (c == -1)
   15.37 +                        break;
   15.38 +                switch(c) {
   15.39 +                case 'h':
   15.40 +                        help();
   15.41 +                        exit(0);
   15.42 +                        break;
   15.43 +                case 'p':
   15.44 +			flags = QCOW_NONSPARSE_FILE;
   15.45 +			break;
   15.46 +		}
   15.47 +	}
   15.48 +
   15.49 +	printf("Optind %d, argc %d\n", optind, argc);
   15.50 +	if ( !(optind == (argc - 2) || optind == (argc - 3)) )
   15.51 +		help();
   15.52 +
   15.53 +	size = atoi(argv[optind++]);
   15.54 +	size = size << 20;
   15.55 +
   15.56 +	if (snprintf(filename, MAX_NAME_LEN, "%s",argv[optind++]) >=
   15.57 +		MAX_NAME_LEN) {
   15.58 +		fprintf(stderr,"Device name too long\n");
   15.59  		exit(-1);
   15.60  	}
   15.61  
   15.62 -	size = atoi(argv[1]);
   15.63 -	size = size << 20;
   15.64 -	DFPRINTF("Creating file size %llu\n",(long long unsigned)size);
   15.65 -	switch(argc) {
   15.66 -	case 3: 
   15.67 -		ret = qcow_create(argv[2],size,NULL,0);
   15.68 -		break;
   15.69 -	case 4:
   15.70 -		ret = qcow_create(argv[2],size,argv[3],0);
   15.71 -		break;		
   15.72 +	if (optind != argc) {
   15.73 +		backed = 1;
   15.74 +		if (snprintf(bfilename, MAX_NAME_LEN, "%s",argv[optind++]) >=
   15.75 +			MAX_NAME_LEN) {
   15.76 +			fprintf(stderr,"Device name too long\n");
   15.77 +			exit(-1);
   15.78 +		}
   15.79  	}
   15.80 +
   15.81 +	DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size, filename);
   15.82 +	if (!backed)
   15.83 +		ret = qcow_create(filename,size,NULL,flags);
   15.84 +	else
   15.85 +		ret = qcow_create(filename,size,bfilename,flags);
   15.86 +
   15.87  	if (ret < 0) DPRINTF("Unable to create QCOW file\n");
   15.88  	else DPRINTF("QCOW file successfully created\n");
   15.89  
    16.1 --- a/tools/check/check_crypto_lib	Fri Dec 15 10:59:33 2006 -0700
    16.2 +++ b/tools/check/check_crypto_lib	Fri Dec 15 11:32:58 2006 -0700
    16.3 @@ -1,11 +1,14 @@
    16.4 -#!/bin/bash
    16.5 +#!/bin/sh
    16.6  # CHECK-BUILD CHECK-INSTALL
    16.7  
    16.8 -function error {
    16.9 -    echo
   16.10 -    echo "  *** Check for crypto library FAILED"
   16.11 -    exit 1
   16.12 -}
   16.13 +RC=0
   16.14  
   16.15  set -e
   16.16 -ldconfig -p | grep -q libcrypto.so || error
   16.17 +ldconfig -v 2>&1 | grep -q libcrypto.so || RC=1
   16.18 +
   16.19 +if test ${RC} -ne 0; then
   16.20 +        echo
   16.21 +        echo " *** Check for crypto library FAILED"
   16.22 +fi
   16.23 +
   16.24 +exit ${RC}
    17.1 --- a/tools/check/check_openssl_devel	Fri Dec 15 10:59:33 2006 -0700
    17.2 +++ b/tools/check/check_openssl_devel	Fri Dec 15 11:32:58 2006 -0700
    17.3 @@ -1,11 +1,14 @@
    17.4 -#!/bin/bash
    17.5 +#!/bin/sh
    17.6  # CHECK-BUILD
    17.7  
    17.8 -function error {
    17.9 -    echo
   17.10 -    echo "  *** Check for openssl headers FAILED"
   17.11 -    exit 1
   17.12 -}
   17.13 +RC=0
   17.14  
   17.15  set -e
   17.16 -[ -e /usr/include/openssl/md5.h ] || error
   17.17 +test -r /usr/include/openssl/md5.h || RC=1 
   17.18 +
   17.19 +if test ${RC} -ne 0; then
   17.20 +	echo
   17.21 +	echo " *** Check for openssl headers FAILED"
   17.22 +fi
   17.23 +
   17.24 +exit ${RC}
    18.1 --- a/tools/check/check_python	Fri Dec 15 10:59:33 2006 -0700
    18.2 +++ b/tools/check/check_python	Fri Dec 15 11:32:58 2006 -0700
    18.3 @@ -3,7 +3,10 @@
    18.4  
    18.5  RC=0
    18.6  
    18.7 -python -V 2>&1 | cut -d ' ' -f 2 | grep -q '^2.[2345]' || RC=1
    18.8 +python -c '
    18.9 +import sys
   18.10 +sys.exit(sys.version_info[0] < 2 or sys.version_info[1] < 2)
   18.11 +' || RC=1
   18.12  
   18.13  if test ${RC} -ne 0; then
   18.14  	echo
    19.1 --- a/tools/check/check_python_devel	Fri Dec 15 10:59:33 2006 -0700
    19.2 +++ b/tools/check/check_python_devel	Fri Dec 15 11:32:58 2006 -0700
    19.3 @@ -1,11 +1,7 @@
    19.4 -#!/bin/bash
    19.5 +#!/bin/sh
    19.6  # CHECK-BUILD
    19.7  
    19.8 -function error {
    19.9 -    echo
   19.10 -    echo "  *** Check for python development environment FAILED"
   19.11 -    exit 1
   19.12 -}
   19.13 +RC=0
   19.14  
   19.15  python -c '
   19.16  import os.path, sys
   19.17 @@ -13,4 +9,11 @@ for p in sys.path:
   19.18  	if os.path.exists(p + "/config/Makefile"):
   19.19  		sys.exit(0)
   19.20  sys.exit(1)
   19.21 -' || error
   19.22 +' || RC=1 
   19.23 +
   19.24 +if test ${RC} -ne 0; then
   19.25 +	echo
   19.26 +	echo " *** Check for python development environment FAILED"
   19.27 +fi
   19.28 +
   19.29 +exit ${RC}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/check/check_python_xml	Fri Dec 15 11:32:58 2006 -0700
    20.3 @@ -0,0 +1,8 @@
    20.4 +#!/bin/sh
    20.5 +# CHECK-INSTALL
    20.6 +
    20.7 +python -c 'import xml.dom.minidom' 2>/dev/null || {
    20.8 +    echo
    20.9 +    echo "  *** Check for python-xml package FAILED"
   20.10 +    exit 1
   20.11 +}
    21.1 --- a/tools/check/check_udev	Fri Dec 15 10:59:33 2006 -0700
    21.2 +++ b/tools/check/check_udev	Fri Dec 15 11:32:58 2006 -0700
    21.3 @@ -1,16 +1,34 @@
    21.4 -#!/bin/bash
    21.5 +#!/bin/sh
    21.6  # CHECK-INSTALL
    21.7  
    21.8 -function error {
    21.9 -   echo
   21.10 -   echo '  *** Check for udev/hotplug FAILED'
   21.11 -   exit 1
   21.12 -}
   21.13 -[ -x "$(which udevinfo)" ] && \
   21.14 -  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
   21.15 +RC=0
   21.16  
   21.17 -if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
   21.18 -  exit 0
   21.19 +case ${OS} in
   21.20 +OpenBSD|NetBSD|FreeBSD)
   21.21 +	TOOL="vnconfig"
   21.22 +	which ${TOOL} 1>/dev/null 2>&1 || RC=1
   21.23 +	;;
   21.24 +Linux)
   21.25 +	TOOL="udevinfo"
   21.26 +	UDEV_VERSION="0"
   21.27 +	test -x "$(which ${TOOL})" && \
   21.28 +		UDEV_VERSION=$(${TOOL} -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
   21.29 +	if test "${UDEV_VERSION}" -ge 059; then
   21.30 +		RC=0
   21.31 +	else
   21.32 +		TOOL="hotplug"
   21.33 +		which ${TOOL} 1>/dev/null 2>&1 || RC=1
   21.34 +	fi
   21.35 +	;;
   21.36 +*)
   21.37 +	TOOL=""
   21.38 +	echo "Unknown OS" && RC=1
   21.39 +	;;
   21.40 +esac
   21.41 +
   21.42 +if test ${RC} -ne 0; then
   21.43 +	echo
   21.44 +	echo ' *** Check for ${TOOL} FAILED'
   21.45  fi
   21.46  
   21.47 -which hotplug 1>/dev/null 2>&1 || error
   21.48 +exit ${RC}
    22.1 --- a/tools/check/check_x11_devel	Fri Dec 15 10:59:33 2006 -0700
    22.2 +++ b/tools/check/check_x11_devel	Fri Dec 15 11:32:58 2006 -0700
    22.3 @@ -1,11 +1,15 @@
    22.4 -#!/bin/bash
    22.5 +#!/bin/sh
    22.6  # CHECK-BUILD
    22.7  
    22.8 -function error {
    22.9 -    echo
   22.10 -    echo "  *** Check for x11 headers FAILED"
   22.11 -    exit 1
   22.12 -}
   22.13 +RC=0
   22.14  
   22.15  set -e
   22.16 -[ -e /usr/include/X11/keysymdef.h ] || error
   22.17 +test -r /usr/include/X11/keysymdef.h || \
   22.18 +test -r /usr/X11R6/include/X11/keysymdef.h || RC=1
   22.19 +
   22.20 +if test ${RC} -ne 0; then
   22.21 +	echo
   22.22 +	echo " *** Check for x11 headers FAILED"
   22.23 +fi
   22.24 +
   22.25 +exit ${RC}
    23.1 --- a/tools/examples/external-device-migrate	Fri Dec 15 10:59:33 2006 -0700
    23.2 +++ b/tools/examples/external-device-migrate	Fri Dec 15 11:32:58 2006 -0700
    23.3 @@ -60,8 +60,8 @@ function evaluate_params()
    23.4  		-step)		step=$2; shift 2;;
    23.5  		-host)		host=$2; shift 2;;
    23.6  		-domname)	domname=$2; shift 2;;
    23.7 -		-type)		type=$2; shift 2;;
    23.8 -		-subtype)	subtype=$2; shift 2;;
    23.9 +		-type)		typ=$2; shift 2;;
   23.10 +		-subtype)	stype=$2; shift 2;;
   23.11  		-recover)	recover=1; shift;;
   23.12  		-help)		ext_dev_migrate_usage; exit 0;;
   23.13  		*)		break;;
    24.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Fri Dec 15 10:59:33 2006 -0700
    24.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Fri Dec 15 11:32:58 2006 -0700
    24.3 @@ -439,7 +439,12 @@ void cpu_physical_memory_rw(target_phys_
    24.4      int l, io_index;
    24.5      uint8_t *ptr;
    24.6      uint32_t val;
    24.7 -    
    24.8 +
    24.9 +#if defined(__i386__) || defined(__x86_64__)
   24.10 +    static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
   24.11 +    pthread_mutex_lock(&mutex);
   24.12 +#endif
   24.13 +
   24.14      while (len > 0) {
   24.15          /* How much can we copy before the next page boundary? */
   24.16          l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
   24.17 @@ -504,6 +509,10 @@ void cpu_physical_memory_rw(target_phys_
   24.18          buf += l;
   24.19          addr += l;
   24.20      }
   24.21 +
   24.22 +#if defined(__i386__) || defined(__x86_64__)
   24.23 +    pthread_mutex_unlock(&mutex);
   24.24 +#endif
   24.25  }
   24.26  #endif
   24.27  
    25.1 --- a/tools/ioemu/vl.c	Fri Dec 15 10:59:33 2006 -0700
    25.2 +++ b/tools/ioemu/vl.c	Fri Dec 15 11:32:58 2006 -0700
    25.3 @@ -5820,8 +5820,8 @@ static int qemu_map_cache_init(unsigned 
    25.4      if (nr_pages < max_pages)
    25.5          max_pages = nr_pages;
    25.6  
    25.7 -    nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT;
    25.8 -
    25.9 +    nr_buckets   = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1;
   25.10 +    nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
   25.11      fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
   25.12  
   25.13      mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
   25.14 @@ -5857,8 +5857,7 @@ uint8_t *qemu_map_cache(target_phys_addr
   25.15  
   25.16      entry = &mapcache_entry[address_index % nr_buckets];
   25.17  
   25.18 -    if (entry->vaddr_base == NULL || entry->paddr_index != address_index)
   25.19 -    { 
   25.20 +    if (entry->vaddr_base == NULL || entry->paddr_index != address_index) {
   25.21          /* We need to remap a bucket. */
   25.22          uint8_t *vaddr_base;
   25.23          unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
    26.1 --- a/tools/libaio/src/syscall-ppc.h	Fri Dec 15 10:59:33 2006 -0700
    26.2 +++ b/tools/libaio/src/syscall-ppc.h	Fri Dec 15 11:32:58 2006 -0700
    26.3 @@ -1,3 +1,6 @@
    26.4 +#include <asm/unistd.h>
    26.5 +#include <errno.h>
    26.6 +
    26.7  #define __NR_io_setup		227
    26.8  #define __NR_io_destroy		228
    26.9  #define __NR_io_getevents	229
   26.10 @@ -9,7 +12,7 @@
   26.11   * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
   26.12   * an error return status).
   26.13   */
   26.14 -
   26.15 +#ifndef __syscall_nr
   26.16  #define __syscall_nr(nr, type, name, args...)				\
   26.17  	unsigned long __sc_ret, __sc_err;				\
   26.18  	{								\
   26.19 @@ -37,6 +40,7 @@
   26.20  	}								\
   26.21  	if (__sc_err & 0x10000000) return -((int)__sc_ret);		\
   26.22  	return (type) __sc_ret
   26.23 +#endif
   26.24  
   26.25  #define __sc_loadargs_0(name, dummy...)					\
   26.26  	__sc_0 = __NR_##name
    27.1 --- a/tools/libxc/ia64/xc_ia64_hvm_build.c	Fri Dec 15 10:59:33 2006 -0700
    27.2 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c	Fri Dec 15 11:32:58 2006 -0700
    27.3 @@ -660,8 +660,14 @@ setup_guest(int xc_handle, uint32_t dom,
    27.4          goto error_out;
    27.5      }
    27.6  
    27.7 -    // Get number of vcpus, stored by pyxc_hvm_build()
    27.8 -    xc_get_hvm_param(xc_handle, dom, HVM_PARAM_VCPUS, &vcpus);
    27.9 +    domctl.cmd = XEN_DOMCTL_getdomaininfo;
   27.10 +    domctl.domain = (domid_t)dom;
   27.11 +    if (xc_domctl(xc_handle, &domctl) < 0) {
   27.12 +        PERROR("Could not get info on domain");
   27.13 +        goto error_out;
   27.14 +    }
   27.15 +
   27.16 +    vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1;
   27.17  
   27.18      // Hand-off state passed to guest firmware 
   27.19      if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus) < 0) {
    28.1 --- a/tools/libxc/powerpc64/Makefile	Fri Dec 15 10:59:33 2006 -0700
    28.2 +++ b/tools/libxc/powerpc64/Makefile	Fri Dec 15 11:32:58 2006 -0700
    28.3 @@ -1,4 +1,6 @@
    28.4 +GUEST_SRCS-y += powerpc64/flatdevtree.c
    28.5  GUEST_SRCS-y += powerpc64/xc_linux_build.c
    28.6 -GUEST_SRCS-y += powerpc64/flatdevtree.c
    28.7 +GUEST_SRCS-y += powerpc64/xc_prose_build.c
    28.8 +GUEST_SRCS-y += powerpc64/utils.c
    28.9  
   28.10  CTRL_SRCS-y += powerpc64/xc_memory.c
    29.1 --- a/tools/libxc/powerpc64/flatdevtree.c	Fri Dec 15 10:59:33 2006 -0700
    29.2 +++ b/tools/libxc/powerpc64/flatdevtree.c	Fri Dec 15 11:32:58 2006 -0700
    29.3 @@ -220,6 +220,29 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
    29.4  	cxt->p_anchor = cxt->pres + 16;	/* over the terminator */
    29.5  }
    29.6  
    29.7 +int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size)
    29.8 +{
    29.9 +	const struct boot_param_header *bph = bphp;
   29.10 +	u64 *p_rsvmap = (u64 *)
   29.11 +		((char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
   29.12 +	u32 i;
   29.13 +
   29.14 +	for (i = 0;; i++) {
   29.15 +		u64 addr, sz;
   29.16 +
   29.17 +		addr = be64_to_cpu(p_rsvmap[i * 2]);
   29.18 +		sz = be64_to_cpu(p_rsvmap[i * 2 + 1]);
   29.19 +		if (addr == 0 && size == 0)
   29.20 +			break;
   29.21 +		if (m == i) {
   29.22 +			p_rsvmap[i * 2] = cpu_to_be64(physaddr);
   29.23 +			p_rsvmap[i * 2 + 1] = cpu_to_be64(size);
   29.24 +			return 0;
   29.25 +		}
   29.26 +	}
   29.27 +	return -1;
   29.28 +}
   29.29 +
   29.30  void ft_begin_tree(struct ft_cxt *cxt)
   29.31  {
   29.32  	cxt->p_begin = cxt->p_anchor;
    30.1 --- a/tools/libxc/powerpc64/flatdevtree.h	Fri Dec 15 10:59:33 2006 -0700
    30.2 +++ b/tools/libxc/powerpc64/flatdevtree.h	Fri Dec 15 11:32:58 2006 -0700
    30.3 @@ -66,8 +66,10 @@ void ft_prop_str(struct ft_cxt *cxt, con
    30.4  void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
    30.5  void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
    30.6  void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
    30.7 +int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size);
    30.8  
    30.9  void ft_dump_blob(const void *bphp);
   30.10 +void ft_backtrack_node(struct ft_cxt *cxt);
   30.11  void ft_merge_blob(struct ft_cxt *cxt, void *blob);
   30.12  
   30.13  void *ft_find_node(const void *bphp, const char *srch_path);
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/libxc/powerpc64/utils.c	Fri Dec 15 11:32:58 2006 -0700
    31.3 @@ -0,0 +1,211 @@
    31.4 +/*
    31.5 + * This program is free software; you can redistribute it and/or modify
    31.6 + * it under the terms of the GNU General Public License as published by
    31.7 + * the Free Software Foundation; either version 2 of the License, or
    31.8 + * (at your option) any later version.
    31.9 + *
   31.10 + * This program is distributed in the hope that it will be useful,
   31.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.13 + * GNU General Public License for more details.
   31.14 + *
   31.15 + * You should have received a copy of the GNU General Public License
   31.16 + * along with this program; if not, write to the Free Software
   31.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   31.18 + *
   31.19 + * Copyright (C) IBM Corporation 2006
   31.20 + *
   31.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   31.22 + *          Jimi Xenidis <jimix@watson.ibm.com>
   31.23 + */
   31.24 +#include <stdio.h>
   31.25 +#include <stdint.h>
   31.26 +#include <stdlib.h>
   31.27 +#include <string.h>
   31.28 +#include <unistd.h>
   31.29 +#include <fcntl.h>
   31.30 +#include <sys/types.h>
   31.31 +#include <inttypes.h>
   31.32 +
   31.33 +#include <xen/xen.h>
   31.34 +#include <xen/memory.h>
   31.35 +#include <xc_private.h>
   31.36 +#include <xg_private.h>
   31.37 +#include <xenctrl.h>
   31.38 +
   31.39 +#include "flatdevtree_env.h"
   31.40 +#include "flatdevtree.h"
   31.41 +#include "utils.h"
   31.42 +
   31.43 +unsigned long get_rma_pages(void *devtree)
   31.44 +{
   31.45 +    void *rma;
   31.46 +    uint64_t rma_reg[2];
   31.47 +    int rc;
   31.48 +
   31.49 +    rma = ft_find_node(devtree, "/memory@0");
   31.50 +    if (rma == NULL) {
   31.51 +        DPRINTF("couldn't find /memory@0\n");
   31.52 +        return 0;
   31.53 +    }
   31.54 +    rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
   31.55 +    if (rc < 0) {
   31.56 +        DPRINTF("couldn't get /memory@0/reg\n");
   31.57 +        return 0;
   31.58 +    }
   31.59 +    if (rma_reg[0] != 0) {
   31.60 +        DPRINTF("RMA did not start at 0\n");
   31.61 +        return 0;
   31.62 +    }
   31.63 +    return rma_reg[1] >> PAGE_SHIFT;
   31.64 +}
   31.65 +
   31.66 +int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
   31.67 +		       unsigned long nr_pages)
   31.68 +{
   31.69 +    int rc;
   31.70 +    int i;
   31.71 +    xen_pfn_t *p;
   31.72 +
   31.73 +    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   31.74 +    if (*page_array == NULL) {
   31.75 +        perror("malloc");
   31.76 +        return -1;
   31.77 +    }
   31.78 +
   31.79 +    DPRINTF("xc_get_pfn_list\n");
   31.80 +    /* We know that the RMA is machine contiguous so lets just get the
   31.81 +     * first MFN and fill the rest in ourselves */
   31.82 +    rc = xc_get_pfn_list(xc_handle, domid, *page_array, 1);
   31.83 +    if (rc == -1) {
   31.84 +        perror("Could not get the page frame list");
   31.85 +        return -1;
   31.86 +    }
   31.87 +    p = *page_array;
   31.88 +    for (i = 1; i < nr_pages; i++)
   31.89 +        p[i] = p[i - 1] + 1;
   31.90 +    return 0;
   31.91 +}
   31.92 +
   31.93 +int install_image(
   31.94 +        int xc_handle,
   31.95 +        int domid,
   31.96 +        xen_pfn_t *page_array,
   31.97 +        void *image,
   31.98 +        unsigned long paddr,
   31.99 +        unsigned long size)
  31.100 +{
  31.101 +    uint8_t *img = image;
  31.102 +    int i;
  31.103 +    int rc = 0;
  31.104 +
  31.105 +    if (paddr & ~PAGE_MASK) {
  31.106 +        printf("*** unaligned address\n");
  31.107 +        return -1;
  31.108 +    }
  31.109 +
  31.110 +    for (i = 0; i < size; i += PAGE_SIZE) {
  31.111 +        void *page = img + i;
  31.112 +        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
  31.113 +        xen_pfn_t mfn = page_array[pfn];
  31.114 +
  31.115 +        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
  31.116 +        if (rc < 0) {
  31.117 +            perror("xc_copy_to_domain_page");
  31.118 +            break;
  31.119 +        }
  31.120 +    }
  31.121 +    return rc;
  31.122 +}
  31.123 +
  31.124 +void *load_file(const char *path, unsigned long *filesize)
  31.125 +{
  31.126 +    void *img;
  31.127 +    ssize_t size;
  31.128 +    int fd;
  31.129 +
  31.130 +    DPRINTF("load_file(%s)\n", path);
  31.131 +
  31.132 +    fd = open(path, O_RDONLY);
  31.133 +    if (fd < 0) {
  31.134 +        perror(path);
  31.135 +        return NULL;
  31.136 +    }
  31.137 +
  31.138 +    size = lseek(fd, 0, SEEK_END);
  31.139 +    if (size < 0) {
  31.140 +        perror(path);
  31.141 +        close(fd);
  31.142 +        return NULL;
  31.143 +    }
  31.144 +    lseek(fd, 0, SEEK_SET);
  31.145 +
  31.146 +    img = malloc(size);
  31.147 +    if (img == NULL) {
  31.148 +        perror(path);
  31.149 +        close(fd);
  31.150 +        return NULL;
  31.151 +    }
  31.152 +
  31.153 +    size = read(fd, img, size);
  31.154 +    if (size <= 0) {
  31.155 +        perror(path);
  31.156 +        close(fd);
  31.157 +        free(img);
  31.158 +        return NULL;
  31.159 +    }
  31.160 +
  31.161 +    if (filesize)
  31.162 +        *filesize = size;
  31.163 +    close(fd);
  31.164 +    return img;
  31.165 +}
  31.166 +
  31.167 +int load_elf_kernel(
  31.168 +    int xc_handle,
  31.169 +    int domid,
  31.170 +    const char *kernel_path,
  31.171 +    struct domain_setup_info *dsi,
  31.172 +    xen_pfn_t *page_array)
  31.173 +{
  31.174 +    struct load_funcs load_funcs;
  31.175 +    char *kernel_img;
  31.176 +    unsigned long kernel_size;
  31.177 +    int rc;
  31.178 +
  31.179 +    /* load the kernel ELF file */
  31.180 +    kernel_img = load_file(kernel_path, &kernel_size);
  31.181 +    if (kernel_img == NULL) {
  31.182 +        rc = -1;
  31.183 +        goto out;
  31.184 +    }
  31.185 +
  31.186 +    DPRINTF("probe_elf\n");
  31.187 +    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
  31.188 +    if (rc < 0) {
  31.189 +        rc = -1;
  31.190 +        printf("%s is not an ELF file\n", kernel_path);
  31.191 +        goto out;
  31.192 +    }
  31.193 +
  31.194 +    DPRINTF("parseimage\n");
  31.195 +    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
  31.196 +    if (rc < 0) {
  31.197 +        rc = -1;
  31.198 +        goto out;
  31.199 +    }
  31.200 +
  31.201 +    DPRINTF("loadimage\n");
  31.202 +    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
  31.203 +            page_array, dsi);
  31.204 +
  31.205 +    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
  31.206 +    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
  31.207 +    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
  31.208 +    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
  31.209 +    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
  31.210 +
  31.211 +out:
  31.212 +    free(kernel_img);
  31.213 +    return rc;
  31.214 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/libxc/powerpc64/utils.h	Fri Dec 15 11:32:58 2006 -0700
    32.3 @@ -0,0 +1,38 @@
    32.4 +/*
    32.5 + * This program is free software; you can redistribute it and/or modify
    32.6 + * it under the terms of the GNU General Public License as published by
    32.7 + * the Free Software Foundation; either version 2 of the License, or
    32.8 + * (at your option) any later version.
    32.9 + *
   32.10 + * This program is distributed in the hope that it will be useful,
   32.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.13 + * GNU General Public License for more details.
   32.14 + *
   32.15 + * You should have received a copy of the GNU General Public License
   32.16 + * along with this program; if not, write to the Free Software
   32.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   32.18 + *
   32.19 + * Copyright (C) IBM Corporation 2006
   32.20 + *
   32.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   32.22 + *          Jimi Xenidis <jimix@watson.ibm.com>
   32.23 + */
   32.24 +
   32.25 +extern unsigned long get_rma_pages(void *devtree);
   32.26 +extern int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
   32.27 +			      unsigned long nr_pages);
   32.28 +extern int install_image(int xc_handle, int domid, xen_pfn_t *page_array,
   32.29 +			 void *image, unsigned long paddr, unsigned long size);
   32.30 +extern void *load_file(const char *path, unsigned long *filesize);
   32.31 +extern int load_elf_kernel(int xc_handle, int domid,  const char *kernel_path,
   32.32 +			   struct domain_setup_info *dsi,
   32.33 +			   xen_pfn_t *page_array);
   32.34 +
   32.35 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
   32.36 +
   32.37 +#define max(x,y) ({ \
   32.38 +        const typeof(x) _x = (x);       \
   32.39 +        const typeof(y) _y = (y);       \
   32.40 +        (void) (&_x == &_y);            \
   32.41 +        _x > _y ? _x : _y; })
    33.1 --- a/tools/libxc/powerpc64/xc_linux_build.c	Fri Dec 15 10:59:33 2006 -0700
    33.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c	Fri Dec 15 11:32:58 2006 -0700
    33.3 @@ -35,61 +35,11 @@
    33.4  
    33.5  #include "flatdevtree_env.h"
    33.6  #include "flatdevtree.h"
    33.7 +#include "utils.h"
    33.8  
    33.9  #define INITRD_ADDR (24UL << 20)
   33.10  #define DEVTREE_ADDR (16UL << 20)
   33.11  
   33.12 -#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
   33.13 -
   33.14 -#define max(x,y) ({ \
   33.15 -        const typeof(x) _x = (x);       \
   33.16 -        const typeof(y) _y = (y);       \
   33.17 -        (void) (&_x == &_y);            \
   33.18 -        _x > _y ? _x : _y; })
   33.19 -
   33.20 -static void *load_file(const char *path, unsigned long *filesize)
   33.21 -{
   33.22 -    void *img;
   33.23 -    ssize_t size;
   33.24 -    int fd;
   33.25 -
   33.26 -    DPRINTF("load_file(%s)\n", path);
   33.27 -
   33.28 -    fd = open(path, O_RDONLY);
   33.29 -    if (fd < 0) {
   33.30 -        perror(path);
   33.31 -        return NULL;
   33.32 -    }
   33.33 -
   33.34 -    size = lseek(fd, 0, SEEK_END);
   33.35 -    if (size < 0) {
   33.36 -        perror(path);
   33.37 -        close(fd);
   33.38 -        return NULL;
   33.39 -    }
   33.40 -    lseek(fd, 0, SEEK_SET);
   33.41 -
   33.42 -    img = malloc(size);
   33.43 -    if (img == NULL) {
   33.44 -        perror(path);
   33.45 -        close(fd);
   33.46 -        return NULL;
   33.47 -    }
   33.48 -
   33.49 -    size = read(fd, img, size);
   33.50 -    if (size <= 0) {
   33.51 -        perror(path);
   33.52 -        close(fd);
   33.53 -        free(img);
   33.54 -        return NULL;
   33.55 -    }
   33.56 -
   33.57 -    if (filesize)
   33.58 -        *filesize = size;
   33.59 -    close(fd);
   33.60 -    return img;
   33.61 -}
   33.62 -
   33.63  static int init_boot_vcpu(
   33.64      int xc_handle,
   33.65      int domid,
   33.66 @@ -128,37 +78,6 @@ static int init_boot_vcpu(
   33.67      return rc;
   33.68  }
   33.69  
   33.70 -static int install_image(
   33.71 -        int xc_handle,
   33.72 -        int domid,
   33.73 -        xen_pfn_t *page_array,
   33.74 -        void *image,
   33.75 -        unsigned long paddr,
   33.76 -        unsigned long size)
   33.77 -{
   33.78 -    uint8_t *img = image;
   33.79 -    int i;
   33.80 -    int rc = 0;
   33.81 -
   33.82 -    if (paddr & ~PAGE_MASK) {
   33.83 -        printf("*** unaligned address\n");
   33.84 -        return -1;
   33.85 -    }
   33.86 -
   33.87 -    for (i = 0; i < size; i += PAGE_SIZE) {
   33.88 -        void *page = img + i;
   33.89 -        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   33.90 -        xen_pfn_t mfn = page_array[pfn];
   33.91 -
   33.92 -        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   33.93 -        if (rc < 0) {
   33.94 -            perror("xc_copy_to_domain_page");
   33.95 -            break;
   33.96 -        }
   33.97 -    }
   33.98 -    return rc;
   33.99 -}
  33.100 -
  33.101  static int load_devtree(
  33.102      int xc_handle,
  33.103      int domid,
  33.104 @@ -167,10 +86,10 @@ static int load_devtree(
  33.105      unsigned long devtree_addr,
  33.106      uint64_t initrd_base,
  33.107      unsigned long initrd_len,
  33.108 -    start_info_t *si,
  33.109 -    unsigned long si_addr)
  33.110 +    start_info_t *start_info __attribute__((unused)),
  33.111 +    unsigned long start_info_addr)
  33.112  {
  33.113 -    uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
  33.114 +    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
  33.115      struct boot_param_header *header;
  33.116      void *chosen;
  33.117      void *xen;
  33.118 @@ -208,9 +127,14 @@ static int load_devtree(
  33.119          return rc;
  33.120      }
  33.121  
  33.122 +    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
  33.123 +    if (rc < 0) {
  33.124 +        DPRINTF("couldn't set initrd reservation\n");
  33.125 +        return ~0UL;
  33.126 +    }
  33.127 +
  33.128      /* start-info (XXX being removed soon) */
  33.129 -    rc = ft_set_prop(&devtree, xen, "start-info",
  33.130 -            start_info, sizeof(start_info));
  33.131 +    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
  33.132      if (rc < 0) {
  33.133          DPRINTF("couldn't set /xen/start-info\n");
  33.134          return rc;
  33.135 @@ -218,93 +142,21 @@ static int load_devtree(
  33.136  
  33.137      header = devtree;
  33.138      devtree_size = header->totalsize;
  33.139 +    {
  33.140 +        static const char dtb[] = "/tmp/xc_domU.dtb";
  33.141 +        int dfd = creat(dtb, 0666);
  33.142 +        if (dfd != -1) {
  33.143 +            write(dfd, devtree, devtree_size);
  33.144 +            close(dfd);
  33.145 +        } else
  33.146 +            DPRINTF("could not open(\"%s\")\n", dtb);
  33.147 +    }
  33.148  
  33.149      DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
  33.150      return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
  33.151                         devtree_size);
  33.152  }
  33.153  
  33.154 -unsigned long spin_list[] = {
  33.155 -#if 0
  33.156 -    0x100,
  33.157 -    0x200,
  33.158 -    0x300,
  33.159 -    0x380,
  33.160 -    0x400,
  33.161 -    0x480,
  33.162 -    0x500,
  33.163 -    0x700,
  33.164 -    0x900,
  33.165 -    0xc00,
  33.166 -#endif
  33.167 -    0
  33.168 -};
  33.169 -
  33.170 -/* XXX yes, this is a hack */
  33.171 -static void hack_kernel_img(char *img)
  33.172 -{
  33.173 -    const off_t file_offset = 0x10000;
  33.174 -    unsigned long *addr = spin_list;
  33.175 -
  33.176 -    while (*addr) {
  33.177 -        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
  33.178 -        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
  33.179 -        *instruction = 0x48000000;
  33.180 -        addr++;
  33.181 -    }
  33.182 -}
  33.183 -
  33.184 -static int load_kernel(
  33.185 -    int xc_handle,
  33.186 -    int domid,
  33.187 -    const char *kernel_path,
  33.188 -    struct domain_setup_info *dsi,
  33.189 -    xen_pfn_t *page_array)
  33.190 -{
  33.191 -    struct load_funcs load_funcs;
  33.192 -    char *kernel_img;
  33.193 -    unsigned long kernel_size;
  33.194 -    int rc;
  33.195 -
  33.196 -    /* load the kernel ELF file */
  33.197 -    kernel_img = load_file(kernel_path, &kernel_size);
  33.198 -    if (kernel_img == NULL) {
  33.199 -        rc = -1;
  33.200 -        goto out;
  33.201 -    }
  33.202 -
  33.203 -    hack_kernel_img(kernel_img);
  33.204 -
  33.205 -    DPRINTF("probe_elf\n");
  33.206 -    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
  33.207 -    if (rc < 0) {
  33.208 -        rc = -1;
  33.209 -        printf("%s is not an ELF file\n", kernel_path);
  33.210 -        goto out;
  33.211 -    }
  33.212 -
  33.213 -    DPRINTF("parseimage\n");
  33.214 -    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
  33.215 -    if (rc < 0) {
  33.216 -        rc = -1;
  33.217 -        goto out;
  33.218 -    }
  33.219 -
  33.220 -    DPRINTF("loadimage\n");
  33.221 -    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
  33.222 -            page_array, dsi);
  33.223 -
  33.224 -    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
  33.225 -    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
  33.226 -    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
  33.227 -    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
  33.228 -    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
  33.229 -
  33.230 -out:
  33.231 -    free(kernel_img);
  33.232 -    return rc;
  33.233 -}
  33.234 -
  33.235  static int load_initrd(
  33.236      int xc_handle,
  33.237      int domid,
  33.238 @@ -334,49 +186,38 @@ out:
  33.239      return rc;
  33.240  }
  33.241  
  33.242 -static unsigned long create_start_info(start_info_t *si,
  33.243 +static unsigned long create_start_info(
  33.244 +	void *devtree, start_info_t *start_info,
  33.245          unsigned int console_evtchn, unsigned int store_evtchn,
  33.246 -        unsigned long nr_pages)
  33.247 +	unsigned long nr_pages, unsigned long rma_pages)
  33.248  {
  33.249 -    unsigned long si_addr;
  33.250 -
  33.251 -    memset(si, 0, sizeof(*si));
  33.252 -    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
  33.253 -
  33.254 -    si->nr_pages = nr_pages;
  33.255 -    si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
  33.256 -    si->store_mfn = si->nr_pages - 2;
  33.257 -    si->store_evtchn = store_evtchn;
  33.258 -    si->console.domU.mfn = si->nr_pages - 3;
  33.259 -    si->console.domU.evtchn = console_evtchn;
  33.260 -    si_addr = (si->nr_pages - 4) << PAGE_SHIFT;
  33.261 -
  33.262 -    return si_addr;
  33.263 -}
  33.264 -
  33.265 -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
  33.266 -                          unsigned long *nr_pages)
  33.267 -{
  33.268 +    unsigned long start_info_addr;
  33.269 +    uint64_t rma_top;
  33.270      int rc;
  33.271  
  33.272 -    DPRINTF("xc_get_tot_pages\n");
  33.273 -    *nr_pages = xc_get_tot_pages(xc_handle, domid);
  33.274 -    DPRINTF("  0x%lx\n", *nr_pages);
  33.275 +    memset(start_info, 0, sizeof(*start_info));
  33.276 +    snprintf(start_info->magic, sizeof(start_info->magic),
  33.277 +             "xen-%d.%d-powerpc64HV", 3, 0);
  33.278 +
  33.279 +    rma_top = rma_pages << PAGE_SHIFT;
  33.280 +    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
  33.281  
  33.282 -    *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
  33.283 -    if (*page_array == NULL) {
  33.284 -        perror("malloc");
  33.285 -        return -1;
  33.286 +    start_info->nr_pages = nr_pages;
  33.287 +    start_info->shared_info = rma_top - PAGE_SIZE;
  33.288 +    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
  33.289 +    start_info->store_evtchn = store_evtchn;
  33.290 +    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
  33.291 +    start_info->console.domU.evtchn = console_evtchn;
  33.292 +    start_info_addr = rma_top - 4*PAGE_SIZE;
  33.293 +
  33.294 +    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
  33.295 +    if (rc < 0) {
  33.296 +        DPRINTF("couldn't set start_info reservation\n");
  33.297 +        return ~0UL;
  33.298      }
  33.299  
  33.300 -    DPRINTF("xc_get_pfn_list\n");
  33.301 -    rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
  33.302 -    if (rc != *nr_pages) {
  33.303 -        perror("Could not get the page frame list");
  33.304 -        return -1;
  33.305 -    }
  33.306  
  33.307 -    return 0;
  33.308 +    return start_info_addr;
  33.309  }
  33.310  
  33.311  static void free_page_array(xen_pfn_t *page_array)
  33.312 @@ -388,6 +229,7 @@ static void free_page_array(xen_pfn_t *p
  33.313  
  33.314  int xc_linux_build(int xc_handle,
  33.315                     uint32_t domid,
  33.316 +                   unsigned int mem_mb,
  33.317                     const char *image_name,
  33.318                     const char *initrd_name,
  33.319                     const char *cmdline,
  33.320 @@ -399,7 +241,7 @@ int xc_linux_build(int xc_handle,
  33.321                     unsigned long *console_mfn,
  33.322                     void *devtree)
  33.323  {
  33.324 -    start_info_t si;
  33.325 +    start_info_t start_info;
  33.326      struct domain_setup_info dsi;
  33.327      xen_pfn_t *page_array = NULL;
  33.328      unsigned long nr_pages;
  33.329 @@ -407,18 +249,28 @@ int xc_linux_build(int xc_handle,
  33.330      unsigned long kern_addr;
  33.331      unsigned long initrd_base = 0;
  33.332      unsigned long initrd_len = 0;
  33.333 -    unsigned long si_addr;
  33.334 +    unsigned long start_info_addr;
  33.335 +    unsigned long rma_pages;
  33.336      int rc = 0;
  33.337  
  33.338      DPRINTF("%s\n", __func__);
  33.339  
  33.340 -    if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
  33.341 +    nr_pages = mem_mb << (20 - PAGE_SHIFT);
  33.342 +    DPRINTF("nr_pages 0x%lx\n", nr_pages);
  33.343 +
  33.344 +    rma_pages = get_rma_pages(devtree);
  33.345 +    if (rma_pages == 0) {
  33.346 +	    rc = -1;
  33.347 +	    goto out;
  33.348 +    }
  33.349 +
  33.350 +    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
  33.351          rc = -1;
  33.352          goto out;
  33.353      }
  33.354  
  33.355      DPRINTF("loading image '%s'\n", image_name);
  33.356 -    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  33.357 +    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  33.358          rc = -1;
  33.359          goto out;
  33.360      }
  33.361 @@ -434,11 +286,12 @@ int xc_linux_build(int xc_handle,
  33.362      }
  33.363  
  33.364      /* start_info stuff: about to be removed  */
  33.365 -    si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
  33.366 -    *console_mfn = page_array[si.console.domU.mfn];
  33.367 -    *store_mfn = page_array[si.store_mfn];
  33.368 -    if (install_image(xc_handle, domid, page_array, &si, si_addr,
  33.369 -                sizeof(start_info_t))) {
  33.370 +    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
  33.371 +                                        store_evtchn, nr_pages, rma_pages);
  33.372 +    *console_mfn = page_array[start_info.console.domU.mfn];
  33.373 +    *store_mfn = page_array[start_info.store_mfn];
  33.374 +    if (install_image(xc_handle, domid, page_array, &start_info,
  33.375 +                      start_info_addr, sizeof(start_info_t))) {
  33.376          rc = -1;
  33.377          goto out;
  33.378      }
  33.379 @@ -447,7 +300,8 @@ int xc_linux_build(int xc_handle,
  33.380          DPRINTF("loading flattened device tree\n");
  33.381          devtree_addr = DEVTREE_ADDR;
  33.382          if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
  33.383 -                     initrd_base, initrd_len, &si, si_addr)) {
  33.384 +                         initrd_base, initrd_len, &start_info,
  33.385 +                         start_info_addr)) {
  33.386              DPRINTF("couldn't load flattened device tree.\n");
  33.387              rc = -1;
  33.388              goto out;
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tools/libxc/powerpc64/xc_prose_build.c	Fri Dec 15 11:32:58 2006 -0700
    34.3 @@ -0,0 +1,323 @@
    34.4 +/*
    34.5 + * This program is free software; you can redistribute it and/or modify
    34.6 + * it under the terms of the GNU General Public License as published by
    34.7 + * the Free Software Foundation; either version 2 of the License, or
    34.8 + * (at your option) any later version.
    34.9 + *
   34.10 + * This program is distributed in the hope that it will be useful,
   34.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.13 + * GNU General Public License for more details.
   34.14 + *
   34.15 + * You should have received a copy of the GNU General Public License
   34.16 + * along with this program; if not, write to the Free Software
   34.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   34.18 + *
   34.19 + * Copyright (C) IBM Corporation 2006
   34.20 + *
   34.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   34.22 + *          Jonathan Appavoo <jappavoo@us.ibm.com>
   34.23 + */
   34.24 +
   34.25 +#include <stdio.h>
   34.26 +#include <stdint.h>
   34.27 +#include <stdlib.h>
   34.28 +#include <string.h>
   34.29 +#include <unistd.h>
   34.30 +#include <fcntl.h>
   34.31 +#include <sys/types.h>
   34.32 +#include <inttypes.h>
   34.33 +
   34.34 +#include <xen/xen.h>
   34.35 +#include <xen/memory.h>
   34.36 +#include <xc_private.h>
   34.37 +#include <xg_private.h>
   34.38 +#include <xenctrl.h>
   34.39 +
   34.40 +#include "flatdevtree_env.h"
   34.41 +#include "flatdevtree.h"
   34.42 +#include "utils.h"
   34.43 +
   34.44 +#define INITRD_ADDR (24UL << 20)
   34.45 +#define DEVTREE_ADDR (16UL << 20)
   34.46 +
   34.47 +static int init_boot_vcpu(
   34.48 +    int xc_handle,
   34.49 +    int domid,
   34.50 +    struct domain_setup_info *dsi,
   34.51 +    unsigned long devtree_addr,
   34.52 +    unsigned long kern_addr)
   34.53 +{
   34.54 +    vcpu_guest_context_t ctxt;
   34.55 +    int rc;
   34.56 +
   34.57 +    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   34.58 +    ctxt.user_regs.pc = dsi->v_kernentry;
   34.59 +    ctxt.user_regs.msr = 0;
   34.60 +    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   34.61 +    ctxt.user_regs.gprs[3] = devtree_addr;
   34.62 +    ctxt.user_regs.gprs[4] = kern_addr;
   34.63 +    ctxt.user_regs.gprs[5] = 0; /* reserved for specifying OF handler */
   34.64 +    /* There is a buggy kernel that does not zero the "local_paca", so
   34.65 +     * we must make sure this register is 0 */
   34.66 +    ctxt.user_regs.gprs[13] = 0;
   34.67 +
   34.68 +    DPRINTF("xc_vcpu_setvcpucontext:\n"
   34.69 +                 "  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
   34.70 +                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   34.71 +                 " %016"PRIx64"\n",
   34.72 +                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   34.73 +                 ctxt.user_regs.gprs[1],
   34.74 +                 ctxt.user_regs.gprs[2],
   34.75 +                 ctxt.user_regs.gprs[3],
   34.76 +                 ctxt.user_regs.gprs[4],
   34.77 +                 ctxt.user_regs.gprs[5]);
   34.78 +    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   34.79 +    if (rc < 0)
   34.80 +        perror("setdomaininfo");
   34.81 +
   34.82 +    return rc;
   34.83 +}
   34.84 +
   34.85 +static int load_devtree(
   34.86 +    int xc_handle,
   34.87 +    int domid,
   34.88 +    xen_pfn_t *page_array,
   34.89 +    void *devtree,
   34.90 +    unsigned long devtree_addr,
   34.91 +    uint64_t initrd_base,
   34.92 +    unsigned long initrd_len,
   34.93 +    start_info_t *start_info __attribute__((unused)),
   34.94 +    unsigned long start_info_addr)
   34.95 +{
   34.96 +    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
   34.97 +    struct boot_param_header *header;
   34.98 +    void *chosen;
   34.99 +    void *xen;
  34.100 +    uint64_t initrd_end = initrd_base + initrd_len;
  34.101 +    unsigned int devtree_size;
  34.102 +    int rc = 0;
  34.103 +
  34.104 +    DPRINTF("adding initrd props\n");
  34.105 +
  34.106 +    chosen = ft_find_node(devtree, "/chosen");
  34.107 +    if (chosen == NULL) {
  34.108 +        DPRINTF("couldn't find /chosen\n");
  34.109 +        return -1;
  34.110 +    }
  34.111 +
  34.112 +    xen = ft_find_node(devtree, "/xen");
  34.113 +    if (xen == NULL) {
  34.114 +        DPRINTF("couldn't find /xen\n");
  34.115 +        return -1;
  34.116 +    }
  34.117 +
  34.118 +    /* initrd-start */
  34.119 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
  34.120 +            &initrd_base, sizeof(initrd_base));
  34.121 +    if (rc < 0) {
  34.122 +        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
  34.123 +        return rc;
  34.124 +    }
  34.125 +
  34.126 +    /* initrd-end */
  34.127 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
  34.128 +            &initrd_end, sizeof(initrd_end));
  34.129 +    if (rc < 0) {
  34.130 +        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
  34.131 +        return rc;
  34.132 +    }
  34.133 +
  34.134 +    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
  34.135 +    if (rc < 0) {
  34.136 +        DPRINTF("couldn't set initrd reservation\n");
  34.137 +        return ~0UL;
  34.138 +    }
  34.139 +
  34.140 +    /* start-info (XXX being removed soon) */
  34.141 +    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
  34.142 +    if (rc < 0) {
  34.143 +        DPRINTF("couldn't set /xen/start-info\n");
  34.144 +        return rc;
  34.145 +    }
  34.146 +
  34.147 +    header = devtree;
  34.148 +    devtree_size = header->totalsize;
  34.149 +    {
  34.150 +        static const char dtb[] = "/tmp/xc_domU.dtb";
  34.151 +        int dfd = creat(dtb, 0666);
  34.152 +        if (dfd != -1) {
  34.153 +            write(dfd, devtree, devtree_size);
  34.154 +            close(dfd);
  34.155 +        } else
  34.156 +            DPRINTF("could not open(\"%s\")\n", dtb);
  34.157 +    }
  34.158 +
  34.159 +    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
  34.160 +    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
  34.161 +                       devtree_size);
  34.162 +}
  34.163 +
  34.164 +static int load_initrd(
  34.165 +    int xc_handle,
  34.166 +    int domid,
  34.167 +    xen_pfn_t *page_array,
  34.168 +    const char *initrd_path,
  34.169 +    unsigned long *base,
  34.170 +    unsigned long *len)
  34.171 +{
  34.172 +    uint8_t *initrd_img;
  34.173 +    int rc = -1;
  34.174 +
  34.175 +    /* load the initrd file */
  34.176 +    initrd_img = load_file(initrd_path, len);
  34.177 +    if (initrd_img == NULL)
  34.178 +        return -1;
  34.179 +
  34.180 +    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
  34.181 +    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
  34.182 +                *len))
  34.183 +        goto out;
  34.184 +
  34.185 +    *base = INITRD_ADDR;
  34.186 +    rc = 0;
  34.187 +
  34.188 +out:
  34.189 +    free(initrd_img);
  34.190 +    return rc;
  34.191 +}
  34.192 +
  34.193 +static unsigned long create_start_info(
  34.194 +	void *devtree, start_info_t *start_info,
  34.195 +        unsigned int console_evtchn, unsigned int store_evtchn,
  34.196 +	unsigned long nr_pages, unsigned long rma_pages, const char *cmdline)
  34.197 +{
  34.198 +    unsigned long start_info_addr;
  34.199 +    uint64_t rma_top;
  34.200 +    int rc;
  34.201 +
  34.202 +    memset(start_info, 0, sizeof(*start_info));
  34.203 +    snprintf(start_info->magic, sizeof(start_info->magic),
  34.204 +             "xen-%d.%d-powerpc64HV", 3, 0);
  34.205 +
  34.206 +    rma_top = rma_pages << PAGE_SHIFT;
  34.207 +    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
  34.208 +
  34.209 +    start_info->nr_pages = nr_pages;
  34.210 +    start_info->shared_info = rma_top - PAGE_SIZE;
  34.211 +    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
  34.212 +    start_info->store_evtchn = store_evtchn;
  34.213 +    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
  34.214 +    start_info->console.domU.evtchn = console_evtchn;
  34.215 +    strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
  34.216 +    /* just in case we truncated cmdline with strncpy add 0 at the end */
  34.217 +    start_info->cmd_line[MAX_GUEST_CMDLINE-1]=0;
  34.218 +    start_info_addr = rma_top - 4*PAGE_SIZE;
  34.219 +
  34.220 +    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
  34.221 +    if (rc < 0) {
  34.222 +        DPRINTF("couldn't set start_info reservation\n");
  34.223 +        return ~0UL;
  34.224 +    }
  34.225 +
  34.226 +    return start_info_addr;
  34.227 +}
  34.228 +
  34.229 +static void free_page_array(xen_pfn_t *page_array)
  34.230 +{
  34.231 +    free(page_array);
  34.232 +}
  34.233 +
  34.234 +int xc_prose_build(int xc_handle,
  34.235 +                   uint32_t domid,
  34.236 +                   unsigned int mem_mb,
  34.237 +                   const char *image_name,
  34.238 +                   const char *initrd_name,
  34.239 +                   const char *cmdline,
  34.240 +                   const char *features,
  34.241 +                   unsigned long flags,
  34.242 +                   unsigned int store_evtchn,
  34.243 +                   unsigned long *store_mfn,
  34.244 +                   unsigned int console_evtchn,
  34.245 +                   unsigned long *console_mfn,
  34.246 +                   void *devtree)
  34.247 +{
  34.248 +    start_info_t start_info;
  34.249 +    struct domain_setup_info dsi;
  34.250 +    xen_pfn_t *page_array = NULL;
  34.251 +    unsigned long nr_pages;
  34.252 +    unsigned long devtree_addr = 0;
  34.253 +    unsigned long kern_addr;
  34.254 +    unsigned long initrd_base = 0;
  34.255 +    unsigned long initrd_len = 0;
  34.256 +    unsigned long start_info_addr;
  34.257 +    unsigned long rma_pages;
  34.258 +    int rc = 0;
  34.259 +
  34.260 +    DPRINTF("%s\n", __func__);
  34.261 +
  34.262 +    DPRINTF("cmdline=%s\n", cmdline);
  34.263 +
  34.264 +    nr_pages = mem_mb << (20 - PAGE_SHIFT);
  34.265 +    DPRINTF("nr_pages 0x%lx\n", nr_pages);
  34.266 +
  34.267 +    rma_pages = get_rma_pages(devtree);
  34.268 +    if (rma_pages == 0) {
  34.269 +	    rc = -1;
  34.270 +	    goto out;
  34.271 +    }
  34.272 +
  34.273 +    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
  34.274 +        rc = -1;
  34.275 +        goto out;
  34.276 +    }
  34.277 +
  34.278 +    DPRINTF("loading image '%s'\n", image_name);
  34.279 +    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  34.280 +        rc = -1;
  34.281 +        goto out;
  34.282 +    }
  34.283 +    kern_addr = 0;
  34.284 +
  34.285 +    if (initrd_name && initrd_name[0] != '\0') {
  34.286 +        DPRINTF("loading initrd '%s'\n", initrd_name);
  34.287 +        if (load_initrd(xc_handle, domid, page_array, initrd_name,
  34.288 +                &initrd_base, &initrd_len)) {
  34.289 +            rc = -1;
  34.290 +            goto out;
  34.291 +        }
  34.292 +    }
  34.293 +
  34.294 +    /* start_info stuff: about to be removed  */
  34.295 +    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
  34.296 +                                        store_evtchn, nr_pages,
  34.297 +					rma_pages, cmdline);
  34.298 +    *console_mfn = page_array[start_info.console.domU.mfn];
  34.299 +    *store_mfn = page_array[start_info.store_mfn];
  34.300 +    if (install_image(xc_handle, domid, page_array, &start_info,
  34.301 +                      start_info_addr, sizeof(start_info_t))) {
  34.302 +        rc = -1;
  34.303 +        goto out;
  34.304 +    }
  34.305 +
  34.306 +    if (devtree) {
  34.307 +        DPRINTF("loading flattened device tree\n");
  34.308 +        devtree_addr = DEVTREE_ADDR;
  34.309 +        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
  34.310 +                         initrd_base, initrd_len, &start_info,
  34.311 +                         start_info_addr)) {
  34.312 +            DPRINTF("couldn't load flattened device tree.\n");
  34.313 +            rc = -1;
  34.314 +            goto out;
  34.315 +        }
  34.316 +    }
  34.317 +
  34.318 +    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
  34.319 +        rc = -1;
  34.320 +        goto out;
  34.321 +    }
  34.322 +
  34.323 +out:
  34.324 +    free_page_array(page_array);
  34.325 +    return rc;
  34.326 +}
    35.1 --- a/tools/libxc/xc_linux_build.c	Fri Dec 15 10:59:33 2006 -0700
    35.2 +++ b/tools/libxc/xc_linux_build.c	Fri Dec 15 11:32:58 2006 -0700
    35.3 @@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
    35.4      }
    35.5  
    35.6      if (strstr(xen_caps, "xen-3.0-x86_32p")) {
    35.7 -        if (dsi->pae_kernel == PAEKERN_no) {
    35.8 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
    35.9 +            dsi->pae_kernel = PAEKERN_extended_cr3;
   35.10 +        } else if (dsi->pae_kernel == PAEKERN_no) {
   35.11              xc_set_error(XC_INVALID_KERNEL,
   35.12                           "Non PAE-kernel on PAE host.");
   35.13              return 0;
   35.14          }
   35.15 -    } else if (dsi->pae_kernel != PAEKERN_no) {
   35.16 -        xc_set_error(XC_INVALID_KERNEL,
   35.17 -                     "PAE-kernel on non-PAE host.");
   35.18 -        return 0;
   35.19 +    } else {
   35.20 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
   35.21 +            dsi->pae_kernel = PAEKERN_no;
   35.22 +        } else if (dsi->pae_kernel != PAEKERN_no) {
   35.23 +            xc_set_error(XC_INVALID_KERNEL,
   35.24 +                         "PAE-kernel on non-PAE host.");
   35.25 +            return 0;
   35.26 +        }
   35.27      }
   35.28  
   35.29      return 1;
    36.1 --- a/tools/libxc/xc_load_elf.c	Fri Dec 15 10:59:33 2006 -0700
    36.2 +++ b/tools/libxc/xc_load_elf.c	Fri Dec 15 11:32:58 2006 -0700
    36.3 @@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
    36.4          return -EINVAL;
    36.5      }
    36.6  
    36.7 -    /* Find the section-header strings table. */
    36.8 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
    36.9 -    {
   36.10 -        xc_set_error(XC_INVALID_KERNEL,
   36.11 -                     "ELF image has no section-header strings table (shstrtab).");
   36.12 -        return -EINVAL;
   36.13 -    }
   36.14 -    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
   36.15 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
   36.16 -    shstrtab = image + shdr->sh_offset;
   36.17 -
   36.18      dsi->__elfnote_section = NULL;
   36.19      dsi->__xen_guest_string = NULL;
   36.20  
   36.21 @@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
   36.22      /* Fall back to looking for the special '__xen_guest' section. */
   36.23      if ( dsi->__elfnote_section == NULL )
   36.24      {
   36.25 +        /* Find the section-header strings table. */
   36.26 +        if ( ehdr->e_shstrndx == SHN_UNDEF )
   36.27 +        {
   36.28 +            xc_set_error(XC_INVALID_KERNEL,
   36.29 +                         "ELF image has no section-header strings table.");
   36.30 +            return -EINVAL;
   36.31 +        }
   36.32 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
   36.33 +                            (ehdr->e_shstrndx*ehdr->e_shentsize));
   36.34 +        shstrtab = image + shdr->sh_offset;
   36.35 +
   36.36          for ( h = 0; h < ehdr->e_shnum; h++ )
   36.37          {
   36.38              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   36.39 @@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
   36.40      }
   36.41  
   36.42      /*
   36.43 +     * A "bimodal" ELF note indicates the kernel will adjust to the
   36.44 +     * current paging mode, including handling extended cr3 syntax.
   36.45       * If we have ELF notes then PAE=yes implies that we must support
   36.46       * the extended cr3 syntax. Otherwise we need to find the
   36.47       * [extended-cr3] syntax in the __xen_guest string.
   36.48 @@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
   36.49      if ( dsi->__elfnote_section )
   36.50      {
   36.51          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   36.52 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   36.53 +        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
   36.54 +            dsi->pae_kernel = PAEKERN_bimodal;
   36.55 +        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   36.56              dsi->pae_kernel = PAEKERN_extended_cr3;
   36.57  
   36.58      }
    37.1 --- a/tools/libxc/xenctrl.h	Fri Dec 15 10:59:33 2006 -0700
    37.2 +++ b/tools/libxc/xenctrl.h	Fri Dec 15 11:32:58 2006 -0700
    37.3 @@ -728,4 +728,8 @@ const char *xc_error_code_to_desc(int co
    37.4   */
    37.5  xc_error_handler xc_set_error_handler(xc_error_handler handler);
    37.6  
    37.7 +/* PowerPC specific. */
    37.8 +int xc_alloc_real_mode_area(int xc_handle,
    37.9 +                            uint32_t domid,
   37.10 +                            unsigned int log);
   37.11  #endif
    38.1 --- a/tools/libxc/xenguest.h	Fri Dec 15 10:59:33 2006 -0700
    38.2 +++ b/tools/libxc/xenguest.h	Fri Dec 15 11:32:58 2006 -0700
    38.3 @@ -122,4 +122,19 @@ int xc_set_hvm_param(
    38.4  int xc_get_hvm_param(
    38.5      int handle, domid_t dom, int param, unsigned long *value);
    38.6  
    38.7 +/* PowerPC specific. */
    38.8 +int xc_prose_build(int xc_handle,
    38.9 +                   uint32_t domid,
   38.10 +                   unsigned int mem_mb,
   38.11 +                   const char *image_name,
   38.12 +                   const char *ramdisk_name,
   38.13 +                   const char *cmdline,
   38.14 +                   const char *features,
   38.15 +                   unsigned long flags,
   38.16 +                   unsigned int store_evtchn,
   38.17 +                   unsigned long *store_mfn,
   38.18 +                   unsigned int console_evtchn,
   38.19 +                   unsigned long *console_mfn,
   38.20 +                   void *arch_args);
   38.21 +
   38.22  #endif /* XENGUEST_H */
    39.1 --- a/tools/libxc/xg_private.h	Fri Dec 15 10:59:33 2006 -0700
    39.2 +++ b/tools/libxc/xg_private.h	Fri Dec 15 11:32:58 2006 -0700
    39.3 @@ -132,6 +132,7 @@ struct domain_setup_info
    39.4  #define PAEKERN_no           0
    39.5  #define PAEKERN_yes          1
    39.6  #define PAEKERN_extended_cr3 2
    39.7 +#define PAEKERN_bimodal      3
    39.8      unsigned int  pae_kernel;
    39.9  
   39.10      unsigned int  load_symtab;
    40.1 --- a/tools/libxen/include/xen_boot_type.h	Fri Dec 15 10:59:33 2006 -0700
    40.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.3 @@ -1,87 +0,0 @@
    40.4 -/*
    40.5 - * Copyright (c) 2006, XenSource Inc.
    40.6 - *
    40.7 - * This library is free software; you can redistribute it and/or
    40.8 - * modify it under the terms of the GNU Lesser General Public
    40.9 - * License as published by the Free Software Foundation; either
   40.10 - * version 2.1 of the License, or (at your option) any later version.
   40.11 - *
   40.12 - * This library is distributed in the hope that it will be useful,
   40.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   40.15 - * Lesser General Public License for more details.
   40.16 - *
   40.17 - * You should have received a copy of the GNU Lesser General Public
   40.18 - * License along with this library; if not, write to the Free Software
   40.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   40.20 - */
   40.21 -
   40.22 -#ifndef XEN_BOOT_TYPE_H
   40.23 -#define XEN_BOOT_TYPE_H
   40.24 -
   40.25 -
   40.26 -#include "xen_common.h"
   40.27 -
   40.28 -
   40.29 -enum xen_boot_type
   40.30 -{
   40.31 -    /**
   40.32 -     * boot an HVM guest using an emulated BIOS
   40.33 -     */
   40.34 -    XEN_BOOT_TYPE_BIOS,
   40.35 -
   40.36 -    /**
   40.37 -     * boot from inside the machine using grub
   40.38 -     */
   40.39 -    XEN_BOOT_TYPE_GRUB,
   40.40 -
   40.41 -    /**
   40.42 -     * boot from an external kernel
   40.43 -     */
   40.44 -    XEN_BOOT_TYPE_KERNEL_EXTERNAL,
   40.45 -
   40.46 -    /**
   40.47 -     * boot from a kernel inside the guest filesystem
   40.48 -     */
   40.49 -    XEN_BOOT_TYPE_KERNEL_INTERNAL
   40.50 -};
   40.51 -
   40.52 -
   40.53 -typedef struct xen_boot_type_set
   40.54 -{
   40.55 -    size_t size;
   40.56 -    enum xen_boot_type contents[];
   40.57 -} xen_boot_type_set;
   40.58 -
   40.59 -/**
   40.60 - * Allocate a xen_boot_type_set of the given size.
   40.61 - */
   40.62 -extern xen_boot_type_set *
   40.63 -xen_boot_type_set_alloc(size_t size);
   40.64 -
   40.65 -/**
   40.66 - * Free the given xen_boot_type_set.  The given set must have been
   40.67 - * allocated by this library.
   40.68 - */
   40.69 -extern void
   40.70 -xen_boot_type_set_free(xen_boot_type_set *set);
   40.71 -
   40.72 -
   40.73 -/**
   40.74 - * Return the name corresponding to the given code.  This string must
   40.75 - * not be modified or freed.
   40.76 - */
   40.77 -extern const char *
   40.78 -xen_boot_type_to_string(enum xen_boot_type val);
   40.79 -
   40.80 -
   40.81 -/**
   40.82 - * Return the correct code for the given string, or set the session
   40.83 - * object to failure and return an undefined value if the given string does
   40.84 - * not match a known code.
   40.85 - */
   40.86 -extern enum xen_boot_type
   40.87 -xen_boot_type_from_string(xen_session *session, const char *str);
   40.88 -
   40.89 -
   40.90 -#endif
    41.1 --- a/tools/libxen/include/xen_boot_type_internal.h	Fri Dec 15 10:59:33 2006 -0700
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,37 +0,0 @@
    41.4 -/*
    41.5 - * Copyright (c) 2006, XenSource Inc.
    41.6 - *
    41.7 - * This library is free software; you can redistribute it and/or
    41.8 - * modify it under the terms of the GNU Lesser General Public
    41.9 - * License as published by the Free Software Foundation; either
   41.10 - * version 2.1 of the License, or (at your option) any later version.
   41.11 - *
   41.12 - * This library is distributed in the hope that it will be useful,
   41.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   41.15 - * Lesser General Public License for more details.
   41.16 - *
   41.17 - * You should have received a copy of the GNU Lesser General Public
   41.18 - * License along with this library; if not, write to the Free Software
   41.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   41.20 - */
   41.21 -
   41.22 -
   41.23 -/*
   41.24 - * Declarations of the abstract types used during demarshalling of enum
   41.25 - * xen_boot_type.  Internal to this library -- do not use from outside.
   41.26 - */
   41.27 -
   41.28 -
   41.29 -#ifndef XEN_BOOT_TYPE_INTERNAL_H
   41.30 -#define XEN_BOOT_TYPE_INTERNAL_H
   41.31 -
   41.32 -
   41.33 -#include "xen_internal.h"
   41.34 -
   41.35 -
   41.36 -extern const abstract_type xen_boot_type_abstract_type_;
   41.37 -extern const abstract_type xen_boot_type_set_abstract_type_;
   41.38 -
   41.39 -
   41.40 -#endif
    42.1 --- a/tools/libxen/include/xen_console.h	Fri Dec 15 10:59:33 2006 -0700
    42.2 +++ b/tools/libxen/include/xen_console.h	Fri Dec 15 11:32:58 2006 -0700
    42.3 @@ -149,14 +149,14 @@ xen_console_record_opt_set_free(xen_cons
    42.4  
    42.5  
    42.6  /**
    42.7 - * Get the current state of the given console.
    42.8 + * Get a record containing the current state of the given console.
    42.9   */
   42.10  extern bool
   42.11  xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console);
   42.12  
   42.13  
   42.14  /**
   42.15 - * Get a reference to the object with the specified UUID.
   42.16 + * Get a reference to the console instance with the specified UUID.
   42.17   */
   42.18  extern bool
   42.19  xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid);
    43.1 --- a/tools/libxen/include/xen_host.h	Fri Dec 15 10:59:33 2006 -0700
    43.2 +++ b/tools/libxen/include/xen_host.h	Fri Dec 15 11:32:58 2006 -0700
    43.3 @@ -154,14 +154,14 @@ xen_host_record_opt_set_free(xen_host_re
    43.4  
    43.5  
    43.6  /**
    43.7 - * Get the current state of the given host.  !!!
    43.8 + * Get a record containing the current state of the given host.
    43.9   */
   43.10  extern bool
   43.11  xen_host_get_record(xen_session *session, xen_host_record **result, xen_host host);
   43.12  
   43.13  
   43.14  /**
   43.15 - * Get a reference to the object with the specified UUID.  !!!
   43.16 + * Get a reference to the host instance with the specified UUID.
   43.17   */
   43.18  extern bool
   43.19  xen_host_get_by_uuid(xen_session *session, xen_host *result, char *uuid);
    44.1 --- a/tools/libxen/include/xen_host_cpu.h	Fri Dec 15 10:59:33 2006 -0700
    44.2 +++ b/tools/libxen/include/xen_host_cpu.h	Fri Dec 15 11:32:58 2006 -0700
    44.3 @@ -153,14 +153,14 @@ xen_host_cpu_record_opt_set_free(xen_hos
    44.4  
    44.5  
    44.6  /**
    44.7 - * Get the current state of the given host_cpu.  !!!
    44.8 + * Get a record containing the current state of the given host_cpu.
    44.9   */
   44.10  extern bool
   44.11  xen_host_cpu_get_record(xen_session *session, xen_host_cpu_record **result, xen_host_cpu host_cpu);
   44.12  
   44.13  
   44.14  /**
   44.15 - * Get a reference to the object with the specified UUID.  !!!
   44.16 + * Get a reference to the host_cpu instance with the specified UUID.
   44.17   */
   44.18  extern bool
   44.19  xen_host_cpu_get_by_uuid(xen_session *session, xen_host_cpu *result, char *uuid);
    45.1 --- a/tools/libxen/include/xen_internal.h	Fri Dec 15 10:59:33 2006 -0700
    45.2 +++ b/tools/libxen/include/xen_internal.h	Fri Dec 15 11:32:58 2006 -0700
    45.3 @@ -128,7 +128,6 @@ xen_enum_lookup_(xen_session *session, c
    45.4      xen_enum_lookup_(session__, str__, lookup_table__,  \
    45.5                       sizeof(lookup_table__) /           \
    45.6                       sizeof(lookup_table__[0]))         \
    45.7 -                                                        \
    45.8  
    45.9  #define XEN_ALLOC(type__)                       \
   45.10  type__ *                                        \
    46.1 --- a/tools/libxen/include/xen_network.h	Fri Dec 15 10:59:33 2006 -0700
    46.2 +++ b/tools/libxen/include/xen_network.h	Fri Dec 15 11:32:58 2006 -0700
    46.3 @@ -152,14 +152,14 @@ xen_network_record_opt_set_free(xen_netw
    46.4  
    46.5  
    46.6  /**
    46.7 - * Get the current state of the given network.  !!!
    46.8 + * Get a record containing the current state of the given network.
    46.9   */
   46.10  extern bool
   46.11  xen_network_get_record(xen_session *session, xen_network_record **result, xen_network network);
   46.12  
   46.13  
   46.14  /**
   46.15 - * Get a reference to the object with the specified UUID.  !!!
   46.16 + * Get a reference to the network instance with the specified UUID.
   46.17   */
   46.18  extern bool
   46.19  xen_network_get_by_uuid(xen_session *session, xen_network *result, char *uuid);
    47.1 --- a/tools/libxen/include/xen_pif.h	Fri Dec 15 10:59:33 2006 -0700
    47.2 +++ b/tools/libxen/include/xen_pif.h	Fri Dec 15 11:32:58 2006 -0700
    47.3 @@ -155,14 +155,14 @@ xen_pif_record_opt_set_free(xen_pif_reco
    47.4  
    47.5  
    47.6  /**
    47.7 - * Get the current state of the given PIF.  !!!
    47.8 + * Get a record containing the current state of the given PIF.
    47.9   */
   47.10  extern bool
   47.11  xen_pif_get_record(xen_session *session, xen_pif_record **result, xen_pif pif);
   47.12  
   47.13  
   47.14  /**
   47.15 - * Get a reference to the object with the specified UUID.  !!!
   47.16 + * Get a reference to the PIF instance with the specified UUID.
   47.17   */
   47.18  extern bool
   47.19  xen_pif_get_by_uuid(xen_session *session, xen_pif *result, char *uuid);
    48.1 --- a/tools/libxen/include/xen_sr.h	Fri Dec 15 10:59:33 2006 -0700
    48.2 +++ b/tools/libxen/include/xen_sr.h	Fri Dec 15 11:32:58 2006 -0700
    48.3 @@ -153,14 +153,14 @@ xen_sr_record_opt_set_free(xen_sr_record
    48.4  
    48.5  
    48.6  /**
    48.7 - * Get the current state of the given SR.  !!!
    48.8 + * Get a record containing the current state of the given SR.
    48.9   */
   48.10  extern bool
   48.11  xen_sr_get_record(xen_session *session, xen_sr_record **result, xen_sr sr);
   48.12  
   48.13  
   48.14  /**
   48.15 - * Get a reference to the object with the specified UUID.  !!!
   48.16 + * Get a reference to the SR instance with the specified UUID.
   48.17   */
   48.18  extern bool
   48.19  xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid);
    49.1 --- a/tools/libxen/include/xen_user.h	Fri Dec 15 10:59:33 2006 -0700
    49.2 +++ b/tools/libxen/include/xen_user.h	Fri Dec 15 11:32:58 2006 -0700
    49.3 @@ -146,14 +146,14 @@ xen_user_record_opt_set_free(xen_user_re
    49.4  
    49.5  
    49.6  /**
    49.7 - * Get the current state of the given user.  !!!
    49.8 + * Get a record containing the current state of the given user.
    49.9   */
   49.10  extern bool
   49.11  xen_user_get_record(xen_session *session, xen_user_record **result, xen_user user);
   49.12  
   49.13  
   49.14  /**
   49.15 - * Get a reference to the object with the specified UUID.  !!!
   49.16 + * Get a reference to the user instance with the specified UUID.
   49.17   */
   49.18  extern bool
   49.19  xen_user_get_by_uuid(xen_session *session, xen_user *result, char *uuid);
    50.1 --- a/tools/libxen/include/xen_vdi.h	Fri Dec 15 10:59:33 2006 -0700
    50.2 +++ b/tools/libxen/include/xen_vdi.h	Fri Dec 15 11:32:58 2006 -0700
    50.3 @@ -159,14 +159,14 @@ xen_vdi_record_opt_set_free(xen_vdi_reco
    50.4  
    50.5  
    50.6  /**
    50.7 - * Get the current state of the given VDI.  !!!
    50.8 + * Get a record containing the current state of the given VDI.
    50.9   */
   50.10  extern bool
   50.11  xen_vdi_get_record(xen_session *session, xen_vdi_record **result, xen_vdi vdi);
   50.12  
   50.13  
   50.14  /**
   50.15 - * Get a reference to the object with the specified UUID.  !!!
   50.16 + * Get a reference to the VDI instance with the specified UUID.
   50.17   */
   50.18  extern bool
   50.19  xen_vdi_get_by_uuid(xen_session *session, xen_vdi *result, char *uuid);
    51.1 --- a/tools/libxen/include/xen_vif.h	Fri Dec 15 10:59:33 2006 -0700
    51.2 +++ b/tools/libxen/include/xen_vif.h	Fri Dec 15 11:32:58 2006 -0700
    51.3 @@ -156,14 +156,14 @@ xen_vif_record_opt_set_free(xen_vif_reco
    51.4  
    51.5  
    51.6  /**
    51.7 - * Get the current state of the given VIF.  !!!
    51.8 + * Get a record containing the current state of the given VIF.
    51.9   */
   51.10  extern bool
   51.11  xen_vif_get_record(xen_session *session, xen_vif_record **result, xen_vif vif);
   51.12  
   51.13  
   51.14  /**
   51.15 - * Get a reference to the object with the specified UUID.  !!!
   51.16 + * Get a reference to the VIF instance with the specified UUID.
   51.17   */
   51.18  extern bool
   51.19  xen_vif_get_by_uuid(xen_session *session, xen_vif *result, char *uuid);
    52.1 --- a/tools/libxen/include/xen_vm.h	Fri Dec 15 10:59:33 2006 -0700
    52.2 +++ b/tools/libxen/include/xen_vm.h	Fri Dec 15 11:32:58 2006 -0700
    52.3 @@ -19,7 +19,6 @@
    52.4  #ifndef XEN_VM_H
    52.5  #define XEN_VM_H
    52.6  
    52.7 -#include "xen_boot_type.h"
    52.8  #include "xen_common.h"
    52.9  #include "xen_console_decl.h"
   52.10  #include "xen_cpu_feature.h"
   52.11 @@ -36,9 +35,36 @@
   52.12  
   52.13  
   52.14  /*
   52.15 - * The VM class. 
   52.16 - *  
   52.17 + * The VM class.
   52.18 + * 
   52.19   * A virtual machine (or 'guest').
   52.20 + * 
   52.21 + * VM booting is controlled by setting one of the two mutually exclusive
   52.22 + * groups: "PV", and "HVM".  If HVM.boot is the empty string, then paravirtual
   52.23 + * domain building and booting will be used; otherwise the VM will be loaded
   52.24 + * as an HVM domain, and booted using an emulated BIOS.
   52.25 + * 
   52.26 + * When paravirtual booting is in use, the PV/bootloader field indicates the
   52.27 + * bootloader to use.  It may be "pygrub", in which case the platform's
   52.28 + * default installation of pygrub will be used, or a full path within the
   52.29 + * control domain to some other bootloader.  The other fields, PV/kernel,
   52.30 + * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader
   52.31 + * unmodified, and interpretation of those fields is then specific to the
   52.32 + * bootloader itself, including the possibility that the bootloader will
   52.33 + * ignore some or all of those given values.
   52.34 + * 
   52.35 + * If the bootloader is pygrub, then the menu.lst is parsed if present in the
   52.36 + * guest's filesystem, otherwise the specified kernel and ramdisk are used, or
   52.37 + * an autodetected kernel is used if nothing is specified and autodetection is
   52.38 + * possible.  PV/args is appended to the kernel command line, no matter which
   52.39 + * mechanism is used for finding the kernel.
   52.40 + * 
   52.41 + * If PV/bootloader is empty but PV/kernel is specified, then the kernel and
   52.42 + * ramdisk values will be treated as paths within the control domain.  If both
   52.43 + * PV/bootloader and PV/kernel are empty, then the behaviour is as if
   52.44 + * PV/bootloader was specified as "pygrub".
   52.45 + * 
   52.46 + * When using HVM booting, HVM/boot specifies the order of the boot devices.
   52.47   */
   52.48  
   52.49  
   52.50 @@ -79,6 +105,7 @@ typedef struct xen_vm_record
   52.51      char *name_description;
   52.52      int64_t user_version;
   52.53      bool is_a_template;
   52.54 +    bool auto_power_on;
   52.55      struct xen_host_record_opt *resident_on;
   52.56      int64_t memory_static_max;
   52.57      int64_t memory_dynamic_max;
   52.58 @@ -101,18 +128,17 @@ typedef struct xen_vm_record
   52.59      struct xen_vif_record_opt_set *vifs;
   52.60      struct xen_vbd_record_opt_set *vbds;
   52.61      struct xen_vtpm_record_opt_set *vtpms;
   52.62 -    char *bios_boot;
   52.63 +    char *pv_bootloader;
   52.64 +    char *pv_kernel;
   52.65 +    char *pv_ramdisk;
   52.66 +    char *pv_args;
   52.67 +    char *pv_bootloader_args;
   52.68 +    char *hvm_boot;
   52.69      bool platform_std_vga;
   52.70      char *platform_serial;
   52.71      bool platform_localtime;
   52.72      bool platform_clock_offset;
   52.73      bool platform_enable_audio;
   52.74 -    char *builder;
   52.75 -    enum xen_boot_type boot_method;
   52.76 -    char *kernel_kernel;
   52.77 -    char *kernel_initrd;
   52.78 -    char *kernel_args;
   52.79 -    char *grub_cmdline;
   52.80      char *pci_bus;
   52.81      xen_string_string_map *tools_version;
   52.82      xen_string_string_map *otherconfig;
   52.83 @@ -198,14 +224,14 @@ xen_vm_record_opt_set_free(xen_vm_record
   52.84  
   52.85  
   52.86  /**
   52.87 - * Get the current state of the given VM.  !!!
   52.88 + * Get a record containing the current state of the given VM.
   52.89   */
   52.90  extern bool
   52.91  xen_vm_get_record(xen_session *session, xen_vm_record **result, xen_vm vm);
   52.92  
   52.93  
   52.94  /**
   52.95 - * Get a reference to the object with the specified UUID.  !!!
   52.96 + * Get a reference to the VM instance with the specified UUID.
   52.97   */
   52.98  extern bool
   52.99  xen_vm_get_by_uuid(xen_session *session, xen_vm *result, char *uuid);
  52.100 @@ -277,6 +303,13 @@ xen_vm_get_is_a_template(xen_session *se
  52.101  
  52.102  
  52.103  /**
  52.104 + * Get the auto_power_on field of the given VM.
  52.105 + */
  52.106 +extern bool
  52.107 +xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm);
  52.108 +
  52.109 +
  52.110 +/**
  52.111   * Get the resident_on field of the given VM.
  52.112   */
  52.113  extern bool
  52.114 @@ -431,10 +464,45 @@ xen_vm_get_vtpms(xen_session *session, s
  52.115  
  52.116  
  52.117  /**
  52.118 - * Get the bios/boot field of the given VM.
  52.119 + * Get the PV/bootloader field of the given VM.
  52.120 + */
  52.121 +extern bool
  52.122 +xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm);
  52.123 +
  52.124 +
  52.125 +/**
  52.126 + * Get the PV/kernel field of the given VM.
  52.127 + */
  52.128 +extern bool
  52.129 +xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm);
  52.130 +
  52.131 +
  52.132 +/**
  52.133 + * Get the PV/ramdisk field of the given VM.
  52.134   */
  52.135  extern bool
  52.136 -xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm);
  52.137 +xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm);
  52.138 +
  52.139 +
  52.140 +/**
  52.141 + * Get the PV/args field of the given VM.
  52.142 + */
  52.143 +extern bool
  52.144 +xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm);
  52.145 +
  52.146 +
  52.147 +/**
  52.148 + * Get the PV/bootloader_args field of the given VM.
  52.149 + */
  52.150 +extern bool
  52.151 +xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
  52.152 +
  52.153 +
  52.154 +/**
  52.155 + * Get the HVM/boot field of the given VM.
  52.156 + */
  52.157 +extern bool
  52.158 +xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
  52.159  
  52.160  
  52.161  /**
  52.162 @@ -473,48 +541,6 @@ xen_vm_get_platform_enable_audio(xen_ses
  52.163  
  52.164  
  52.165  /**
  52.166 - * Get the builder field of the given VM.
  52.167 - */
  52.168 -extern bool
  52.169 -xen_vm_get_builder(xen_session *session, char **result, xen_vm vm);
  52.170 -
  52.171 -
  52.172 -/**
  52.173 - * Get the boot_method field of the given VM.
  52.174 - */
  52.175 -extern bool
  52.176 -xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, xen_vm vm);
  52.177 -
  52.178 -
  52.179 -/**
  52.180 - * Get the kernel/kernel field of the given VM.
  52.181 - */
  52.182 -extern bool
  52.183 -xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm);
  52.184 -
  52.185 -
  52.186 -/**
  52.187 - * Get the kernel/initrd field of the given VM.
  52.188 - */
  52.189 -extern bool
  52.190 -xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm);
  52.191 -
  52.192 -
  52.193 -/**
  52.194 - * Get the kernel/args field of the given VM.
  52.195 - */
  52.196 -extern bool
  52.197 -xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm);
  52.198 -
  52.199 -
  52.200 -/**
  52.201 - * Get the grub/cmdline field of the given VM.
  52.202 - */
  52.203 -extern bool
  52.204 -xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm);
  52.205 -
  52.206 -
  52.207 -/**
  52.208   * Get the PCI_bus field of the given VM.
  52.209   */
  52.210  extern bool
  52.211 @@ -564,6 +590,13 @@ xen_vm_set_is_a_template(xen_session *se
  52.212  
  52.213  
  52.214  /**
  52.215 + * Set the auto_power_on field of the given VM.
  52.216 + */
  52.217 +extern bool
  52.218 +xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on);
  52.219 +
  52.220 +
  52.221 +/**
  52.222   * Set the memory/dynamic_max field of the given VM.
  52.223   */
  52.224  extern bool
  52.225 @@ -592,6 +625,13 @@ xen_vm_set_vcpus_params(xen_session *ses
  52.226  
  52.227  
  52.228  /**
  52.229 + * Set the VCPUs/number field of the given VM.
  52.230 + */
  52.231 +extern bool
  52.232 +xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number);
  52.233 +
  52.234 +
  52.235 +/**
  52.236   * Set the VCPUs/features/force_on field of the given VM.
  52.237   */
  52.238  extern bool
  52.239 @@ -599,6 +639,22 @@ xen_vm_set_vcpus_features_force_on(xen_s
  52.240  
  52.241  
  52.242  /**
  52.243 + * Add the given value to the VCPUs/features/force_on field of the
  52.244 + * given VM.  If the value is already in that Set, then do nothing.
  52.245 + */
  52.246 +extern bool
  52.247 +xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  52.248 +
  52.249 +
  52.250 +/**
  52.251 + * Remove the given value from the VCPUs/features/force_on field of the
  52.252 + * given VM.  If the value is not in that Set, then do nothing.
  52.253 + */
  52.254 +extern bool
  52.255 +xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  52.256 +
  52.257 +
  52.258 +/**
  52.259   * Set the VCPUs/features/force_off field of the given VM.
  52.260   */
  52.261  extern bool
  52.262 @@ -606,6 +662,22 @@ xen_vm_set_vcpus_features_force_off(xen_
  52.263  
  52.264  
  52.265  /**
  52.266 + * Add the given value to the VCPUs/features/force_off field of the
  52.267 + * given VM.  If the value is already in that Set, then do nothing.
  52.268 + */
  52.269 +extern bool
  52.270 +xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  52.271 +
  52.272 +
  52.273 +/**
  52.274 + * Remove the given value from the VCPUs/features/force_off field of
  52.275 + * the given VM.  If the value is not in that Set, then do nothing.
  52.276 + */
  52.277 +extern bool
  52.278 +xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  52.279 +
  52.280 +
  52.281 +/**
  52.282   * Set the actions/after_shutdown field of the given VM.
  52.283   */
  52.284  extern bool
  52.285 @@ -634,10 +706,45 @@ xen_vm_set_actions_after_crash(xen_sessi
  52.286  
  52.287  
  52.288  /**
  52.289 - * Set the bios/boot field of the given VM.
  52.290 + * Set the PV/bootloader field of the given VM.
  52.291 + */
  52.292 +extern bool
  52.293 +xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader);
  52.294 +
  52.295 +
  52.296 +/**
  52.297 + * Set the PV/kernel field of the given VM.
  52.298 + */
  52.299 +extern bool
  52.300 +xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel);
  52.301 +
  52.302 +
  52.303 +/**
  52.304 + * Set the PV/ramdisk field of the given VM.
  52.305   */
  52.306  extern bool
  52.307 -xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot);
  52.308 +xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk);
  52.309 +
  52.310 +
  52.311 +/**
  52.312 + * Set the PV/args field of the given VM.
  52.313 + */
  52.314 +extern bool
  52.315 +xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args);
  52.316 +
  52.317 +
  52.318 +/**
  52.319 + * Set the PV/bootloader_args field of the given VM.
  52.320 + */
  52.321 +extern bool
  52.322 +xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_args);
  52.323 +
  52.324 +
  52.325 +/**
  52.326 + * Set the HVM/boot field of the given VM.
  52.327 + */
  52.328 +extern bool
  52.329 +xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
  52.330  
  52.331  
  52.332  /**
  52.333 @@ -676,48 +783,6 @@ xen_vm_set_platform_enable_audio(xen_ses
  52.334  
  52.335  
  52.336  /**
  52.337 - * Set the builder field of the given VM.
  52.338 - */
  52.339 -extern bool
  52.340 -xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder);
  52.341 -
  52.342 -
  52.343 -/**
  52.344 - * Set the boot_method field of the given VM.
  52.345 - */
  52.346 -extern bool
  52.347 -xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type boot_method);
  52.348 -
  52.349 -
  52.350 -/**
  52.351 - * Set the kernel/kernel field of the given VM.
  52.352 - */
  52.353 -extern bool
  52.354 -xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel);
  52.355 -
  52.356 -
  52.357 -/**
  52.358 - * Set the kernel/initrd field of the given VM.
  52.359 - */
  52.360 -extern bool
  52.361 -xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd);
  52.362 -
  52.363 -
  52.364 -/**
  52.365 - * Set the kernel/args field of the given VM.
  52.366 - */
  52.367 -extern bool
  52.368 -xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args);
  52.369 -
  52.370 -
  52.371 -/**
  52.372 - * Set the grub/cmdline field of the given VM.
  52.373 - */
  52.374 -extern bool
  52.375 -xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline);
  52.376 -
  52.377 -
  52.378 -/**
  52.379   * Set the otherConfig field of the given VM.
  52.380   */
  52.381  extern bool
  52.382 @@ -760,8 +825,8 @@ xen_vm_unpause(xen_session *session, xen
  52.383  
  52.384  /**
  52.385   * Attempt to cleanly shutdown the specified VM. (Note: this may not be
  52.386 - * supported---e.g. if a guest agent is not installed). 
  52.387 - *  
  52.388 + * supported---e.g. if a guest agent is not installed).
  52.389 + * 
  52.390   * Once shutdown has been completed perform poweroff action specified in guest
  52.391   * configuration.
  52.392   */
  52.393 @@ -771,8 +836,8 @@ xen_vm_clean_shutdown(xen_session *sessi
  52.394  
  52.395  /**
  52.396   * Attempt to cleanly shutdown the specified VM (Note: this may not be
  52.397 - * supported---e.g. if a guest agent is not installed). 
  52.398 - *  
  52.399 + * supported---e.g. if a guest agent is not installed).
  52.400 + * 
  52.401   * Once shutdown has been completed perform reboot action specified in guest
  52.402   * configuration.
  52.403   */
  52.404 @@ -817,12 +882,4 @@ extern bool
  52.405  xen_vm_get_all(xen_session *session, struct xen_vm_set **result);
  52.406  
  52.407  
  52.408 -/**
  52.409 - * Destroy the specified VM.  The VM is completely removed from the system.
  52.410 - * This function can only be called when the VM is in the Halted State.
  52.411 - */
  52.412 -extern bool
  52.413 -xen_vm_destroy(xen_session *session, xen_vm vm);
  52.414 -
  52.415 -
  52.416  #endif
    53.1 --- a/tools/libxen/include/xen_vtpm.h	Fri Dec 15 10:59:33 2006 -0700
    53.2 +++ b/tools/libxen/include/xen_vtpm.h	Fri Dec 15 11:32:58 2006 -0700
    53.3 @@ -151,14 +151,14 @@ xen_vtpm_record_opt_set_free(xen_vtpm_re
    53.4  
    53.5  
    53.6  /**
    53.7 - * Get the current state of the given VTPM.  !!!
    53.8 + * Get a record containing the current state of the given VTPM.
    53.9   */
   53.10  extern bool
   53.11  xen_vtpm_get_record(xen_session *session, xen_vtpm_record **result, xen_vtpm vtpm);
   53.12  
   53.13  
   53.14  /**
   53.15 - * Get a reference to the object with the specified UUID.  !!!
   53.16 + * Get a reference to the VTPM instance with the specified UUID.
   53.17   */
   53.18  extern bool
   53.19  xen_vtpm_get_by_uuid(xen_session *session, xen_vtpm *result, char *uuid);
    54.1 --- a/tools/libxen/src/xen_boot_type.c	Fri Dec 15 10:59:33 2006 -0700
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,83 +0,0 @@
    54.4 -/*
    54.5 - * Copyright (c) 2006, XenSource Inc.
    54.6 - *
    54.7 - * This library is free software; you can redistribute it and/or
    54.8 - * modify it under the terms of the GNU Lesser General Public
    54.9 - * License as published by the Free Software Foundation; either
   54.10 - * version 2.1 of the License, or (at your option) any later version.
   54.11 - *
   54.12 - * This library is distributed in the hope that it will be useful,
   54.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   54.15 - * Lesser General Public License for more details.
   54.16 - *
   54.17 - * You should have received a copy of the GNU Lesser General Public
   54.18 - * License along with this library; if not, write to the Free Software
   54.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   54.20 - */
   54.21 -
   54.22 -#include <string.h>
   54.23 -
   54.24 -#include "xen_internal.h"
   54.25 -#include "xen_boot_type.h"
   54.26 -#include "xen_boot_type_internal.h"
   54.27 -
   54.28 -
   54.29 -/*
   54.30 - * Maintain this in the same order as the enum declaration!
   54.31 - */
   54.32 -static const char *lookup_table[] =
   54.33 -{
   54.34 -    "bios",
   54.35 -    "grub",
   54.36 -    "kernel_external",
   54.37 -    "kernel_internal"
   54.38 -};
   54.39 -
   54.40 -
   54.41 -extern xen_boot_type_set *
   54.42 -xen_boot_type_set_alloc(size_t size)
   54.43 -{
   54.44 -    return calloc(1, sizeof(xen_boot_type_set) +
   54.45 -                  size * sizeof(enum xen_boot_type));
   54.46 -}
   54.47 -
   54.48 -
   54.49 -extern void
   54.50 -xen_boot_type_set_free(xen_boot_type_set *set)
   54.51 -{
   54.52 -    free(set);
   54.53 -}
   54.54 -
   54.55 -
   54.56 -const char *
   54.57 -xen_boot_type_to_string(enum xen_boot_type val)
   54.58 -{
   54.59 -    return lookup_table[val];
   54.60 -}
   54.61 -
   54.62 -
   54.63 -extern enum xen_boot_type
   54.64 -xen_boot_type_from_string(xen_session *session, const char *str)
   54.65 -{
   54.66 -    return ENUM_LOOKUP(session, str, lookup_table);
   54.67 -}
   54.68 -
   54.69 -
   54.70 -const abstract_type xen_boot_type_abstract_type_ =
   54.71 -    {
   54.72 -        .typename = ENUM,
   54.73 -        .enum_marshaller =
   54.74 -             (const char *(*)(int))&xen_boot_type_to_string,
   54.75 -        .enum_demarshaller =
   54.76 -             (int (*)(xen_session *, const char *))&xen_boot_type_from_string
   54.77 -    };
   54.78 -
   54.79 -
   54.80 -const abstract_type xen_boot_type_set_abstract_type_ =
   54.81 -    {
   54.82 -        .typename = SET,
   54.83 -        .child = &xen_boot_type_abstract_type_
   54.84 -    };
   54.85 -
   54.86 -
    55.1 --- a/tools/libxen/src/xen_console.c	Fri Dec 15 10:59:33 2006 -0700
    55.2 +++ b/tools/libxen/src/xen_console.c	Fri Dec 15 11:32:58 2006 -0700
    55.3 @@ -158,9 +158,7 @@ xen_console_get_protocol(xen_session *se
    55.4          };
    55.5  
    55.6      abstract_type result_type = xen_console_protocol_abstract_type_;
    55.7 -    char *result_str = NULL;
    55.8      XEN_CALL_("console.get_protocol");
    55.9 -    *result = xen_console_protocol_from_string(session, result_str);
   55.10      return session->ok;
   55.11  }
   55.12  
    56.1 --- a/tools/libxen/src/xen_vif.c	Fri Dec 15 10:59:33 2006 -0700
    56.2 +++ b/tools/libxen/src/xen_vif.c	Fri Dec 15 11:32:58 2006 -0700
    56.3 @@ -197,9 +197,7 @@ xen_vif_get_type(xen_session *session, e
    56.4          };
    56.5  
    56.6      abstract_type result_type = xen_driver_type_abstract_type_;
    56.7 -    char *result_str = NULL;
    56.8      XEN_CALL_("VIF.get_type");
    56.9 -    *result = xen_driver_type_from_string(session, result_str);
   56.10      return session->ok;
   56.11  }
   56.12  
    57.1 --- a/tools/libxen/src/xen_vm.c	Fri Dec 15 10:59:33 2006 -0700
    57.2 +++ b/tools/libxen/src/xen_vm.c	Fri Dec 15 11:32:58 2006 -0700
    57.3 @@ -20,7 +20,6 @@
    57.4  #include <stddef.h>
    57.5  #include <stdlib.h>
    57.6  
    57.7 -#include "xen_boot_type_internal.h"
    57.8  #include "xen_common.h"
    57.9  #include "xen_console.h"
   57.10  #include "xen_cpu_feature.h"
   57.11 @@ -67,6 +66,9 @@ static const struct_member xen_vm_record
   57.12          { .key = "is_a_template",
   57.13            .type = &abstract_type_bool,
   57.14            .offset = offsetof(xen_vm_record, is_a_template) },
   57.15 +        { .key = "auto_power_on",
   57.16 +          .type = &abstract_type_bool,
   57.17 +          .offset = offsetof(xen_vm_record, auto_power_on) },
   57.18          { .key = "resident_on",
   57.19            .type = &abstract_type_ref,
   57.20            .offset = offsetof(xen_vm_record, resident_on) },
   57.21 @@ -133,9 +135,24 @@ static const struct_member xen_vm_record
   57.22          { .key = "VTPMs",
   57.23            .type = &abstract_type_ref_set,
   57.24            .offset = offsetof(xen_vm_record, vtpms) },
   57.25 -        { .key = "bios_boot",
   57.26 +        { .key = "PV_bootloader",
   57.27 +          .type = &abstract_type_string,
   57.28 +          .offset = offsetof(xen_vm_record, pv_bootloader) },
   57.29 +        { .key = "PV_kernel",
   57.30 +          .type = &abstract_type_string,
   57.31 +          .offset = offsetof(xen_vm_record, pv_kernel) },
   57.32 +        { .key = "PV_ramdisk",
   57.33            .type = &abstract_type_string,
   57.34 -          .offset = offsetof(xen_vm_record, bios_boot) },
   57.35 +          .offset = offsetof(xen_vm_record, pv_ramdisk) },
   57.36 +        { .key = "PV_args",
   57.37 +          .type = &abstract_type_string,
   57.38 +          .offset = offsetof(xen_vm_record, pv_args) },
   57.39 +        { .key = "PV_bootloader_args",
   57.40 +          .type = &abstract_type_string,
   57.41 +          .offset = offsetof(xen_vm_record, pv_bootloader_args) },
   57.42 +        { .key = "HVM_boot",
   57.43 +          .type = &abstract_type_string,
   57.44 +          .offset = offsetof(xen_vm_record, hvm_boot) },
   57.45          { .key = "platform_std_VGA",
   57.46            .type = &abstract_type_bool,
   57.47            .offset = offsetof(xen_vm_record, platform_std_vga) },
   57.48 @@ -151,24 +168,6 @@ static const struct_member xen_vm_record
   57.49          { .key = "platform_enable_audio",
   57.50            .type = &abstract_type_bool,
   57.51            .offset = offsetof(xen_vm_record, platform_enable_audio) },
   57.52 -        { .key = "builder",
   57.53 -          .type = &abstract_type_string,
   57.54 -          .offset = offsetof(xen_vm_record, builder) },
   57.55 -        { .key = "boot_method",
   57.56 -          .type = &xen_boot_type_abstract_type_,
   57.57 -          .offset = offsetof(xen_vm_record, boot_method) },
   57.58 -        { .key = "kernel_kernel",
   57.59 -          .type = &abstract_type_string,
   57.60 -          .offset = offsetof(xen_vm_record, kernel_kernel) },
   57.61 -        { .key = "kernel_initrd",
   57.62 -          .type = &abstract_type_string,
   57.63 -          .offset = offsetof(xen_vm_record, kernel_initrd) },
   57.64 -        { .key = "kernel_args",
   57.65 -          .type = &abstract_type_string,
   57.66 -          .offset = offsetof(xen_vm_record, kernel_args) },
   57.67 -        { .key = "grub_cmdline",
   57.68 -          .type = &abstract_type_string,
   57.69 -          .offset = offsetof(xen_vm_record, grub_cmdline) },
   57.70          { .key = "PCI_bus",
   57.71            .type = &abstract_type_string,
   57.72            .offset = offsetof(xen_vm_record, pci_bus) },
   57.73 @@ -213,13 +212,13 @@ xen_vm_record_free(xen_vm_record *record
   57.74      xen_vif_record_opt_set_free(record->vifs);
   57.75      xen_vbd_record_opt_set_free(record->vbds);
   57.76      xen_vtpm_record_opt_set_free(record->vtpms);
   57.77 -    free(record->bios_boot);
   57.78 +    free(record->pv_bootloader);
   57.79 +    free(record->pv_kernel);
   57.80 +    free(record->pv_ramdisk);
   57.81 +    free(record->pv_args);
   57.82 +    free(record->pv_bootloader_args);
   57.83 +    free(record->hvm_boot);
   57.84      free(record->platform_serial);
   57.85 -    free(record->builder);
   57.86 -    free(record->kernel_kernel);
   57.87 -    free(record->kernel_initrd);
   57.88 -    free(record->kernel_args);
   57.89 -    free(record->grub_cmdline);
   57.90      free(record->pci_bus);
   57.91      xen_string_string_map_free(record->tools_version);
   57.92      xen_string_string_map_free(record->otherconfig);
   57.93 @@ -325,9 +324,7 @@ xen_vm_get_power_state(xen_session *sess
   57.94          };
   57.95  
   57.96      abstract_type result_type = xen_vm_power_state_abstract_type_;
   57.97 -    char *result_str = NULL;
   57.98      XEN_CALL_("VM.get_power_state");
   57.99 -    *result = xen_vm_power_state_from_string(session, result_str);
  57.100      return session->ok;
  57.101  }
  57.102  
  57.103 @@ -399,6 +396,22 @@ xen_vm_get_is_a_template(xen_session *se
  57.104  
  57.105  
  57.106  bool
  57.107 +xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm)
  57.108 +{
  57.109 +    abstract_value param_values[] =
  57.110 +        {
  57.111 +            { .type = &abstract_type_string,
  57.112 +              .u.string_val = vm }
  57.113 +        };
  57.114 +
  57.115 +    abstract_type result_type = abstract_type_bool;
  57.116 +
  57.117 +    XEN_CALL_("VM.get_auto_power_on");
  57.118 +    return session->ok;
  57.119 +}
  57.120 +
  57.121 +
  57.122 +bool
  57.123  xen_vm_get_resident_on(xen_session *session, xen_host *result, xen_vm vm)
  57.124  {
  57.125      abstract_value param_values[] =
  57.126 @@ -640,9 +653,7 @@ xen_vm_get_actions_after_shutdown(xen_se
  57.127          };
  57.128  
  57.129      abstract_type result_type = xen_on_normal_exit_abstract_type_;
  57.130 -    char *result_str = NULL;
  57.131      XEN_CALL_("VM.get_actions_after_shutdown");
  57.132 -    *result = xen_on_normal_exit_from_string(session, result_str);
  57.133      return session->ok;
  57.134  }
  57.135  
  57.136 @@ -657,9 +668,7 @@ xen_vm_get_actions_after_reboot(xen_sess
  57.137          };
  57.138  
  57.139      abstract_type result_type = xen_on_normal_exit_abstract_type_;
  57.140 -    char *result_str = NULL;
  57.141      XEN_CALL_("VM.get_actions_after_reboot");
  57.142 -    *result = xen_on_normal_exit_from_string(session, result_str);
  57.143      return session->ok;
  57.144  }
  57.145  
  57.146 @@ -674,9 +683,7 @@ xen_vm_get_actions_after_suspend(xen_ses
  57.147          };
  57.148  
  57.149      abstract_type result_type = xen_on_normal_exit_abstract_type_;
  57.150 -    char *result_str = NULL;
  57.151      XEN_CALL_("VM.get_actions_after_suspend");
  57.152 -    *result = xen_on_normal_exit_from_string(session, result_str);
  57.153      return session->ok;
  57.154  }
  57.155  
  57.156 @@ -691,9 +698,7 @@ xen_vm_get_actions_after_crash(xen_sessi
  57.157          };
  57.158  
  57.159      abstract_type result_type = xen_on_crash_behaviour_abstract_type_;
  57.160 -    char *result_str = NULL;
  57.161      XEN_CALL_("VM.get_actions_after_crash");
  57.162 -    *result = xen_on_crash_behaviour_from_string(session, result_str);
  57.163      return session->ok;
  57.164  }
  57.165  
  57.166 @@ -767,7 +772,41 @@ xen_vm_get_vtpms(xen_session *session, s
  57.167  
  57.168  
  57.169  bool
  57.170 -xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm)
  57.171 +xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm)
  57.172 +{
  57.173 +    abstract_value param_values[] =
  57.174 +        {
  57.175 +            { .type = &abstract_type_string,
  57.176 +              .u.string_val = vm }
  57.177 +        };
  57.178 +
  57.179 +    abstract_type result_type = abstract_type_string;
  57.180 +
  57.181 +    *result = NULL;
  57.182 +    XEN_CALL_("VM.get_PV_bootloader");
  57.183 +    return session->ok;
  57.184 +}
  57.185 +
  57.186 +
  57.187 +bool
  57.188 +xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm)
  57.189 +{
  57.190 +    abstract_value param_values[] =
  57.191 +        {
  57.192 +            { .type = &abstract_type_string,
  57.193 +              .u.string_val = vm }
  57.194 +        };
  57.195 +
  57.196 +    abstract_type result_type = abstract_type_string;
  57.197 +
  57.198 +    *result = NULL;
  57.199 +    XEN_CALL_("VM.get_PV_kernel");
  57.200 +    return session->ok;
  57.201 +}
  57.202 +
  57.203 +
  57.204 +bool
  57.205 +xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm)
  57.206  {
  57.207      abstract_value param_values[] =
  57.208          {
  57.209 @@ -778,7 +817,58 @@ xen_vm_get_bios_boot(xen_session *sessio
  57.210      abstract_type result_type = abstract_type_string;
  57.211  
  57.212      *result = NULL;
  57.213 -    XEN_CALL_("VM.get_bios_boot");
  57.214 +    XEN_CALL_("VM.get_PV_ramdisk");
  57.215 +    return session->ok;
  57.216 +}
  57.217 +
  57.218 +
  57.219 +bool
  57.220 +xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm)
  57.221 +{
  57.222 +    abstract_value param_values[] =
  57.223 +        {
  57.224 +            { .type = &abstract_type_string,
  57.225 +              .u.string_val = vm }
  57.226 +        };
  57.227 +
  57.228 +    abstract_type result_type = abstract_type_string;
  57.229 +
  57.230 +    *result = NULL;
  57.231 +    XEN_CALL_("VM.get_PV_args");
  57.232 +    return session->ok;
  57.233 +}
  57.234 +
  57.235 +
  57.236 +bool
  57.237 +xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
  57.238 +{
  57.239 +    abstract_value param_values[] =
  57.240 +        {
  57.241 +            { .type = &abstract_type_string,
  57.242 +              .u.string_val = vm }
  57.243 +        };
  57.244 +
  57.245 +    abstract_type result_type = abstract_type_string;
  57.246 +
  57.247 +    *result = NULL;
  57.248 +    XEN_CALL_("VM.get_PV_bootloader_args");
  57.249 +    return session->ok;
  57.250 +}
  57.251 +
  57.252 +
  57.253 +bool
  57.254 +xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
  57.255 +{
  57.256 +    abstract_value param_values[] =
  57.257 +        {
  57.258 +            { .type = &abstract_type_string,
  57.259 +              .u.string_val = vm }
  57.260 +        };
  57.261 +
  57.262 +    abstract_type result_type = abstract_type_string;
  57.263 +
  57.264 +    *result = NULL;
  57.265 +    XEN_CALL_("VM.get_HVM_boot");
  57.266      return session->ok;
  57.267  }
  57.268  
  57.269 @@ -865,108 +955,6 @@ xen_vm_get_platform_enable_audio(xen_ses
  57.270  
  57.271  
  57.272  bool
  57.273 -xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
  57.274 -{
  57.275 -    abstract_value param_values[] =
  57.276 -        {
  57.277 -            { .type = &abstract_type_string,
  57.278 -              .u.string_val = vm }
  57.279 -        };
  57.280 -
  57.281 -    abstract_type result_type = abstract_type_string;
  57.282 -
  57.283 -    *result = NULL;
  57.284 -    XEN_CALL_("VM.get_builder");
  57.285 -    return session->ok;
  57.286 -}
  57.287 -
  57.288 -
  57.289 -bool
  57.290 -xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, xen_vm vm)
  57.291 -{
  57.292 -    abstract_value param_values[] =
  57.293 -        {
  57.294 -            { .type = &abstract_type_string,
  57.295 -              .u.string_val = vm }
  57.296 -        };
  57.297 -
  57.298 -    abstract_type result_type = xen_boot_type_abstract_type_;
  57.299 -    char *result_str = NULL;
  57.300 -    XEN_CALL_("VM.get_boot_method");
  57.301 -    *result = xen_boot_type_from_string(session, result_str);
  57.302 -    return session->ok;
  57.303 -}
  57.304 -
  57.305 -
  57.306 -bool
  57.307 -xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
  57.308 -{
  57.309 -    abstract_value param_values[] =
  57.310 -        {
  57.311 -            { .type = &abstract_type_string,
  57.312 -              .u.string_val = vm }
  57.313 -        };
  57.314 -
  57.315 -    abstract_type result_type = abstract_type_string;
  57.316 -
  57.317 -    *result = NULL;
  57.318 -    XEN_CALL_("VM.get_kernel_kernel");
  57.319 -    return session->ok;
  57.320 -}
  57.321 -
  57.322 -
  57.323 -bool
  57.324 -xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
  57.325 -{
  57.326 -    abstract_value param_values[] =
  57.327 -        {
  57.328 -            { .type = &abstract_type_string,
  57.329 -              .u.string_val = vm }
  57.330 -        };
  57.331 -
  57.332 -    abstract_type result_type = abstract_type_string;
  57.333 -
  57.334 -    *result = NULL;
  57.335 -    XEN_CALL_("VM.get_kernel_initrd");
  57.336 -    return session->ok;
  57.337 -}
  57.338 -
  57.339 -
  57.340 -bool
  57.341 -xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
  57.342 -{
  57.343 -    abstract_value param_values[] =
  57.344 -        {
  57.345 -            { .type = &abstract_type_string,
  57.346 -              .u.string_val = vm }
  57.347 -        };
  57.348 -
  57.349 -    abstract_type result_type = abstract_type_string;
  57.350 -
  57.351 -    *result = NULL;
  57.352 -    XEN_CALL_("VM.get_kernel_args");
  57.353 -    return session->ok;
  57.354 -}
  57.355 -
  57.356 -
  57.357 -bool
  57.358 -xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
  57.359 -{
  57.360 -    abstract_value param_values[] =
  57.361 -        {
  57.362 -            { .type = &abstract_type_string,
  57.363 -              .u.string_val = vm }
  57.364 -        };
  57.365 -
  57.366 -    abstract_type result_type = abstract_type_string;
  57.367 -
  57.368 -    *result = NULL;
  57.369 -    XEN_CALL_("VM.get_grub_cmdline");
  57.370 -    return session->ok;
  57.371 -}
  57.372 -
  57.373 -
  57.374 -bool
  57.375  xen_vm_get_pci_bus(xen_session *session, char **result, xen_vm vm)
  57.376  {
  57.377      abstract_value param_values[] =
  57.378 @@ -1082,6 +1070,22 @@ xen_vm_set_is_a_template(xen_session *se
  57.379  
  57.380  
  57.381  bool
  57.382 +xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on)
  57.383 +{
  57.384 +    abstract_value param_values[] =
  57.385 +        {
  57.386 +            { .type = &abstract_type_string,
  57.387 +              .u.string_val = vm },
  57.388 +            { .type = &abstract_type_bool,
  57.389 +              .u.bool_val = auto_power_on }
  57.390 +        };
  57.391 +
  57.392 +    xen_call_(session, "VM.set_auto_power_on", param_values, 2, NULL, NULL);
  57.393 +    return session->ok;
  57.394 +}
  57.395 +
  57.396 +
  57.397 +bool
  57.398  xen_vm_set_memory_dynamic_max(xen_session *session, xen_vm vm, int64_t dynamic_max)
  57.399  {
  57.400      abstract_value param_values[] =
  57.401 @@ -1146,6 +1150,22 @@ xen_vm_set_vcpus_params(xen_session *ses
  57.402  
  57.403  
  57.404  bool
  57.405 +xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number)
  57.406 +{
  57.407 +    abstract_value param_values[] =
  57.408 +        {
  57.409 +            { .type = &abstract_type_string,
  57.410 +              .u.string_val = vm },
  57.411 +            { .type = &abstract_type_int,
  57.412 +              .u.int_val = number }
  57.413 +        };
  57.414 +
  57.415 +    xen_call_(session, "VM.set_VCPUs_number", param_values, 2, NULL, NULL);
  57.416 +    return session->ok;
  57.417 +}
  57.418 +
  57.419 +
  57.420 +bool
  57.421  xen_vm_set_vcpus_features_force_on(xen_session *session, xen_vm vm, struct xen_cpu_feature_set *force_on)
  57.422  {
  57.423      abstract_value param_values[] =
  57.424 @@ -1162,6 +1182,38 @@ xen_vm_set_vcpus_features_force_on(xen_s
  57.425  
  57.426  
  57.427  bool
  57.428 +xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  57.429 +{
  57.430 +    abstract_value param_values[] =
  57.431 +        {
  57.432 +            { .type = &abstract_type_string,
  57.433 +              .u.string_val = vm },
  57.434 +            { .type = &xen_cpu_feature_abstract_type_,
  57.435 +              .u.string_val = xen_cpu_feature_to_string(value) }
  57.436 +        };
  57.437 +
  57.438 +    xen_call_(session, "VM.add_VCPUs_features_force_on", param_values, 2, NULL, NULL);
  57.439 +    return session->ok;
  57.440 +}
  57.441 +
  57.442 +
  57.443 +bool
  57.444 +xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  57.445 +{
  57.446 +    abstract_value param_values[] =
  57.447 +        {
  57.448 +            { .type = &abstract_type_string,
  57.449 +              .u.string_val = vm },
  57.450 +            { .type = &xen_cpu_feature_abstract_type_,
  57.451 +              .u.string_val = xen_cpu_feature_to_string(value) }
  57.452 +        };
  57.453 +
  57.454 +    xen_call_(session, "VM.remove_VCPUs_features_force_on", param_values, 2, NULL, NULL);
  57.455 +    return session->ok;
  57.456 +}
  57.457 +
  57.458 +
  57.459 +bool
  57.460  xen_vm_set_vcpus_features_force_off(xen_session *session, xen_vm vm, struct xen_cpu_feature_set *force_off)
  57.461  {
  57.462      abstract_value param_values[] =
  57.463 @@ -1178,6 +1230,38 @@ xen_vm_set_vcpus_features_force_off(xen_
  57.464  
  57.465  
  57.466  bool
  57.467 +xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  57.468 +{
  57.469 +    abstract_value param_values[] =
  57.470 +        {
  57.471 +            { .type = &abstract_type_string,
  57.472 +              .u.string_val = vm },
  57.473 +            { .type = &xen_cpu_feature_abstract_type_,
  57.474 +              .u.string_val = xen_cpu_feature_to_string(value) }
  57.475 +        };
  57.476 +
  57.477 +    xen_call_(session, "VM.add_VCPUs_features_force_off", param_values, 2, NULL, NULL);
  57.478 +    return session->ok;
  57.479 +}
  57.480 +
  57.481 +
  57.482 +bool
  57.483 +xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  57.484 +{
  57.485 +    abstract_value param_values[] =
  57.486 +        {
  57.487 +            { .type = &abstract_type_string,
  57.488 +              .u.string_val = vm },
  57.489 +            { .type = &xen_cpu_feature_abstract_type_,
  57.490 +              .u.string_val = xen_cpu_feature_to_string(value) }
  57.491 +        };
  57.492 +
  57.493 +    xen_call_(session, "VM.remove_VCPUs_features_force_off", param_values, 2, NULL, NULL);
  57.494 +    return session->ok;
  57.495 +}
  57.496 +
  57.497 +
  57.498 +bool
  57.499  xen_vm_set_actions_after_shutdown(xen_session *session, xen_vm vm, enum xen_on_normal_exit after_shutdown)
  57.500  {
  57.501      abstract_value param_values[] =
  57.502 @@ -1242,7 +1326,87 @@ xen_vm_set_actions_after_crash(xen_sessi
  57.503  
  57.504  
  57.505  bool
  57.506 -xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot)
  57.507 +xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader)
  57.508 +{
  57.509 +    abstract_value param_values[] =
  57.510 +        {
  57.511 +            { .type = &abstract_type_string,
  57.512 +              .u.string_val = vm },
  57.513 +            { .type = &abstract_type_string,
  57.514 +              .u.string_val = bootloader }
  57.515 +        };
  57.516 +
  57.517 +    xen_call_(session, "VM.set_PV_bootloader", param_values, 2, NULL, NULL);
  57.518 +    return session->ok;
  57.519 +}
  57.520 +
  57.521 +
  57.522 +bool
  57.523 +xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel)
  57.524 +{
  57.525 +    abstract_value param_values[] =
  57.526 +        {
  57.527 +            { .type = &abstract_type_string,
  57.528 +              .u.string_val = vm },
  57.529 +            { .type = &abstract_type_string,
  57.530 +              .u.string_val = kernel }
  57.531 +        };
  57.532 +
  57.533 +    xen_call_(session, "VM.set_PV_kernel", param_values, 2, NULL, NULL);
  57.534 +    return session->ok;
  57.535 +}
  57.536 +
  57.537 +
  57.538 +bool
  57.539 +xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk)
  57.540 +{
  57.541 +    abstract_value param_values[] =
  57.542 +        {
  57.543 +            { .type = &abstract_type_string,
  57.544 +              .u.string_val = vm },
  57.545 +            { .type = &abstract_type_string,
  57.546 +              .u.string_val = ramdisk }
  57.547 +        };
  57.548 +
  57.549 +    xen_call_(session, "VM.set_PV_ramdisk", param_values, 2, NULL, NULL);
  57.550 +    return session->ok;
  57.551 +}
  57.552 +
  57.553 +
  57.554 +bool
  57.555 +xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args)
  57.556 +{
  57.557 +    abstract_value param_values[] =
  57.558 +        {
  57.559 +            { .type = &abstract_type_string,
  57.560 +              .u.string_val = vm },
  57.561 +            { .type = &abstract_type_string,
  57.562 +              .u.string_val = args }
  57.563 +        };
  57.564 +
  57.565 +    xen_call_(session, "VM.set_PV_args", param_values, 2, NULL, NULL);
  57.566 +    return session->ok;
  57.567 +}
  57.568 +
  57.569 +
  57.570 +bool
  57.571 +xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_args)
  57.572 +{
  57.573 +    abstract_value param_values[] =
  57.574 +        {
  57.575 +            { .type = &abstract_type_string,
  57.576 +              .u.string_val = vm },
  57.577 +            { .type = &abstract_type_string,
  57.578 +              .u.string_val = bootloader_args }
  57.579 +        };
  57.580 +
  57.581 +    xen_call_(session, "VM.set_PV_bootloader_args", param_values, 2, NULL, NULL);
  57.582 +    return session->ok;
  57.583 +}
  57.584 +
  57.585 +
  57.586 +bool
  57.587 +xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
  57.588  {
  57.589      abstract_value param_values[] =
  57.590          {
  57.591 @@ -1252,7 +1416,7 @@ xen_vm_set_bios_boot(xen_session *sessio
  57.592                .u.string_val = boot }
  57.593          };
  57.594  
  57.595 -    xen_call_(session, "VM.set_bios_boot", param_values, 2, NULL, NULL);
  57.596 +    xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
  57.597      return session->ok;
  57.598  }
  57.599  
  57.600 @@ -1268,7 +1432,7 @@ xen_vm_set_platform_std_vga(xen_session 
  57.601                .u.bool_val = std_vga }
  57.602          };
  57.603  
  57.604 -    xen_call_(session, "VM.set_platform_std_vga", param_values, 2, NULL, NULL);
  57.605 +    xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
  57.606      return session->ok;
  57.607  }
  57.608  
  57.609 @@ -1338,102 +1502,6 @@ xen_vm_set_platform_enable_audio(xen_ses
  57.610  
  57.611  
  57.612  bool
  57.613 -xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder)
  57.614 -{
  57.615 -    abstract_value param_values[] =
  57.616 -        {
  57.617 -            { .type = &abstract_type_string,
  57.618 -              .u.string_val = vm },
  57.619 -            { .type = &abstract_type_string,
  57.620 -              .u.string_val = builder }
  57.621 -        };
  57.622 -
  57.623 -    xen_call_(session, "VM.set_builder", param_values, 2, NULL, NULL);
  57.624 -    return session->ok;
  57.625 -}
  57.626 -
  57.627 -
  57.628 -bool
  57.629 -xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type boot_method)
  57.630 -{
  57.631 -    abstract_value param_values[] =
  57.632 -        {
  57.633 -            { .type = &abstract_type_string,
  57.634 -              .u.string_val = vm },
  57.635 -            { .type = &xen_boot_type_abstract_type_,
  57.636 -              .u.string_val = xen_boot_type_to_string(boot_method) }
  57.637 -        };
  57.638 -
  57.639 -    xen_call_(session, "VM.set_boot_method", param_values, 2, NULL, NULL);
  57.640 -    return session->ok;
  57.641 -}
  57.642 -
  57.643 -
  57.644 -bool
  57.645 -xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel)
  57.646 -{
  57.647 -    abstract_value param_values[] =
  57.648 -        {
  57.649 -            { .type = &abstract_type_string,
  57.650 -              .u.string_val = vm },
  57.651 -            { .type = &abstract_type_string,
  57.652 -              .u.string_val = kernel }
  57.653 -        };
  57.654 -
  57.655 -    xen_call_(session, "VM.set_kernel_kernel", param_values, 2, NULL, NULL);
  57.656 -    return session->ok;
  57.657 -}
  57.658 -
  57.659 -
  57.660 -bool
  57.661 -xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd)
  57.662 -{
  57.663 -    abstract_value param_values[] =
  57.664 -        {
  57.665 -            { .type = &abstract_type_string,
  57.666 -              .u.string_val = vm },
  57.667 -            { .type = &abstract_type_string,
  57.668 -              .u.string_val = initrd }
  57.669 -        };
  57.670 -
  57.671 -    xen_call_(session, "VM.set_kernel_initrd", param_values, 2, NULL, NULL);
  57.672 -    return session->ok;
  57.673 -}
  57.674 -
  57.675 -
  57.676 -bool
  57.677 -xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args)
  57.678 -{
  57.679 -    abstract_value param_values[] =
  57.680 -        {
  57.681 -            { .type = &abstract_type_string,
  57.682 -              .u.string_val = vm },
  57.683 -            { .type = &abstract_type_string,
  57.684 -              .u.string_val = args }
  57.685 -        };
  57.686 -
  57.687 -    xen_call_(session, "VM.set_kernel_args", param_values, 2, NULL, NULL);
  57.688 -    return session->ok;
  57.689 -}
  57.690 -
  57.691 -
  57.692 -bool
  57.693 -xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline)
  57.694 -{
  57.695 -    abstract_value param_values[] =
  57.696 -        {
  57.697 -            { .type = &abstract_type_string,
  57.698 -              .u.string_val = vm },
  57.699 -            { .type = &abstract_type_string,
  57.700 -              .u.string_val = cmdline }
  57.701 -        };
  57.702 -
  57.703 -    xen_call_(session, "VM.set_grub_cmdline", param_values, 2, NULL, NULL);
  57.704 -    return session->ok;
  57.705 -}
  57.706 -
  57.707 -
  57.708 -bool
  57.709  xen_vm_set_otherconfig(xen_session *session, xen_vm vm, xen_string_string_map *otherconfig)
  57.710  {
  57.711      abstract_value param_values[] =
  57.712 @@ -1444,7 +1512,7 @@ xen_vm_set_otherconfig(xen_session *sess
  57.713                .u.set_val = (arbitrary_set *)otherconfig }
  57.714          };
  57.715  
  57.716 -    xen_call_(session, "VM.set_otherconfig", param_values, 2, NULL, NULL);
  57.717 +    xen_call_(session, "VM.set_otherConfig", param_values, 2, NULL, NULL);
  57.718      return session->ok;
  57.719  }
  57.720  
    58.1 --- a/tools/libxen/src/xen_vtpm.c	Fri Dec 15 10:59:33 2006 -0700
    58.2 +++ b/tools/libxen/src/xen_vtpm.c	Fri Dec 15 11:32:58 2006 -0700
    58.3 @@ -196,9 +196,7 @@ xen_vtpm_get_driver(xen_session *session
    58.4          };
    58.5  
    58.6      abstract_type result_type = xen_driver_type_abstract_type_;
    58.7 -    char *result_str = NULL;
    58.8      XEN_CALL_("VTPM.get_driver");
    58.9 -    *result = xen_driver_type_from_string(session, result_str);
   58.10      return session->ok;
   58.11  }
   58.12  
    59.1 --- a/tools/libxen/test/test_bindings.c	Fri Dec 15 10:59:33 2006 -0700
    59.2 +++ b/tools/libxen/test/test_bindings.c	Fri Dec 15 11:32:58 2006 -0700
    59.3 @@ -58,7 +58,8 @@ typedef struct
    59.4  } xen_comms;
    59.5  
    59.6  
    59.7 -static void create_new_vm(xen_session *session);
    59.8 +static xen_vm create_new_vm(xen_session *session);
    59.9 +static void print_vm_power_state(xen_session *session, xen_vm vm);
   59.10  
   59.11  
   59.12  static size_t
   59.13 @@ -244,7 +245,7 @@ int main(int argc, char **argv)
   59.14      xen_string_string_map_free(versions);
   59.15  
   59.16  
   59.17 -    create_new_vm(session);
   59.18 +    xen_vm new_vm = create_new_vm(session);
   59.19      if (!session->ok)
   59.20      {
   59.21          /* Error has been logged, just clean up. */
   59.22 @@ -252,6 +253,16 @@ int main(int argc, char **argv)
   59.23          return 1;
   59.24      }
   59.25  
   59.26 +    print_vm_power_state(session, new_vm);
   59.27 +    if (!session->ok)
   59.28 +    {
   59.29 +        /* Error has been logged, just clean up. */
   59.30 +        xen_vm_free(new_vm);
   59.31 +        CLEANUP;
   59.32 +        return 1;
   59.33 +    }
   59.34 +
   59.35 +    xen_vm_free(new_vm);
   59.36      CLEANUP;
   59.37  
   59.38      return 0;
   59.39 @@ -264,7 +275,7 @@ int main(int argc, char **argv)
   59.40   * allocation patterns can be used, as long as the allocation and free are
   59.41   * paired correctly.
   59.42   */
   59.43 -static void create_new_vm(xen_session *session)
   59.44 +static xen_vm create_new_vm(xen_session *session)
   59.45  {
   59.46      xen_cpu_feature_set *empty_cpu_feature_set =
   59.47          xen_cpu_feature_set_alloc(0);
   59.48 @@ -294,12 +305,12 @@ static void create_new_vm(xen_session *s
   59.49              .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
   59.50              .actions_after_suspend = XEN_ON_NORMAL_EXIT_DESTROY,
   59.51              .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
   59.52 -            .bios_boot = "hd(0,0)",
   59.53 -            .builder = "Linux",
   59.54 -            .boot_method = XEN_BOOT_TYPE_KERNEL_EXTERNAL,
   59.55 -            .kernel_kernel = "vmlinuz",
   59.56 -            .kernel_initrd = "initrd.img",
   59.57 -            .kernel_args = ""
   59.58 +            .hvm_boot = "",
   59.59 +            .pv_bootloader = "pygrub",
   59.60 +            .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
   59.61 +            .pv_ramdisk = "",
   59.62 +            .pv_args = "",
   59.63 +            .pv_bootloader_args = ""
   59.64          };
   59.65  
   59.66  
   59.67 @@ -313,7 +324,7 @@ static void create_new_vm(xen_session *s
   59.68      {
   59.69          fprintf(stderr, "VM creation failed.\n");
   59.70          print_error(session);
   59.71 -        return;
   59.72 +        return NULL;
   59.73      }
   59.74  
   59.75  
   59.76 @@ -327,7 +338,7 @@ static void create_new_vm(xen_session *s
   59.77          fprintf(stderr, "SR lookup failed.\n");
   59.78          print_error(session);
   59.79          xen_vm_free(vm);
   59.80 -        return;
   59.81 +        return NULL;
   59.82      }
   59.83  
   59.84      xen_sr_record_opt sr_record =
   59.85 @@ -339,7 +350,7 @@ static void create_new_vm(xen_session *s
   59.86              .name_label = "MyRootFS",
   59.87              .name_description = "MyRootFS description",
   59.88              .sr = &sr_record,
   59.89 -            .virtual_size = (1 << 20) / 512,
   59.90 +            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
   59.91              .sector_size = 512,
   59.92              .type = XEN_VDI_TYPE_SYSTEM,
   59.93              .sharable = false,
   59.94 @@ -354,7 +365,7 @@ static void create_new_vm(xen_session *s
   59.95  
   59.96          xen_sr_set_free(srs);
   59.97          xen_vm_free(vm);
   59.98 -        return;
   59.99 +        return NULL;
  59.100      }
  59.101  
  59.102  
  59.103 @@ -370,7 +381,7 @@ static void create_new_vm(xen_session *s
  59.104          {
  59.105              .vm = &vm_record_opt,
  59.106              .vdi = &vdi0_record_opt,
  59.107 -            .device = "sda1",
  59.108 +            .device = "xvda1",
  59.109              .mode = XEN_VBD_MODE_RW,
  59.110              .driver = XEN_DRIVER_TYPE_PARAVIRTUALISED
  59.111          };
  59.112 @@ -384,7 +395,7 @@ static void create_new_vm(xen_session *s
  59.113          xen_vdi_free(vdi0);
  59.114          xen_sr_set_free(srs);
  59.115          xen_vm_free(vm);
  59.116 -        return;
  59.117 +        return NULL;
  59.118      }
  59.119  
  59.120      char *vm_uuid;
  59.121 @@ -407,7 +418,7 @@ static void create_new_vm(xen_session *s
  59.122          xen_vdi_free(vdi0);
  59.123          xen_sr_set_free(srs);
  59.124          xen_vm_free(vm);
  59.125 -        return;
  59.126 +        return NULL;
  59.127      }
  59.128  
  59.129      fprintf(stderr,
  59.130 @@ -420,5 +431,34 @@ static void create_new_vm(xen_session *s
  59.131      xen_vbd_free(vbd0);
  59.132      xen_vdi_free(vdi0);
  59.133      xen_sr_set_free(srs);
  59.134 -    xen_vm_free(vm);
  59.135 +
  59.136 +    return vm;
  59.137  }
  59.138 +
  59.139 +
  59.140 +/**
  59.141 + * Print the power state for the given VM.
  59.142 + */
  59.143 +static void print_vm_power_state(xen_session *session, xen_vm vm)
  59.144 +{
  59.145 +    char *vm_uuid;
  59.146 +    enum xen_vm_power_state power_state;
  59.147 +
  59.148 +    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
  59.149 +    {
  59.150 +        print_error(session);
  59.151 +        return;
  59.152 +    }
  59.153 +
  59.154 +    if (!xen_vm_get_power_state(session, &power_state, vm))
  59.155 +    {
  59.156 +        xen_uuid_free(vm_uuid);
  59.157 +        print_error(session);
  59.158 +        return;
  59.159 +    }
  59.160 +
  59.161 +    printf("VM %s power state is %s.\n", vm_uuid,
  59.162 +           xen_vm_power_state_to_string(power_state));
  59.163 +
  59.164 +    xen_uuid_free(vm_uuid);
  59.165 +}
    60.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Dec 15 10:59:33 2006 -0700
    60.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Dec 15 11:32:58 2006 -0700
    60.3 @@ -408,10 +408,6 @@ static PyObject *pyxc_hvm_build(XcObject
    60.4                                        &image, &vcpus, &pae, &acpi, &apic) )
    60.5          return NULL;
    60.6  
    60.7 -#if defined(__ia64__)
    60.8 -    /* Set vcpus to later be retrieved in setup_guest() */
    60.9 -    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_VCPUS, vcpus);
   60.10 -#endif
   60.11      if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
   60.12          return pyxc_error_to_exception();
   60.13  
   60.14 @@ -919,6 +915,68 @@ static PyObject *dom_op(XcObject *self, 
   60.15      return zero;
   60.16  }
   60.17  
   60.18 +#ifdef __powerpc__
   60.19 +static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
   60.20 +                                           PyObject *args,
   60.21 +                                           PyObject *kwds)
   60.22 +{
   60.23 +    uint32_t dom;
   60.24 +    unsigned int log;
   60.25 +
   60.26 +    static char *kwd_list[] = { "dom", "log", NULL };
   60.27 +
   60.28 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
   60.29 +                                      &dom, &log) )
   60.30 +        return NULL;
   60.31 +
   60.32 +    if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
   60.33 +        return PyErr_SetFromErrno(xc_error);
   60.34 +
   60.35 +    Py_INCREF(zero);
   60.36 +    return zero;
   60.37 +}
   60.38 +
   60.39 +static PyObject *pyxc_prose_build(XcObject *self,
   60.40 +                                  PyObject *args,
   60.41 +                                  PyObject *kwds)
   60.42 +{
   60.43 +    uint32_t dom;
   60.44 +    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
   60.45 +    int flags = 0;
   60.46 +    int store_evtchn, console_evtchn;
   60.47 +    unsigned long store_mfn = 0;
   60.48 +    unsigned long console_mfn = 0;
   60.49 +    void *arch_args = NULL;
   60.50 +    int unused;
   60.51 +
   60.52 +    static char *kwd_list[] = { "dom", "store_evtchn",
   60.53 +                                "console_evtchn", "image",
   60.54 +                                /* optional */
   60.55 +                                "ramdisk", "cmdline", "flags",
   60.56 +                                "features", "arch_args", NULL };
   60.57 +
   60.58 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
   60.59 +                                      &dom, &store_evtchn,
   60.60 +                                      &console_evtchn, &image,
   60.61 +                                      /* optional */
   60.62 +                                      &ramdisk, &cmdline, &flags,
   60.63 +                                      &features, &arch_args, &unused) )
   60.64 +        return NULL;
   60.65 +
   60.66 +    if ( xc_prose_build(self->xc_handle, dom, image,
   60.67 +                        ramdisk, cmdline, features, flags,
   60.68 +                        store_evtchn, &store_mfn,
   60.69 +                        console_evtchn, &console_mfn,
   60.70 +                        arch_args) != 0 ) {
   60.71 +        if (!errno)
   60.72 +             errno = EINVAL;
   60.73 +        return PyErr_SetFromErrno(xc_error);
   60.74 +    }
   60.75 +    return Py_BuildValue("{s:i,s:i}", 
   60.76 +                         "store_mfn", store_mfn,
   60.77 +                         "console_mfn", console_mfn);
   60.78 +}
   60.79 +#endif /* powerpc */
   60.80  
   60.81  static PyMethodDef pyxc_methods[] = {
   60.82      { "handle",
   60.83 @@ -1225,6 +1283,27 @@ static PyMethodDef pyxc_methods[] = {
   60.84        " dom        [int]: Domain whose time offset is being set.\n"
   60.85        "Returns: [int] 0 on success; -1 on error.\n" },
   60.86  
   60.87 +#ifdef __powerpc__
   60.88 +    { "arch_alloc_real_mode_area", 
   60.89 +      (PyCFunction)pyxc_alloc_real_mode_area, 
   60.90 +      METH_VARARGS | METH_KEYWORDS, "\n"
   60.91 +      "Allocate a domain's real mode area.\n"
   60.92 +      " dom [int]: Identifier of domain.\n"
   60.93 +      " log [int]: Specifies the area's size.\n"
   60.94 +      "Returns: [int] 0 on success; -1 on error.\n" },
   60.95 +
   60.96 +    { "arch_prose_build", 
   60.97 +      (PyCFunction)pyxc_prose_build, 
   60.98 +      METH_VARARGS | METH_KEYWORDS, "\n"
   60.99 +      "Build a new Linux guest OS.\n"
  60.100 +      " dom     [int]:      Identifier of domain to build into.\n"
  60.101 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
  60.102 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
  60.103 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
  60.104 +      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
  60.105 +      "Returns: [int] 0 on success; -1 on error.\n" },
  60.106 +#endif /* __powerpc */
  60.107 +
  60.108      { NULL, NULL, 0, NULL }
  60.109  };
  60.110  
    61.1 --- a/tools/python/xen/xend/FlatDeviceTree.py	Fri Dec 15 10:59:33 2006 -0700
    61.2 +++ b/tools/python/xen/xend/FlatDeviceTree.py	Fri Dec 15 11:32:58 2006 -0700
    61.3 @@ -22,6 +22,10 @@ import sys
    61.4  import struct
    61.5  import stat
    61.6  import re
    61.7 +import glob
    61.8 +import math
    61.9 +
   61.10 +_host_devtree_root = '/proc/device-tree'
   61.11  
   61.12  _OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
   61.13  _OF_DT_BEGIN_NODE = 0x1
   61.14 @@ -33,8 +37,10 @@ def _bincat(seq, separator=''):
   61.15      '''Concatenate the contents of seq into a bytestream.'''
   61.16      strs = []
   61.17      for item in seq:
   61.18 -        if type(item) == type(0):
   61.19 +        if isinstance(item, int):
   61.20              strs.append(struct.pack(">I", item))
   61.21 +        elif isinstance(item, long):
   61.22 +            strs.append(struct.pack(">Q", item))
   61.23          else:
   61.24              try:
   61.25                  strs.append(item.to_bin())
   61.26 @@ -231,38 +237,51 @@ class Tree(_Node):
   61.27          header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
   61.28          return _pad(header.to_bin(), 8) + payload
   61.29  
   61.30 -_host_devtree_root = '/proc/device-tree'
   61.31 -def _getprop(propname):
   61.32 -    '''Extract a property from the system's device tree.'''
   61.33 -    f = file(os.path.join(_host_devtree_root, propname), 'r')
   61.34 +def _readfile(fullpath):
   61.35 +    '''Return full contents of a file.'''
   61.36 +    f = file(fullpath, 'r')
   61.37      data = f.read()
   61.38      f.close()
   61.39      return data
   61.40  
   61.41 +def _find_first_cpu(dirpath):
   61.42 +    '''Find the first node of type 'cpu' in a directory tree.'''
   61.43 +    cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
   61.44 +    for node in cpulist:
   61.45 +        try:
   61.46 +            data = _readfile(os.path.join(node, 'device_type'))
   61.47 +        except IOError:
   61.48 +            continue
   61.49 +        if 'cpu' in data:
   61.50 +            return node
   61.51 +    raise IOError("couldn't find any CPU nodes under " + dirpath)
   61.52 +
   61.53  def _copynode(node, dirpath, propfilter):
   61.54 -    '''Extract all properties from a node in the system's device tree.'''
   61.55 +    '''Copy all properties and children nodes from a directory tree.'''
   61.56      dirents = os.listdir(dirpath)
   61.57      for dirent in dirents:
   61.58          fullpath = os.path.join(dirpath, dirent)
   61.59          st = os.lstat(fullpath)
   61.60          if stat.S_ISDIR(st.st_mode):
   61.61              child = node.addnode(dirent)
   61.62 -            _copytree(child, fullpath, propfilter)
   61.63 +            _copynode(child, fullpath, propfilter)
   61.64          elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
   61.65 -            node.addprop(dirent, _getprop(fullpath))
   61.66 -
   61.67 -def _copytree(node, dirpath, propfilter):
   61.68 -    path = os.path.join(_host_devtree_root, dirpath)
   61.69 -    _copynode(node, path, propfilter)
   61.70 +            node.addprop(dirent, _readfile(fullpath))
   61.71  
   61.72  def build(imghandler):
   61.73      '''Construct a device tree by combining the domain's configuration and
   61.74      the host's device tree.'''
   61.75      root = Tree()
   61.76  
   61.77 -    # 4 pages: start_info, console, store, shared_info
   61.78 +    # 1st reseravtion entry used for start_info, console, store, shared_info
   61.79      root.reserve(0x3ffc000, 0x4000)
   61.80  
   61.81 +    # 2nd reservation enrty used for initrd, later on when we load the
   61.82 +    # initrd we may fill this in with zeroes which signifies the end
   61.83 +    # of the reservation map.  So as to avoid adding a zero map now we
   61.84 +    # put some bogus yet sensible numbers here.
   61.85 +    root.reserve(0x1000000, 0x1000)
   61.86 +
   61.87      root.addprop('device_type', 'chrp-but-not-really\0')
   61.88      root.addprop('#size-cells', 2)
   61.89      root.addprop('#address-cells', 2)
   61.90 @@ -270,35 +289,52 @@ def build(imghandler):
   61.91      root.addprop('compatible', 'Momentum,Maple\0')
   61.92  
   61.93      xen = root.addnode('xen')
   61.94 -    xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
   61.95 +    xen.addprop('start-info', long(0x3ffc000), long(0x1000))
   61.96      xen.addprop('version', 'Xen-3.0-unstable\0')
   61.97 -    xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
   61.98 +    xen.addprop('reg', long(imghandler.vm.domid), long(0))
   61.99      xen.addprop('domain-name', imghandler.vm.getName() + '\0')
  61.100      xencons = xen.addnode('console')
  61.101      xencons.addprop('interrupts', 1, 0)
  61.102  
  61.103 -    # XXX split out RMA node
  61.104 -    mem = root.addnode('memory@0')
  61.105 +    # add memory nodes
  61.106      totalmem = imghandler.vm.getMemoryTarget() * 1024
  61.107 -    mem.addprop('reg', 0, 0, 0, totalmem)
  61.108 -    mem.addprop('device_type', 'memory\0')
  61.109 +    rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
  61.110 +    rma_bytes = 1 << rma_log
  61.111 +
  61.112 +    # RMA node
  61.113 +    rma = root.addnode('memory@0')
  61.114 +    rma.addprop('reg', long(0), long(rma_bytes))
  61.115 +    rma.addprop('device_type', 'memory\0')
  61.116  
  61.117 +    # all the rest in a single node
  61.118 +    remaining = totalmem - rma_bytes
  61.119 +    if remaining > 0:
  61.120 +        mem = root.addnode('memory@1')
  61.121 +        mem.addprop('reg', long(rma_bytes), long(remaining))
  61.122 +        mem.addprop('device_type', 'memory\0')
  61.123 +
  61.124 +    # add CPU nodes
  61.125      cpus = root.addnode('cpus')
  61.126      cpus.addprop('smp-enabled')
  61.127      cpus.addprop('#size-cells', 0)
  61.128      cpus.addprop('#address-cells', 1)
  61.129  
  61.130      # Copy all properties the system firmware gave us, except for 'linux,'
  61.131 -    # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are
  61.132 -    # identical...
  61.133 +    # properties, from the first CPU node in the device tree. Do this once for
  61.134 +    # every vcpu. Hopefully all cpus are identical...
  61.135      cpu0 = None
  61.136 +    cpu0path = _find_first_cpu(_host_devtree_root)
  61.137      def _nolinuxprops(fullpath):
  61.138          return not os.path.basename(fullpath).startswith('linux,')
  61.139      for i in range(imghandler.vm.getVCpuCount()):
  61.140 -        cpu = cpus.addnode('PowerPC,970@0')
  61.141 -        _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops)
  61.142 -        # and then overwrite what we need to
  61.143 -        pft_size = imghandler.vm.info.get('pft-size', 0x14)
  61.144 +        # create new node and copy all properties
  61.145 +        cpu = cpus.addnode('PowerPC,970@%d' % i)
  61.146 +        _copynode(cpu, cpu0path, _nolinuxprops)
  61.147 +
  61.148 +        # overwrite what we need to
  61.149 +        shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
  61.150 +        shadow_mb_log = int(math.log(shadow_mb, 2))
  61.151 +        pft_size = shadow_mb_log + 20
  61.152          cpu.setprop('ibm,pft-size', 0, pft_size)
  61.153  
  61.154          # set default CPU
  61.155 @@ -307,13 +343,13 @@ def build(imghandler):
  61.156  
  61.157      chosen = root.addnode('chosen')
  61.158      chosen.addprop('cpu', cpu0.get_phandle())
  61.159 -    chosen.addprop('memory', mem.get_phandle())
  61.160 +    chosen.addprop('memory', rma.get_phandle())
  61.161      chosen.addprop('linux,stdout-path', '/xen/console\0')
  61.162      chosen.addprop('interrupt-controller', xen.get_phandle())
  61.163      chosen.addprop('bootargs', imghandler.cmdline + '\0')
  61.164      # xc_linux_load.c will overwrite these 64-bit properties later
  61.165 -    chosen.addprop('linux,initrd-start', 0, 0)
  61.166 -    chosen.addprop('linux,initrd-end', 0, 0)
  61.167 +    chosen.addprop('linux,initrd-start', long(0))
  61.168 +    chosen.addprop('linux,initrd-end', long(0))
  61.169  
  61.170      if 1:
  61.171          f = file('/tmp/domU.dtb', 'w')
    62.1 --- a/tools/python/xen/xend/XendAPI.py	Fri Dec 15 10:59:33 2006 -0700
    62.2 +++ b/tools/python/xen/xend/XendAPI.py	Fri Dec 15 11:32:58 2006 -0700
    62.3 @@ -118,11 +118,16 @@ def valid_vm(func):
    62.4      @param func: function with params: (self, session, vm_ref)
    62.5      @rtype: callable object
    62.6      """    
    62.7 -    def check_vm_ref(self, session, vm_ref, *args, **kwargs):
    62.8 +    def check_vm_ref(self, session, *args, **kwargs):
    62.9 +        if len(args) == 0:
   62.10 +            return {'Status': 'Failure',
   62.11 +                    'ErrorDescription': XEND_ERROR_VM_INVALID}
   62.12 +
   62.13 +        vm_ref = args[0]
   62.14          xendom = XendDomain.instance()
   62.15          if type(vm_ref) == type(str()) and \
   62.16                 xendom.is_valid_vm(vm_ref):
   62.17 -            return func(self, session, vm_ref, *args, **kwargs)
   62.18 +            return func(self, session, *args, **kwargs)
   62.19          else:
   62.20              return {'Status': 'Failure',
   62.21                      'ErrorDescription': XEND_ERROR_VM_INVALID}
   62.22 @@ -567,6 +572,7 @@ class XendAPI:
   62.23                    'VCPUs_utilisation',
   62.24                    'VCPUs_features_required',
   62.25                    'VCPUs_can_use',
   62.26 +                  'consoles',
   62.27                    'VIFs',
   62.28                    'VBDs',
   62.29                    'VTPMs',
   62.30 @@ -578,6 +584,7 @@ class XendAPI:
   62.31                    'name_description',
   62.32                    'user_version',
   62.33                    'is_a_template',
   62.34 +                  'auto_power_on',
   62.35                    'memory_dynamic_max',
   62.36                    'memory_dynamic_min',
   62.37                    'VCPUs_policy',
   62.38 @@ -588,19 +595,18 @@ class XendAPI:
   62.39                    'actions_after_reboot',
   62.40                    'actions_after_suspend',
   62.41                    'actions_after_crash',
   62.42 -                  'bios_boot',
   62.43 +                  'PV_bootloader',
   62.44 +                  'PV_kernel',
   62.45 +                  'PV_ramdisk',
   62.46 +                  'PV_args',
   62.47 +                  'PV_bootloader_args',
   62.48 +                  'HVM_boot',
   62.49                    'platform_std_VGA',
   62.50                    'platform_serial',
   62.51                    'platform_localtime',
   62.52                    'platform_clock_offset',
   62.53                    'platform_enable_audio',
   62.54                    'platform_keymap',
   62.55 -                  'builder',
   62.56 -                  'boot_method',
   62.57 -                  'kernel_kernel',
   62.58 -                  'kernel_initrd',
   62.59 -                  'kernel_args',
   62.60 -                  'grub_cmdline',
   62.61                    'otherConfig']
   62.62  
   62.63      VM_methods = ['clone',
   62.64 @@ -636,26 +642,34 @@ class XendAPI:
   62.65          'actions_after_reboot',
   62.66          'actions_after_suspend',
   62.67          'actions_after_crash',
   62.68 -        'bios_boot',
   62.69 +        'PV_bootloader',
   62.70 +        'PV_kernel',
   62.71 +        'PV_ramdisk',
   62.72 +        'PV_args',
   62.73 +        'PV_bootloader_args',
   62.74 +        'HVM_boot',
   62.75          'platform_std_VGA',
   62.76          'platform_serial',
   62.77          'platform_localtime',
   62.78          'platform_clock_offset',
   62.79          'platform_enable_audio',
   62.80          'platform_keymap',
   62.81 -        'builder',
   62.82 -        'boot_method',
   62.83 -        'kernel_kernel',
   62.84 -        'kernel_initrd',
   62.85 -        'kernel_args',
   62.86          'grub_cmdline',
   62.87          'PCI_bus',
   62.88          'otherConfig']
   62.89          
   62.90 +    def VM_get(self, name, session, vm_ref):
   62.91 +        return xen_api_success(
   62.92 +            XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
   62.93 +
   62.94 +    def VM_set(self, name, session, vm_ref, value):
   62.95 +        XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
   62.96 +        return xen_api_success_void()
   62.97 +
   62.98      # attributes (ro)
   62.99      def VM_get_power_state(self, session, vm_ref):
  62.100          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.101 -        return xen_api_success(dom.state)
  62.102 +        return xen_api_success(dom.get_power_state())
  62.103      
  62.104      def VM_get_resident_on(self, session, vm_ref):
  62.105          return xen_api_success(XendNode.instance().uuid)
  62.106 @@ -765,9 +779,23 @@ class XendAPI:
  62.107          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.108          return xen_api_success(dom.get_on_crash())
  62.109      
  62.110 -    def VM_get_bios_boot(self, session, vm_ref):
  62.111 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.112 -        return xen_api_success(dom.get_bios_boot())
  62.113 +    def VM_get_PV_bootloader(self, session, vm_ref):
  62.114 +        return self.VM_get('PV_bootloader', session, vm_ref)
  62.115 +    
  62.116 +    def VM_get_PV_kernel(self, session, vm_ref):
  62.117 +        return self.VM_get('PV_kernel', session, vm_ref)
  62.118 +    
  62.119 +    def VM_get_PV_ramdisk(self, session, vm_ref):
  62.120 +        return self.VM_get('PV_ramdisk', session, vm_ref)
  62.121 +    
  62.122 +    def VM_get_PV_args(self, session, vm_ref):
  62.123 +        return self.VM_get('PV_args', session, vm_ref)
  62.124 +
  62.125 +    def VM_get_PV_bootloader_args(self, session, vm_ref):
  62.126 +        return self.VM_get('PV_bootloader_args', session, vm_ref)
  62.127 +
  62.128 +    def VM_get_HVM_boot(self, session, vm_ref):
  62.129 +        return self.VM_get('HVM_boot', session, vm_ref)
  62.130      
  62.131      def VM_get_platform_std_VGA(self, session, vm_ref):
  62.132          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.133 @@ -793,34 +821,10 @@ class XendAPI:
  62.134          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.135          return xen_api_todo()
  62.136      
  62.137 -    def VM_get_builder(self, session, vm_ref):
  62.138 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.139 -        return xen_api_success(dom.get_builder())
  62.140 -    
  62.141 -    def VM_get_boot_method(self, session, vm_ref):
  62.142 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.143 -        return xen_api_success(dom.get_boot_method())
  62.144 -    
  62.145 -    def VM_get_kernel_kernel(self, session, vm_ref):
  62.146 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.147 -        return xen_api_success('')
  62.148 -    
  62.149 -    def VM_get_kernel_initrd(self, session, vm_ref):
  62.150 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.151 -        return xen_api_success('')
  62.152 -    
  62.153 -    def VM_get_kernel_args(self, session, vm_ref):
  62.154 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.155 -        return xen_api_success('')
  62.156 -    
  62.157 -    def VM_get_grub_cmdline(self, session, vm_ref):
  62.158 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.159 -        return xen_api_success('')
  62.160 -    
  62.161      def VM_get_otherConfig(self, session, vm_ref):
  62.162          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.163          return xen_api_todo()
  62.164 -    
  62.165 +
  62.166      def VM_set_name_label(self, session, vm_ref, label):
  62.167          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.168          dom.setName(label)
  62.169 @@ -877,11 +881,25 @@ class XendAPI:
  62.170      def VM_set_actions_after_crash(self, session, vm_ref):
  62.171          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.172          return xen_api_success_void()
  62.173 -    
  62.174 -    def VM_set_bios_boot(self, session, vm_ref):
  62.175 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.176 -        return xen_api_success_void()
  62.177 -    
  62.178 +
  62.179 +    def VM_set_HVM_boot(self, session, vm_ref, value):
  62.180 +        return self.VM_set('HVM_boot', session, vm_ref, value)
  62.181 +
  62.182 +    def VM_set_PV_bootloader(self, session, vm_ref, value):
  62.183 +        return self.VM_set('PV_bootloader', session, vm_ref, value)
  62.184 +
  62.185 +    def VM_set_PV_kernel(self, session, vm_ref, value):
  62.186 +        return self.VM_set('PV_kernel', session, vm_ref, value)
  62.187 +
  62.188 +    def VM_set_PV_ramdisk(self, session, vm_ref, value):
  62.189 +        return self.VM_set('PV_ramdisk', session, vm_ref, value)
  62.190 +
  62.191 +    def VM_set_PV_args(self, session, vm_ref, value):
  62.192 +        return self.VM_set('PV_args', session, vm_ref, value)
  62.193 +
  62.194 +    def VM_set_PV_bootloader_args(self, session, vm_ref, value):
  62.195 +        return self.VM_set('PV_bootloader_args', session, vm_ref, value)
  62.196 +
  62.197      def VM_set_platform_std_VGA(self, session, vm_ref):
  62.198          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.199          return xen_api_success_void()
  62.200 @@ -902,30 +920,6 @@ class XendAPI:
  62.201          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.202          return xen_api_success_void()
  62.203      
  62.204 -    def VM_set_builder(self, session, vm_ref):
  62.205 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.206 -        return xen_api_success_void()
  62.207 -    
  62.208 -    def VM_set_boot_method(self, session, vm_ref):
  62.209 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.210 -        return xen_api_success_void()
  62.211 -    
  62.212 -    def VM_set_kernel_kernel(self, session, vm_ref):
  62.213 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.214 -        return xen_api_success_void()
  62.215 -    
  62.216 -    def VM_set_kernel_initrd(self, session, vm_ref):
  62.217 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.218 -        return xen_api_success_void()
  62.219 -    
  62.220 -    def VM_set_kernel_args(self, session, vm_ref):
  62.221 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.222 -        return xen_api_success_void()
  62.223 -    
  62.224 -    def VM_set_grub_cmdline(self, session, vm_ref):
  62.225 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.226 -        return xen_api_success_void()
  62.227 -    
  62.228      def VM_set_otherConfig(self, session, vm_ref):
  62.229          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  62.230          return xen_api_success_void()
  62.231 @@ -961,6 +955,7 @@ class XendAPI:
  62.232              'name_description': xeninfo.getName(),
  62.233              'user_version': 1,
  62.234              'is_a_template': False,
  62.235 +            'auto_power_on': False,
  62.236              'resident_on': XendNode.instance().uuid,
  62.237              'memory_static_min': xeninfo.get_memory_static_min(),
  62.238              'memory_static_max': xeninfo.get_memory_static_max(),
  62.239 @@ -979,22 +974,22 @@ class XendAPI:
  62.240              'actions_after_reboot': xeninfo.get_on_reboot(),
  62.241              'actions_after_suspend': xeninfo.get_on_suspend(),
  62.242              'actions_after_crash': xeninfo.get_on_crash(),
  62.243 +            'consoles': xeninfo.get_consoles(),
  62.244              'VIFs': xeninfo.get_vifs(),
  62.245              'VBDs': xeninfo.get_vbds(),
  62.246              'VTPMs': xeninfo.get_vtpms(),
  62.247 -            'bios_boot': xeninfo.get_bios_boot(),
  62.248 +            'PV_bootloader': xeninfo.info.get('PV_bootloader'),
  62.249 +            'PV_kernel': xeninfo.info.get('PV_kernel'),
  62.250 +            'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
  62.251 +            'PV_args': xeninfo.info.get('PV_args'),
  62.252 +            'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
  62.253 +            'HVM_boot': xeninfo.info.get('HVM_boot'),
  62.254              'platform_std_VGA': xeninfo.get_platform_std_vga(),
  62.255              'platform_serial': xeninfo.get_platform_serial(),
  62.256              'platform_localtime': xeninfo.get_platform_localtime(),
  62.257              'platform_clock_offset': xeninfo.get_platform_clock_offset(),
  62.258              'platform_enable_audio': xeninfo.get_platform_enable_audio(),
  62.259              'platform_keymap': xeninfo.get_platform_keymap(),
  62.260 -            'builder': xeninfo.get_builder(),
  62.261 -            'boot_method': xeninfo.get_boot_method(),
  62.262 -            'kernel_kernel': xeninfo.get_kernel_image(),
  62.263 -            'kernel_initrd': xeninfo.get_kernel_initrd(),
  62.264 -            'kernel_args': xeninfo.get_kernel_args(),
  62.265 -            'grub_cmdline': xeninfo.get_grub_cmdline(),
  62.266              'PCI_bus': xeninfo.get_pci_bus(),
  62.267              'tools_version': xeninfo.get_tools_version(),
  62.268              'otherConfig': xeninfo.get_other_config()
    63.1 --- a/tools/python/xen/xend/XendBootloader.py	Fri Dec 15 10:59:33 2006 -0700
    63.2 +++ b/tools/python/xen/xend/XendBootloader.py	Fri Dec 15 11:32:58 2006 -0700
    63.3 @@ -21,7 +21,8 @@ from xen.util import mkdir
    63.4  from XendLogging import log
    63.5  from XendError import VmError
    63.6  
    63.7 -def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
    63.8 +def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
    63.9 +               ramdisk = '', kernel_args = ''):
   63.10      """Run the boot loader executable on the given disk and return a
   63.11      config image.
   63.12      @param blexec  Binary to use as the boot loader
   63.13 @@ -55,18 +56,19 @@ def bootloader(blexec, disk, quiet = 0, 
   63.14          if quiet:
   63.15              args.append("-q")
   63.16          args.append("--output=%s" % fifo)
   63.17 -        if blargs is not None:
   63.18 +        if blargs:
   63.19              args.extend(shlex.split(blargs))
   63.20          args.append(disk)
   63.21  
   63.22          try:
   63.23 +            log.debug("Launching bootloader as %s." % str(args))
   63.24              os.execvp(args[0], args)
   63.25          except OSError, e:
   63.26              print e
   63.27              pass
   63.28          os._exit(1)
   63.29  
   63.30 -    while 1:
   63.31 +    while True:
   63.32          try:
   63.33              r = os.open(fifo, os.O_RDONLY)
   63.34          except OSError, e:
   63.35 @@ -74,7 +76,7 @@ def bootloader(blexec, disk, quiet = 0, 
   63.36                  continue
   63.37          break
   63.38      ret = ""
   63.39 -    while 1:
   63.40 +    while True:
   63.41          select.select([r], [], [])
   63.42          s = os.read(r, 1024)
   63.43          ret = ret + s
   63.44 @@ -94,9 +96,4 @@ def bootloader(blexec, disk, quiet = 0, 
   63.45      pin.input(ret)
   63.46      pin.input_eof()
   63.47      blcfg = pin.val
   63.48 -
   63.49 -    if imgcfg is None:
   63.50 -        return blcfg
   63.51 -    else:
   63.52 -        c = sxp.merge(blcfg, imgcfg)
   63.53 -        return c
   63.54 +    return blcfg
    64.1 --- a/tools/python/xen/xend/XendConfig.py	Fri Dec 15 10:59:33 2006 -0700
    64.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Dec 15 11:32:58 2006 -0700
    64.3 @@ -103,7 +103,7 @@ XENAPI_HVM_CFG = {
    64.4      'platform_keymap' : 'keymap',
    64.5  }    
    64.6  
    64.7 -# List of XendConfig configuration keys that have no equivalent
    64.8 +# List of XendConfig configuration keys that have no direct equivalent
    64.9  # in the old world.
   64.10  
   64.11  XENAPI_CFG_TYPES = {
   64.12 @@ -132,19 +132,18 @@ XENAPI_CFG_TYPES = {
   64.13      'actions_after_crash': str,
   64.14      'tpm_instance': int,
   64.15      'tpm_backend': int,    
   64.16 -    'bios_boot': str,
   64.17 +    'PV_bootloader': str,
   64.18 +    'PV_kernel': str,
   64.19 +    'PV_initrd': str,
   64.20 +    'PV_args': str,
   64.21 +    'PV_bootloader_args': str,
   64.22 +    'HVM_boot': str,
   64.23      'platform_std_vga': bool0,
   64.24      'platform_serial': str,
   64.25      'platform_localtime': bool0,
   64.26      'platform_clock_offset': bool0,
   64.27      'platform_enable_audio': bool0,
   64.28      'platform_keymap': str,
   64.29 -    'boot_method': str,
   64.30 -    'builder': str,
   64.31 -    'kernel_kernel': str,
   64.32 -    'kernel_initrd': str,
   64.33 -    'kernel_args': str,
   64.34 -    'grub_cmdline': str,
   64.35      'pci_bus': str,
   64.36      'tools_version': dict,
   64.37      'otherconfig': dict,
   64.38 @@ -160,8 +159,6 @@ LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
   64.39      'vcpu_avail',
   64.40      'cpu_weight',
   64.41      'cpu_cap',
   64.42 -    'bootloader',
   64.43 -    'bootloader_args',
   64.44      'features',
   64.45      # read/write
   64.46      'on_xend_start',
   64.47 @@ -188,8 +185,6 @@ LEGACY_CFG_TYPES = {
   64.48      'cpu_cap':         int,
   64.49      'cpu_weight':      int,
   64.50      'cpu_time':      float,
   64.51 -    'bootloader':      str,
   64.52 -    'bootloader_args': str,
   64.53      'features':        str,
   64.54      'localtime':       int,
   64.55      'name':        str,
   64.56 @@ -331,16 +326,18 @@ class XendConfig(dict):
   64.57              'actions_after_crash': 'restart',
   64.58              'actions_after_suspend': '',
   64.59              'features': '',
   64.60 -            'builder': 'linux',
   64.61 +            'PV_bootloader': '',
   64.62 +            'PV_kernel': '',
   64.63 +            'PV_ramdisk': '',
   64.64 +            'PV_args': '',
   64.65 +            'PV_bootloader_args': '',
   64.66 +            'HVM_boot': '',
   64.67              'memory_static_min': 0,
   64.68              'memory_dynamic_min': 0,
   64.69              'shadow_memory': 0,
   64.70              'memory_static_max': 0,
   64.71              'memory_dynamic_max': 0,
   64.72              'memory_actual': 0,
   64.73 -            'boot_method': None,
   64.74 -            'bootloader': None,
   64.75 -            'bootloader_args': None,
   64.76              'devices': {},
   64.77              'image': {},
   64.78              'security': None,
   64.79 @@ -353,6 +350,7 @@ class XendConfig(dict):
   64.80              'online_vcpus': 1,
   64.81              'max_vcpu_id': 0,
   64.82              'vcpu_avail': 1,
   64.83 +            'console_refs': [],
   64.84              'vif_refs': [],
   64.85              'vbd_refs': [],
   64.86              'vtpm_refs': [],
   64.87 @@ -382,10 +380,6 @@ class XendConfig(dict):
   64.88                  raise XendConfigError('Invalid event handling mode: ' +
   64.89                                        event)
   64.90  
   64.91 -    def _builder_sanity_check(self):
   64.92 -        if self['builder'] not in ('hvm', 'linux'):
   64.93 -            raise XendConfigError('Invalid builder configuration')
   64.94 -
   64.95      def _vcpus_sanity_check(self):
   64.96          if self.get('vcpus_number') != None:
   64.97              self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
   64.98 @@ -397,7 +391,6 @@ class XendConfig(dict):
   64.99      def validate(self):
  64.100          self._memory_sanity_check()
  64.101          self._actions_sanity_check()
  64.102 -        self._builder_sanity_check()
  64.103          self._vcpus_sanity_check()
  64.104          self._uuid_sanity_check()
  64.105  
  64.106 @@ -597,23 +590,12 @@ class XendConfig(dict):
  64.107              except KeyError:
  64.108                  pass
  64.109  
  64.110 -        # Convert Legacy "image" config to Xen API kernel_*
  64.111 -        # configuration
  64.112 +        self['PV_bootloader']      = cfg.get('bootloader',      '')
  64.113 +        self['PV_bootloader_args'] = cfg.get('bootloader_args', '')
  64.114 +        
  64.115          image_sxp = sxp.child_value(sxp_cfg, 'image', [])
  64.116          if image_sxp:
  64.117 -            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
  64.118 -            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
  64.119 -            kernel_args = sxp.child_value(image_sxp, 'args', '')
  64.120 -
  64.121 -            # attempt to extract extra arguments from SXP config
  64.122 -            arg_ip = sxp.child_value(image_sxp, 'ip')
  64.123 -            if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
  64.124 -                kernel_args += ' ip=%s' % arg_ip
  64.125 -            arg_root = sxp.child_value(image_sxp, 'root')
  64.126 -            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
  64.127 -                kernel_args += ' root=%s' % arg_root
  64.128 -            
  64.129 -            self['kernel_args'] = kernel_args
  64.130 +            self.update_with_image_sxp(image_sxp)
  64.131  
  64.132          # Convert Legacy HVM parameters to Xen API configuration
  64.133          self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
  64.134 @@ -621,15 +603,6 @@ class XendConfig(dict):
  64.135          self['platform_localtime'] = bool0(cfg.get('localtime', 0))
  64.136          self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
  64.137  
  64.138 -        # Convert path to bootloader to boot_method
  64.139 -        if not cfg.get('bootloader'):
  64.140 -            if self.get('kernel_kernel','').endswith('hvmloader'):
  64.141 -                self['boot_method'] = 'bios'
  64.142 -            else:
  64.143 -                self['boot_method'] = 'kernel_external'
  64.144 -        else:
  64.145 -            self['boot_method'] = 'grub'
  64.146 -
  64.147          # make sure a sane maximum is set
  64.148          if self['memory_static_max'] <= 0:
  64.149              self['memory_static_max'] = self['memory_static_min']
  64.150 @@ -643,6 +616,7 @@ class XendConfig(dict):
  64.151          # set device references in the configuration
  64.152          self['devices'] = cfg.get('devices', {})
  64.153          
  64.154 +        self['console_refs'] = []
  64.155          self['vif_refs'] = []
  64.156          self['vbd_refs'] = []
  64.157          self['vtpm_refs'] = []
  64.158 @@ -703,9 +677,6 @@ class XendConfig(dict):
  64.159          if backend:
  64.160              self['backend'] = backend
  64.161  
  64.162 -        if self['image'].has_key('hvm'):
  64.163 -            self['builder'] = 'hvm'
  64.164 -            
  64.165          # Parse and convert other Non Xen API parameters.
  64.166          def _set_cfg_if_exists(sxp_arg):
  64.167              val = sxp.child_value(sxp_cfg, sxp_arg)
  64.168 @@ -715,7 +686,6 @@ class XendConfig(dict):
  64.169                  else:
  64.170                      self[sxp_arg] = val
  64.171  
  64.172 -        _set_cfg_if_exists('bootloader')
  64.173          _set_cfg_if_exists('shadow_memory')
  64.174          _set_cfg_if_exists('security')
  64.175          _set_cfg_if_exists('features')
  64.176 @@ -739,8 +709,9 @@ class XendConfig(dict):
  64.177          """
  64.178  
  64.179          # populate image
  64.180 -        self['image']['type'] = self['builder']
  64.181 -        if self['builder'] == 'hvm':
  64.182 +        hvm = self['HVM_boot'] != ''
  64.183 +        self['image']['type'] = hvm and 'hvm' or 'linux'
  64.184 +        if hvm:
  64.185              self['image']['hvm'] = {}
  64.186              for xapi, cfgapi in XENAPI_HVM_CFG.items():
  64.187                  self['image']['hvm'][cfgapi] = self[xapi]
  64.188 @@ -778,8 +749,10 @@ class XendConfig(dict):
  64.189          @type xapi: dict
  64.190          """
  64.191          for key, val in xapi.items():
  64.192 -            key = key.lower()
  64.193              type_conv = XENAPI_CFG_TYPES.get(key)
  64.194 +            if type_conv is None:
  64.195 +                key = key.lower()
  64.196 +                type_conv = XENAPI_CFG_TYPES.get(key)
  64.197              if callable(type_conv):
  64.198                  self[key] = type_conv(val)
  64.199              else:
  64.200 @@ -1098,8 +1071,8 @@ class XendConfig(dict):
  64.201      def update_with_image_sxp(self, image_sxp):
  64.202          # Convert Legacy "image" config to Xen API kernel_*
  64.203          # configuration
  64.204 -        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
  64.205 -        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
  64.206 +        self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
  64.207 +        self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
  64.208          kernel_args = sxp.child_value(image_sxp, 'args', '')
  64.209          
  64.210          # attempt to extract extra arguments from SXP config
  64.211 @@ -1109,7 +1082,7 @@ class XendConfig(dict):
  64.212          arg_root = sxp.child_value(image_sxp, 'root')
  64.213          if arg_root and not re.search(r'root=', kernel_args):
  64.214              kernel_args += ' root=%s' % arg_root
  64.215 -        self['kernel_args'] = kernel_args
  64.216 +        self['PV_args'] = kernel_args
  64.217  
  64.218          # Store image SXP in python dictionary format
  64.219          image = {}
    65.1 --- a/tools/python/xen/xend/XendDomain.py	Fri Dec 15 10:59:33 2006 -0700
    65.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri Dec 15 11:32:58 2006 -0700
    65.3 @@ -591,7 +591,9 @@ class XendDomain:
    65.4          try:
    65.5              self.domains_lock.acquire()
    65.6              result = [d.get_uuid() for d in self.domains.values()]
    65.7 -            result += self.managed_domains.keys()
    65.8 +            for d in self.managed_domains.keys():
    65.9 +                if d not in result:
   65.10 +                    result.append(d)
   65.11              return result
   65.12          finally:
   65.13              self.domains_lock.release()
   65.14 @@ -1337,11 +1339,7 @@ class XendDomain:
   65.15          dominfo = self.domain_lookup_nr(domid)
   65.16          if not dominfo:
   65.17              raise XendInvalidDomain(str(domid))
   65.18 -        maxmem = int(mem) * 1024
   65.19 -        try:
   65.20 -            return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
   65.21 -        except Exception, ex:
   65.22 -            raise XendError(str(ex))
   65.23 +        dominfo.setMemoryMaximum(mem)
   65.24  
   65.25      def domain_ioport_range_enable(self, domid, first, last):
   65.26          """Enable access to a range of IO ports for a domain
    66.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 15 10:59:33 2006 -0700
    66.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 15 11:32:58 2006 -0700
    66.3 @@ -51,6 +51,7 @@ from xen.xend.XendConstants import *
    66.4  from xen.xend.XendAPIConstants import *
    66.5  
    66.6  MIGRATE_TIMEOUT = 30.0
    66.7 +BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
    66.8  
    66.9  xc = xen.lowlevel.xc.xc()
   66.10  xroot = XendRoot.instance()
   66.11 @@ -59,65 +60,6 @@ log = logging.getLogger("xend.XendDomain
   66.12  #log.setLevel(logging.TRACE)
   66.13  
   66.14  
   66.15 -def bool0(v):
   66.16 -    return v != "0" and bool(v)
   66.17 -
   66.18 -
   66.19 -##
   66.20 -# All parameters of VMs that may be configured on-the-fly, or at start-up.
   66.21 -# 
   66.22 -VM_CONFIG_PARAMS = [
   66.23 -    ('name',        str),
   66.24 -    ('on_poweroff', str),
   66.25 -    ('on_reboot',   str),
   66.26 -    ('on_crash',    str),
   66.27 -    ]
   66.28 -
   66.29 -
   66.30 -##
   66.31 -# Configuration entries that we expect to round-trip -- be read from the
   66.32 -# config file or xc, written to save-files (i.e. through sxpr), and reused as
   66.33 -# config on restart or restore, all without munging.  Some configuration
   66.34 -# entries are munged for backwards compatibility reasons, or because they
   66.35 -# don't come out of xc in the same form as they are specified in the config
   66.36 -# file, so those are handled separately.
   66.37 -ROUNDTRIPPING_CONFIG_ENTRIES = [
   66.38 -    ('uuid',            str),
   66.39 -    ('vcpus',           int),
   66.40 -    ('vcpu_avail',      int),
   66.41 -    ('cpu_cap',         int),
   66.42 -    ('cpu_weight',      int),
   66.43 -    ('memory',          int),
   66.44 -    ('shadow_memory',   int),
   66.45 -    ('maxmem',          int),
   66.46 -    ('bootloader',      str),
   66.47 -    ('bootloader_args', str),
   66.48 -    ('features',        str),
   66.49 -    ('localtime',       bool0),
   66.50 -    ]
   66.51 -
   66.52 -ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
   66.53 -
   66.54 -
   66.55 -##
   66.56 -# All entries written to the store.  This is VM_CONFIG_PARAMS, plus those
   66.57 -# entries written to the store that cannot be reconfigured on-the-fly.
   66.58 -#
   66.59 -VM_STORE_ENTRIES = [
   66.60 -    ('uuid',          str),
   66.61 -    ('vcpus',         int),
   66.62 -    ('vcpu_avail',    int),
   66.63 -    ('memory',        int),
   66.64 -    ('shadow_memory', int),
   66.65 -    ('maxmem',        int),
   66.66 -    ('start_time',    float),
   66.67 -    ('on_xend_start', str),
   66.68 -    ('on_xend_stop', str),
   66.69 -    ]
   66.70 -
   66.71 -VM_STORE_ENTRIES += VM_CONFIG_PARAMS
   66.72 -
   66.73 -
   66.74  #
   66.75  # There are a number of CPU-related fields:
   66.76  #
   66.77 @@ -167,7 +109,7 @@ def recreate(info, priv):
   66.78  
   66.79      @param xeninfo: Parsed configuration
   66.80      @type  xeninfo: Dictionary
   66.81 -    @param priv: TODO, unknown, something to do with memory
   66.82 +    @param priv: Is a privileged domain (Dom 0)
   66.83      @type  priv: bool
   66.84  
   66.85      @rtype:  XendDomainInfo
   66.86 @@ -381,7 +323,7 @@ class XendDomainInfo:
   66.87          @type    dompath: string
   66.88          @keyword augment: Augment given info with xenstored VM info
   66.89          @type    augment: bool
   66.90 -        @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
   66.91 +        @keyword priv: Is a privileged domain (Dom 0)
   66.92          @type    priv: bool
   66.93          @keyword resume: Is this domain being resumed?
   66.94          @type    resume: bool
   66.95 @@ -497,6 +439,7 @@ class XendDomainInfo:
   66.96              xc.domain_pause(self.domid)
   66.97              self._stateSet(DOM_STATE_PAUSED)
   66.98          except Exception, ex:
   66.99 +            log.exception(ex)
  66.100              raise XendError("Domain unable to be paused: %s" % str(ex))
  66.101  
  66.102      def unpause(self):
  66.103 @@ -508,6 +451,7 @@ class XendDomainInfo:
  66.104              xc.domain_unpause(self.domid)
  66.105              self._stateSet(DOM_STATE_RUNNING)
  66.106          except Exception, ex:
  66.107 +            log.exception(ex)
  66.108              raise XendError("Domain unable to be unpaused: %s" % str(ex))
  66.109  
  66.110      def send_sysrq(self, key):
  66.111 @@ -526,7 +470,8 @@ class XendDomainInfo:
  66.112          dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
  66.113          dev_config_dict = self.info['devices'][dev_uuid][1]
  66.114          log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict))
  66.115 -        devid = self._createDevice(dev_type, dev_config_dict)
  66.116 +        dev_config_dict['devid'] = devid = \
  66.117 +             self._createDevice(dev_type, dev_config_dict)
  66.118          self._waitForDevice(dev_type, devid)
  66.119          return self.getDeviceController(dev_type).sxpr(devid)
  66.120  
  66.121 @@ -563,7 +508,7 @@ class XendDomainInfo:
  66.122          for devclass in XendDevices.valid_devices():
  66.123              self.getDeviceController(devclass).waitForDevices()
  66.124  
  66.125 -    def destroyDevice(self, deviceClass, devid):
  66.126 +    def destroyDevice(self, deviceClass, devid, force = False):
  66.127          try:
  66.128              devid = int(devid)
  66.129          except ValueError:
  66.130 @@ -578,7 +523,7 @@ class XendDomainInfo:
  66.131                      devid = entry
  66.132                      break
  66.133                  
  66.134 -        return self.getDeviceController(deviceClass).destroyDevice(devid)
  66.135 +        return self.getDeviceController(deviceClass).destroyDevice(devid, force)
  66.136  
  66.137  
  66.138  
  66.139 @@ -606,8 +551,34 @@ class XendDomainInfo:
  66.140              raise XendError('Invalid memory size')
  66.141          
  66.142          self.info['memory_static_min'] = target
  66.143 -        self.storeVm("memory", target)
  66.144 -        self.storeDom("memory/target", target << 10)
  66.145 +        if self.domid >= 0:
  66.146 +            self.storeVm("memory", target)
  66.147 +            self.storeDom("memory/target", target << 10)
  66.148 +        else:
  66.149 +            self.info['memory_dynamic_min'] = target
  66.150 +            xen.xend.XendDomain.instance().managed_config_save(self)
  66.151 +
  66.152 +    def setMemoryMaximum(self, limit):
  66.153 +        """Set the maximum memory limit of this domain
  66.154 +        @param limit: In MiB.
  66.155 +        """
  66.156 +        log.debug("Setting memory maximum of domain %s (%d) to %d MiB.",
  66.157 +                  self.info['name_label'], self.domid, limit)
  66.158 +
  66.159 +        if limit <= 0:
  66.160 +            raise XendError('Invalid memory size')
  66.161 +
  66.162 +        self.info['memory_static_max'] = limit
  66.163 +        if self.domid >= 0:
  66.164 +            maxmem = int(limit) * 1024
  66.165 +            try:
  66.166 +                return xc.domain_setmaxmem(self.domid, maxmem)
  66.167 +            except Exception, ex:
  66.168 +                raise XendError(str(ex))
  66.169 +        else:
  66.170 +            self.info['memory_dynamic_max'] = limit
  66.171 +            xen.xend.XendDomain.instance().managed_config_save(self)
  66.172 +
  66.173  
  66.174      def getVCPUInfo(self):
  66.175          try:
  66.176 @@ -647,6 +618,8 @@ class XendDomainInfo:
  66.177          if priv:
  66.178              augment_entries.remove('memory')
  66.179              augment_entries.remove('maxmem')
  66.180 +            augment_entries.remove('vcpus')
  66.181 +            augment_entries.remove('vcpu_avail')
  66.182  
  66.183          vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
  66.184                                           for k in augment_entries])
  66.185 @@ -664,6 +637,14 @@ class XendDomainInfo:
  66.186                  else:
  66.187                      self.info[arg] = val
  66.188  
  66.189 +        # For dom0, we ignore any stored value for the vcpus fields, and
  66.190 +        # read the current value from Xen instead.  This allows boot-time
  66.191 +        # settings to take precedence over any entries in the store.
  66.192 +        if priv:
  66.193 +            xeninfo = dom_get(self.domid)
  66.194 +            self.info['vcpus_number'] = xeninfo['online_vcpus']
  66.195 +            self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
  66.196 +
  66.197          # read image value
  66.198          image_sxp = self._readVm('image')
  66.199          if image_sxp:
  66.200 @@ -876,18 +857,23 @@ class XendDomainInfo:
  66.201  
  66.202      def setVCpuCount(self, vcpus):
  66.203          self.info['vcpu_avail'] = (1 << vcpus) - 1
  66.204 -        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
  66.205 -        # update dom differently depending on whether we are adjusting
  66.206 -        # vcpu number up or down, otherwise _vcpuDomDetails does not
  66.207 -        # disable the vcpus
  66.208 -        if self.info['vcpus_number'] > vcpus:
  66.209 -            # decreasing
  66.210 -            self._writeDom(self._vcpuDomDetails())
  66.211 +        if self.domid >= 0:
  66.212 +            self.storeVm('vcpu_avail', self.info['vcpu_avail'])
  66.213 +            # update dom differently depending on whether we are adjusting
  66.214 +            # vcpu number up or down, otherwise _vcpuDomDetails does not
  66.215 +            # disable the vcpus
  66.216 +            if self.info['vcpus_number'] > vcpus:
  66.217 +                # decreasing
  66.218 +                self._writeDom(self._vcpuDomDetails())
  66.219 +                self.info['vcpus_number'] = vcpus
  66.220 +            else:
  66.221 +                # same or increasing
  66.222 +                self.info['vcpus_number'] = vcpus
  66.223 +                self._writeDom(self._vcpuDomDetails())
  66.224 +        else:
  66.225              self.info['vcpus_number'] = vcpus
  66.226 -        else:
  66.227 -            # same or increasing
  66.228 -            self.info['vcpus_number'] = vcpus
  66.229 -            self._writeDom(self._vcpuDomDetails())
  66.230 +            self.info['online_vcpus'] = vcpus
  66.231 +            xen.xend.XendDomain.instance().managed_config_save(self)
  66.232  
  66.233      def getLabel(self):
  66.234          return security.get_security_info(self.info, 'label')
  66.235 @@ -896,6 +882,10 @@ class XendDomainInfo:
  66.236          """Get this domain's target memory size, in KB."""
  66.237          return self.info['memory_static_min'] * 1024
  66.238  
  66.239 +    def getMemoryMaximum(self):
  66.240 +        """Get this domain's maximum memory size, in KB."""
  66.241 +        return self.info['memory_static_max'] * 1024
  66.242 +
  66.243      def getResume(self):
  66.244          return str(self._resume)
  66.245  
  66.246 @@ -1017,7 +1007,8 @@ class XendDomainInfo:
  66.247              self.refresh_shutdown_lock.release()
  66.248  
  66.249          if restart_reason:
  66.250 -            self._maybeRestart(restart_reason)
  66.251 +            threading.Thread(target = self._maybeRestart,
  66.252 +                             args = (restart_reason,)).start()
  66.253  
  66.254  
  66.255      #
  66.256 @@ -1060,7 +1051,6 @@ class XendDomainInfo:
  66.257          """
  66.258          from xen.xend import XendDomain
  66.259          
  66.260 -        self._configureBootloader()
  66.261          config = self.sxpr()
  66.262  
  66.263          if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
  66.264 @@ -1186,6 +1176,10 @@ class XendDomainInfo:
  66.265      def _waitForDevice(self, deviceClass, devid):
  66.266          return self.getDeviceController(deviceClass).waitForDevice(devid)
  66.267  
  66.268 +    def _waitForDeviceUUID(self, dev_uuid):
  66.269 +        deviceClass, config = self.info['devices'].get(dev_uuid)
  66.270 +        self._waitForDevice(deviceClass, config['devid'])
  66.271 +
  66.272      def _reconfigureDevice(self, deviceClass, devid, devconfig):
  66.273          return self.getDeviceController(deviceClass).reconfigureDevice(
  66.274              devid, devconfig)
  66.275 @@ -1289,6 +1283,8 @@ class XendDomainInfo:
  66.276  
  66.277          log.debug('XendDomainInfo.constructDomain')
  66.278  
  66.279 +        self.shutdownStartTime = None
  66.280 +
  66.281          image_cfg = self.info.get('image', {})
  66.282          hvm = image_cfg.has_key('hvm')
  66.283  
  66.284 @@ -1333,10 +1329,7 @@ class XendDomainInfo:
  66.285                    self.domid,
  66.286                    self.info['cpu_weight'])
  66.287  
  66.288 -        # if we have a boot loader but no image, then we need to set things
  66.289 -        # up by running the boot loader non-interactively
  66.290 -        if self.info.get('bootloader'):
  66.291 -            self._configureBootloader()
  66.292 +        self._configureBootloader()
  66.293  
  66.294          if not self._infoIsSet('image'):
  66.295              raise VmError('Missing image in configuration')
  66.296 @@ -1363,9 +1356,9 @@ class XendDomainInfo:
  66.297              # Use architecture- and image-specific calculations to determine
  66.298              # the various headrooms necessary, given the raw configured
  66.299              # values. maxmem, memory, and shadow are all in KiB.
  66.300 -            maxmem = self.image.getRequiredAvailableMemory(
  66.301 +            memory = self.image.getRequiredAvailableMemory(
  66.302                  self.info['memory_static_min'] * 1024)
  66.303 -            memory = self.image.getRequiredAvailableMemory(
  66.304 +            maxmem = self.image.getRequiredAvailableMemory(
  66.305                  self.info['memory_static_max'] * 1024)
  66.306              shadow = self.image.getRequiredShadowMemory(
  66.307                  self.info['shadow_memory'] * 1024,
  66.308 @@ -1397,17 +1390,14 @@ class XendDomainInfo:
  66.309  
  66.310              self._createDevices()
  66.311  
  66.312 -            if self.info['bootloader']:
  66.313 -                self.image.cleanupBootloading()
  66.314 +            self.image.cleanupBootloading()
  66.315  
  66.316              self.info['start_time'] = time.time()
  66.317  
  66.318              self._stateSet(DOM_STATE_RUNNING)
  66.319          except RuntimeError, exn:
  66.320              log.exception("XendDomainInfo.initDomain: exception occurred")
  66.321 -            if self.info['bootloader'] not in (None, 'kernel_external') \
  66.322 -                   and self.image is not None:
  66.323 -                self.image.cleanupBootloading()
  66.324 +            self.image.cleanupBootloading()
  66.325              raise VmError(str(exn))
  66.326  
  66.327  
  66.328 @@ -1538,33 +1528,78 @@ class XendDomainInfo:
  66.329  
  66.330      def _configureBootloader(self):
  66.331          """Run the bootloader if we're configured to do so."""
  66.332 -        if not self.info.get('bootloader'):
  66.333 -            return
  66.334 -        blcfg = None
  66.335 +
  66.336 +        blexec          = self.info['PV_bootloader']
  66.337 +        bootloader_args = self.info['PV_bootloader_args']
  66.338 +        kernel          = self.info['PV_kernel']
  66.339 +        ramdisk         = self.info['PV_ramdisk']
  66.340 +        args            = self.info['PV_args']
  66.341 +        boot            = self.info['HVM_boot']
  66.342  
  66.343 -        # FIXME: this assumes that we want to use the first disk device
  66.344 -        for (devtype, devinfo) in self.info.all_devices_sxpr():
  66.345 -            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
  66.346 -                continue
  66.347 -            disk = None
  66.348 -            for param in devinfo:
  66.349 -                if param[0] == 'uname':
  66.350 -                    disk = param[1]
  66.351 -                    break
  66.352 +        if boot:
  66.353 +            # HVM booting.
  66.354 +            self.info['image']['type'] = 'hvm'
  66.355 +            self.info['image']['devices']['boot'] = boot
  66.356 +        elif not blexec and kernel:
  66.357 +            # Boot from dom0.  Nothing left to do -- the kernel and ramdisk
  66.358 +            # will be picked up by image.py.
  66.359 +            pass
  66.360 +        else:
  66.361 +            # Boot using bootloader
  66.362 +            if not blexec or blexec == 'pygrub':
  66.363 +                blexec = '/usr/bin/pygrub'
  66.364 +
  66.365 +            blcfg = None
  66.366 +            for (devtype, devinfo) in self.info.all_devices_sxpr():
  66.367 +                if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
  66.368 +                    continue
  66.369 +                disk = None
  66.370 +                for param in devinfo:
  66.371 +                    if param[0] == 'uname':
  66.372 +                        disk = param[1]
  66.373 +                        break
  66.374  
  66.375 -            if disk is None:
  66.376 -                continue
  66.377 -            fn = blkdev_uname_to_file(disk)
  66.378 -            blcfg = bootloader(self.info['bootloader'], fn, 1,
  66.379 -                               self.info['bootloader_args'],
  66.380 -                               self.info['image'])
  66.381 -            break
  66.382 -        if blcfg is None:
  66.383 -            msg = "Had a bootloader specified, but can't find disk"
  66.384 -            log.error(msg)
  66.385 -            raise VmError(msg)
  66.386 +                if disk is None:
  66.387 +                    continue
  66.388 +                fn = blkdev_uname_to_file(disk)
  66.389 +                mounted = devtype == 'tap' and not os.stat(fn).st_rdev
  66.390 +                if mounted:
  66.391 +                    # This is a file, not a device.  pygrub can cope with a
  66.392 +                    # file if it's raw, but if it's QCOW or other such formats
  66.393 +                    # used through blktap, then we need to mount it first.
  66.394 +
  66.395 +                    log.info("Mounting %s on %s." %
  66.396 +                             (fn, BOOTLOADER_LOOPBACK_DEVICE))
  66.397 +
  66.398 +                    vbd = {
  66.399 +                        'mode': 'RO',
  66.400 +                        'device': BOOTLOADER_LOOPBACK_DEVICE,
  66.401 +                        }
  66.402 +
  66.403 +                    from xen.xend import XendDomain
  66.404 +                    dom0 = XendDomain.instance().privilegedDomain()
  66.405 +                    dom0._waitForDeviceUUID(dom0.create_vbd_with_vdi(vbd, fn))
  66.406 +                    fn = BOOTLOADER_LOOPBACK_DEVICE
  66.407 +
  66.408 +                try:
  66.409 +                    blcfg = bootloader(blexec, fn, True,
  66.410 +                                       bootloader_args, kernel, ramdisk, args)
  66.411 +                finally:
  66.412 +                    if mounted:
  66.413 +                        log.info("Unmounting %s from %s." %
  66.414 +                                 (fn, BOOTLOADER_LOOPBACK_DEVICE))
  66.415 +
  66.416 +                        dom0.destroyDevice('tap', '/dev/xvdp')
  66.417 +
  66.418 +                break
  66.419 +
  66.420 +            if blcfg is None:
  66.421 +                msg = "Had a bootloader specified, but can't find disk"
  66.422 +                log.error(msg)
  66.423 +                raise VmError(msg)
  66.424          
  66.425 -        self.info.update_with_image_sxp(blcfg)
  66.426 +            self.info.update_with_image_sxp(blcfg)
  66.427 +
  66.428  
  66.429      # 
  66.430      # VM Functions
  66.431 @@ -1727,7 +1762,7 @@ class XendDomainInfo:
  66.432              raise VmError("VM name '%s' already exists%s" %
  66.433                            (name,
  66.434                             dom.domid is not None and
  66.435 -                           ("as domain %s" % str(dom.domid)) or ""))
  66.436 +                           (" as domain %s" % str(dom.domid)) or ""))
  66.437          
  66.438  
  66.439      def update(self, info = None, refresh = True):
  66.440 @@ -1809,8 +1844,6 @@ class XendDomainInfo:
  66.441          return '' # TODO
  66.442      def get_power_state(self):
  66.443          return XEN_API_VM_POWER_STATE[self.state]
  66.444 -    def get_bios_boot(self):
  66.445 -        return '' # TODO
  66.446      def get_platform_std_vga(self):
  66.447          return self.info.get('platform_std_vga', False)    
  66.448      def get_platform_keymap(self):
  66.449 @@ -1825,18 +1858,6 @@ class XendDomainInfo:
  66.450          return self.info.get('platform_enable_audio', False)
  66.451      def get_platform_keymap(self):
  66.452          return self.info.get('platform_keymap', '')
  66.453 -    def get_builder(self):
  66.454 -        return self.info.get('builder', 0)
  66.455 -    def get_boot_method(self):
  66.456 -        return self.info.get('boot_method', XEN_API_BOOT_TYPE[2])
  66.457 -    def get_kernel_image(self):
  66.458 -        return self.info.get('kernel_kernel', '')
  66.459 -    def get_kernel_initrd(self):
  66.460 -        return self.info.get('kernel_initrd', '')
  66.461 -    def get_kernel_args(self):
  66.462 -        return self.info.get('kernel_args', '')
  66.463 -    def get_grub_cmdline(self):
  66.464 -        return '' # TODO
  66.465      def get_pci_bus(self):
  66.466          return '' # TODO
  66.467      def get_tools_version(self):
  66.468 @@ -1972,6 +1993,9 @@ class XendDomainInfo:
  66.469                  
  66.470          return vcpu_util
  66.471  
  66.472 +    def get_consoles(self):
  66.473 +        return self.info.get('console_refs', [])
  66.474 +
  66.475      def get_vifs(self):
  66.476          return self.info.get('vif_refs', [])
  66.477  
  66.478 @@ -1992,10 +2016,9 @@ class XendDomainInfo:
  66.479          if not dev_uuid:
  66.480              raise XendError('Failed to create device')
  66.481          
  66.482 -        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
  66.483 -            sxpr = self.info.device_sxpr(dev_uuid)
  66.484 -            devid = self.getDeviceController('vbd').createDevice(sxpr)
  66.485 -            raise XendError("Device creation failed")
  66.486 +        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
  66.487 +            _, config = self.info['devices'][dev_uuid]
  66.488 +            config['devid'] = self.getDeviceController('vbd').createDevice(config)
  66.489  
  66.490          return dev_uuid
  66.491  
  66.492 @@ -2013,10 +2036,9 @@ class XendDomainInfo:
  66.493          if not dev_uuid:
  66.494              raise XendError('Failed to create device')
  66.495  
  66.496 -        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
  66.497 -            sxpr = self.info.device_sxpr(dev_uuid)
  66.498 -            devid = self.getDeviceController('tap').createDevice(sxpr)
  66.499 -            raise XendError("Device creation failed")
  66.500 +        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
  66.501 +            _, config = self.info['devices'][dev_uuid]
  66.502 +            config['devid'] = self.getDeviceController('tap').createDevice(config)
  66.503  
  66.504          return dev_uuid
  66.505  
  66.506 @@ -2031,10 +2053,9 @@ class XendDomainInfo:
  66.507          if not dev_uuid:
  66.508              raise XendError('Failed to create device')
  66.509          
  66.510 -        if self.state in (DOM_STATE_HALTED,):
  66.511 -            sxpr = self.info.device_sxpr(dev_uuid)
  66.512 -            devid = self.getDeviceController('vif').createDevice(sxpr)
  66.513 -            raise XendError("Device creation failed")
  66.514 +        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
  66.515 +            _, config = self.info['devices'][dev_uuid]
  66.516 +            config['devid'] = self.getDeviceController('vif').createDevice(config)
  66.517  
  66.518          return dev_uuid
  66.519  
    67.1 --- a/tools/python/xen/xend/XendStorageRepository.py	Fri Dec 15 10:59:33 2006 -0700
    67.2 +++ b/tools/python/xen/xend/XendStorageRepository.py	Fri Dec 15 11:32:58 2006 -0700
    67.3 @@ -20,6 +20,7 @@
    67.4  #
    67.5  
    67.6  import commands
    67.7 +import logging
    67.8  import os
    67.9  import stat
   67.10  import threading
   67.11 @@ -33,9 +34,12 @@ XEND_STORAGE_MAX_IGNORE = -1
   67.12  XEND_STORAGE_DIR = "/var/lib/xend/storage/"
   67.13  XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
   67.14  XEND_STORAGE_VDICFG_FILENAME = "%s.vdi.xml"
   67.15 -QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s"
   67.16 +QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create -p %d %s"
   67.17  
   67.18 -MB = 1024 *1024
   67.19 +MB = 1024 * 1024
   67.20 +
   67.21 +log = logging.getLogger("xend.XendStorageRepository")
   67.22 +
   67.23  
   67.24  class DeviceInvalidError(Exception):
   67.25      pass
   67.26 @@ -89,8 +93,7 @@ class XendStorageRepository:
   67.27                  open(uuid_file, 'w').write(new_uuid + '\n')
   67.28                  return new_uuid
   67.29          except IOError:
   67.30 -            # TODO: log warning
   67.31 -            pass
   67.32 +            log.exception("Failed to determine SR UUID")
   67.33  
   67.34          return uuid.createString()
   67.35  
   67.36 @@ -229,8 +232,7 @@ class XendStorageRepository:
   67.37                      if cfg_path and os.path.exists(cfg_path):
   67.38                          os.unlink(cfg_path)
   67.39                  except OSError:
   67.40 -                    # TODO: log warning
   67.41 -                    pass
   67.42 +                    log.exception("Failed to destroy image")
   67.43                  del self.images[image_uuid]
   67.44                  return True
   67.45          finally:
    68.1 --- a/tools/python/xen/xend/image.py	Fri Dec 15 10:59:33 2006 -0700
    68.2 +++ b/tools/python/xen/xend/image.py	Fri Dec 15 11:32:58 2006 -0700
    68.3 @@ -68,6 +68,7 @@ class ImageHandler:
    68.4      def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
    68.5          self.vm = vm
    68.6  
    68.7 +        self.bootloader = None
    68.8          self.kernel = None
    68.9          self.ramdisk = None
   68.10          self.cmdline = None
   68.11 @@ -76,9 +77,10 @@ class ImageHandler:
   68.12  
   68.13      def configure(self, vmConfig, imageConfig, _):
   68.14          """Config actions common to all unix-like domains."""
   68.15 -        self.kernel = vmConfig['kernel_kernel']
   68.16 -        self.cmdline = vmConfig['kernel_args']
   68.17 -        self.ramdisk = vmConfig['kernel_initrd']
   68.18 +        self.bootloader = vmConfig['PV_bootloader']
   68.19 +        self.kernel = vmConfig['PV_kernel']
   68.20 +        self.cmdline = vmConfig['PV_args']
   68.21 +        self.ramdisk = vmConfig['PV_ramdisk']
   68.22          self.vm.storeVm(("image/ostype", self.ostype),
   68.23                          ("image/kernel", self.kernel),
   68.24                          ("image/cmdline", self.cmdline),
   68.25 @@ -86,8 +88,9 @@ class ImageHandler:
   68.26  
   68.27  
   68.28      def cleanupBootloading(self):
   68.29 -        self.unlink(self.kernel)
   68.30 -        self.unlink(self.ramdisk)
   68.31 +        if self.bootloader:
   68.32 +            self.unlink(self.kernel)
   68.33 +            self.unlink(self.ramdisk)
   68.34  
   68.35  
   68.36      def unlink(self, f):
   68.37 @@ -145,6 +148,14 @@ class ImageHandler:
   68.38          add headroom where necessary."""
   68.39          return self.getRequiredAvailableMemory(self.vm.getMemoryTarget())
   68.40  
   68.41 +    def getRequiredMaximumReservation(self):
   68.42 +        """@param mem_kb The maximum possible memory, in KiB.
   68.43 +        @return The corresponding required amount of memory to be free, also
   68.44 +        in KiB. This is normally the same as getRequiredAvailableMemory, but
   68.45 +        architecture- or image-specific code may override this to
   68.46 +        add headroom where necessary."""
   68.47 +        return self.getRequiredAvailableMemory(self.vm.getMemoryMaximum())
   68.48 +
   68.49      def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   68.50          """@param shadow_mem_kb The configured shadow memory, in KiB.
   68.51          @param maxmem_kb The configured maxmem, in KiB.
   68.52 @@ -235,6 +246,60 @@ class PPC_LinuxImageHandler(LinuxImageHa
   68.53                                features       = self.vm.getFeatures(),
   68.54                                arch_args      = devtree.to_bin())
   68.55  
   68.56 +    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   68.57 +        """@param shadow_mem_kb The configured shadow memory, in KiB.
   68.58 +        @param maxmem_kb The configured maxmem, in KiB.
   68.59 +        @return The corresponding required amount of shadow memory, also in
   68.60 +        KiB.
   68.61 +        PowerPC currently uses "shadow memory" to refer to the hash table."""
   68.62 +        return max(maxmem_kb / 64, shadow_mem_kb)
   68.63 +
   68.64 +
   68.65 +class PPC_ProseImageHandler(LinuxImageHandler):
   68.66 +
   68.67 +    ostype = "prose"
   68.68 +
   68.69 +    def configure(self, imageConfig, deviceConfig):
   68.70 +        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
   68.71 +        self.imageConfig = imageConfig
   68.72 +
   68.73 +    def buildDomain(self):
   68.74 +        store_evtchn = self.vm.getStorePort()
   68.75 +        console_evtchn = self.vm.getConsolePort()
   68.76 +
   68.77 +        mem_mb = self.getRequiredInitialReservation() / 1024
   68.78 +
   68.79 +        log.debug("dom            = %d", self.vm.getDomid())
   68.80 +        log.debug("memsize        = %d", mem_mb)
   68.81 +        log.debug("image          = %s", self.kernel)
   68.82 +        log.debug("store_evtchn   = %d", store_evtchn)
   68.83 +        log.debug("console_evtchn = %d", console_evtchn)
   68.84 +        log.debug("cmdline        = %s", self.cmdline)
   68.85 +        log.debug("ramdisk        = %s", self.ramdisk)
   68.86 +        log.debug("vcpus          = %d", self.vm.getVCpuCount())
   68.87 +        log.debug("features       = %s", self.vm.getFeatures())
   68.88 +
   68.89 +        devtree = FlatDeviceTree.build(self)
   68.90 +
   68.91 +        return xc.arch_prose_build(dom            = self.vm.getDomid(),
   68.92 +                                   memsize        = mem_mb,
   68.93 +                                   image          = self.kernel,
   68.94 +                                   store_evtchn   = store_evtchn,
   68.95 +                                   console_evtchn = console_evtchn,
   68.96 +                                   cmdline        = self.cmdline,
   68.97 +                                   ramdisk        = self.ramdisk,
   68.98 +                                   features       = self.vm.getFeatures(),
   68.99 +                                   arch_args      = devtree.to_bin())
  68.100 +
  68.101 +    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
  68.102 +        """@param shadow_mem_kb The configured shadow memory, in KiB.
  68.103 +        @param maxmem_kb The configured maxmem, in KiB.
  68.104 +        @return The corresponding required amount of shadow memory, also in
  68.105 +        KiB.
  68.106 +        PowerPC currently uses "shadow memory" to refer to the hash table."""
  68.107 +        return max(maxmem_kb / 64, shadow_mem_kb)
  68.108 +
  68.109 +
  68.110  class HVMImageHandler(ImageHandler):
  68.111  
  68.112      ostype = "hvm"
  68.113 @@ -539,6 +604,9 @@ class X86_HVM_ImageHandler(HVMImageHandl
  68.114      def getRequiredInitialReservation(self):
  68.115          return self.vm.getMemoryTarget()
  68.116  
  68.117 +    def getRequiredMaximumReservation(self):
  68.118 +        return self.vm.getMemoryMaximum()
  68.119 +
  68.120      def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
  68.121          # 256 pages (1MB) per vcpu,
  68.122          # plus 1 page per MiB of RAM for the P2M map,
  68.123 @@ -553,13 +621,14 @@ class X86_Linux_ImageHandler(LinuxImageH
  68.124      def buildDomain(self):
  68.125          # set physical mapping limit
  68.126          # add an 8MB slack to balance backend allocations.
  68.127 -        mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
  68.128 +        mem_kb = self.getRequiredMaximumReservation() + (8 * 1024)
  68.129          xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
  68.130          return LinuxImageHandler.buildDomain(self)
  68.131  
  68.132  _handlers = {
  68.133      "powerpc": {
  68.134          "linux": PPC_LinuxImageHandler,
  68.135 +        "prose": PPC_ProseImageHandler,
  68.136      },
  68.137      "ia64": {
  68.138          "linux": LinuxImageHandler,
    69.1 --- a/tools/python/xen/xend/server/DevController.py	Fri Dec 15 10:59:33 2006 -0700
    69.2 +++ b/tools/python/xen/xend/server/DevController.py	Fri Dec 15 11:32:58 2006 -0700
    69.3 @@ -19,13 +19,15 @@
    69.4  from threading import Event
    69.5  import types
    69.6  
    69.7 -from xen.xend import sxp
    69.8 +from xen.xend import sxp, XendRoot
    69.9  from xen.xend.XendError import VmError
   69.10  from xen.xend.XendLogging import log
   69.11  
   69.12  from xen.xend.xenstore.xstransact import xstransact, complete
   69.13  from xen.xend.xenstore.xswatch import xswatch
   69.14  
   69.15 +import os
   69.16 +
   69.17  DEVICE_CREATE_TIMEOUT = 100
   69.18  HOTPLUG_STATUS_NODE = "hotplug-status"
   69.19  HOTPLUG_ERROR_NODE  = "hotplug-error"
   69.20 @@ -48,6 +50,8 @@ xenbusState = {
   69.21      'Closed'       : 6,
   69.22      }
   69.23  
   69.24 +xroot = XendRoot.instance()
   69.25 +
   69.26  xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys())))
   69.27  
   69.28  
   69.29 @@ -151,13 +155,13 @@ class DevController:
   69.30          status = self.waitForBackend(devid)
   69.31  
   69.32          if status == Timeout:
   69.33 -            self.destroyDevice(devid)
   69.34 +            self.destroyDevice(devid, False)
   69.35              raise VmError("Device %s (%s) could not be connected. "
   69.36                            "Hotplug scripts not working." %
   69.37                            (devid, self.deviceClass))
   69.38  
   69.39          elif status == Error:
   69.40 -            self.destroyDevice(devid)
   69.41 +            self.destroyDevice(devid, False)
   69.42              raise VmError("Device %s (%s) could not be connected. "
   69.43                            "Backend device not found." %
   69.44                            (devid, self.deviceClass))
   69.45 @@ -176,7 +180,7 @@ class DevController:
   69.46              if not err:
   69.47                  err = "Busy."
   69.48                  
   69.49 -            self.destroyDevice(devid)
   69.50 +            self.destroyDevice(devid, False)
   69.51              raise VmError("Device %s (%s) could not be connected.\n%s" %
   69.52                            (devid, self.deviceClass, err))
   69.53  
   69.54 @@ -191,7 +195,7 @@ class DevController:
   69.55          raise VmError('%s devices may not be reconfigured' % self.deviceClass)
   69.56  
   69.57  
   69.58 -    def destroyDevice(self, devid):
   69.59 +    def destroyDevice(self, devid, force):
   69.60          """Destroy the specified device.
   69.61  
   69.62          @param devid The device ID, or something device-specific from which
   69.63 @@ -212,6 +216,13 @@ class DevController:
   69.64          self.writeBackend(devid, 'online', "0")
   69.65          self.writeBackend(devid, 'state', str(xenbusState['Closing']))
   69.66  
   69.67 +        if force:
   69.68 +            frontpath = self.frontendPath(devid)
   69.69 +            backpath = xstransact.Read(frontpath, "backend")
   69.70 +            if backpath:
   69.71 +                xstransact.Remove(backpath)
   69.72 +            xstransact.Remove(frontpath)
   69.73 +
   69.74  
   69.75      def configurations(self):
   69.76          return map(self.configuration, self.deviceIDs())
   69.77 @@ -313,6 +324,16 @@ class DevController:
   69.78                        Make sure that the migration has finished and only
   69.79                        then return from the call.
   69.80          """
   69.81 +        tool = xroot.get_external_migration_tool()
   69.82 +        if tool:
   69.83 +            log.info("Calling external migration tool for step %d" % step)
   69.84 +            fd = os.popen("%s -type %s -step %d -host %s -domname %s" %
   69.85 +                          (tool, self.deviceClass, step, dst, domName))
   69.86 +            for line in fd:
   69.87 +                log.info(line.rstrip())
   69.88 +            rc = fd.close()
   69.89 +            if rc:
   69.90 +                raise VmError('Migration tool returned %d' % (rc >> 8))
   69.91          return 0
   69.92  
   69.93  
   69.94 @@ -320,6 +341,16 @@ class DevController:
   69.95          """ Recover from device migration. The given step was the
   69.96              last one that was successfully executed.
   69.97          """
   69.98 +        tool = xroot.get_external_migration_tool()
   69.99 +        if tool:
  69.100 +            log.info("Calling external migration tool")
  69.101 +            fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" %
  69.102 +                          (tool, self.deviceClass, step, dst, domName))
  69.103 +            for line in fd:
  69.104 +                log.info(line.rstrip())
  69.105 +            rc = fd.close()
  69.106 +            if rc:
  69.107 +                raise VmError('Migration tool returned %d' % (rc >> 8))
  69.108          return 0
  69.109  
  69.110  
    70.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Fri Dec 15 10:59:33 2006 -0700
    70.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Fri Dec 15 11:32:58 2006 -0700
    70.3 @@ -160,12 +160,9 @@ class SrvDomain(SrvDir):
    70.4          return val
    70.5  
    70.6      def op_maxmem_set(self, _, req):
    70.7 -        fn = FormFn(self.xd.domain_maxmem_set,
    70.8 -                    [['dom',    'int'],
    70.9 -                     ['memory', 'int']])
   70.10 -        val = fn(req.args, {'dom': self.dom.domid})
   70.11 -        return val
   70.12 -
   70.13 +        return self.call(self.dom.setMemoryMaximum,
   70.14 +                         [['memory', 'int']],
   70.15 +                         req)
   70.16      
   70.17      def call(self, fn, args, req):
   70.18          return FormFn(fn, args)(req.args)
    71.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Dec 15 10:59:33 2006 -0700
    71.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Dec 15 11:32:58 2006 -0700
    71.3 @@ -133,7 +133,7 @@ class BlkifController(DevController):
    71.4  
    71.5          return config
    71.6  
    71.7 -    def destroyDevice(self, devid):
    71.8 +    def destroyDevice(self, devid, force):
    71.9          """@see DevController.destroyDevice"""
   71.10  
   71.11          # If we are given a device name, then look up the device ID from it,
   71.12 @@ -142,13 +142,13 @@ class BlkifController(DevController):
   71.13          # superclass's method.
   71.14  
   71.15          try:
   71.16 -            DevController.destroyDevice(self, int(devid))
   71.17 +            DevController.destroyDevice(self, int(devid), force)
   71.18          except ValueError:
   71.19              devid_end = type(devid) is str and devid.split('/')[-1] or None
   71.20  
   71.21              for i in self.deviceIDs():
   71.22                  d = self.readBackend(i, 'dev')
   71.23                  if d == devid or (devid_end and d == devid_end):
   71.24 -                    DevController.destroyDevice(self, i)
   71.25 +                    DevController.destroyDevice(self, i, force)
   71.26                      return
   71.27              raise VmError("Device %s not connected" % devid)
    72.1 --- a/tools/python/xen/xm/XenAPI.py	Fri Dec 15 10:59:33 2006 -0700
    72.2 +++ b/tools/python/xen/xm/XenAPI.py	Fri Dec 15 11:32:58 2006 -0700
    72.3 @@ -82,7 +82,7 @@ class Session(xen.util.xmlrpclib2.Server
    72.4          self._session = None
    72.5  
    72.6  
    72.7 -    def _xen_request(self, methodname, params):
    72.8 +    def xenapi_request(self, methodname, params):
    72.9          full_params = (self._session,) + params
   72.10          return _parse_result(getattr(self, methodname)(*full_params))
   72.11  
   72.12 @@ -94,7 +94,7 @@ class Session(xen.util.xmlrpclib2.Server
   72.13  
   72.14      def __getattr__(self, name):
   72.15          if name == 'xenapi':
   72.16 -            return _Dispatcher(self._xen_request, None)
   72.17 +            return _Dispatcher(self.xenapi_request, None)
   72.18          elif name.startswith('login'):
   72.19              return lambda u, p: self._login(name, u, p)
   72.20          else:
    73.1 --- a/tools/python/xen/xm/main.py	Fri Dec 15 10:59:33 2006 -0700
    73.2 +++ b/tools/python/xen/xm/main.py	Fri Dec 15 11:32:58 2006 -0700
    73.3 @@ -22,7 +22,10 @@
    73.4  """Grand unified management application for Xen.
    73.5  """
    73.6  import atexit
    73.7 +import cmd
    73.8  import os
    73.9 +import pprint
   73.10 +import shlex
   73.11  import sys
   73.12  import re
   73.13  import getopt
   73.14 @@ -77,6 +80,8 @@ USAGE_FOOTER = '<Domain> can either be t
   73.15  
   73.16  SUBCOMMAND_HELP = {
   73.17      # common commands
   73.18 +
   73.19 +    'shell'       : ('', 'Launch an interactive shell.'),
   73.20      
   73.21      'console'     : ('[-q|--quiet] <Domain>',
   73.22                       'Attach to <Domain>\'s console.'),
   73.23 @@ -142,14 +147,15 @@ SUBCOMMAND_HELP = {
   73.24                          'Create a new virtual block device.'),
   73.25      'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
   73.26                          'Change block device configuration'),
   73.27 -    'block-detach'  :  ('<Domain> <DevId>',
   73.28 +    'block-detach'  :  ('<Domain> <DevId> [-f|--force]',
   73.29                          'Destroy a domain\'s virtual block device.'),
   73.30      'block-list'    :  ('<Domain> [--long]',
   73.31                          'List virtual block devices for a domain.'),
   73.32 -    'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
   73.33 -                        '[--mac=<mac>]',
   73.34 +    'network-attach':  ('<Domain> [type=<type>] [mac=<mac>] [bridge=<bridge>] '
   73.35 +                        '[ip=<ip>] [script=<script>] [backend=<BackDomain>] '
   73.36 +                        '[vifname=<name>]',
   73.37                          'Create a new virtual network device.'),
   73.38 -    'network-detach':  ('<Domain> <DevId>',
   73.39 +    'network-detach':  ('<Domain> <DevId> [-f|--force]',
   73.40                          'Destroy a domain\'s virtual network device.'),
   73.41      'network-list'  :  ('<Domain> [--long]',
   73.42                          'List virtual network interfaces for a domain.'),
   73.43 @@ -245,6 +251,7 @@ common_commands = [
   73.44      "restore",
   73.45      "resume",
   73.46      "save",
   73.47 +    "shell",
   73.48      "shutdown",
   73.49      "start",
   73.50      "suspend",
   73.51 @@ -328,7 +335,7 @@ acm_commands = [
   73.52      ]
   73.53  
   73.54  all_commands = (domain_commands + host_commands + scheduler_commands +
   73.55 -                device_commands + vnet_commands + acm_commands)
   73.56 +                device_commands + vnet_commands + acm_commands + ['shell'])
   73.57  
   73.58  
   73.59  ##
   73.60 @@ -362,6 +369,7 @@ def parseAuthentication():
   73.61              server.getAttribute('password'))
   73.62  
   73.63  serverType, serverURI = parseServer()
   73.64 +server = None
   73.65  
   73.66  
   73.67  ####################################################################
   73.68 @@ -455,12 +463,16 @@ def longHelp():
   73.69      print
   73.70      print USAGE_FOOTER        
   73.71  
   73.72 -def usage(cmd = None):
   73.73 -    """ Print help usage information and exits """
   73.74 +def _usage(cmd):
   73.75 +    """ Print help usage information """
   73.76      if cmd:
   73.77          cmdHelp(cmd)
   73.78      else:
   73.79          shortHelp()
   73.80 +
   73.81 +def usage(cmd = None):
   73.82 +    """ Print help usage information and exits """
   73.83 +    _usage(cmd)
   73.84      sys.exit(1)
   73.85  
   73.86  
   73.87 @@ -523,6 +535,49 @@ def get_single_vm(dom):
   73.88          dominfo = server.xend.domain(dom, False)
   73.89          return dominfo['uuid']
   73.90  
   73.91 +##
   73.92 +#
   73.93 +# Xen-API Shell
   73.94 +#
   73.95 +##
   73.96 +
   73.97 +class Shell(cmd.Cmd):
   73.98 +    def __init__(self):
   73.99 +        cmd.Cmd.__init__(self)
  73.100 +        self.prompt = "xm> "
  73.101 +
  73.102 +    def default(self, line):
  73.103 +        words = shlex.split(line)
  73.104 +        if len(words) > 0 and words[0] == 'xm':
  73.105 +            words = words[1:]
  73.106 +        if len(words) > 0:
  73.107 +            cmd = xm_lookup_cmd(words[0])
  73.108 +            if cmd:
  73.109 +                _run_cmd(cmd, words[0], words[1:])
  73.110 +            elif serverType == SERVER_XEN_API:
  73.111 +                ok, res = _run_cmd(lambda x: server.xenapi_request(words[0],
  73.112 +                                                                   tuple(x)),
  73.113 +                                   words[0], words[1:])
  73.114 +                if ok and res != '':
  73.115 +                    pprint.pprint(res)
  73.116 +            else:
  73.117 +                print '*** Unknown command: %s' % words[0]
  73.118 +        return False
  73.119 +
  73.120 +    def emptyline(self):
  73.121 +        pass
  73.122 +
  73.123 +    def do_EOF(self, line):
  73.124 +        print
  73.125 +        sys.exit(0)
  73.126 +
  73.127 +    def do_help(self, line):
  73.128 +        _usage(line)
  73.129 +
  73.130 +
  73.131 +def xm_shell(args):
  73.132 +    Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
  73.133 +
  73.134  
  73.135  #########################################################################
  73.136  #
  73.137 @@ -554,7 +609,7 @@ def xm_restore(args):
  73.138          (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
  73.139      except getopt.GetoptError, opterr:
  73.140          err(opterr)
  73.141 -        sys.exit(1)
  73.142 +        usage('restore')
  73.143  
  73.144      paused = False
  73.145      for (k, v) in options:
  73.146 @@ -564,7 +619,6 @@ def xm_restore(args):
  73.147      if len(params) != 1:
  73.148          err("Wrong number of parameters")
  73.149          usage('restore')
  73.150 -        sys.exit(1)
  73.151  
  73.152      savefile = os.path.abspath(params[0])
  73.153  
  73.154 @@ -594,7 +648,6 @@ def xm_list(args):
  73.155      except getopt.GetoptError, opterr:
  73.156          err(opterr)
  73.157          usage('list')
  73.158 -        sys.exit(1)
  73.159      
  73.160      for (k, v) in options:
  73.161          if k in ['-l', '--long']:
  73.162 @@ -709,7 +762,7 @@ def xm_vcpu_list(args):
  73.163          dominfo = map(server.xend.domain.getVCPUInfo, doms)
  73.164  
  73.165      print '%-32s %3s %5s %5s %5s %9s %s' % \
  73.166 -          ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
  73.167 +          ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
  73.168  
  73.169      format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
  73.170               ' %(cpu_time)8.1f %(cpumap)s'
  73.171 @@ -815,7 +868,7 @@ def xm_start(args):
  73.172          (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
  73.173      except getopt.GetoptError, opterr:
  73.174          err(opterr)
  73.175 -        sys.exit(1)
  73.176 +        usage('start')
  73.177  
  73.178      paused = False
  73.179      for (k, v) in options:
  73.180 @@ -825,7 +878,6 @@ def xm_start(args):
  73.181      if len(params) != 1:
  73.182          err("Wrong number of parameters")
  73.183          usage('start')
  73.184 -        sys.exit(1)
  73.185  
  73.186      dom = params[0]
  73.187      if serverType == SERVER_XEN_API:
  73.188 @@ -856,7 +908,7 @@ def xm_resume(args):
  73.189          (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
  73.190      except getopt.GetoptError, opterr:
  73.191          err(opterr)
  73.192 -        sys.exit(1)
  73.193 +        usage('resume')
  73.194  
  73.195      paused = False
  73.196      for (k, v) in options:
  73.197 @@ -866,7 +918,6 @@ def xm_resume(args):
  73.198      if len(params) != 1:
  73.199          err("Wrong number of parameters")
  73.200          usage('resume')
  73.201 -        sys.exit(1)
  73.202  
  73.203      dom = params[0]
  73.204      if serverType == SERVER_XEN_API:
  73.205 @@ -1061,7 +1112,7 @@ def xm_sched_sedf(args):
  73.206              ['period=', 'slice=', 'latency=', 'extratime=', 'weight='])
  73.207      except getopt.GetoptError, opterr:
  73.208          err(opterr)
  73.209 -        sys.exit(1)
  73.210 +        usage('sched-sedf')
  73.211      
  73.212      # convert to nanoseconds if needed 
  73.213      for (k, v) in options:
  73.214 @@ -1122,7 +1173,6 @@ def xm_sched_credit(args):
  73.215      except getopt.GetoptError, opterr:
  73.216          err(opterr)
  73.217          usage('sched-credit')
  73.218 -        sys.exit(1)
  73.219  
  73.220      domain = None
  73.221      weight = None
  73.222 @@ -1140,7 +1190,6 @@ def xm_sched_credit(args):
  73.223          # place holder for system-wide scheduler parameters
  73.224          err("No domain given.")
  73.225          usage('sched-credit')
  73.226 -        sys.exit(1)
  73.227  
  73.228      if weight is None and cap is None:
  73.229          print server.xend.domain.sched_credit_get(domain)
  73.230 @@ -1169,7 +1218,7 @@ def xm_console(args):
  73.231          (options, params) = getopt.gnu_getopt(args, 'q', ['quiet'])
  73.232      except getopt.GetoptError, opterr:
  73.233          err(opterr)
  73.234 -        sys.exit(1)
  73.235 +        usage('console')
  73.236  
  73.237      for (k, v) in options:
  73.238          if k in ['-q', '--quiet']:
  73.239 @@ -1180,7 +1229,6 @@ def xm_console(args):
  73.240      if len(params) != 1:
  73.241          err('No domain given')
  73.242          usage('console')
  73.243 -        sys.exit(1)
  73.244  
  73.245      dom = params[0]
  73.246  
  73.247 @@ -1208,7 +1256,7 @@ def xm_uptime(args):
  73.248          (options, params) = getopt.gnu_getopt(args, 's', ['short'])
  73.249      except getopt.GetoptError, opterr:
  73.250          err(opterr)
  73.251 -        sys.exit(1)
  73.252 +        usage('uptime')
  73.253  
  73.254      for (k, v) in options:
  73.255          if k in ['-s', '--short']:
  73.256 @@ -1273,7 +1321,7 @@ def xm_dmesg(args):
  73.257          (options, params) = getopt.gnu_getopt(args, 'c', ['clear'])
  73.258      except getopt.GetoptError, opterr:
  73.259          err(opterr)
  73.260 -        sys.exit(1)
  73.261 +        usage('dmesg')
  73.262      
  73.263      use_clear = 0
  73.264      for (k, v) in options:
  73.265 @@ -1283,7 +1331,6 @@ def xm_dmesg(args):
  73.266      if len(params) :
  73.267          err("No parameter required")
  73.268          usage('dmesg')
  73.269 -        sys.exit(1)
  73.270  
  73.271      if not use_clear:
  73.272          print server.xend.node.dmesg.info()
  73.273 @@ -1493,16 +1540,24 @@ def xm_network_attach(args):
  73.274  
  73.275  
  73.276  def detach(args, command, deviceClass):
  73.277 -    arg_check(args, command, 2)
  73.278 +    arg_check(args, command, 2, 3)
  73.279  
  73.280      dom = args[0]
  73.281      dev = args[1]
  73.282 +    try:
  73.283 +        force = args[2]
  73.284 +        if (force != "--force") and (force != "-f"):
  73.285 +            print "Ignoring option %s"%(force)
  73.286 +            force = None
  73.287 +    except IndexError:
  73.288 +        force = None
  73.289  
  73.290 -    server.xend.domain.destroyDevice(dom, deviceClass, dev)
  73.291 +    server.xend.domain.destroyDevice(dom, deviceClass, dev, force)
  73.292  
  73.293  
  73.294  def xm_block_detach(args):
  73.295      detach(args, 'block-detach', 'vbd')
  73.296 +    detach(args, 'block-detach', 'tap')
  73.297  
  73.298  
  73.299  def xm_network_detach(args):
  73.300 @@ -1514,7 +1569,7 @@ def xm_vnet_list(args):
  73.301          (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
  73.302      except getopt.GetoptError, opterr:
  73.303          err(opterr)
  73.304 -        sys.exit(1)
  73.305 +        usage('vnet-list')
  73.306      
  73.307      use_long = 0
  73.308      for (k, v) in options:
  73.309 @@ -1552,6 +1607,7 @@ def xm_vnet_delete(args):
  73.310      server.xend_vnet_delete(vnet)
  73.311  
  73.312  commands = {
  73.313 +    "shell": xm_shell,
  73.314      # console commands
  73.315      "console": xm_console,
  73.316      # xenstat commands
  73.317 @@ -1655,17 +1711,13 @@ def xm_lookup_cmd(cmd):
  73.318              # only execute if there is only 1 match
  73.319              if len(same_prefix_cmds) == 1:
  73.320                  return same_prefix_cmds[0]
  73.321 -            
  73.322 -        err('Sub Command %s not found!' % cmd)
  73.323 -        usage()
  73.324 +        return None
  73.325  
  73.326  def deprecated(old,new):
  73.327      print >>sys.stderr, (
  73.328          "Command %s is deprecated.  Please use xm %s instead." % (old, new))
  73.329  
  73.330  def main(argv=sys.argv):
  73.331 -    global server
  73.332 -
  73.333      if len(argv) < 2:
  73.334          usage()
  73.335  
  73.336 @@ -1674,16 +1726,26 @@ def main(argv=sys.argv):
  73.337          if help in argv[1:]:
  73.338              if help == argv[1]:
  73.339                  longHelp()
  73.340 +                sys.exit(0)
  73.341              else:
  73.342                  usage(argv[1])
  73.343 -            sys.exit(0)
  73.344 -
  73.345 -    cmd = xm_lookup_cmd(argv[1])
  73.346  
  73.347 -    # strip off prog name and subcmd
  73.348 -    args = argv[2:]
  73.349 +    cmd_name = argv[1]
  73.350 +    cmd = xm_lookup_cmd(cmd_name)
  73.351      if cmd:
  73.352 -        try:
  73.353 +        # strip off prog name and subcmd
  73.354 +        args = argv[2:]
  73.355 +        _, rc = _run_cmd(cmd, cmd_name, args)
  73.356 +        sys.exit(rc)
  73.357 +    else:
  73.358 +        err('Subcommand %s not found!' % cmd_name)
  73.359 +        usage()
  73.360 +
  73.361 +def _run_cmd(cmd, cmd_name, args):
  73.362 +    global server
  73.363 +
  73.364 +    try:
  73.365 +        if server is None:
  73.366              if serverType == SERVER_XEN_API:
  73.367                  server = XenAPI.Session(serverURI)
  73.368                  username, password = parseAuthentication()
  73.369 @@ -1697,66 +1759,55 @@ def main(argv=sys.argv):
  73.370              else:
  73.371                  server = ServerProxy(serverURI)
  73.372  
  73.373 -            rc = cmd(args)
  73.374 -            if rc:
  73.375 -                usage()
  73.376 -        except socket.error, ex:
  73.377 -            if os.geteuid() != 0:
  73.378 -                err("Most commands need root access. Please try again as root.")
  73.379 -            else:
  73.380 -                err("Unable to connect to xend: %s. Is xend running?" % ex[1])
  73.381 -            sys.exit(1)
  73.382 -        except KeyboardInterrupt:
  73.383 -            print "Interrupted."
  73.384 -            sys.exit(1)
  73.385 -        except IOError, ex:
  73.386 -            if os.geteuid() != 0:
  73.387 -                err("Most commands need root access.  Please try again as root.")
  73.388 -            else:
  73.389 -                err("Unable to connect to xend: %s." % ex[1])
  73.390 -            sys.exit(1)
  73.391 -        except SystemExit:
  73.392 -            sys.exit(1)
  73.393 -        except XenAPI.Failure, exn:
  73.394 -            err(str(exn))
  73.395 -            sys.exit(1)
  73.396 -        except xmlrpclib.Fault, ex:
  73.397 -            if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
  73.398 -                err("Domain '%s' does not exist." % ex.faultString)
  73.399 -            else:
  73.400 -                err(ex.faultString)
  73.401 -            usage(argv[1])
  73.402 -            sys.exit(1)
  73.403 -        except xmlrpclib.ProtocolError, ex:
  73.404 -            if ex.errcode == -1:
  73.405 -                print  >>sys.stderr, (
  73.406 -                    "Xend has probably crashed!  Invalid or missing HTTP "
  73.407 -                    "status code.")
  73.408 -            else:
  73.409 -                print  >>sys.stderr, (
  73.410 -                    "Xend has probably crashed!  ProtocolError(%d, %s)." %
  73.411 -                    (ex.errcode, ex.errmsg))
  73.412 -            sys.exit(1)
  73.413 -        except (ValueError, OverflowError):
  73.414 -            err("Invalid argument.")
  73.415 -            usage(argv[1])
  73.416 -            sys.exit(1)
  73.417 -        except OptionError, e:
  73.418 -            err(str(e))
  73.419 -            usage(argv[1])
  73.420 -            print e.usage()
  73.421 -            sys.exit(1)
  73.422 -        except security.ACMError, e:
  73.423 -            err(str(e))
  73.424 -            sys.exit(1)
  73.425 -        except:
  73.426 -            print "Unexpected error:", sys.exc_info()[0]
  73.427 -            print
  73.428 -            print "Please report to xen-devel@lists.xensource.com"
  73.429 -            raise
  73.430 -                
  73.431 -    else:
  73.432 -        usage()
  73.433 +        return True, cmd(args)
  73.434 +    except socket.error, ex:
  73.435 +        if os.geteuid() != 0:
  73.436 +            err("Most commands need root access. Please try again as root.")
  73.437 +        else:
  73.438 +            err("Unable to connect to xend: %s. Is xend running?" % ex[1])
  73.439 +    except KeyboardInterrupt:
  73.440 +        print "Interrupted."
  73.441 +        return True, ''
  73.442 +    except IOError, ex:
  73.443 +        if os.geteuid() != 0:
  73.444 +            err("Most commands need root access.  Please try again as root.")
  73.445 +        else:
  73.446 +            err("Unable to connect to xend: %s." % ex[1])
  73.447 +    except SystemExit, code:
  73.448 +        return code == 0, code
  73.449 +    except XenAPI.Failure, exn:
  73.450 +        err(str(exn))
  73.451 +    except xmlrpclib.Fault, ex:
  73.452 +        if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
  73.453 +            err("Domain '%s' does not exist." % ex.faultString)
  73.454 +        else:
  73.455 +            err(ex.faultString)
  73.456 +        _usage(cmd_name)
  73.457 +    except xmlrpclib.ProtocolError, ex:
  73.458 +        if ex.errcode == -1:
  73.459 +            print  >>sys.stderr, (
  73.460 +                "Xend has probably crashed!  Invalid or missing HTTP "
  73.461 +                "status code.")
  73.462 +        else:
  73.463 +            print  >>sys.stderr, (
  73.464 +                "Xend has probably crashed!  ProtocolError(%d, %s)." %
  73.465 +                (ex.errcode, ex.errmsg))
  73.466 +    except (ValueError, OverflowError):
  73.467 +        err("Invalid argument.")
  73.468 +        _usage(cmd_name)
  73.469 +    except OptionError, e:
  73.470 +        err(str(e))
  73.471 +        _usage(cmd_name)
  73.472 +        print e.usage()
  73.473 +    except security.ACMError, e:
  73.474 +        err(str(e))
  73.475 +    except:
  73.476 +        print "Unexpected error:", sys.exc_info()[0]
  73.477 +        print
  73.478 +        print "Please report to xen-devel@lists.xensource.com"
  73.479 +        raise
  73.480 +
  73.481 +    return False, 1
  73.482  
  73.483  if __name__ == "__main__":
  73.484      main()
    74.1 --- a/tools/xenstore/xenstored_domain.c	Fri Dec 15 10:59:33 2006 -0700
    74.2 +++ b/tools/xenstore/xenstored_domain.c	Fri Dec 15 11:32:58 2006 -0700
    74.3 @@ -459,6 +459,8 @@ static int dom0_init(void)
    74.4  		return -1;
    74.5  
    74.6  	dom0 = new_domain(NULL, 0, port); 
    74.7 +	if (dom0 == NULL)
    74.8 +		return -1;
    74.9  
   74.10  	dom0->interface = xenbus_map();
   74.11  	if (dom0->interface == NULL)
    75.1 --- a/xen/arch/ia64/xen/xensetup.c	Fri Dec 15 10:59:33 2006 -0700
    75.2 +++ b/xen/arch/ia64/xen/xensetup.c	Fri Dec 15 11:32:58 2006 -0700
    75.3 @@ -51,7 +51,7 @@ extern void trap_init(void);
    75.4  extern void xen_patch_kernel(void);
    75.5  
    75.6  /* opt_nosmp: If true, secondary processors are ignored. */
    75.7 -static int opt_nosmp = 0;
    75.8 +static int opt_nosmp;
    75.9  boolean_param("nosmp", opt_nosmp);
   75.10  
   75.11  /* maxcpus: maximum number of CPUs to activate. */
   75.12 @@ -65,7 +65,7 @@ static int opt_xencons = 1;
   75.13  integer_param("xencons", opt_xencons);
   75.14  
   75.15  /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
   75.16 -static int opt_xencons_poll = 0;
   75.17 +static int opt_xencons_poll;
   75.18  boolean_param("xencons_poll", opt_xencons_poll);
   75.19  
   75.20  /*
   75.21 @@ -163,7 +163,7 @@ struct ns16550_defaults ns16550_com2 = {
   75.22  };
   75.23  
   75.24  /* efi_print: print efi table at boot */
   75.25 -static int opt_efi_print = 0;
   75.26 +static int opt_efi_print;
   75.27  boolean_param("efi_print", opt_efi_print);
   75.28  
   75.29  /* print EFI memory map: */
    76.1 --- a/xen/arch/powerpc/Makefile	Fri Dec 15 10:59:33 2006 -0700
    76.2 +++ b/xen/arch/powerpc/Makefile	Fri Dec 15 11:32:58 2006 -0700
    76.3 @@ -9,10 +9,10 @@ obj-y += audit.o
    76.4  obj-y += backtrace.o
    76.5  obj-y += bitops.o
    76.6  obj-y += boot_of.o
    76.7 +obj-y += cmdline.o
    76.8  obj-y += dart.o
    76.9  obj-y += dart_u3.o
   76.10  obj-y += dart_u4.o
   76.11 -obj-y += delay.o
   76.12  obj-y += domctl.o
   76.13  obj-y += domain_build.o
   76.14  obj-y += domain.o
   76.15 @@ -22,11 +22,12 @@ obj-y += float.o
   76.16  obj-y += hcalls.o
   76.17  obj-y += iommu.o
   76.18  obj-y += irq.o
   76.19 -obj-y += mambo.o
   76.20 +obj-y += systemsim.o
   76.21  obj-y += memory.o
   76.22  obj-y += mm.o
   76.23  obj-y += mpic.o
   76.24  obj-y += mpic_init.o
   76.25 +obj-y += numa.o
   76.26  obj-y += of-devtree.o
   76.27  obj-y += of-devwalk.o
   76.28  obj-y += ofd_fixup.o
   76.29 @@ -36,6 +37,7 @@ obj-y += rtas.o
   76.30  obj-y += setup.o
   76.31  obj-y += shadow.o
   76.32  obj-y += smp.o
   76.33 +obj-y += smpboot.o
   76.34  obj-y += smp-tbsync.o
   76.35  obj-y += sysctl.o
   76.36  obj-y += time.o
   76.37 @@ -57,11 +59,6 @@ PPC_C_WARNINGS += -Wundef -Wmissing-prot
   76.38  PPC_C_WARNINGS += -Wshadow
   76.39  CFLAGS += $(PPC_C_WARNINGS)
   76.40  
   76.41 -LINK=0x400000
   76.42 -boot32_link_base = $(LINK)
   76.43 -xen_link_offset  = 100
   76.44 -xen_link_base    = $(patsubst %000,%$(xen_link_offset),$(LINK))
   76.45 -
   76.46  #
   76.47  # The following flags are fed to gcc in order to link several
   76.48  # objects into a single ELF segment and to not link in any additional
   76.49 @@ -72,34 +69,39 @@ OMAGIC = -N -nodefaultlibs -nostartfiles
   76.50  firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
   76.51  	$(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
   76.52  
   76.53 -firmware_image: firmware
   76.54 +firmware_image.bin: firmware
   76.55  	$(CROSS_COMPILE)objcopy --output-target=binary $< $@
   76.56  
   76.57 -firmware_image.o: firmware_image
   76.58 -	$(CROSS_COMPILE)objcopy --input-target=binary \
   76.59 -		--output-target=elf64-powerpc \
   76.60 -		--binary-architecture=powerpc \
   76.61 -		--redefine-sym _binary_$<_start=$(@:%.o=%)_start \
   76.62 -		--redefine-sym _binary_$<_end=$(@:%.o=%)_end \
   76.63 -		--redefine-sym _binary_$<_size=$(@:%.o=%)_size  $< $@
   76.64 -
   76.65  #
   76.66  # Hacks for included C files
   76.67  #
   76.68  irq.o: ../x86/irq.c
   76.69  physdev.o: ../x86/physdev.c
   76.70 +numa.o: ../x86/numa.c
   76.71  
   76.72  HDRS += $(wildcard *.h)
   76.73  
   76.74 +ifneq ($(CMDLINE),)
   76.75  # The first token in the arguments will be silently dropped.
   76.76 -IMAGENAME = xen
   76.77 -CMDLINE = ""
   76.78 -boot_of.o: CFLAGS += -DCMDLINE="\"$(IMAGENAME) $(CMDLINE)\""
   76.79 +FULL_CMDLINE := xen $(CMDLINE)
   76.80 +endif
   76.81  
   76.82 -start.o: boot/start.S
   76.83 -	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
   76.84 +ifeq ($(wildcard cmdline.dep),)
   76.85 +cmdline.dep:
   76.86 +	echo $(FULL_CMDLINE) > cmdline.dep
   76.87 +else
   76.88 +ifneq ($(FULL_CMDLINE),$(shell cat cmdline.dep))
   76.89 +cmdline.dep::
   76.90 +	echo $(FULL_CMDLINE) > cmdline.dep
   76.91 +else
   76.92 +cmdline.dep:
   76.93 +endif
   76.94 +endif
   76.95  
   76.96 -TARGET_OPTS = $(OMAGIC) -Wl,-Ttext,$(xen_link_base),-T,xen.lds
   76.97 +cmdline.o: cmdline.dep
   76.98 +cmdline.o: CFLAGS += -DCMDLINE="\"$(FULL_CMDLINE)\""
   76.99 +
  76.100 +TARGET_OPTS = $(OMAGIC) -Wl,-T,xen.lds
  76.101  TARGET_OPTS += start.o $(ALL_OBJS)
  76.102  
  76.103  .xen-syms: start.o $(ALL_OBJS) xen.lds
  76.104 @@ -122,22 +124,10 @@ xen-syms.o: xen-syms.S
  76.105  $(TARGET)-syms: start.o $(ALL_OBJS) xen-syms.o xen.lds
  76.106  	$(CC) $(CFLAGS) $(TARGET_OPTS) xen-syms.o -o $@
  76.107  
  76.108 -$(TARGET).bin: $(TARGET)-syms
  76.109 -	$(CROSS_COMPILE)objcopy --output-target=binary $< $@
  76.110 -
  76.111 -$(TARGET).bin.o: $(TARGET).bin
  76.112 -	$(CROSS_COMPILE)objcopy --input-target=binary \
  76.113 -		--output-target=elf32-powerpc \
  76.114 -		--binary-architecture=powerpc  $< $@
  76.115 -
  76.116 -boot32.o: boot/boot32.S
  76.117 -	$(CC) -m32 -Wa,-a32,-mppc64bridge \
  76.118 -		-D__ASSEMBLY__ -D__BRIDGE64__ $(CFLAGS) -c $< -o $@
  76.119 -
  76.120 -$(TARGET): boot32.o $(TARGET).bin.o
  76.121 -	$(CC) -m32 -N -Wl,-melf32ppclinux -static -nostdlib \
  76.122 -		-Wl,-Ttext,$(boot32_link_base)  -Wl,-Tdata,$(xen_link_base) \
  76.123 -		$(CFLAGS) $^ -o $@
  76.124 +# our firmware only loads 32-bit ELF files
  76.125 +OCPYFLAGS := --input-target=elf64-powerpc --output-target=elf32-powerpc
  76.126 +$(TARGET): $(TARGET)-syms
  76.127 +	$(CROSS_COMPILE)objcopy $(OCPYFLAGS) $^ $@
  76.128  
  76.129  asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
  76.130  	$(CC) $(CFLAGS) -S -o $@ $<
  76.131 @@ -150,4 +140,5 @@ dom0.bin: $(DOM0_IMAGE)
  76.132  
  76.133  clean::
  76.134  	$(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean
  76.135 -	rm -f firmware firmware_image dom0.bin .xen-syms
  76.136 +	rm -f firmware firmware_image.bin dom0.bin .xen-syms xen-syms.S \
  76.137 +		xen.lds asm-offsets.s cmdline.dep
    77.1 --- a/xen/arch/powerpc/backtrace.c	Fri Dec 15 10:59:33 2006 -0700
    77.2 +++ b/xen/arch/powerpc/backtrace.c	Fri Dec 15 11:32:58 2006 -0700
    77.3 @@ -14,6 +14,7 @@
    77.4  #include <xen/console.h>
    77.5  #include <xen/sched.h>
    77.6  #include <xen/symbols.h>
    77.7 +#include <asm/debugger.h>
    77.8  
    77.9  static char namebuf[KSYM_NAME_LEN+1];
   77.10  
   77.11 @@ -192,6 +193,19 @@ void show_backtrace(ulong sp, ulong lr, 
   77.12      console_end_sync();
   77.13  }
   77.14  
   77.15 +void show_backtrace_regs(struct cpu_user_regs *regs)
   77.16 +{
   77.17 +    console_start_sync();
   77.18 +    
   77.19 +    show_registers(regs);
   77.20 +    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
   77.21 +    printk("hid4 0x%016lx\n", regs->hid4);
   77.22 +    printk("---[ backtrace ]---\n");
   77.23 +    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
   77.24 +
   77.25 +    console_end_sync();
   77.26 +}
   77.27 +
   77.28  void __warn(char *file, int line)
   77.29  {
   77.30      ulong sp;
   77.31 @@ -202,9 +216,19 @@ void __warn(char *file, int line)
   77.32  
   77.33      sp = (ulong)__builtin_frame_address(0);
   77.34      lr = (ulong)__builtin_return_address(0);
   77.35 +    backtrace(sp, lr, lr);
   77.36  
   77.37 -    backtrace(sp, lr, lr);
   77.38      console_end_sync();
   77.39  }
   77.40  
   77.41 -    
   77.42 +void dump_execution_state(void)
   77.43 +{
   77.44 +    struct vcpu *v = current;
   77.45 +    struct cpu_user_regs *regs = &v->arch.ctxt;
   77.46 +
   77.47 +    show_registers(regs);
   77.48 +    if (regs->msr & MSR_HV) {
   77.49 +        printk("In Xen:\n");
   77.50 +        show_backtrace(regs->gprs[1], regs->pc, regs->lr);
   77.51 +    }
   77.52 +}
    78.1 --- a/xen/arch/powerpc/bitops.c	Fri Dec 15 10:59:33 2006 -0700
    78.2 +++ b/xen/arch/powerpc/bitops.c	Fri Dec 15 11:32:58 2006 -0700
    78.3 @@ -12,42 +12,42 @@
    78.4   * @size: The maximum size to search
    78.5   */
    78.6  unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
    78.7 -			    unsigned long offset)
    78.8 +                            unsigned long offset)
    78.9  {
   78.10 -	const unsigned long *p = addr + BITOP_WORD(offset);
   78.11 -	unsigned long result = offset & ~(BITS_PER_LONG-1);
   78.12 -	unsigned long tmp;
   78.13 +    const unsigned long *p = addr + BITOP_WORD(offset);
   78.14 +    unsigned long result = offset & ~(BITS_PER_LONG-1);
   78.15 +    unsigned long tmp;
   78.16  
   78.17 -	if (offset >= size)
   78.18 -		return size;
   78.19 -	size -= result;
   78.20 -	offset %= BITS_PER_LONG;
   78.21 -	if (offset) {
   78.22 -		tmp = *(p++);
   78.23 -		tmp &= (~0UL << offset);
   78.24 -		if (size < BITS_PER_LONG)
   78.25 -			goto found_first;
   78.26 -		if (tmp)
   78.27 -			goto found_middle;
   78.28 -		size -= BITS_PER_LONG;
   78.29 -		result += BITS_PER_LONG;
   78.30 -	}
   78.31 -	while (size & ~(BITS_PER_LONG-1)) {
   78.32 -		if ((tmp = *(p++)))
   78.33 -			goto found_middle;
   78.34 -		result += BITS_PER_LONG;
   78.35 -		size -= BITS_PER_LONG;
   78.36 -	}
   78.37 -	if (!size)
   78.38 -		return result;
   78.39 -	tmp = *p;
   78.40 +    if (offset >= size)
   78.41 +        return size;
   78.42 +    size -= result;
   78.43 +    offset %= BITS_PER_LONG;
   78.44 +    if (offset) {
   78.45 +        tmp = *(p++);
   78.46 +        tmp &= (~0UL << offset);
   78.47 +        if (size < BITS_PER_LONG)
   78.48 +            goto found_first;
   78.49 +        if (tmp)
   78.50 +            goto found_middle;
   78.51 +        size -= BITS_PER_LONG;
   78.52 +        result += BITS_PER_LONG;
   78.53 +    }
   78.54 +    while (size & ~(BITS_PER_LONG-1)) {
   78.55 +        if ((tmp = *(p++)))
   78.56 +            goto found_middle;
   78.57 +        result += BITS_PER_LONG;
   78.58 +        size -= BITS_PER_LONG;
   78.59 +    }
   78.60 +    if (!size)
   78.61 +        return result;
   78.62 +    tmp = *p;
   78.63  
   78.64  found_first:
   78.65 -	tmp &= (~0UL >> (BITS_PER_LONG - size));
   78.66 -	if (tmp == 0UL)		/* Are any bits set? */
   78.67 -		return result + size;	/* Nope. */
   78.68 +    tmp &= (~0UL >> (BITS_PER_LONG - size));
   78.69 +    if (tmp == 0UL)        /* Are any bits set? */
   78.70 +        return result + size;    /* Nope. */
   78.71  found_middle:
   78.72 -	return result + __ffs(tmp);
   78.73 +    return result + __ffs(tmp);
   78.74  }
   78.75  
   78.76  /*
   78.77 @@ -55,40 +55,40 @@ found_middle:
   78.78   * Linus' asm-alpha/bitops.h.
   78.79   */
   78.80  unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
   78.81 -				 unsigned long offset)
   78.82 +                                 unsigned long offset)
   78.83  {
   78.84 -	const unsigned long *p = addr + BITOP_WORD(offset);
   78.85 -	unsigned long result = offset & ~(BITS_PER_LONG-1);
   78.86 -	unsigned long tmp;
   78.87 +    const unsigned long *p = addr + BITOP_WORD(offset);
   78.88 +    unsigned long result = offset & ~(BITS_PER_LONG-1);
   78.89 +    unsigned long tmp;
   78.90  
   78.91 -	if (offset >= size)
   78.92 -		return size;
   78.93 -	size -= result;
   78.94 -	offset %= BITS_PER_LONG;
   78.95 -	if (offset) {
   78.96 -		tmp = *(p++);
   78.97 -		tmp |= ~0UL >> (BITS_PER_LONG - offset);
   78.98 -		if (size < BITS_PER_LONG)
   78.99 -			goto found_first;
  78.100 -		if (~tmp)
  78.101 -			goto found_middle;
  78.102 -		size -= BITS_PER_LONG;
  78.103 -		result += BITS_PER_LONG;
  78.104 -	}
  78.105 -	while (size & ~(BITS_PER_LONG-1)) {
  78.106 -		if (~(tmp = *(p++)))
  78.107 -			goto found_middle;
  78.108 -		result += BITS_PER_LONG;
  78.109 -		size -= BITS_PER_LONG;
  78.110 -	}
  78.111 -	if (!size)
  78.112 -		return result;
  78.113 -	tmp = *p;
  78.114 +    if (offset >= size)
  78.115 +        return size;
  78.116 +    size -= result;
  78.117 +    offset %= BITS_PER_LONG;
  78.118 +    if (offset) {
  78.119 +        tmp = *(p++);
  78.120 +        tmp |= ~0UL >> (BITS_PER_LONG - offset);
  78.121 +        if (size < BITS_PER_LONG)
  78.122 +            goto found_first;
  78.123 +        if (~tmp)
  78.124 +            goto found_middle;
  78.125 +        size -= BITS_PER_LONG;
  78.126 +        result += BITS_PER_LONG;
  78.127 +    }
  78.128 +    while (size & ~(BITS_PER_LONG-1)) {
  78.129 +        if (~(tmp = *(p++)))
  78.130 +            goto found_middle;
  78.131 +        result += BITS_PER_LONG;
  78.132 +        size -= BITS_PER_LONG;
  78.133 +    }
  78.134 +    if (!size)
  78.135 +        return result;
  78.136 +    tmp = *p;
  78.137  
  78.138  found_first:
  78.139 -	tmp |= ~0UL << size;
  78.140 -	if (tmp == ~0UL)	/* Are any bits zero? */
  78.141 -		return result + size;	/* Nope. */
  78.142 +    tmp |= ~0UL << size;
  78.143 +    if (tmp == ~0UL)    /* Are any bits zero? */
  78.144 +        return result + size;    /* Nope. */
  78.145  found_middle:
  78.146 -	return result + ffz(tmp);
  78.147 +    return result + ffz(tmp);
  78.148  }
    79.1 --- a/xen/arch/powerpc/boot/boot32.S	Fri Dec 15 10:59:33 2006 -0700
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,75 +0,0 @@
    79.4 -/*
    79.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    79.6 - *
    79.7 - * This program is free software; you can redistribute it and/or modify
    79.8 - * it under the terms of the GNU General Public License as published by
    79.9 - * the Free Software Foundation; either version 2 of the License, or
   79.10 - * (at your option) any later version.
   79.11 - * 
   79.12 - * This program is distributed in the hope that it will be useful,
   79.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   79.15 - * GNU General Public License for more details.
   79.16 - * 
   79.17 - * You should have received a copy of the GNU General Public License
   79.18 - * along with this program; if not, write to the Free Software
   79.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   79.20 - *
   79.21 - */
   79.22 -	
   79.23 -### 32 bit strapping code so Of will like us
   79.24 -	.section	".text"
   79.25 -	.align 3
   79.26 -	.globl _start
   79.27 -		
   79.28 -_start:
   79.29 -	## Double word align the MSR value below
   79.30 -	nop
   79.31 -	bl _real_start
   79.32 -	## static value for MSR
   79.33 -	.llong 0x9000000000001000
   79.34 -
   79.35 -	## see also docs/reference/ppc/msr.txt
   79.36 -##bit C  Hex               Name Desc
   79.37 -##  0 63 80000000 00000000 SF   64-bit Mode
   79.38 -##  3 60 10000000 00000000 HV   Hypervisor State iff PR = 0 in hypervisor state.
   79.39 -## 51 12 00000000 00001000 ME   Machine Check Enable
   79.40 -
   79.41 -_real_start:		
   79.42 -	# pass the original msr as argument to hype_init
   79.43 -	mfmsr   8
   79.44 -
   79.45 -	## Set PC
   79.46 -	li	21, 0
   79.47 -	oris	21, 21, _hype64@h
   79.48 -	ori	21, 21, _hype64@l
   79.49 -#ifdef __BRIDGE64__
   79.50 -	## In 64bit we use rfid to switch from 32bit to 64 bit
   79.51 -	mtsrr0	21
   79.52 -
   79.53 -	## Set MSR
   79.54 -	mflr	21
   79.55 -	ld	22, 0(21)
   79.56 -	mtsrr1	22
   79.57 -	bl __leap
   79.58 -	/* should never return */
   79.59 -	trap
   79.60 -__leap:		
   79.61 -	rfid
   79.62 -#else
   79.63 -	mtctr 21
   79.64 -	bctrl
   79.65 -	/* should never return */
   79.66 -	trap
   79.67 -#endif
   79.68 -
   79.69 -	
   79.70 -_real_end:
   79.71 -	.data
   79.72 -	.align 3
   79.73 -	## Hypervisor starts here, at the first data address
   79.74 -	## linker magic positions _hype64 0x100 after _start
   79.75 -	## hype/ppc64/Makefile.isa 
   79.76 -_hype64:		
   79.77 -
   79.78 -
    80.1 --- a/xen/arch/powerpc/boot/start.S	Fri Dec 15 10:59:33 2006 -0700
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,51 +0,0 @@
    80.4 -/*
    80.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    80.6 - *
    80.7 - * This program is free software; you can redistribute it and/or modify
    80.8 - * it under the terms of the GNU General Public License as published by
    80.9 - * the Free Software Foundation; either version 2 of the License, or
   80.10 - * (at your option) any later version.
   80.11 - * 
   80.12 - * This program is distributed in the hope that it will be useful,
   80.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   80.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   80.15 - * GNU General Public License for more details.
   80.16 - * 
   80.17 - * You should have received a copy of the GNU General Public License
   80.18 - * along with this program; if not, write to the Free Software
   80.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   80.20 - *
   80.21 - */
   80.22 -
   80.23 -#include <asm/config.h>
   80.24 -#include <asm/processor.h>
   80.25 -#include <asm/page.h>
   80.26 -
   80.27 -    .globl _start
   80.28 -_start:
   80.29 -    /* load up the stack */
   80.30 -    SET_REG_TO_LABEL(r1, cpu0_stack)
   80.31 -
   80.32 -    /* call the init function */
   80.33 -    LOADADDR(r21,__start_xen_ppc)
   80.34 -
   80.35 -#ifdef __PPC64__
   80.36 -    ld r2, 8(r21)
   80.37 -    ld r21, 0(r21)
   80.38 -#endif
   80.39 -    mtctr r21
   80.40 -    bctrl
   80.41 -    /* should never return */
   80.42 -    trap
   80.43 -
   80.44 -    /* Note! GDB 6.3 makes the very stupid assumption that PC > SP means we are
   80.45 -     * in a Linux signal trampoline, and it begins groping for a struct
   80.46 -     * rt_sigframe on the stack. Naturally, this fails miserably for our
   80.47 -     * backtrace. To work around this behavior, we must make certain that our
   80.48 -     * stack is always above our text, e.g. in the data section. */
   80.49 -    .data /* DO NOT REMOVE; see GDB note above */
   80.50 -    .align 4
   80.51 -cpu0_stack_bottom:
   80.52 -    .space STACK_SIZE
   80.53 -cpu0_stack:
   80.54 -    .space STACK_FRAME_OVERHEAD
    81.1 --- a/xen/arch/powerpc/boot_of.c	Fri Dec 15 10:59:33 2006 -0700
    81.2 +++ b/xen/arch/powerpc/boot_of.c	Fri Dec 15 11:32:58 2006 -0700
    81.3 @@ -16,6 +16,7 @@
    81.4   * Copyright (C) IBM Corp. 2005, 2006
    81.5   *
    81.6   * Authors: Jimi Xenidis <jimix@watson.ibm.com>
    81.7 + *          Hollis Blanchard <hollisb@us.ibm.com>
    81.8   */
    81.9  
   81.10  #include <xen/config.h>
   81.11 @@ -32,6 +33,7 @@
   81.12  #include "exceptions.h"
   81.13  #include "of-devtree.h"
   81.14  #include "oftree.h"
   81.15 +#include "rtas.h"
   81.16  
   81.17  /* Secondary processors use this for handshaking with main processor.  */
   81.18  volatile unsigned int __spin_ack;
   81.19 @@ -39,15 +41,16 @@ volatile unsigned int __spin_ack;
   81.20  static ulong of_vec;
   81.21  static ulong of_msr;
   81.22  static int of_out;
   81.23 -static char bootargs[256];
   81.24 +static ulong eomem;
   81.25  
   81.26 -#define COMMAND_LINE_SIZE 512
   81.27 -static char builtin_cmdline[COMMAND_LINE_SIZE]
   81.28 -    __attribute__((section("__builtin_cmdline"))) = CMDLINE;
   81.29 +#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)
   81.30 +static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);
   81.31  
   81.32 +extern char builtin_cmdline[];
   81.33  extern struct ns16550_defaults ns16550;
   81.34  
   81.35  #undef OF_DEBUG
   81.36 +#undef OF_DEBUG_LOW
   81.37  
   81.38  #ifdef OF_DEBUG
   81.39  #define DBG(args...) of_printf(args)
   81.40 @@ -55,6 +58,12 @@ extern struct ns16550_defaults ns16550;
   81.41  #define DBG(args...)
   81.42  #endif
   81.43  
   81.44 +#ifdef OF_DEBUG_LOW
   81.45 +#define DBG_LOW(args...) of_printf(args)
   81.46 +#else
   81.47 +#define DBG_LOW(args...)
   81.48 +#endif
   81.49 +
   81.50  #define of_panic(MSG...) \
   81.51      do { of_printf(MSG); of_printf("\nHANG\n"); for (;;); } while (0)
   81.52  
   81.53 @@ -68,7 +77,6 @@ struct of_service {
   81.54  static int bof_chosen;
   81.55  
   81.56  static struct of_service s;
   81.57 -extern s32 prom_call(void *arg, ulong rtas_base, ulong func, ulong msr);
   81.58  
   81.59  static int __init of_call(
   81.60      const char *service, u32 nargs, u32 nrets, s32 rets[], ...)
   81.61 @@ -78,7 +86,6 @@ static int __init of_call(
   81.62      if (of_vec != 0) {
   81.63          va_list args;
   81.64          int i;
   81.65 -
   81.66          memset(&s, 0, sizeof (s));
   81.67          s.ofs_service = (ulong)service;
   81.68          s.ofs_nargs = nargs;
   81.69 @@ -189,7 +196,7 @@ static int __init of_finddevice(const ch
   81.70          DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]);
   81.71          return OF_FAILURE;
   81.72      }
   81.73 -    DBG("finddevice %s -> %d\n",devspec, rets[0]);
   81.74 +    DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]);
   81.75      return rets[0];
   81.76  }
   81.77  
   81.78 @@ -200,11 +207,11 @@ static int __init of_getprop(int ph, con
   81.79      of_call("getprop", 4, 1, rets, ph, name, buf, buflen);
   81.80  
   81.81      if (rets[0] == OF_FAILURE) {
   81.82 -        DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
   81.83 +        DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name);
   81.84          return OF_FAILURE;
   81.85      }
   81.86  
   81.87 -    DBG("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
   81.88 +    DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
   81.89      return rets[0];
   81.90  }
   81.91  
   81.92 @@ -220,7 +227,7 @@ static int __init of_setprop(
   81.93          return OF_FAILURE;
   81.94      }
   81.95  
   81.96 -    DBG("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
   81.97 +    DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
   81.98      return rets[0];
   81.99  }
  81.100  
  81.101 @@ -232,7 +239,7 @@ static int __init of_getchild(int ph)
  81.102      int rets[1] = { OF_FAILURE };
  81.103  
  81.104      of_call("child", 1, 1, rets, ph);
  81.105 -    DBG("getchild 0x%x -> 0x%x\n", ph, rets[0]);
  81.106 +    DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]);
  81.107  
  81.108      return rets[0];
  81.109  }
  81.110 @@ -245,7 +252,7 @@ static int __init of_getpeer(int ph)
  81.111      int rets[1] = { OF_FAILURE };
  81.112  
  81.113      of_call("peer", 1, 1, rets, ph);
  81.114 -    DBG("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
  81.115 +    DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
  81.116  
  81.117      return rets[0];
  81.118  }
  81.119 @@ -259,7 +266,7 @@ static int __init of_getproplen(int ph, 
  81.120          DBG("getproplen 0x%x %s -> FAILURE\n", ph, name);
  81.121          return OF_FAILURE;
  81.122      }
  81.123 -    DBG("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
  81.124 +    DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
  81.125      return rets[0];
  81.126  }
  81.127  
  81.128 @@ -272,7 +279,7 @@ static int __init of_package_to_path(int
  81.129          DBG("%s 0x%x -> FAILURE\n", __func__, ph);
  81.130          return OF_FAILURE;
  81.131      }
  81.132 -    DBG("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
  81.133 +    DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
  81.134      if (rets[0] <= buflen)
  81.135          buffer[rets[0]] = '\0';
  81.136      return rets[0];
  81.137 @@ -289,7 +296,7 @@ static int __init of_nextprop(int ph, co
  81.138          return OF_FAILURE;
  81.139      }
  81.140  
  81.141 -    DBG("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
  81.142 +    DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
  81.143      return rets[0];
  81.144  }
  81.145  
  81.146 @@ -336,7 +343,7 @@ static int __init of_claim(u32 virt, u32
  81.147          return OF_FAILURE;
  81.148      }
  81.149  
  81.150 -    DBG("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,
  81.151 +    DBG_LOW("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,
  81.152          rets[0]);
  81.153      return rets[0];
  81.154  }
  81.155 @@ -358,29 +365,194 @@ static int __init of_getparent(int ph)
  81.156  
  81.157      of_call("parent", 1, 1, rets, ph);
  81.158  
  81.159 -    DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
  81.160 +    DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]);
  81.161 +    return rets[0];
  81.162 +}
  81.163 +
  81.164 +static int __init of_open(const char *devspec)
  81.165 +{
  81.166 +    int rets[1] = { OF_FAILURE };
  81.167 +
  81.168 +    of_call("open", 1, 1, rets, devspec);
  81.169      return rets[0];
  81.170  }
  81.171  
  81.172 -static void boot_of_probemem(multiboot_info_t *mbi)
  81.173 +static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells)
  81.174 +{
  81.175 +    int rc;
  81.176 +    uint pg;
  81.177 +    uint a[64];
  81.178 +    int tst;
  81.179 +    u64 start;
  81.180 +    u64 size;
  81.181 +
  81.182 +    rc = of_getprop(m, "available", a, sizeof (a));
  81.183 +    if (rc > 0) {
  81.184 +        int l =  rc / sizeof(a[0]);
  81.185 +        int r = 0;
  81.186 +
  81.187 +#ifdef OF_DEBUG
  81.188 +        { 
  81.189 +            int i;
  81.190 +            of_printf("avail:\n");
  81.191 +            for (i = 0; i < l; i += 4)
  81.192 +                of_printf("  0x%x%x, 0x%x%x\n",
  81.193 +                          a[i], a[i + 1],
  81.194 +                          a[i + 2] ,a[i + 3]);
  81.195 +        }
  81.196 +#endif
  81.197 +            
  81.198 +        pg = 0;
  81.199 +        while (pg < MEM_AVAILABLE_PAGES && r < l) {
  81.200 +            ulong end;
  81.201 +
  81.202 +            start = a[r++];
  81.203 +            if (addr_cells == 2 && (r < l) )
  81.204 +                start = (start << 32) | a[r++];
  81.205 +            
  81.206 +            size = a[r++];
  81.207 +            if (size_cells == 2 && (r < l) )
  81.208 +                size = (size << 32) | a[r++];
  81.209 +                
  81.210 +            end = ALIGN_DOWN(start + size, PAGE_SIZE);
  81.211 +
  81.212 +            start = ALIGN_UP(start, PAGE_SIZE);
  81.213 +
  81.214 +            DBG("%s: marking 0x%x - 0x%lx\n", __func__,
  81.215 +                pg << PAGE_SHIFT, start);
  81.216 +
  81.217 +            start >>= PAGE_SHIFT;
  81.218 +            while (pg < MEM_AVAILABLE_PAGES && pg < start) {
  81.219 +                set_bit(pg, mem_available_pages);
  81.220 +                pg++;
  81.221 +            }
  81.222 +
  81.223 +            pg = end  >> PAGE_SHIFT;
  81.224 +        }
  81.225 +    }
  81.226 +
  81.227 +    /* Now make sure we mark our own memory */
  81.228 +    pg =  (ulong)_start >> PAGE_SHIFT;
  81.229 +    start = (ulong)_end >> PAGE_SHIFT;
  81.230 +
  81.231 +    DBG("%s: marking 0x%x - 0x%lx\n", __func__,
  81.232 +        pg << PAGE_SHIFT, start << PAGE_SHIFT);
  81.233 +
  81.234 +    /* Lets try and detect if our image has stepped on something. It
  81.235 +     * is possible that FW has already subtracted our image from
  81.236 +     * available memory so we must make sure that the previous bits
  81.237 +     * are the same for the whole image */
  81.238 +    tst = test_and_set_bit(pg, mem_available_pages);
  81.239 +    ++pg;
  81.240 +    while (pg <= start) {
  81.241 +        if (test_and_set_bit(pg, mem_available_pages) != tst)
  81.242 +            of_panic("%s: pg :0x%x of our image is different\n",
  81.243 +                     __func__, pg);
  81.244 +        ++pg;
  81.245 +    }
  81.246 +
  81.247 +    DBG("%s: marking 0x%x - 0x%x\n", __func__,
  81.248 +        0 << PAGE_SHIFT, 3 << PAGE_SHIFT);
  81.249 +    /* First for pages (where the vectors are) should be left alone as well */
  81.250 +    set_bit(0, mem_available_pages);
  81.251 +    set_bit(1, mem_available_pages);
  81.252 +    set_bit(2, mem_available_pages);
  81.253 +    set_bit(3, mem_available_pages);
  81.254 +}
  81.255 +
  81.256 +#ifdef BOOT_OF_FREE
  81.257 +/* this is here in case we ever need a free call at a later date */
  81.258 +static void boot_of_free(ulong addr, ulong size)
  81.259 +{
  81.260 +    ulong bits;
  81.261 +    ulong pos;
  81.262 +    ulong i;
  81.263 +
  81.264 +    size = ALIGN_UP(size, PAGE_SIZE);
  81.265 +    bits = size >> PAGE_SHIFT;
  81.266 +    pos = addr >> PAGE_SHIFT;
  81.267 +
  81.268 +    for (i = 0; i < bits; i++) {
  81.269 +        if (!test_and_clear_bit(pos + i, mem_available_pages))
  81.270 +            of_panic("%s: pg :0x%lx was never allocated\n",
  81.271 +                     __func__, pos + i);
  81.272 +    }
  81.273 +}
  81.274 +#endif
  81.275 +
  81.276 +static ulong boot_of_alloc(ulong size)
  81.277 +{
  81.278 +    ulong bits;
  81.279 +    ulong pos;
  81.280 +
  81.281 +    if (size == 0)
  81.282 +        return 0;
  81.283 +
  81.284 +    DBG("%s(0x%lx)\n", __func__, size);
  81.285 +
  81.286 +    size = ALIGN_UP(size, PAGE_SIZE);
  81.287 +    bits = size >> PAGE_SHIFT;
  81.288 +    pos = 0;
  81.289 +    for (;;) {
  81.290 +        ulong i;
  81.291 +
  81.292 +        pos = find_next_zero_bit(mem_available_pages,
  81.293 +                                 MEM_AVAILABLE_PAGES, pos);
  81.294 +        DBG("%s: found start bit at: 0x%lx\n", __func__, pos);
  81.295 +
  81.296 +        /* found nothing */
  81.297 +        if ((pos + bits) > MEM_AVAILABLE_PAGES) {
  81.298 +            of_printf("%s: allocation of size: 0x%lx failed\n",
  81.299 +                     __func__, size);
  81.300 +            return 0;
  81.301 +        }
  81.302 +
  81.303 +        /* find a set that fits */
  81.304 +        DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos);
  81.305 +
  81.306 +        i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);  
  81.307 +        if (i - pos >= bits) {
  81.308 +            uint addr = pos << PAGE_SHIFT;
  81.309 +
  81.310 +            /* make sure OF is happy with our choice */
  81.311 +            if (of_claim(addr, size, 0) != OF_FAILURE) {
  81.312 +                for (i = 0; i < bits; i++)
  81.313 +                    set_bit(pos + i, mem_available_pages);
  81.314 +
  81.315 +                DBG("%s: 0x%lx is good returning 0x%x\n",
  81.316 +                    __func__, pos, addr);
  81.317 +                return addr;
  81.318 +            }
  81.319 +            /* if OF did not like the address then simply start from
  81.320 +             * the next bit */
  81.321 +            i = 1;
  81.322 +        }
  81.323 +
  81.324 +        pos = pos + i;
  81.325 +    }
  81.326 +}
  81.327 +
  81.328 +static ulong boot_of_mem_init(void)
  81.329  {
  81.330      int root;
  81.331      int p;
  81.332 -    u32 addr_cells = 1;
  81.333 -    u32 size_cells = 1;
  81.334      int rc;
  81.335 -    int mcount = 0;
  81.336 -    static memory_map_t mmap[16];
  81.337 +    uint addr_cells;
  81.338 +    uint size_cells;
  81.339  
  81.340      root = of_finddevice("/");
  81.341      p = of_getchild(root);
  81.342  
  81.343      /* code is writen to assume sizes of 1 */
  81.344 -    of_getprop(root, "#address-cells", &addr_cells, sizeof (addr_cells));
  81.345 -    of_getprop(root, "#size-cells", &size_cells, sizeof (size_cells));
  81.346 +    of_getprop(root, "#address-cells", &addr_cells,
  81.347 +               sizeof (addr_cells));
  81.348 +    of_getprop(root, "#size-cells", &size_cells,
  81.349 +               sizeof (size_cells));
  81.350      DBG("%s: address_cells=%d  size_cells=%d\n",
  81.351                      __func__, addr_cells, size_cells);
  81.352 -    
  81.353 +
  81.354 +    /* We do ream memory discovery later, for now we only want to find
  81.355 +     * the first LMB */
  81.356      do {
  81.357          const char memory[] = "memory";
  81.358          char type[32];
  81.359 @@ -389,82 +561,69 @@ static void boot_of_probemem(multiboot_i
  81.360  
  81.361          of_getprop(p, "device_type", type, sizeof (type));
  81.362          if (strncmp(type, memory, sizeof (memory)) == 0) {
  81.363 -            u32 reg[48];  
  81.364 -            u32 al, ah, ll, lh;
  81.365 +            uint reg[48];  
  81.366 +            u64 start;
  81.367 +            u64 size;
  81.368              int r;
  81.369 +            int l;
  81.370  
  81.371              rc = of_getprop(p, "reg", reg, sizeof (reg));
  81.372              if (rc == OF_FAILURE) {
  81.373                  of_panic("no reg property for memory node: 0x%x.\n", p);
  81.374              }
  81.375 -            int l = rc/sizeof(u32); /* number reg element */
  81.376 +
  81.377 +            l = rc / sizeof(reg[0]); /* number reg element */
  81.378              DBG("%s: number of bytes in property 'reg' %d\n",
  81.379                              __func__, rc);
  81.380              
  81.381              r = 0;
  81.382              while (r < l) {
  81.383 -                al = ah = ll = lh = 0;
  81.384 -                if (addr_cells == 2) {
  81.385 -                    ah = reg[r++];
  81.386 -                    if (r >= l)
  81.387 -                        break;  /* partial line.  Skip  */
  81.388 -                    al = reg[r++];
  81.389 -                    if (r >= l)
  81.390 -                        break;  /* partial line.  Skip */
  81.391 -                } else {
  81.392 -                    al = reg[r++];
  81.393 -                    if (r >= l)
  81.394 -                        break;  /* partial line.  Skip */
  81.395 -                }
  81.396 -                if (size_cells == 2) {
  81.397 -                    lh = reg[r++];
  81.398 -                    if (r >= l)
  81.399 -                        break;  /* partial line.  Skip */
  81.400 -                    ll = reg[r++];
  81.401 -                } else {
  81.402 -                    ll = reg[r++];
  81.403 +                start = reg[r++];
  81.404 +                if (addr_cells == 2 && (r < l) )
  81.405 +                    start = (start << 32) | reg[r++];
  81.406 +
  81.407 +                if (r >= l)
  81.408 +                    break;  /* partial line.  Skip */
  81.409 +
  81.410 +                if (start > 0) {
  81.411 +                    /* this is not the first LMB so we skip it */
  81.412 +                    break;
  81.413                  }
  81.414  
  81.415 -                if ((ll != 0) || (lh != 0)) {
  81.416 -                    mmap[mcount].size = 20; /* - size field */
  81.417 -                    mmap[mcount].type = 1; /* Regular ram */
  81.418 -                    mmap[mcount].length_high = lh;
  81.419 -                    mmap[mcount].length_low = ll;
  81.420 -                    mmap[mcount].base_addr_high = ah;
  81.421 -                    mmap[mcount].base_addr_low = al;
  81.422 -                    of_printf("%s: memory 0x%016lx[0x%08lx]\n",
  81.423 -                      __func__,
  81.424 -                      (u64)(((u64)mmap[mcount].base_addr_high << 32)
  81.425 -                            | mmap[mcount].base_addr_low),
  81.426 -                      (u64)(((u64)mmap[mcount].length_high << 32)
  81.427 -                            | mmap[mcount].length_low));
  81.428 -                    ++mcount;
  81.429 -                }
  81.430 +                size = reg[r++];
  81.431 +                if (size_cells == 2 && (r < l) )
  81.432 +                    size = (size << 32) | reg[r++];
  81.433 +                
  81.434 +                if (r > l)
  81.435 +                    break;  /* partial line.  Skip */
  81.436 +
  81.437 +                boot_of_alloc_init(p, addr_cells, size_cells);
  81.438 +                
  81.439 +                eomem = size;
  81.440 +                return size;
  81.441              }
  81.442          }
  81.443          p = of_getpeer(p);
  81.444      } while (p != OF_FAILURE && p != 0);
  81.445  
  81.446 -    if (mcount > 0) {
  81.447 -        mbi->flags |= MBI_MEMMAP;
  81.448 -        mbi->mmap_length = sizeof (mmap[0]) * mcount;
  81.449 -        mbi->mmap_addr = (ulong)mmap;
  81.450 -    }
  81.451 +    return 0;
  81.452  }
  81.453  
  81.454  static void boot_of_bootargs(multiboot_info_t *mbi)
  81.455  {
  81.456      int rc;
  81.457  
  81.458 -    rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
  81.459 -    if (rc == OF_FAILURE || bootargs[0] == '\0') {
  81.460 -        strlcpy(bootargs, builtin_cmdline, sizeof(bootargs));
  81.461 +    if (builtin_cmdline[0] == '\0') {
  81.462 +        rc = of_getprop(bof_chosen, "bootargs", builtin_cmdline,
  81.463 +                CONFIG_CMDLINE_SIZE);
  81.464 +        if (rc > CONFIG_CMDLINE_SIZE)
  81.465 +            of_panic("bootargs[] not big enough for /chosen/bootargs\n");
  81.466      }
  81.467  
  81.468      mbi->flags |= MBI_CMDLINE;
  81.469 -    mbi->cmdline = (u32)bootargs;
  81.470 +    mbi->cmdline = (ulong)builtin_cmdline;
  81.471  
  81.472 -    of_printf("bootargs = %s\n", bootargs);
  81.473 +    of_printf("bootargs = %s\n", builtin_cmdline);
  81.474  }
  81.475  
  81.476  static int save_props(void *m, ofdn_t n, int pkg)
  81.477 @@ -500,7 +659,8 @@ static int save_props(void *m, ofdn_t n,
  81.478                      of_panic("obj array not big enough for 0x%x\n", sz);
  81.479                  }
  81.480                  actual = of_getprop(pkg, name, obj, sz);
  81.481 -                if (actual > sz) of_panic("obj too small");
  81.482 +                if (actual > sz)
  81.483 +                    of_panic("obj too small");
  81.484              }
  81.485  
  81.486              if (strncmp(name, name_str, sizeof(name_str)) == 0) {
  81.487 @@ -512,7 +672,8 @@ static int save_props(void *m, ofdn_t n,
  81.488              }
  81.489  
  81.490              pos = ofd_prop_add(m, n, name, obj, actual);
  81.491 -            if (pos == 0) of_panic("prop_create");
  81.492 +            if (pos == 0)
  81.493 +                of_panic("prop_create");
  81.494          }
  81.495  
  81.496          result = of_nextprop(pkg, name, name);
  81.497 @@ -536,10 +697,12 @@ retry:
  81.498  
  81.499      if (pnext != 0) {
  81.500          sz = of_package_to_path(pnext, path, psz);
  81.501 -        if (sz == OF_FAILURE) of_panic("bad path\n");
  81.502 +        if (sz == OF_FAILURE)
  81.503 +            of_panic("bad path\n");
  81.504  
  81.505          nnext = ofd_node_child_create(m, n, path, sz);
  81.506 -        if (nnext == 0) of_panic("out of mem\n");
  81.507 +        if (nnext == 0)
  81.508 +            of_panic("out of mem\n");
  81.509  
  81.510          do_pkg(m, nnext, pnext, path, psz);
  81.511      }
  81.512 @@ -551,7 +714,8 @@ retry:
  81.513          sz = of_package_to_path(pnext, path, psz);
  81.514  
  81.515          nnext = ofd_node_peer_create(m, n, path, sz);
  81.516 -        if (nnext <= 0) of_panic("out of space in OFD tree.\n");
  81.517 +        if (nnext <= 0)
  81.518 +            of_panic("out of space in OFD tree.\n");
  81.519  
  81.520          n = nnext;
  81.521          p = pnext;
  81.522 @@ -559,7 +723,7 @@ retry:
  81.523      }
  81.524  }
  81.525  
  81.526 -static int pkg_save(void *mem)
  81.527 +static long pkg_save(void *mem)
  81.528  {
  81.529      int root;
  81.530      char path[256];
  81.531 @@ -570,11 +734,12 @@ static int pkg_save(void *mem)
  81.532  
  81.533      /* get root */
  81.534      root = of_getpeer(0);
  81.535 -    if (root == OF_FAILURE) of_panic("no root package\n");
  81.536 +    if (root == OF_FAILURE)
  81.537 +        of_panic("no root package\n");
  81.538  
  81.539      do_pkg(mem, OFD_ROOT, root, path, sizeof(path));
  81.540  
  81.541 -    r = (((ofdn_t *)mem)[1] + 1) * sizeof (u64);
  81.542 +    r = ofd_size(mem);
  81.543  
  81.544      of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r);
  81.545  
  81.546 @@ -604,7 +769,8 @@ static int boot_of_fixup_refs(void *mem)
  81.547              char ofpath[256];
  81.548  
  81.549              path = ofd_node_path(mem, c);
  81.550 -            if (path == NULL) of_panic("no path to found prop: %s\n", name);
  81.551 +            if (path == NULL)
  81.552 +                of_panic("no path to found prop: %s\n", name);
  81.553  
  81.554              rp = of_finddevice(path);
  81.555              if (rp == OF_FAILURE)
  81.556 @@ -629,13 +795,15 @@ static int boot_of_fixup_refs(void *mem)
  81.557                           "ref 0x%x\n", name, path, rp, ref);
  81.558  
  81.559              dp = ofd_node_find(mem, ofpath);
  81.560 -            if (dp <= 0) of_panic("no ofd node for OF node[0x%x]: %s\n",
  81.561 -                                  ref, ofpath);
  81.562 +            if (dp <= 0)
  81.563 +                of_panic("no ofd node for OF node[0x%x]: %s\n",
  81.564 +                         ref, ofpath);
  81.565  
  81.566              ref = dp;
  81.567  
  81.568              upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref));
  81.569 -            if (upd <= 0) of_panic("update failed: %s\n", name);
  81.570 +            if (upd <= 0)
  81.571 +                of_panic("update failed: %s\n", name);
  81.572  
  81.573  #ifdef DEBUG
  81.574              of_printf("%s: %s/%s -> %s\n", __func__,
  81.575 @@ -658,7 +826,8 @@ static int boot_of_fixup_chosen(void *me
  81.576      char ofpath[256];
  81.577  
  81.578      ch = of_finddevice("/chosen");
  81.579 -    if (ch == OF_FAILURE) of_panic("/chosen not found\n");
  81.580 +    if (ch == OF_FAILURE)
  81.581 +        of_panic("/chosen not found\n");
  81.582  
  81.583      rc = of_getprop(ch, "cpu", &val, sizeof (val));
  81.584  
  81.585 @@ -667,16 +836,19 @@ static int boot_of_fixup_chosen(void *me
  81.586  
  81.587          if (rc > 0) {
  81.588              dn = ofd_node_find(mem, ofpath);
  81.589 -            if (dn <= 0) of_panic("no node for: %s\n", ofpath);
  81.590 +            if (dn <= 0)
  81.591 +                of_panic("no node for: %s\n", ofpath);
  81.592  
  81.593              ofd_boot_cpu = dn;
  81.594              val = dn;
  81.595  
  81.596              dn = ofd_node_find(mem, "/chosen");
  81.597 -            if (dn <= 0) of_panic("no /chosen node\n");
  81.598 +            if (dn <= 0)
  81.599 +                of_panic("no /chosen node\n");
  81.600  
  81.601              dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val));
  81.602 -            if (dc <= 0) of_panic("could not fix /chosen/cpu\n");
  81.603 +            if (dc <= 0)
  81.604 +                of_panic("could not fix /chosen/cpu\n");
  81.605              rc = 1;
  81.606          } else {
  81.607              of_printf("*** can't find path to booting cpu, "
  81.608 @@ -687,56 +859,6 @@ static int boot_of_fixup_chosen(void *me
  81.609      return rc;
  81.610  }
  81.611  
  81.612 -static ulong space_base;
  81.613 -
  81.614 -/*
  81.615 - * The following function is necessary because we cannot depend on all
  81.616 - * FW to actually allocate us any space, so we look for it _hoping_
  81.617 - * that at least is will fail if we try to claim something that
  81.618 - * belongs to FW.  This hope does not seem to be true on some version
  81.619 - * of PIBS.
  81.620 - */
  81.621 -static ulong find_space(u32 size, u32 align, multiboot_info_t *mbi)
  81.622 -{
  81.623 -    memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr);
  81.624 -    ulong eomem = ((u64)map->length_high << 32) | (u64)map->length_low;
  81.625 -    ulong base;
  81.626 -
  81.627 -    if (size == 0)
  81.628 -        return 0;
  81.629 -
  81.630 -    if (align == 0)
  81.631 -        of_panic("cannot call %s() with align of 0\n", __func__);
  81.632 -
  81.633 -#ifdef BROKEN_CLAIM_WORKAROUND
  81.634 -    {
  81.635 -        static int broken_claim;
  81.636 -        if (!broken_claim) {
  81.637 -            /* just try and claim it to the FW chosen address */
  81.638 -            base = of_claim(0, size, align);
  81.639 -            if (base != OF_FAILURE)
  81.640 -                return base;
  81.641 -            of_printf("%s: Firmware does not allocate memory for you\n",
  81.642 -                      __func__);
  81.643 -            broken_claim = 1;
  81.644 -        }
  81.645 -    }
  81.646 -#endif
  81.647 -
  81.648 -    of_printf("%s base=0x%016lx  eomem=0x%016lx  size=0x%08x  align=0x%x\n",
  81.649 -                    __func__, space_base, eomem, size, align);
  81.650 -    base = ALIGN_UP(space_base, PAGE_SIZE);
  81.651 -
  81.652 -    while ((base + size) < rma_size(cpu_default_rma_order_pages())) {
  81.653 -        if (of_claim(base, size, 0) != OF_FAILURE) {
  81.654 -            space_base = base + size;
  81.655 -            return base;
  81.656 -        }
  81.657 -        base += (PAGE_SIZE >  align) ? PAGE_SIZE : align;
  81.658 -    }
  81.659 -    of_panic("Cannot find memory in the RMA\n");
  81.660 -}
  81.661 -
  81.662  /* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges
  81.663   * property.  The values are bad, and it doesn't even have the
  81.664   * right number of cells. */
  81.665 @@ -798,8 +920,10 @@ static int __init boot_of_serial(void *o
  81.666              of_panic("package-to-path failed\n");
  81.667  
  81.668          rc = of_getprop(p, "device_type", type, sizeof (type));
  81.669 -        if (rc == OF_FAILURE)
  81.670 -            of_panic("fetching device type failed\n");
  81.671 +        if (rc == OF_FAILURE) {
  81.672 +            of_printf("%s: fetching type of `%s' failed\n", __func__, buf);
  81.673 +            continue;
  81.674 +        }
  81.675  
  81.676          if (strcmp(type, "serial") != 0)
  81.677              continue;
  81.678 @@ -855,17 +979,104 @@ static int __init boot_of_serial(void *o
  81.679      return 1;
  81.680  }
  81.681  
  81.682 -static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
  81.683 +static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi)
  81.684  {
  81.685 -    static module_t mods[3];
  81.686 +    int rtas_node;
  81.687 +    int rtas_instance;
  81.688 +    uint size = 0;
  81.689 +    int res[2];
  81.690 +    int mem;
  81.691 +    int ret;
  81.692 +
  81.693 +    rtas_node = of_finddevice("/rtas");
  81.694 +
  81.695 +    if (rtas_node <= 0) {
  81.696 +        of_printf("No RTAS, Xen has no power control\n");
  81.697 +        return 0;
  81.698 +    }
  81.699 +    of_getprop(rtas_node, "rtas-size", &size, sizeof (size));
  81.700 +    if (size == 0) {
  81.701 +        of_printf("RTAS, has no size\n");
  81.702 +        return 0;
  81.703 +    }
  81.704 +
  81.705 +    rtas_instance = of_open("/rtas");
  81.706 +    if (rtas_instance == OF_FAILURE) {
  81.707 +        of_printf("RTAS, could not open\n");
  81.708 +        return 0;
  81.709 +    }
  81.710 +
  81.711 +    size = ALIGN_UP(size, PAGE_SIZE);
  81.712 +    
  81.713 +    mem = boot_of_alloc(size);
  81.714 +    if (mem == 0)
  81.715 +        of_panic("Could not allocate RTAS tree\n");
  81.716 +
  81.717 +    of_printf("instantiating RTAS at: 0x%x\n", mem);
  81.718 +
  81.719 +    ret = of_call("call-method", 3, 2, res,
  81.720 +                  "instantiate-rtas", rtas_instance, mem);
  81.721 +    if (ret == OF_FAILURE) {
  81.722 +        of_printf("RTAS, could not open\n");
  81.723 +        return 0;
  81.724 +    }
  81.725 +    
  81.726 +    rtas_entry = res[1];
  81.727 +    rtas_base = mem;
  81.728 +    rtas_end = mem + size;
  81.729 +    rtas_msr = of_msr;
  81.730 +
  81.731 +    mod->mod_start = rtas_base;
  81.732 +    mod->mod_end = rtas_end;
  81.733 +    return 1;
  81.734 +}
  81.735 +
  81.736 +static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
  81.737 +{
  81.738      void *oft;
  81.739      ulong oft_sz = 48 * PAGE_SIZE;
  81.740 +
  81.741 +    /* snapshot the tree */
  81.742 +    oft = (void *)boot_of_alloc(oft_sz);
  81.743 +    if (oft == NULL)
  81.744 +        of_panic("Could not allocate OFD tree\n");
  81.745 +
  81.746 +    of_printf("creating oftree at: 0x%p\n", oft);
  81.747 +    of_test("package-to-path");
  81.748 +    oft = ofd_create(oft, oft_sz);
  81.749 +    pkg_save(oft);
  81.750 +
  81.751 +    if (ofd_size(oft) > oft_sz)
  81.752 +         of_panic("Could not fit all of native devtree\n");
  81.753 +
  81.754 +    boot_of_fixup_refs(oft);
  81.755 +    boot_of_fixup_chosen(oft);
  81.756 +
  81.757 +    if (ofd_size(oft) > oft_sz)
  81.758 +         of_panic("Could not fit all devtree fixups\n");
  81.759 +
  81.760 +    ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2);
  81.761 +
  81.762 +    mod->mod_start = (ulong)oft;
  81.763 +    mod->mod_end = mod->mod_start + oft_sz;
  81.764 +    of_printf("%s: devtree mod @ 0x%016x - 0x%016x\n", __func__,
  81.765 +              mod->mod_start, mod->mod_end);
  81.766 +
  81.767 +    return oft;
  81.768 +}
  81.769 +
  81.770 +static void * __init boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
  81.771 +{
  81.772 +    static module_t mods[4];
  81.773      ulong mod0_start;
  81.774      ulong mod0_size;
  81.775 -    static const char sepr[] = " -- ";
  81.776 +    static const char * sepr[] = {" -- ", " || "};
  81.777 +    int sepr_index;
  81.778      extern char dom0_start[] __attribute__ ((weak));
  81.779      extern char dom0_size[] __attribute__ ((weak));
  81.780 -    const char *p;
  81.781 +    const char *p = NULL;
  81.782 +    int mod;
  81.783 +    void *oft;
  81.784  
  81.785      if ((r3 > 0) && (r4 > 0)) {
  81.786          /* was it handed to us in registers ? */
  81.787 @@ -908,57 +1119,50 @@ static void boot_of_module(ulong r3, ulo
  81.788          of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
  81.789      }
  81.790  
  81.791 -    space_base = (ulong)_end;
  81.792 -    mods[0].mod_start = mod0_start;
  81.793 -    mods[0].mod_end = mod0_start + mod0_size;
  81.794 +    mod = 0;
  81.795 +    mods[mod].mod_start = mod0_start;
  81.796 +    mods[mod].mod_end = mod0_start + mod0_size;
  81.797  
  81.798 -    of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__,
  81.799 -              mods[0].mod_start, mods[0].mod_end);
  81.800 -    p = strstr((char *)(ulong)mbi->cmdline, sepr);
  81.801 -    if (p != NULL) {
  81.802 -        p += sizeof (sepr) - 1;
  81.803 -        mods[0].string = (u32)(ulong)p;
  81.804 -        of_printf("%s: mod[0].string: %s\n", __func__, p);
  81.805 +    of_printf("%s: dom0 mod @ 0x%016x[0x%x]\n", __func__,
  81.806 +              mods[mod].mod_start, mods[mod].mod_end);
  81.807 +
  81.808 +    /* look for delimiter: "--" or "||" */
  81.809 +    for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index++){
  81.810 +        p = strstr((char *)(ulong)mbi->cmdline, sepr[sepr_index]);
  81.811 +        if (p != NULL)
  81.812 +            break;
  81.813      }
  81.814  
  81.815 -    /* snapshot the tree */
  81.816 -    oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
  81.817 -    if (oft == 0)
  81.818 -        of_panic("Could not allocate OFD tree\n");
  81.819 -
  81.820 -    of_printf("creating oft\n");
  81.821 -    of_test("package-to-path");
  81.822 -    oft = ofd_create(oft, oft_sz);
  81.823 -    pkg_save(oft);
  81.824 -
  81.825 -    if (ofd_size(oft) > oft_sz)
  81.826 -         of_panic("Could not fit all of native devtree\n");
  81.827 +    if (p != NULL) {
  81.828 +        /* Xen proper should never know about the dom0 args.  */
  81.829 +        *(char *)p = '\0';
  81.830 +        p += strlen(sepr[sepr_index]);
  81.831 +        mods[mod].string = (u32)(ulong)p;
  81.832 +        of_printf("%s: dom0 mod string: %s\n", __func__, p);
  81.833 +    }
  81.834  
  81.835 -    boot_of_fixup_refs(oft);
  81.836 -    boot_of_fixup_chosen(oft);
  81.837 -
  81.838 -    if (ofd_size(oft) > oft_sz)
  81.839 -         of_panic("Could not fit all devtree fixups\n");
  81.840 +    ++mod;
  81.841 +    if (boot_of_rtas(&mods[mod], mbi))
  81.842 +        ++mod;
  81.843  
  81.844 -    ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
  81.845 +    oft = boot_of_devtree(&mods[mod], mbi);
  81.846 +    if (oft == NULL)
  81.847 +        of_panic("%s: boot_of_devtree failed\n", __func__);
  81.848  
  81.849 -    mods[1].mod_start = (ulong)oft;
  81.850 -    mods[1].mod_end = mods[1].mod_start + oft_sz;
  81.851 -    of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
  81.852 -              mods[1].mod_start, mods[1].mod_end);
  81.853 -
  81.854 +    ++mod;
  81.855  
  81.856      mbi->flags |= MBI_MODULES;
  81.857 -    mbi->mods_count = 2;
  81.858 +    mbi->mods_count = mod;
  81.859      mbi->mods_addr = (u32)mods;
  81.860  
  81.861 -    boot_of_serial(oft);
  81.862 +    return oft;
  81.863  }
  81.864  
  81.865  static int __init boot_of_cpus(void)
  81.866  {
  81.867 -    int cpus_node;
  81.868 -    int cpu_node, bootcpu_node, logical;
  81.869 +    int cpus_node, cpu_node;
  81.870 +    int bootcpu_instance, bootcpu_node;
  81.871 +    int logical;
  81.872      int result;
  81.873      s32 cpuid;
  81.874      u32 cpu_clock[2];
  81.875 @@ -967,9 +1171,13 @@ static int __init boot_of_cpus(void)
  81.876      /* Look up which CPU we are running on right now and get all info
  81.877       * from there */
  81.878      result = of_getprop(bof_chosen, "cpu",
  81.879 -                        &bootcpu_node, sizeof (bootcpu_node));
  81.880 +                        &bootcpu_instance, sizeof (bootcpu_instance));
  81.881      if (result == OF_FAILURE)
  81.882 -        of_panic("Failed to look up boot cpu\n");
  81.883 +        of_panic("Failed to look up boot cpu instance\n");
  81.884 +
  81.885 +    bootcpu_node = of_instance_to_package(bootcpu_instance);
  81.886 +    if (result == OF_FAILURE)
  81.887 +        of_panic("Failed to look up boot cpu package\n");
  81.888  
  81.889      cpu_node = bootcpu_node;
  81.890  
  81.891 @@ -1070,15 +1278,12 @@ static int __init boot_of_cpus(void)
  81.892      return 1;
  81.893  }
  81.894  
  81.895 -static int __init boot_of_rtas(void)
  81.896 -{
  81.897 -    return 1;
  81.898 -}
  81.899 -
  81.900  multiboot_info_t __init *boot_of_init(
  81.901          ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
  81.902  {
  81.903      static multiboot_info_t mbi;
  81.904 +    void *oft;
  81.905 +    int r;
  81.906  
  81.907      of_vec = vec;
  81.908      of_msr = orig_msr;
  81.909 @@ -1098,18 +1303,20 @@ multiboot_info_t __init *boot_of_init(
  81.910              r3, r4, vec, r6, r7, orig_msr);
  81.911  
  81.912      if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
  81.913 -        of_printf("Hmm.. OF[0x%lx] seems to have stepped on our image "
  81.914 -                "that ranges: %p .. %p.\n HANG!\n",
  81.915 +        of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
  81.916 +                "that ranges: %p .. %p.\n",
  81.917                  vec, _start, _end);
  81.918      }
  81.919      of_printf("%s: _start %p _end %p 0x%lx\n", __func__, _start, _end, r6);
  81.920  
  81.921      boot_of_fix_maple();
  81.922 -    boot_of_probemem(&mbi);
  81.923 +    r = boot_of_mem_init();
  81.924 +    if (r == 0)
  81.925 +        of_panic("failure to initialize memory allocator");
  81.926      boot_of_bootargs(&mbi);
  81.927 -    boot_of_module(r3, r4, &mbi);
  81.928 +    oft = boot_of_module(r3, r4, &mbi);
  81.929      boot_of_cpus();
  81.930 -    boot_of_rtas();
  81.931 +    boot_of_serial(oft);
  81.932  
  81.933      /* end of OF */
  81.934      of_printf("Quiescing Open Firmware ...\n");
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/xen/arch/powerpc/cmdline.c	Fri Dec 15 11:32:58 2006 -0700
    82.3 @@ -0,0 +1,24 @@
    82.4 +/*
    82.5 + * This program is free software; you can redistribute it and/or modify
    82.6 + * it under the terms of the GNU General Public License as published by
    82.7 + * the Free Software Foundation; either version 2 of the License, or
    82.8 + * (at your option) any later version.
    82.9 + *
   82.10 + * This program is distributed in the hope that it will be useful,
   82.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   82.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   82.13 + * GNU General Public License for more details.
   82.14 + *
   82.15 + * You should have received a copy of the GNU General Public License
   82.16 + * along with this program; if not, write to the Free Software
   82.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   82.18 + *
   82.19 + * Copyright (C) IBM Corp. 2006
   82.20 + *
   82.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   82.22 + */
   82.23 +
   82.24 +#include <asm/config.h>
   82.25 +
   82.26 +char builtin_cmdline[CONFIG_CMDLINE_SIZE] 
   82.27 +        __attribute__((section("__builtin_cmdline"))) = CMDLINE;
    83.1 --- a/xen/arch/powerpc/crash.c	Fri Dec 15 10:59:33 2006 -0700
    83.2 +++ b/xen/arch/powerpc/crash.c	Fri Dec 15 11:32:58 2006 -0700
    83.3 @@ -1,5 +1,6 @@
    83.4  #include <xen/lib.h>       /* for printk() used in stub */
    83.5  #include <xen/types.h>
    83.6 +#include <xen/kexec.h>
    83.7  #include <public/kexec.h>
    83.8  
    83.9  void machine_crash_shutdown(void)
    84.1 --- a/xen/arch/powerpc/dart.c	Fri Dec 15 10:59:33 2006 -0700
    84.2 +++ b/xen/arch/powerpc/dart.c	Fri Dec 15 11:32:58 2006 -0700
    84.3 @@ -60,8 +60,8 @@ union dart_entry {
    84.4      u32 de_word;
    84.5      struct {
    84.6          u32 de_v:1;             /* valid */
    84.7 -        u32 de_rp:1;             /* read protected*/
    84.8 -        u32 de_wp:1;             /* write protected*/
    84.9 +        u32 de_rp:1;             /* read protected */
   84.10 +        u32 de_wp:1;             /* write protected */
   84.11          u32 _de_res:5;
   84.12          u32 de_ppn:24;         /* 24 bit Physical Page Number
   84.13                                   * representing address [28:51] */
   84.14 @@ -98,7 +98,6 @@ static u32 dart_encode(int perm, ulong r
   84.15      if (perm & DART_WRITE) {
   84.16          e.de_bits.de_wp = 0;
   84.17      }
   84.18 -
   84.19      return e.de_word;
   84.20  }
   84.21  
   84.22 @@ -190,10 +189,8 @@ static int find_dart(struct dart_info *d
   84.23      ofdn_t n;
   84.24      char compat[128];
   84.25  
   84.26 -
   84.27 -    if (on_mambo()) {
   84.28 -        /* mambo has no dart */
   84.29 -        DBG("%s: Mambo does not support a dart\n", __func__);
   84.30 +    if (on_systemsim()) {
   84.31 +        DBG("%s: systemsim does not support a dart\n", __func__);
   84.32          return -1;
   84.33      }
   84.34  
   84.35 @@ -263,7 +260,7 @@ static int init_dart(void)
   84.36  
   84.37      /* Linux uses a dummy page, filling "empty" DART entries with a
   84.38         reference to this page to capture stray DMA's */
   84.39 -    dummy_page = (ulong)alloc_xenheap_pages(1);
   84.40 +    dummy_page = (ulong)alloc_xenheap_pages(0);
   84.41      clear_page((void *)dummy_page);
   84.42      dummy_page >>= PAGE_SHIFT;
   84.43  
    85.1 --- a/xen/arch/powerpc/dart_u4.c	Fri Dec 15 10:59:33 2006 -0700
    85.2 +++ b/xen/arch/powerpc/dart_u4.c	Fri Dec 15 11:32:58 2006 -0700
    85.3 @@ -19,6 +19,7 @@
    85.4   */
    85.5  
    85.6  #undef DEBUG
    85.7 +#define INVALIDATE_ALL
    85.8  
    85.9  #include <xen/config.h>
   85.10  #include <xen/types.h>
   85.11 @@ -123,9 +124,14 @@ static void u4_inv_all(void)
   85.12  
   85.13  static void u4_inv_entry(ulong pgn)
   85.14  {
   85.15 +#ifdef INVALIDATE_ALL
   85.16 +    return u4_inv_all();
   85.17 +#else
   85.18      union dart_ctl dc;
   85.19      ulong retries = 0;
   85.20  
   85.21 +    return u4_inv_all();
   85.22 +
   85.23      dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
   85.24      dc.dc_bits.dc_ilpn = pgn;
   85.25      dc.dc_bits.dc_ione = 1;
   85.26 @@ -139,6 +145,7 @@ static void u4_inv_entry(ulong pgn)
   85.27          if (retries > 1000000)
   85.28              panic("WAY! too long\n");
   85.29      } while (dc.dc_bits.dc_ione != 0);
   85.30 +#endif
   85.31  }
   85.32  
   85.33  static struct dart_ops u4_ops = {
    86.1 --- a/xen/arch/powerpc/delay.c	Fri Dec 15 10:59:33 2006 -0700
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,37 +0,0 @@
    86.4 -/*
    86.5 - * This program is free software; you can redistribute it and/or modify
    86.6 - * it under the terms of the GNU General Public License as published by
    86.7 - * the Free Software Foundation; either version 2 of the License, or
    86.8 - * (at your option) any later version.
    86.9 - *
   86.10 - * This program is distributed in the hope that it will be useful,
   86.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   86.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   86.13 - * GNU General Public License for more details.
   86.14 - *
   86.15 - * You should have received a copy of the GNU General Public License
   86.16 - * along with this program; if not, write to the Free Software
   86.17 - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   86.18 - *
   86.19 - * Copyright (C) IBM Corp. 2005
   86.20 - *
   86.21 - * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   86.22 - */
   86.23 -
   86.24 -#include <xen/config.h>
   86.25 -#include <xen/delay.h>
   86.26 -#include <xen/time.h>
   86.27 -#include <asm/processor.h>
   86.28 -
   86.29 -void udelay(unsigned long usecs)
   86.30 -{
   86.31 -    ulong ticks = usecs * ticks_per_usec;
   86.32 -    ulong s;
   86.33 -    ulong e;
   86.34 -
   86.35 -    s = get_timebase();
   86.36 -    do {
   86.37 -        asm volatile("or 1,1,1"); /* also puts the thread to low priority */
   86.38 -        e = get_timebase();
   86.39 -    } while ((e-s) < ticks);
   86.40 -}
    87.1 --- a/xen/arch/powerpc/domain.c	Fri Dec 15 10:59:33 2006 -0700
    87.2 +++ b/xen/arch/powerpc/domain.c	Fri Dec 15 11:32:58 2006 -0700
    87.3 @@ -33,6 +33,8 @@
    87.4  #include <asm/htab.h>
    87.5  #include <asm/current.h>
    87.6  #include <asm/hcalls.h>
    87.7 +#include "rtas.h"
    87.8 +#include "exceptions.h"
    87.9  
   87.10  #define next_arg(fmt, args) ({                                              \
   87.11      unsigned long __arg;                                                    \
   87.12 @@ -46,7 +48,6 @@
   87.13      }                                                                       \
   87.14      __arg;                                                                  \
   87.15  })
   87.16 -extern void idle_loop(void);
   87.17  
   87.18  unsigned long hypercall_create_continuation(unsigned int op,
   87.19          const char *format, ...)
   87.20 @@ -87,26 +88,44 @@ int arch_domain_create(struct domain *d)
   87.21  
   87.22      INIT_LIST_HEAD(&d->arch.extent_list);
   87.23  
   87.24 +    d->arch.foreign_mfn_count = 1024;
   87.25 +    d->arch.foreign_mfns = xmalloc_array(uint, d->arch.foreign_mfn_count);
   87.26 +    BUG_ON(d->arch.foreign_mfns == NULL);
   87.27 +
   87.28 +    memset(d->arch.foreign_mfns, -1, d->arch.foreign_mfn_count * sizeof(uint));
   87.29 +
   87.30      return 0;
   87.31  }
   87.32  
   87.33  void arch_domain_destroy(struct domain *d)
   87.34  {
   87.35      shadow_teardown(d);
   87.36 +    /* shared_info is part of the RMA so no need to release it */
   87.37  }
   87.38  
   87.39 +static void machine_fail(const char *s)
   87.40 +{
   87.41 +    printk("%s failed, manual powercycle required!\n", s);
   87.42 +    for (;;)
   87.43 +        sleep();
   87.44 +}
   87.45  void machine_halt(void)
   87.46  {
   87.47      printk("machine_halt called: spinning....\n");
   87.48      console_start_sync();
   87.49 -    while(1);
   87.50 +    printk("%s called\n", __func__);
   87.51 +    rtas_halt();
   87.52 +
   87.53 +    machine_fail(__func__);
   87.54  }
   87.55  
   87.56  void machine_restart(char * __unused)
   87.57  {
   87.58      printk("machine_restart called: spinning....\n");
   87.59      console_start_sync();
   87.60 -    while(1);
   87.61 +    printk("%s called\n", __func__);
   87.62 +    rtas_reboot();
   87.63 +    machine_fail(__func__);
   87.64  }
   87.65  
   87.66  struct vcpu *alloc_vcpu_struct(void)
   87.67 @@ -222,6 +241,7 @@ void context_switch(struct vcpu *prev, s
   87.68  
   87.69      mtsdr1(next->domain->arch.htab.sdr1);
   87.70      local_flush_tlb(); /* XXX maybe flush_tlb_mask? */
   87.71 +    cpu_flush_icache();
   87.72  
   87.73      if (is_idle_vcpu(next)) {
   87.74          reset_stack_and_jump(idle_loop);
   87.75 @@ -278,8 +298,10 @@ static void relinquish_memory(struct dom
   87.76  
   87.77  void domain_relinquish_resources(struct domain *d)
   87.78  {
   87.79 +    relinquish_memory(d, &d->xenpage_list);
   87.80      relinquish_memory(d, &d->page_list);
   87.81      free_extents(d);
   87.82 +    xfree(d->arch.foreign_mfns);
   87.83      return;
   87.84  }
   87.85  
   87.86 @@ -291,7 +313,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
   87.87  {
   87.88  }
   87.89  
   87.90 -extern void sleep(void);
   87.91  static void safe_halt(void)
   87.92  {
   87.93      int cpu = smp_processor_id();
    88.1 --- a/xen/arch/powerpc/domain_build.c	Fri Dec 15 10:59:33 2006 -0700
    88.2 +++ b/xen/arch/powerpc/domain_build.c	Fri Dec 15 11:32:58 2006 -0700
    88.3 @@ -178,8 +178,7 @@ int construct_dom0(struct domain *d,
    88.4          shadow_set_allocation(d, opt_dom0_shadow, &preempt);
    88.5      } while (preempt);
    88.6      if (shadow_get_allocation(d) == 0)
    88.7 -        panic("shadow allocation failed 0x%x < 0x%x\n",
    88.8 -              shadow_get_allocation(d), opt_dom0_shadow);
    88.9 +        panic("shadow allocation failed: %dMib\n", opt_dom0_shadow);
   88.10  
   88.11      ASSERT( image_len < rma_sz );
   88.12  
    89.1 --- a/xen/arch/powerpc/domctl.c	Fri Dec 15 10:59:33 2006 -0700
    89.2 +++ b/xen/arch/powerpc/domctl.c	Fri Dec 15 11:32:58 2006 -0700
    89.3 @@ -96,14 +96,14 @@ long arch_do_domctl(struct xen_domctl *d
    89.4      case XEN_DOMCTL_real_mode_area:
    89.5      {
    89.6          struct domain *d;
    89.7 -        unsigned int log = domctl->u.real_mode_area.log;
    89.8 +        unsigned int order = domctl->u.real_mode_area.log - PAGE_SHIFT;
    89.9  
   89.10          ret = -ESRCH;
   89.11          d = find_domain_by_id(domctl->domain);
   89.12          if (d != NULL) {
   89.13              ret = -EINVAL;
   89.14 -            if (cpu_rma_valid(log))
   89.15 -                ret = allocate_rma(d, log - PAGE_SHIFT);
   89.16 +            if (cpu_rma_valid(order))
   89.17 +                ret = allocate_rma(d, order);
   89.18              put_domain(d);
   89.19          }
   89.20      }
    90.1 --- a/xen/arch/powerpc/exceptions.c	Fri Dec 15 10:59:33 2006 -0700
    90.2 +++ b/xen/arch/powerpc/exceptions.c	Fri Dec 15 11:32:58 2006 -0700
    90.3 @@ -25,8 +25,10 @@
    90.4  #include <xen/serial.h>
    90.5  #include <xen/gdbstub.h>
    90.6  #include <xen/console.h>
    90.7 +#include <xen/shutdown.h>
    90.8  #include <asm/time.h>
    90.9  #include <asm/processor.h>
   90.10 +#include <asm/debugger.h>
   90.11  
   90.12  #undef DEBUG
   90.13  
   90.14 @@ -56,25 +58,19 @@ void do_dec(struct cpu_user_regs *regs)
   90.15  
   90.16  void program_exception(struct cpu_user_regs *regs, unsigned long cookie)
   90.17  {
   90.18 -#ifdef CRASH_DEBUG
   90.19 -    __trap_to_gdb(regs, cookie);
   90.20 -#else /* CRASH_DEBUG */
   90.21 -    int recover = 0;
   90.22 -
   90.23 -    console_start_sync();
   90.24 +    if (cookie == 0x200) {
   90.25 +        if (cpu_machinecheck(regs))
   90.26 +            return;
   90.27  
   90.28 -    show_registers(regs);
   90.29 -    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
   90.30 -    printk("hid4 0x%016lx\n", regs->hid4);
   90.31 -    printk("---[ backtrace ]---\n");
   90.32 -    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
   90.33 +        printk("%s: machine check\n", __func__);
   90.34 +    } else {
   90.35 +#ifdef CRASH_DEBUG
   90.36 +        if (__trap_to_gdb(regs, cookie) == 0)
   90.37 +            return;
   90.38 +#endif /* CRASH_DEBUG */
   90.39  
   90.40 -    if (cookie == 0x200)
   90.41 -        recover = cpu_machinecheck(regs);
   90.42 -
   90.43 -    if (!recover)
   90.44 -        panic("%s: 0x%lx\n", __func__, cookie);
   90.45 -
   90.46 -    console_end_sync();
   90.47 -#endif /* CRASH_DEBUG */
   90.48 +        printk("%s: type: 0x%lx\n", __func__, cookie);
   90.49 +        show_backtrace_regs(regs);
   90.50 +    }
   90.51 +    machine_halt();
   90.52  }
    91.1 --- a/xen/arch/powerpc/exceptions.h	Fri Dec 15 10:59:33 2006 -0700
    91.2 +++ b/xen/arch/powerpc/exceptions.h	Fri Dec 15 11:32:58 2006 -0700
    91.3 @@ -43,13 +43,14 @@ extern void program_exception(
    91.4      struct cpu_user_regs *regs, unsigned long cookie);
    91.5  
    91.6  extern long xen_hvcall_jump(struct cpu_user_regs *regs, ulong address);
    91.7 -extern void *mambo_memset(void *, int, ulong);
    91.8 -extern void *mambo_memcpy(void *, const void *, ulong);
    91.9 +
   91.10 +extern void sleep(void);
   91.11 +extern void idle_loop(void);
   91.12  
   91.13  extern ulong *__hypercall_table[];
   91.14  
   91.15  extern char exception_vectors[];
   91.16  extern char exception_vectors_end[];
   91.17  extern int spin_start[];
   91.18 -extern int secondary_cpu_init(int cpuid, unsigned long r4);
   91.19 +extern void secondary_cpu_init(int cpuid, unsigned long r4);
   91.20  #endif
    92.1 --- a/xen/arch/powerpc/external.c	Fri Dec 15 10:59:33 2006 -0700
    92.2 +++ b/xen/arch/powerpc/external.c	Fri Dec 15 11:32:58 2006 -0700
    92.3 @@ -82,7 +82,14 @@ void do_external(struct cpu_user_regs *r
    92.4  
    92.5      vec = xen_mpic_get_irq(regs);
    92.6  
    92.7 -    if (vec != -1) {
    92.8 +    if (irq_desc[vec].status & IRQ_PER_CPU) {
    92.9 +        /* x86 do_IRQ does not respect the per cpu flag.  */
   92.10 +        irq_desc_t *desc = &irq_desc[vec];
   92.11 +        regs->entry_vector = vec;
   92.12 +        desc->handler->ack(vec);
   92.13 +        desc->action->handler(vector_to_irq(vec), desc->action->dev_id, regs);
   92.14 +        desc->handler->end(vec);
   92.15 +    } else if (vec != -1) {
   92.16          DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
   92.17          regs->entry_vector = vec;
   92.18          do_IRQ(regs);
   92.19 @@ -253,3 +260,24 @@ int ioapic_guest_write(unsigned long phy
   92.20      BUG_ON(val != val);
   92.21      return 0;
   92.22  }
   92.23 +
   92.24 +void send_IPI_mask(cpumask_t mask, int vector)
   92.25 +{
   92.26 +    unsigned int cpus;
   92.27 +    int const bits = 8 * sizeof(cpus);
   92.28 +
   92.29 +    switch(vector) {
   92.30 +    case CALL_FUNCTION_VECTOR:
   92.31 +    case EVENT_CHECK_VECTOR:
   92.32 +        break;
   92.33 +    default:
   92.34 +        BUG();
   92.35 +        return;
   92.36 +    }
   92.37 +
   92.38 +    BUG_ON(NR_CPUS > bits);
   92.39 +    BUG_ON(fls(mask.bits[0]) > bits);
   92.40 +
   92.41 +    cpus = mask.bits[0];
   92.42 +    mpic_send_ipi(vector, cpus);
   92.43 +}
    93.1 --- a/xen/arch/powerpc/gdbstub.c	Fri Dec 15 10:59:33 2006 -0700
    93.2 +++ b/xen/arch/powerpc/gdbstub.c	Fri Dec 15 11:32:58 2006 -0700
    93.3 @@ -25,6 +25,7 @@
    93.4  #include <asm/msr.h>
    93.5  #include <asm/bitops.h>
    93.6  #include <asm/cache.h>
    93.7 +#include <asm/debugger.h>
    93.8  #include <asm/processor.h>
    93.9  
   93.10  asm(".globl trap_instruction\n"
    94.1 --- a/xen/arch/powerpc/iommu.c	Fri Dec 15 10:59:33 2006 -0700
    94.2 +++ b/xen/arch/powerpc/iommu.c	Fri Dec 15 11:32:58 2006 -0700
    94.3 @@ -32,6 +32,12 @@
    94.4  #include "tce.h"
    94.5  #include "iommu.h"
    94.6  
    94.7 +#ifdef DEBUG
    94.8 +#define DBG(fmt...) printk(fmt)
    94.9 +#else
   94.10 +#define DBG(fmt...)
   94.11 +#endif
   94.12 +
   94.13  struct iommu_funcs {
   94.14      int (*iommu_put)(ulong, union tce);
   94.15  };
   94.16 @@ -46,17 +52,31 @@ int iommu_put(u32 buid, ulong ioba, unio
   94.17      struct domain *d = v->domain;
   94.18  
   94.19      if (buid < iommu_phbs_num && iommu_phbs[buid].iommu_put != NULL) {
   94.20 -        ulong pfn;
   94.21 +        ulong gmfn;
   94.22          ulong mfn;
   94.23          int mtype;
   94.24  
   94.25 -        pfn = tce.tce_bits.tce_rpn;
   94.26 -        mfn = pfn2mfn(d, pfn, &mtype);
   94.27 +        gmfn = tce.tce_bits.tce_rpn;
   94.28 +
   94.29 +        
   94.30 +        mfn = pfn2mfn(d, gmfn, &mtype);
   94.31          if (mfn != INVALID_MFN) {
   94.32 -#ifdef DEBUG
   94.33 -            printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
   94.34 -                   ioba, pfn, mfn);
   94.35 -#endif
   94.36 +            switch (mtype) {
   94.37 +            case PFN_TYPE_RMA:
   94.38 +            case PFN_TYPE_LOGICAL:
   94.39 +                break;
   94.40 +            case PFN_TYPE_FOREIGN:
   94.41 +                DBG("%s: assigning to Foriegn page: "
   94.42 +                    "gmfn: 0x%lx mfn: 0x%lx\n",  __func__, gmfn, mfn);
   94.43 +                break;
   94.44 +            default:
   94.45 +                printk("%s: unsupported type[%d]: gmfn: 0x%lx mfn: 0x%lx\n",
   94.46 +                       __func__, mtype, gmfn, mfn);
   94.47 +                return -1;
   94.48 +            break;
   94.49 +            }
   94.50 +            DBG("%s: ioba=0x%lx gmfn=0x%lx mfn=0x%lx\n", __func__,
   94.51 +                ioba, gmfn, mfn);
   94.52              tce.tce_bits.tce_rpn = mfn;
   94.53              return iommu_phbs[buid].iommu_put(ioba, tce);
   94.54          }
    95.1 --- a/xen/arch/powerpc/machine_kexec.c	Fri Dec 15 10:59:33 2006 -0700
    95.2 +++ b/xen/arch/powerpc/machine_kexec.c	Fri Dec 15 11:32:58 2006 -0700
    95.3 @@ -1,5 +1,6 @@
    95.4  #include <xen/lib.h>       /* for printk() used in stubs */
    95.5  #include <xen/types.h>
    95.6 +#include <xen/kexec.h>
    95.7  #include <public/kexec.h>
    95.8  
    95.9  int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
   95.10 @@ -13,11 +14,6 @@ void machine_kexec_unload(int type, int 
   95.11      printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   95.12  }
   95.13  
   95.14 -void machine_kexec(xen_kexec_image_t *image)
   95.15 -{
   95.16 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   95.17 -}
   95.18 -
   95.19  void machine_reboot_kexec(xen_kexec_image_t *image)
   95.20  {
   95.21      printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    96.1 --- a/xen/arch/powerpc/mambo.S	Fri Dec 15 10:59:33 2006 -0700
    96.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.3 @@ -1,64 +0,0 @@
    96.4 -/*
    96.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    96.6 - *
    96.7 - * This program is free software; you can redistribute it and/or modify
    96.8 - * it under the terms of the GNU General Public License as published by
    96.9 - * the Free Software Foundation; either version 2 of the License, or
   96.10 - * (at your option) any later version.
   96.11 - * 
   96.12 - * This program is distributed in the hope that it will be useful,
   96.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   96.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   96.15 - * GNU General Public License for more details.
   96.16 - * 
   96.17 - * You should have received a copy of the GNU General Public License
   96.18 - * along with this program; if not, write to the Free Software
   96.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   96.20 - *
   96.21 - */
   96.22 -
   96.23 -#include <asm/config.h>
   96.24 -#include <asm/processor.h>
   96.25 -
   96.26 -_GLOBAL(mambo_callthru)
   96.27 -	.long 0x000eaeb0
   96.28 -	blr
   96.29 -
   96.30 -_GLOBAL(mambo_write)
   96.31 -	mr	r5, r4
   96.32 -	mr	r4, r3
   96.33 -	li	r3, 0		# Write console code
   96.34 -	
   96.35 -	li	r6, 0
   96.36 -	/* need to fix return value */
   96.37 -	mflr	r7
   96.38 -	bl	_ENTRY(mambo_callthru)
   96.39 -	mtlr	r7
   96.40 -	mr	r3, r5
   96.41 -	blr
   96.42 -
   96.43 -_GLOBAL(mambo_memset)
   96.44 -	mr	r6, r5
   96.45 -	mr	r5, r4
   96.46 -	mr	r4, r3
   96.47 -	li	r3, 0x47	# memset
   96.48 -	/* need to fix return value */
   96.49 -	mflr	r7
   96.50 -	bl	_ENTRY(mambo_callthru)
   96.51 -	mtlr	r7
   96.52 -	mr	r3, r4
   96.53 -	blr
   96.54 -
   96.55 -_GLOBAL(mambo_memcpy)
   96.56 -	mr	r6, r5
   96.57 -	mr	r5, r4
   96.58 -	mr	r4, r3
   96.59 -	li	r3, 0x45 # memcpy
   96.60 -	/* need to fix return value */
   96.61 -	mflr	r7
   96.62 -	bl	_ENTRY(mambo_callthru)
   96.63 -	mtlr	r7
   96.64 -	mr	r3, r4
   96.65 -	blr
   96.66 -
   96.67 -	
    97.1 --- a/xen/arch/powerpc/memory.c	Fri Dec 15 10:59:33 2006 -0700
    97.2 +++ b/xen/arch/powerpc/memory.c	Fri Dec 15 11:32:58 2006 -0700
    97.3 @@ -20,10 +20,31 @@
    97.4   */
    97.5  #include <xen/sched.h>
    97.6  #include <xen/mm.h>
    97.7 +#include <xen/numa.h>
    97.8  #include "of-devtree.h"
    97.9  #include "oftree.h"
   97.10 +#include "rtas.h"
   97.11 +
   97.12 +#undef DEBUG
   97.13 +#ifdef DEBUG
   97.14 +#define DBG(fmt...) printk(fmt)
   97.15 +#else
   97.16 +#define DBG(fmt...)
   97.17 +#endif
   97.18 +
   97.19 +/*
   97.20 + * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
   97.21 + * page_info table and allocation bitmap.
   97.22 + */
   97.23 +static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
   97.24 +integer_param("xenheap_megabytes", opt_xenheap_megabytes);
   97.25  
   97.26  unsigned long xenheap_phys_end;
   97.27 +static uint nr_pages;
   97.28 +static ulong xenheap_size;
   97.29 +static ulong save_start;
   97.30 +static ulong save_end;
   97.31 +
   97.32  struct membuf {
   97.33      ulong start;
   97.34      ulong size;
   97.35 @@ -36,15 +57,20 @@ static ulong free_xenheap(ulong start, u
   97.36      start = ALIGN_UP(start, PAGE_SIZE);
   97.37      end = ALIGN_DOWN(end, PAGE_SIZE);
   97.38  
   97.39 -    printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
   97.40 +    DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
   97.41  
   97.42 -    if (oftree <= end && oftree >= start) {
   97.43 -        printk("%s:     Go around the devtree: 0x%lx - 0x%lx\n",
   97.44 -               __func__, oftree, oftree_end);
   97.45 -        init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE));
   97.46 -        init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end);
   97.47 +    /* need to do this better */
   97.48 +    if (save_start <= end && save_start >= start) {
   97.49 +        DBG("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
   97.50 +               __func__, save_start, save_end);
   97.51 +        init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
   97.52 +        xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
   97.53 +
   97.54 +        init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
   97.55 +        xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
   97.56      } else {
   97.57          init_xenheap_pages(start, end);
   97.58 +        xenheap_size += end - start;
   97.59      }
   97.60  
   97.61      return ALIGN_UP(end, PAGE_SIZE);
   97.62 @@ -57,8 +83,10 @@ static void set_max_page(struct membuf *
   97.63      for (i = 0; i < entries; i++) {
   97.64          ulong end_page;
   97.65  
   97.66 +        printk("  %016lx: %016lx\n", mb[i].start, mb[i].size);
   97.67 +        nr_pages += mb[i].size >> PAGE_SHIFT;
   97.68 +
   97.69          end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
   97.70 -
   97.71          if (end_page > max_page)
   97.72              max_page = end_page;
   97.73      }
   97.74 @@ -71,11 +99,11 @@ static void heap_init(struct membuf *mb,
   97.75      ulong start_blk;
   97.76      ulong end_blk = 0;
   97.77  
   97.78 -	for (i = 0; i < entries; i++) {
   97.79 -	    start_blk = mb[i].start;
   97.80 -	    end_blk = start_blk + mb[i].size;
   97.81 +    for (i = 0; i < entries; i++) {
   97.82 +        start_blk = mb[i].start;
   97.83 +        end_blk = start_blk + mb[i].size;
   97.84  
   97.85 -	    if (start_blk < xenheap_phys_end) {
   97.86 +        if (start_blk < xenheap_phys_end) {
   97.87              if (xenheap_phys_end > end_blk) {
   97.88                  panic("xenheap spans LMB\n");
   97.89              }
   97.90 @@ -87,7 +115,7 @@ static void heap_init(struct membuf *mb,
   97.91  
   97.92          init_boot_pages(start_blk, end_blk);
   97.93          total_pages += (end_blk - start_blk) >> PAGE_SHIFT;
   97.94 -	}
   97.95 +    }
   97.96  }
   97.97  
   97.98  static void ofd_walk_mem(void *m, walk_mem_fn fn)
   97.99 @@ -123,7 +151,7 @@ static void setup_xenheap(module_t *mod,
  97.100      for (i = 0; i < mcount; i++) {
  97.101          u32 s;
  97.102  
  97.103 -        if(mod[i].mod_end == mod[i].mod_start)
  97.104 +        if (mod[i].mod_end == mod[i].mod_start)
  97.105              continue;
  97.106  
  97.107          s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
  97.108 @@ -149,19 +177,42 @@ static void setup_xenheap(module_t *mod,
  97.109  void memory_init(module_t *mod, int mcount)
  97.110  {
  97.111      ulong eomem;
  97.112 -    ulong heap_start, heap_size;
  97.113 -
  97.114 -    printk("Physical RAM map:\n");
  97.115 +    ulong heap_start;
  97.116 +    ulong xh_pages;
  97.117  
  97.118      /* lets find out how much memory there is and set max_page */
  97.119      max_page = 0;
  97.120 +    printk("Physical RAM map:\n");
  97.121      ofd_walk_mem((void *)oftree, set_max_page);
  97.122      eomem = max_page << PAGE_SHIFT;
  97.123  
  97.124      if (eomem == 0){
  97.125          panic("ofd_walk_mem() failed\n");
  97.126      }
  97.127 -    printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
  97.128 +
  97.129 +    /* find the portion of memory we need to keep safe */
  97.130 +    save_start = oftree;
  97.131 +    save_end = oftree_end;
  97.132 +    if (rtas_base) {
  97.133 +        if (save_start > rtas_base)
  97.134 +            save_start = rtas_base;
  97.135 +        if (save_end < rtas_end)
  97.136 +            save_end = rtas_end;
  97.137 +    }
  97.138 +
  97.139 +    /* minimum heap has to reach to the end of all Xen required memory */
  97.140 +    xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
  97.141 +    xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
  97.142 +
  97.143 +    /* While we are allocating HTABS from The Xen Heap we need it to
  97.144 +     * be larger */
  97.145 +    xh_pages  += nr_pages >> 5;
  97.146 +
  97.147 +    xenheap_phys_end = xh_pages << PAGE_SHIFT;
  97.148 +    printk("End of Xen Area: %luMiB (%luKiB)\n",
  97.149 +           xenheap_phys_end >> 20, xenheap_phys_end >> 10);
  97.150 +
  97.151 +    printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
  97.152  
  97.153      /* Architecturally the first 4 pages are exception hendlers, we
  97.154       * will also be copying down some code there */
  97.155 @@ -185,22 +236,23 @@ void memory_init(module_t *mod, int mcou
  97.156          panic("total_pages > max_page: 0x%lx > 0x%lx\n",
  97.157                total_pages, max_page);
  97.158  
  97.159 -    printk("total_pages: 0x%016lx\n", total_pages);
  97.160 +    DBG("total_pages: 0x%016lx\n", total_pages);
  97.161  
  97.162      init_frametable();
  97.163 +
  97.164 +    numa_initmem_init(0, max_page);
  97.165 +
  97.166      end_boot_allocator();
  97.167  
  97.168      /* Add memory between the beginning of the heap and the beginning
  97.169 -     * of out text */
  97.170 +     * of our text */
  97.171      free_xenheap(heap_start, (ulong)_start);
  97.172 -
  97.173 -    heap_size = xenheap_phys_end - heap_start;
  97.174 -    printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
  97.175 -
  97.176      setup_xenheap(mod, mcount);
  97.177 +    printk("Xen Heap: %luMiB (%luKiB)\n",
  97.178 +           xenheap_size >> 20, xenheap_size >> 10);
  97.179  
  97.180      eomem = avail_domheap_pages();
  97.181 -    printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
  97.182 +    printk("Dom Heap: %luMiB (%luKiB)\n",
  97.183             (eomem << PAGE_SHIFT) >> 20,
  97.184             (eomem << PAGE_SHIFT) >> 10);
  97.185  }
    98.1 --- a/xen/arch/powerpc/mm.c	Fri Dec 15 10:59:33 2006 -0700
    98.2 +++ b/xen/arch/powerpc/mm.c	Fri Dec 15 11:32:58 2006 -0700
    98.3 @@ -25,9 +25,9 @@
    98.4  #include <xen/kernel.h>
    98.5  #include <xen/sched.h>
    98.6  #include <xen/perfc.h>
    98.7 -#include <asm/misc.h>
    98.8  #include <asm/init.h>
    98.9  #include <asm/page.h>
   98.10 +#include <asm/string.h>
   98.11  
   98.12  #ifdef VERBOSE
   98.13  #define MEM_LOG(_f, _a...)                                  \
   98.14 @@ -42,18 +42,129 @@ struct page_info *frame_table;
   98.15  unsigned long max_page;
   98.16  unsigned long total_pages;
   98.17  
   98.18 +void __init init_frametable(void)
   98.19 +{
   98.20 +    unsigned long p;
   98.21 +    unsigned long nr_pages;
   98.22 +    int i;
   98.23 +
   98.24 +    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
   98.25 +
   98.26 +    p = alloc_boot_pages(nr_pages, 1);
   98.27 +    if (p == 0)
   98.28 +        panic("Not enough memory for frame table\n");
   98.29 +
   98.30 +    frame_table = (struct page_info *)(p << PAGE_SHIFT);
   98.31 +    for (i = 0; i < nr_pages; i += 1)
   98.32 +        clear_page((void *)((p + i) << PAGE_SHIFT));
   98.33 +}
   98.34 +
   98.35 +void share_xen_page_with_guest(
   98.36 +    struct page_info *page, struct domain *d, int readonly)
   98.37 +{
   98.38 +    if ( page_get_owner(page) == d )
   98.39 +        return;
   98.40 +
   98.41 +    /* this causes us to leak pages in the Domain and reuslts in
   98.42 +     * Zombie domains, I think we are missing a piece, until we find
   98.43 +     * it we disable the following code */
   98.44 +    set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
   98.45 +
   98.46 +    spin_lock(&d->page_alloc_lock);
   98.47 +
   98.48 +    /* The incremented type count pins as writable or read-only. */
   98.49 +    page->u.inuse.type_info  = (readonly ? PGT_none : PGT_writable_page);
   98.50 +    page->u.inuse.type_info |= PGT_validated | 1;
   98.51 +
   98.52 +    page_set_owner(page, d);
   98.53 +    wmb(); /* install valid domain ptr before updating refcnt. */
   98.54 +    ASSERT(page->count_info == 0);
   98.55 +    page->count_info |= PGC_allocated | 1;
   98.56 +
   98.57 +    if ( unlikely(d->xenheap_pages++ == 0) )
   98.58 +        get_knownalive_domain(d);
   98.59 +    list_add_tail(&page->list, &d->xenpage_list);
   98.60 +
   98.61 +    spin_unlock(&d->page_alloc_lock);
   98.62 +}
   98.63 +
   98.64 +void share_xen_page_with_privileged_guests(
   98.65 +    struct page_info *page, int readonly)
   98.66 +{
   98.67 +        unimplemented();
   98.68 +}
   98.69 +
   98.70 +static ulong foreign_to_mfn(struct domain *d, ulong pfn)
   98.71 +{
   98.72 +
   98.73 +    pfn -= 1UL << cpu_foreign_map_order();
   98.74 +
   98.75 +    BUG_ON(pfn >= d->arch.foreign_mfn_count);
   98.76 +
   98.77 +    return d->arch.foreign_mfns[pfn];
   98.78 +}
   98.79 +
   98.80 +static int set_foreign(struct domain *d, ulong pfn, ulong mfn)
   98.81 +{
   98.82 +    pfn -= 1UL << cpu_foreign_map_order();
   98.83 +
   98.84 +    BUG_ON(pfn >= d->arch.foreign_mfn_count);
   98.85 +    d->arch.foreign_mfns[pfn] = mfn;
   98.86 +
   98.87 +    return 0;
   98.88 +}
   98.89 +
   98.90 +static int create_grant_va_mapping(
   98.91 +    unsigned long va, unsigned long frame, struct vcpu *v)
   98.92 +{
   98.93 +    if (v->domain->domain_id != 0) {
   98.94 +        printk("only Dom0 can map a grant entry\n");
   98.95 +        BUG();
   98.96 +        return GNTST_permission_denied;
   98.97 +    }
   98.98 +    set_foreign(v->domain, va >> PAGE_SHIFT, frame);
   98.99 +    return GNTST_okay;
  98.100 +}
  98.101 +
  98.102 +static int destroy_grant_va_mapping(
  98.103 +    unsigned long addr, unsigned long frame, struct domain *d)
  98.104 +{
  98.105 +    if (d->domain_id != 0) {
  98.106 +        printk("only Dom0 can map a grant entry\n");
  98.107 +        BUG();
  98.108 +        return GNTST_permission_denied;
  98.109 +    }
  98.110 +    set_foreign(d, addr >> PAGE_SHIFT, ~0UL);
  98.111 +    return GNTST_okay;
  98.112 +}
  98.113 +
  98.114  int create_grant_host_mapping(
  98.115      unsigned long addr, unsigned long frame, unsigned int flags)
  98.116  {
  98.117 -    panic("%s called\n", __func__);
  98.118 -    return 1;
  98.119 +    if (flags & GNTMAP_application_map) {
  98.120 +        printk("%s: GNTMAP_application_map not supported\n", __func__);
  98.121 +        BUG();
  98.122 +        return GNTST_general_error;
  98.123 +    }
  98.124 +    if (flags & GNTMAP_contains_pte) {
  98.125 +        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
  98.126 +        BUG();
  98.127 +        return GNTST_general_error;
  98.128 +    }
  98.129 +    return create_grant_va_mapping(addr, frame, current);
  98.130  }
  98.131  
  98.132  int destroy_grant_host_mapping(
  98.133      unsigned long addr, unsigned long frame, unsigned int flags)
  98.134  {
  98.135 -    panic("%s called\n", __func__);
  98.136 -    return 1;
  98.137 +    if (flags & GNTMAP_contains_pte) {
  98.138 +        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
  98.139 +        BUG();
  98.140 +        return GNTST_general_error;
  98.141 +    }
  98.142 +
  98.143 +    /* may have force the remove here */
  98.144 +    return destroy_grant_va_mapping(addr, frame, current->domain);
  98.145  }
  98.146  
  98.147  int steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
  98.148 @@ -139,7 +250,7 @@ int get_page_type(struct page_info *page
  98.149          {
  98.150              return 0;
  98.151          }
  98.152 -        if ( unlikely(!(x & PGT_validated)) )
  98.153 +        else if ( unlikely(!(x & PGT_validated)) )
  98.154          {
  98.155              /* Someone else is updating validation of this page. Wait... */
  98.156              while ( (y = page->u.inuse.type_info) == x )
  98.157 @@ -158,25 +269,6 @@ int get_page_type(struct page_info *page
  98.158      return 1;
  98.159  }
  98.160  
  98.161 -void __init init_frametable(void)
  98.162 -{
  98.163 -    unsigned long p;
  98.164 -    unsigned long nr_pages;
  98.165 -    int i;
  98.166 -
  98.167 -    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
  98.168 -    nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT)));
  98.169 -    
  98.170 -
  98.171 -    p = alloc_boot_pages(nr_pages, 1);
  98.172 -    if (p == 0)
  98.173 -        panic("Not enough memory for frame table\n");
  98.174 -
  98.175 -    frame_table = (struct page_info *)(p << PAGE_SHIFT);
  98.176 -    for (i = 0; i < nr_pages; i += 1)
  98.177 -        clear_page((void *)((p + i) << PAGE_SHIFT));
  98.178 -}
  98.179 -
  98.180  long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
  98.181  {
  98.182      printk("%s: no PPC specific memory ops\n", __func__);
  98.183 @@ -185,29 +277,28 @@ long arch_memory_op(int op, XEN_GUEST_HA
  98.184  
  98.185  extern void copy_page(void *dp, void *sp)
  98.186  {
  98.187 -    if (on_mambo()) {
  98.188 -        extern void *mambo_memcpy(void *,const void *,__kernel_size_t);
  98.189 -        mambo_memcpy(dp, sp, PAGE_SIZE);
  98.190 +    if (on_systemsim()) {
  98.191 +        systemsim_memcpy(dp, sp, PAGE_SIZE);
  98.192      } else {
  98.193          memcpy(dp, sp, PAGE_SIZE);
  98.194      }
  98.195  }
  98.196  
  98.197 +/* XXX should probably replace with faster data structure */
  98.198  static uint add_extent(struct domain *d, struct page_info *pg, uint order)
  98.199  {
  98.200      struct page_extents *pe;
  98.201  
  98.202      pe = xmalloc(struct page_extents);
  98.203      if (pe == NULL)
  98.204 -        return 0;
  98.205 +        return -ENOMEM;
  98.206  
  98.207      pe->pg = pg;
  98.208      pe->order = order;
  98.209 -    pe->pfn = page_to_mfn(pg);
  98.210  
  98.211      list_add_tail(&pe->pe_list, &d->arch.extent_list);
  98.212  
  98.213 -    return pe->pfn;
  98.214 +    return 0;
  98.215  }
  98.216  
  98.217  void free_extents(struct domain *d)
  98.218 @@ -246,7 +337,7 @@ uint allocate_extents(struct domain *d, 
  98.219          if (pg == NULL)
  98.220              return total_nrpages;
  98.221  
  98.222 -        if (add_extent(d, pg, ext_order) == 0) {
  98.223 +        if (add_extent(d, pg, ext_order) < 0) {
  98.224              free_domheap_pages(pg, ext_order);
  98.225              return total_nrpages;
  98.226          }
  98.227 @@ -299,6 +390,7 @@ int allocate_rma(struct domain *d, unsig
  98.228  
  98.229      return 0;
  98.230  }
  98.231 +
  98.232  void free_rma_check(struct page_info *page)
  98.233  {
  98.234      if (test_bit(_PGC_page_RMA, &page->count_info) &&
  98.235 @@ -306,7 +398,6 @@ void free_rma_check(struct page_info *pa
  98.236          panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
  98.237  }
  98.238  
  98.239 -
  98.240  ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
  98.241  {
  98.242      ulong rma_base_mfn = page_to_mfn(d->arch.rma_page);
  98.243 @@ -314,9 +405,17 @@ ulong pfn2mfn(struct domain *d, ulong pf
  98.244      struct page_extents *pe;
  98.245      ulong mfn = INVALID_MFN;
  98.246      int t = PFN_TYPE_NONE;
  98.247 +    ulong foreign_map_pfn = 1UL << cpu_foreign_map_order();
  98.248  
  98.249      /* quick tests first */
  98.250 -    if (d->is_privileged && cpu_io_mfn(pfn)) {
  98.251 +    if (pfn & foreign_map_pfn) {
  98.252 +        t = PFN_TYPE_FOREIGN;
  98.253 +        mfn = foreign_to_mfn(d, pfn);
  98.254 +    } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) {
  98.255 +        /* Its a grant table access */
  98.256 +        t = PFN_TYPE_GNTTAB;
  98.257 +        mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
  98.258 +    } else if (d->is_privileged && cpu_io_mfn(pfn)) {
  98.259          t = PFN_TYPE_IO;
  98.260          mfn = pfn;
  98.261      } else {
  98.262 @@ -324,17 +423,32 @@ ulong pfn2mfn(struct domain *d, ulong pf
  98.263              t = PFN_TYPE_RMA;
  98.264              mfn = pfn + rma_base_mfn;
  98.265          } else {
  98.266 -            list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  98.267 -                uint end_pfn = pe->pfn + (1 << pe->order);
  98.268 +            ulong cur_pfn = rma_size_mfn;
  98.269  
  98.270 -                if (pfn >= pe->pfn && pfn < end_pfn) {
  98.271 +            list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  98.272 +                uint pe_pages = 1UL << pe->order;
  98.273 +                uint end_pfn = cur_pfn + pe_pages;
  98.274 +
  98.275 +                if (pfn >= cur_pfn && pfn < end_pfn) {
  98.276                      t = PFN_TYPE_LOGICAL;
  98.277 -                    mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
  98.278 +                    mfn = page_to_mfn(pe->pg) + (pfn - cur_pfn);
  98.279                      break;
  98.280                  }
  98.281 +                cur_pfn += pe_pages;
  98.282              }
  98.283          }
  98.284 -        BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d);
  98.285 +#ifdef DEBUG
  98.286 +        if (t != PFN_TYPE_NONE &&
  98.287 +            (d->domain_flags & DOMF_dying) &&
  98.288 +            page_get_owner(mfn_to_page(mfn)) != d) {
  98.289 +            printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
  98.290 +                   __func__, t,
  98.291 +                   page_get_owner(mfn_to_page(mfn))->domain_id,
  98.292 +                   page_get_owner(mfn_to_page(mfn)),
  98.293 +                   d->domain_id, d);
  98.294 +            BUG();
  98.295 +        }
  98.296 +#endif
  98.297      }
  98.298  
  98.299      if (t == PFN_TYPE_NONE) {
  98.300 @@ -368,6 +482,42 @@ ulong pfn2mfn(struct domain *d, ulong pf
  98.301      return mfn;
  98.302  }
  98.303  
  98.304 +unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
  98.305 +{
  98.306 +    struct page_extents *pe;
  98.307 +    ulong cur_pfn;
  98.308 +    ulong gnttab_mfn;
  98.309 +    ulong rma_mfn;
  98.310 +
  98.311 +    /* grant? */
  98.312 +    gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0);
  98.313 +    if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES))
  98.314 +        return max_page + (mfn - gnttab_mfn);
  98.315 +
  98.316 +    /* IO? */
  98.317 +    if (d->is_privileged && cpu_io_mfn(mfn))
  98.318 +        return mfn;
  98.319 +
  98.320 +    rma_mfn = page_to_mfn(d->arch.rma_page);
  98.321 +    if (mfn >= rma_mfn &&
  98.322 +        mfn < (rma_mfn + (1 << d->arch.rma_order)))
  98.323 +        return mfn - rma_mfn;
  98.324 +
  98.325 +    /* Extent? */
  98.326 +    cur_pfn = 1UL << d->arch.rma_order;
  98.327 +    list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  98.328 +        uint pe_pages = 1UL << pe->order;
  98.329 +        uint b_mfn = page_to_mfn(pe->pg);
  98.330 +        uint e_mfn = b_mfn + pe_pages;
  98.331 +
  98.332 +        if (mfn >= b_mfn && mfn < e_mfn) {
  98.333 +            return cur_pfn + (mfn - b_mfn);
  98.334 +        }
  98.335 +        cur_pfn += pe_pages;
  98.336 +    }
  98.337 +    return INVALID_M2P_ENTRY;
  98.338 +}
  98.339 +
  98.340  void guest_physmap_add_page(
  98.341      struct domain *d, unsigned long gpfn, unsigned long mfn)
  98.342  {
  98.343 @@ -382,3 +532,10 @@ void shadow_drop_references(
  98.344      struct domain *d, struct page_info *page)
  98.345  {
  98.346  }
  98.347 +
  98.348 +int arch_domain_add_extent(struct domain *d, struct page_info *page, int order)
  98.349 +{
  98.350 +    if (add_extent(d, page, order) < 0)
  98.351 +        return -ENOMEM;
  98.352 +    return 0;
  98.353 +}
    99.1 --- a/xen/arch/powerpc/mpic.c	Fri Dec 15 10:59:33 2006 -0700
    99.2 +++ b/xen/arch/powerpc/mpic.c	Fri Dec 15 11:32:58 2006 -0700
    99.3 @@ -15,22 +15,18 @@
    99.4  /* XXX Xen hacks ... */
    99.5  /* make this generic */
    99.6  
    99.7 -#define le32_to_cpu(x) \
    99.8 -({ \
    99.9 -	__u32 __x = (x); \
   99.10 -	((__u32)( \
   99.11 -		(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
   99.12 -		(((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) | \
   99.13 -		(((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) | \
   99.14 -		(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
   99.15 -})
   99.16 +#define le32_to_cpu(x)                                          \
   99.17 +    ({                                                          \
   99.18 +        __u32 __x = (x);                                        \
   99.19 +        ((__u32)(                                               \
   99.20 +             (((__u32)(__x) & (__u32)0x000000ffUL) << 24) |     \
   99.21 +             (((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) |     \
   99.22 +             (((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) |     \
   99.23 +             (((__u32)(__x) & (__u32)0xff000000UL) >> 24) ));   \
   99.24 +    })
   99.25  
   99.26  
   99.27  #define alloc_bootmem(x) xmalloc_bytes(x)
   99.28 -#define request_irq(irq, handler, f, devname, dev_id) \
   99.29 -    panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
   99.30 -
   99.31 -typedef int irqreturn_t;
   99.32  
   99.33  #define IRQ_NONE	(0)
   99.34  #define IRQ_HANDLED	(1)
   99.35 @@ -97,11 +93,6 @@ typedef int irqreturn_t;
   99.36  #include <asm/mpic.h>
   99.37  #include <asm/smp.h>
   99.38  
   99.39 -static inline void smp_message_recv(int msg, struct pt_regs *regs)
   99.40 -{
   99.41 -    return;
   99.42 -}
   99.43 -
   99.44  #ifdef DEBUG
   99.45  #define DBG(fmt...) printk(fmt)
   99.46  #else
   99.47 @@ -126,7 +117,7 @@ static DEFINE_SPINLOCK(mpic_lock);
   99.48  
   99.49  
   99.50  static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
   99.51 -			    unsigned int reg)
   99.52 +                             unsigned int reg)
   99.53  {
   99.54  	if (be)
   99.55  		return in_be32(base + (reg >> 2));
   99.56 @@ -135,7 +126,7 @@ static inline u32 _mpic_read(unsigned in
   99.57  }
   99.58  
   99.59  static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
   99.60 -			      unsigned int reg, u32 value)
   99.61 +                               unsigned int reg, u32 value)
   99.62  {
   99.63  	if (be)
   99.64  		out_be32(base + (reg >> 2), value);
   99.65 @@ -186,17 +177,17 @@ static inline u32 _mpic_irq_read(struct 
   99.66  	unsigned int	idx = src_no & mpic->isu_mask;
   99.67  
   99.68  	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
   99.69 -			  reg + (idx * MPIC_IRQ_STRIDE));
   99.70 +                      reg + (idx * MPIC_IRQ_STRIDE));
   99.71  }
   99.72  
   99.73  static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
   99.74 -				   unsigned int reg, u32 value)
   99.75 +                                   unsigned int reg, u32 value)
   99.76  {
   99.77  	unsigned int	isu = src_no >> mpic->isu_shift;
   99.78  	unsigned int	idx = src_no & mpic->isu_mask;
   99.79  
   99.80  	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
   99.81 -		    reg + (idx * MPIC_IRQ_STRIDE), value);
   99.82 +                reg + (idx * MPIC_IRQ_STRIDE), value);
   99.83  }
   99.84  
   99.85  #define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
   99.86 @@ -261,7 +252,7 @@ static inline void mpic_ht_end_irq(struc
   99.87  }
   99.88  
   99.89  static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
   99.90 -				      unsigned int irqflags)
   99.91 +                                      unsigned int irqflags)
   99.92  {
   99.93  	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
   99.94  	unsigned long flags;
   99.95 @@ -284,7 +275,7 @@ static void mpic_startup_ht_interrupt(st
   99.96  }
   99.97  
   99.98  static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
   99.99 -				       unsigned int irqflags)
  99.100 +                                       unsigned int irqflags)
  99.101  {
  99.102  	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
  99.103  	unsigned long flags;
  99.104 @@ -305,7 +296,7 @@ static void mpic_shutdown_ht_interrupt(s
  99.105  }
  99.106  
  99.107  static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
  99.108 -				    unsigned int devfn, u32 vdid)
  99.109 +                                    unsigned int devfn, u32 vdid)
  99.110  {
  99.111  	int i, irq, n;
  99.112  	u8 __iomem *base;
  99.113 @@ -485,8 +476,8 @@ static void mpic_enable_irq(unsigned int
  99.114  	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
  99.115  
  99.116  	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
  99.117 -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
  99.118 -		       ~MPIC_VECPRI_MASK);
  99.119 +                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
  99.120 +                   ~MPIC_VECPRI_MASK);
  99.121  
  99.122  	/* make sure mask gets to controller before we return to user */
  99.123  	do {
  99.124 @@ -532,8 +523,8 @@ static void mpic_disable_irq(unsigned in
  99.125  	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
  99.126  
  99.127  	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
  99.128 -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
  99.129 -		       MPIC_VECPRI_MASK);
  99.130 +                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
  99.131 +                   MPIC_VECPRI_MASK);
  99.132  
  99.133  	/* make sure mask gets to controller before we return to user */
  99.134  	do {
  99.135 @@ -623,7 +614,7 @@ static void mpic_set_affinity(unsigned i
  99.136  	cpus_and(tmp, cpumask, cpu_online_map);
  99.137  
  99.138  	mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
  99.139 -		       mpic_physmask(cpus_addr(tmp)[0]));	
  99.140 +                   mpic_physmask(cpus_addr(tmp)[0]));	
  99.141  }
  99.142  
  99.143  
  99.144 @@ -633,14 +624,14 @@ static void mpic_set_affinity(unsigned i
  99.145  
  99.146  
  99.147  struct mpic * __init mpic_alloc(unsigned long phys_addr,
  99.148 -				unsigned int flags,
  99.149 -				unsigned int isu_size,
  99.150 -				unsigned int irq_offset,
  99.151 -				unsigned int irq_count,
  99.152 -				unsigned int ipi_offset,
  99.153 -				unsigned char *senses,
  99.154 -				unsigned int senses_count,
  99.155 -				const char *name)
  99.156 +                                unsigned int flags,
  99.157 +                                unsigned int isu_size,
  99.158 +                                unsigned int irq_offset,
  99.159 +                                unsigned int irq_count,
  99.160 +                                unsigned int ipi_offset,
  99.161 +                                unsigned char *senses,
  99.162 +                                unsigned int senses_count,
  99.163 +                                const char *name)
  99.164  {
  99.165  	struct mpic	*mpic;
  99.166  	u32		reg;
  99.167 @@ -687,8 +678,8 @@ struct mpic * __init mpic_alloc(unsigned
  99.168  	/* Reset */
  99.169  	if (flags & MPIC_WANTS_RESET) {
  99.170  		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
  99.171 -			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  99.172 -			   | MPIC_GREG_GCONF_RESET);
  99.173 +                   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  99.174 +                   | MPIC_GREG_GCONF_RESET);
  99.175  		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  99.176  		       & MPIC_GREG_GCONF_RESET)
  99.177  			mb();
  99.178 @@ -700,15 +691,15 @@ struct mpic * __init mpic_alloc(unsigned
  99.179  	 */
  99.180  	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
  99.181  	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
  99.182 -			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
  99.183 +                      >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
  99.184  	if (isu_size == 0)
  99.185  		mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
  99.186 -				     >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
  99.187 +                             >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
  99.188  
  99.189  	/* Map the per-CPU registers */
  99.190  	for (i = 0; i < mpic->num_cpus; i++) {
  99.191  		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
  99.192 -					   i * MPIC_CPU_STRIDE, 0x1000);
  99.193 +                                   i * MPIC_CPU_STRIDE, 0x1000);
  99.194  		BUG_ON(mpic->cpuregs[i] == NULL);
  99.195  	}
  99.196  
  99.197 @@ -716,7 +707,7 @@ struct mpic * __init mpic_alloc(unsigned
  99.198  	if (mpic->isu_size == 0) {
  99.199  		mpic->isu_size = mpic->num_sources;
  99.200  		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
  99.201 -					MPIC_IRQ_STRIDE * mpic->isu_size);
  99.202 +                                MPIC_IRQ_STRIDE * mpic->isu_size);
  99.203  		BUG_ON(mpic->isus[0] == NULL);
  99.204  	}
  99.205  	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
  99.206 @@ -752,7 +743,7 @@ struct mpic * __init mpic_alloc(unsigned
  99.207  }
  99.208  
  99.209  void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
  99.210 -			    unsigned long phys_addr)
  99.211 +                            unsigned long phys_addr)
  99.212  {
  99.213  	unsigned int isu_first = isu_num * mpic->isu_size;
  99.214  
  99.215 @@ -764,7 +755,7 @@ void __init mpic_assign_isu(struct mpic 
  99.216  }
  99.217  
  99.218  void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
  99.219 -			       void *data)
  99.220 +                               void *data)
  99.221  {
  99.222  	struct mpic *mpic = mpic_find(irq, NULL);
  99.223  	unsigned long flags;
  99.224 @@ -799,20 +790,20 @@ void __init mpic_init(struct mpic *mpic)
  99.225  	/* Initialize timers: just disable them all */
  99.226  	for (i = 0; i < 4; i++) {
  99.227  		mpic_write(mpic->tmregs,
  99.228 -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
  99.229 +                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
  99.230  		mpic_write(mpic->tmregs,
  99.231 -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
  99.232 -			   MPIC_VECPRI_MASK |
  99.233 -			   (MPIC_VEC_TIMER_0 + i));
  99.234 +                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
  99.235 +                   MPIC_VECPRI_MASK |
  99.236 +                   (MPIC_VEC_TIMER_0 + i));
  99.237  	}
  99.238  
  99.239  	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
  99.240  	mpic_test_broken_ipi(mpic);
  99.241  	for (i = 0; i < 4; i++) {
  99.242  		mpic_ipi_write(i,
  99.243 -			       MPIC_VECPRI_MASK |
  99.244 -			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
  99.245 -			       (MPIC_VEC_IPI_0 + i));
  99.246 +                       MPIC_VECPRI_MASK |
  99.247 +                       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
  99.248 +                       (MPIC_VEC_IPI_0 + i));
  99.249  #ifdef CONFIG_SMP
  99.250  		if (!(mpic->flags & MPIC_PRIMARY))
  99.251  			continue;
  99.252 @@ -859,7 +850,7 @@ void __init mpic_init(struct mpic *mpic)
  99.253  #ifdef CONFIG_MPIC_BROKEN_U3
  99.254  			if (mpic_is_ht_interrupt(mpic, i)) {
  99.255  				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
  99.256 -					    MPIC_VECPRI_POLARITY_MASK);
  99.257 +                            MPIC_VECPRI_POLARITY_MASK);
  99.258  				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
  99.259  			}
  99.260  #else
  99.261 @@ -873,7 +864,7 @@ void __init mpic_init(struct mpic *mpic)
  99.262  		/* init hw */
  99.263  		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
  99.264  		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  99.265 -			       1 << hard_smp_processor_id());
  99.266 +                       1 << hard_smp_processor_id());
  99.267  
  99.268  		/* init linux descriptors */
  99.269  		if (i < mpic->irq_count) {
  99.270 @@ -887,8 +878,8 @@ void __init mpic_init(struct mpic *mpic)
  99.271  
  99.272  	/* Disable 8259 passthrough */
  99.273  	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
  99.274 -		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  99.275 -		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
  99.276 +               mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  99.277 +               | MPIC_GREG_GCONF_8259_PTHROU_DIS);
  99.278  
  99.279  	/* Set current processor priority to 0 */
  99.280  	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
  99.281 @@ -908,12 +899,12 @@ void mpic_irq_set_priority(unsigned int 
  99.282  		reg = mpic_ipi_read(irq - mpic->ipi_offset) &
  99.283  			~MPIC_VECPRI_PRIORITY_MASK;
  99.284  		mpic_ipi_write(irq - mpic->ipi_offset,
  99.285 -			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  99.286 +                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  99.287  	} else {
  99.288  		reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
  99.289  			& ~MPIC_VECPRI_PRIORITY_MASK;
  99.290  		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
  99.291 -			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  99.292 +                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  99.293  	}
  99.294  	spin_unlock_irqrestore(&mpic_lock, flags);
  99.295  }
  99.296 @@ -956,7 +947,7 @@ void mpic_setup_this_cpu(void)
  99.297  	if (distribute_irqs) {
  99.298  	 	for (i = 0; i < mpic->num_sources ; i++)
  99.299  			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  99.300 -				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
  99.301 +                           mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
  99.302  	}
  99.303  
  99.304  	/* Set current processor priority to 0 */
  99.305 @@ -1001,7 +992,7 @@ void mpic_teardown_this_cpu(int secondar
  99.306  	/* let the mpic know we don't want intrs.  */
  99.307  	for (i = 0; i < mpic->num_sources ; i++)
  99.308  		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  99.309 -			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
  99.310 +                       mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
  99.311  
  99.312  	/* Set current processor priority to max */
  99.313  	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
  99.314 @@ -1021,7 +1012,7 @@ void mpic_send_ipi(unsigned int ipi_no, 
  99.315  #endif
  99.316  
  99.317  	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
  99.318 -		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
  99.319 +                   mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
  99.320  }
  99.321  
  99.322  int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
  99.323 @@ -1049,7 +1040,7 @@ int mpic_get_one_irq(struct mpic *mpic, 
  99.324  		return irq + mpic->irq_offset;
  99.325  	}
  99.326  #ifdef DEBUG_IPI
  99.327 -       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
  99.328 +    DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
  99.329  #endif
  99.330  	return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
  99.331  }
  99.332 @@ -1075,13 +1066,13 @@ void mpic_request_ipis(void)
  99.333  
  99.334  	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
  99.335  	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
  99.336 -		    "IPI0 (call function)", mpic);
  99.337 +                "IPI0 (call function)", mpic);
  99.338  	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
  99.339 -		   "IPI1 (reschedule)", mpic);
  99.340 +                "IPI1 (reschedule)", mpic);
  99.341  	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
  99.342 -		   "IPI2 (unused)", mpic);
  99.343 +                "IPI2 (unused)", mpic);
  99.344  	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
  99.345 -		   "IPI3 (debugger break)", mpic);
  99.346 +                "IPI3 (debugger break)", mpic);
  99.347  
  99.348  	printk("IPIs requested... \n");
  99.349  }
   100.1 --- a/xen/arch/powerpc/mpic_init.c	Fri Dec 15 10:59:33 2006 -0700
   100.2 +++ b/xen/arch/powerpc/mpic_init.c	Fri Dec 15 11:32:58 2006 -0700
   100.3 @@ -22,6 +22,7 @@
   100.4  #include <xen/init.h>
   100.5  #include <xen/lib.h>
   100.6  #include <asm/mpic.h>
   100.7 +#include <errno.h>
   100.8  #include "mpic_init.h"
   100.9  #include "oftree.h"
  100.10  #include "of-devtree.h"
  100.11 @@ -74,7 +75,7 @@ static unsigned long reg2(void *oft_p, o
  100.12      rc = ofd_getprop(oft_p, c, "reg", &isa_reg, sizeof(isa_reg));
  100.13  
  100.14      DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
  100.15 -                    isa_reg.address, isa_reg.size);
  100.16 +        isa_reg.address, isa_reg.size);
  100.17      return isa_reg.address;
  100.18  }
  100.19  
  100.20 @@ -92,7 +93,7 @@ static unsigned long reg1(void *oft_p, o
  100.21      rc = ofd_getprop(oft_p, c, "reg", &reg, sizeof(reg));
  100.22  
  100.23      DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
  100.24 -                        reg.address, reg.size);
  100.25 +        reg.address, reg.size);
  100.26      return reg.address;
  100.27  }
  100.28  
  100.29 @@ -173,15 +174,15 @@ static unsigned long find_ranges_addr_fr
  100.30          break;
  100.31      case 2:
  100.32          ranges_addr = (((u64)ranges[ranges_i]) << 32) |
  100.33 -                      ranges[ranges_i + 1];
  100.34 +            ranges[ranges_i + 1];
  100.35          break;
  100.36      case 3:  /* the G5 case, how to squeeze 96 bits into 64 */
  100.37          ranges_addr = (((u64)ranges[ranges_i+1]) << 32) |
  100.38 -                      ranges[ranges_i + 2];
  100.39 +            ranges[ranges_i + 2];
  100.40          break;
  100.41      case 4:
  100.42          ranges_addr = (((u64)ranges[ranges_i+2]) << 32) |
  100.43 -                      ranges[ranges_i + 4];
  100.44 +            ranges[ranges_i + 4];
  100.45          break;
  100.46      default:
  100.47          PANIC("#address-cells out of range\n");
  100.48 @@ -266,7 +267,7 @@ static int find_mpic_canonical_probe(voi
  100.49       * We select the one without an 'interrupt' property.
  100.50       */
  100.51      c = ofd_node_find_by_prop(oft_p, OFD_ROOT, "device_type", mpic_type,
  100.52 -                                        sizeof(mpic_type));
  100.53 +                              sizeof(mpic_type));
  100.54      while (c > 0) {
  100.55          int int_len;
  100.56          int good_mpic;
  100.57 @@ -358,6 +359,42 @@ static struct hw_interrupt_type *share_m
  100.58  
  100.59  #endif
  100.60  
  100.61 +static unsigned int mpic_startup_ipi(unsigned int irq)
  100.62 +{
  100.63 +    mpic->hc_ipi.enable(irq);
  100.64 +    return 0;
  100.65 +}
  100.66 +
  100.67 +int request_irq(unsigned int irq,
  100.68 +                irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
  100.69 +                unsigned long irqflags, const char * devname, void *dev_id)
  100.70 +{
  100.71 +    int retval;
  100.72 +    struct irqaction *action;
  100.73 +    void (*func)(int, void *, struct cpu_user_regs *);
  100.74 +
  100.75 +    action = xmalloc(struct irqaction);
  100.76 +    if (!action) {
  100.77 +        BUG();
  100.78 +        return -ENOMEM;
  100.79 +    }
  100.80 +
  100.81 +    /* Xen's handler prototype is slightly different than Linux's.  */
  100.82 +    func = (void (*)(int, void *, struct cpu_user_regs *))handler;
  100.83 +
  100.84 +    action->handler = func;
  100.85 +    action->name = devname;
  100.86 +    action->dev_id = dev_id;
  100.87 +
  100.88 +    retval = setup_irq(irq, action);
  100.89 +    if (retval) {
  100.90 +        BUG();
  100.91 +        xfree(action);
  100.92 +    }
  100.93 +
  100.94 +    return retval;
  100.95 +}
  100.96 +
  100.97  struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
  100.98  {
  100.99      unsigned int isu_size;
 100.100 @@ -397,6 +434,11 @@ struct hw_interrupt_type *xen_mpic_init(
 100.101      hit = share_mpic(&mpic->hc_irq, xen_irq);
 100.102  
 100.103      printk("%s: success\n", __func__);
 100.104 +
 100.105 +    mpic->hc_ipi.ack = xen_irq->ack;
 100.106 +    mpic->hc_ipi.startup = mpic_startup_ipi;
 100.107 +    mpic_request_ipis();
 100.108 +
 100.109      return hit;
 100.110  }
 100.111  
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/xen/arch/powerpc/numa.c	Fri Dec 15 11:32:58 2006 -0700
   101.3 @@ -0,0 +1,1 @@
   101.4 +#include "../x86/numa.c"
   102.1 --- a/xen/arch/powerpc/of-devtree.h	Fri Dec 15 10:59:33 2006 -0700
   102.2 +++ b/xen/arch/powerpc/of-devtree.h	Fri Dec 15 11:32:58 2006 -0700
   102.3 @@ -33,15 +33,15 @@ enum {
   102.4  union of_pci_hi {
   102.5      u32 word;
   102.6      struct {
   102.7 -        u32	opa_n: 1; /* relocatable */
   102.8 -        u32	opa_p: 1; /* prefetchable */
   102.9 -        u32	opa_t: 1; /* aliased */
  102.10 +        u32 opa_n: 1; /* relocatable */
  102.11 +        u32 opa_p: 1; /* prefetchable */
  102.12 +        u32 opa_t: 1; /* aliased */
  102.13          u32 _opa_res: 3;
  102.14 -        u32	opa: 2; /* space code */
  102.15 +        u32 opa: 2; /* space code */
  102.16          u32  opa_b: 8; /* bus number */
  102.17 -        u32	opa_d: 5; /* device number */
  102.18 -        u32	opa_f: 3; /* function number */
  102.19 -        u32	opa_r: 8; /* register number */
  102.20 +        u32 opa_d: 5; /* device number */
  102.21 +        u32 opa_f: 3; /* function number */
  102.22 +        u32 opa_r: 8; /* register number */
  102.23      } bits;
  102.24  };
  102.25  
  102.26 @@ -79,9 +79,9 @@ struct reg_property32 {
  102.27  typedef s32 ofdn_t;
  102.28  
  102.29  #define OFD_ROOT 1
  102.30 -#define OFD_DUMP_NAMES	0x1
  102.31 -#define OFD_DUMP_VALUES	0x2
  102.32 -#define OFD_DUMP_ALL	(OFD_DUMP_VALUES|OFD_DUMP_NAMES)
  102.33 +#define OFD_DUMP_NAMES 0x1
  102.34 +#define OFD_DUMP_VALUES 0x2
  102.35 +#define OFD_DUMP_ALL (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
  102.36  
  102.37  extern void *ofd_create(void *mem, size_t sz);
  102.38  extern ofdn_t ofd_node_parent(void *mem, ofdn_t n);
  102.39 @@ -90,9 +90,9 @@ extern ofdn_t ofd_node_child(void *mem, 
  102.40  extern const char *ofd_node_path(void *mem, ofdn_t p);
  102.41  extern int ofd_node_to_path(void *mem, ofdn_t p, void *buf, size_t sz);
  102.42  extern ofdn_t ofd_node_child_create(void *mem, ofdn_t parent,
  102.43 -				    const char *path, size_t pathlen);
  102.44 +                                    const char *path, size_t pathlen);
  102.45  extern ofdn_t ofd_node_peer_create(void *mem, ofdn_t sibling,
  102.46 -				   const char *path, size_t pathlen);
  102.47 +                                   const char *path, size_t pathlen);
  102.48  extern ofdn_t ofd_node_find(void *mem, const char *devspec);
  102.49  extern ofdn_t ofd_node_add(void *m, ofdn_t n, const char *path, size_t sz);
  102.50  extern int ofd_node_prune(void *m, ofdn_t n);
  102.51 @@ -102,23 +102,23 @@ extern ofdn_t ofd_node_io(void *mem, ofd
  102.52  extern ofdn_t ofd_nextprop(void *mem, ofdn_t n, const char *prev, char *name);
  102.53  extern ofdn_t ofd_prop_find(void *mem, ofdn_t n, const char *name);
  102.54  extern int ofd_getprop(void *mem, ofdn_t n, const char *name,
  102.55 -			void *buf, size_t sz);
  102.56 +                       void *buf, size_t sz);
  102.57  extern int ofd_getproplen(void *mem, ofdn_t n, const char *name);
  102.58  
  102.59  extern int ofd_setprop(void *mem, ofdn_t n, const char *name,
  102.60 -			const void *buf, size_t sz);
  102.61 +                       const void *buf, size_t sz);
  102.62  extern void ofd_prop_remove(void *mem, ofdn_t node, ofdn_t prop);
  102.63  extern ofdn_t ofd_prop_add(void *mem, ofdn_t n, const char *name,
  102.64 -			   const void *buf, size_t sz);
  102.65 +                           const void *buf, size_t sz);
  102.66  extern ofdn_t ofd_io_create(void *m, ofdn_t node, u64 open);
  102.67  extern u32 ofd_io_open(void *mem, ofdn_t n);
  102.68  extern void ofd_io_close(void *mem, ofdn_t n);
  102.69  
  102.70  
  102.71 -typedef void (*walk_fn)(void *m, ofdn_t p, int arg);
  102.72 -extern void ofd_dump_props(void *m, ofdn_t p, int dump);
  102.73 +typedef void (*walk_fn)(void *m, const char *pre, ofdn_t p, int arg);
  102.74 +extern void ofd_dump_props(void *m, const char *pre, ofdn_t p, int dump);
  102.75  
  102.76 -extern void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg);
  102.77 +extern void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg);
  102.78  
  102.79  
  102.80  /* Recursively look up #address_cells and #size_cells properties */
  102.81 @@ -129,10 +129,10 @@ extern size_t ofd_size(void *mem);
  102.82  extern size_t ofd_space(void *mem);
  102.83  
  102.84  extern void ofd_prop_print(const char *head, const char *path,
  102.85 -			   const char *name, const char *prop, size_t sz);
  102.86 +                           const char *name, const char *prop, size_t sz);
  102.87  
  102.88  extern ofdn_t ofd_node_find_by_prop(void *mem, ofdn_t n, const char *name,
  102.89 -				    const void *val, size_t sz);
  102.90 +                                    const void *val, size_t sz);
  102.91  extern ofdn_t ofd_node_find_next(void *mem, ofdn_t n);
  102.92  extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n);
  102.93  extern void ofd_init(int (*write)(const char *, size_t len));
   103.1 --- a/xen/arch/powerpc/of-devwalk.c	Fri Dec 15 10:59:33 2006 -0700
   103.2 +++ b/xen/arch/powerpc/of-devwalk.c	Fri Dec 15 11:32:58 2006 -0700
   103.3 @@ -80,7 +80,7 @@ void ofd_prop_print(
   103.4  #endif
   103.5  }
   103.6  
   103.7 -void ofd_dump_props(void *mem, ofdn_t n, int dump)
   103.8 +void ofd_dump_props(void *mem, const char *pre, ofdn_t n, int dump)
   103.9  {
  103.10      ofdn_t p;
  103.11      char name[128];
  103.12 @@ -95,7 +95,7 @@ void ofd_dump_props(void *mem, ofdn_t n,
  103.13      }
  103.14  
  103.15      if (dump & OFD_DUMP_NAMES) {
  103.16 -        printk("of_walk: %s: phandle 0x%x\n", path, n);
  103.17 +        printk("%s: %s: phandle 0x%x\n", pre, path, n);
  103.18      }
  103.19  
  103.20      p = ofd_nextprop(mem, n, NULL, name);
  103.21 @@ -106,30 +106,30 @@ void ofd_dump_props(void *mem, ofdn_t n,
  103.22          }
  103.23  
  103.24          if ( dump & OFD_DUMP_VALUES ) {
  103.25 -            ofd_prop_print("of_walk", path, name, prop, sz);
  103.26 +            ofd_prop_print(pre, path, name, prop, sz);
  103.27          }
  103.28  
  103.29          p = ofd_nextprop(mem, n, name, name);
  103.30      }
  103.31  }
  103.32  
  103.33 -void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg)
  103.34 +void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg)
  103.35  {
  103.36      ofdn_t n;
  103.37  
  103.38      if ( fn != NULL ) {
  103.39 -        (*fn)(m, p, arg);
  103.40 +        (*fn)(m, pre, p, arg);
  103.41      }
  103.42  
  103.43      /* child */
  103.44      n = ofd_node_child(m, p);
  103.45      if ( n != 0 ) {
  103.46 -        ofd_walk(m, n, fn, arg);
  103.47 +        ofd_walk(m, pre, n, fn, arg);
  103.48      }
  103.49  
  103.50      /* peer */
  103.51      n = ofd_node_peer(m, p);
  103.52      if ( n != 0 ) {
  103.53 -        ofd_walk(m, n, fn, arg);
  103.54 +        ofd_walk(m, pre, n, fn, arg);
  103.55      }
  103.56  }
   104.1 --- a/xen/arch/powerpc/of_handler/console.c	Fri Dec 15 10:59:33 2006 -0700
   104.2 +++ b/xen/arch/powerpc/of_handler/console.c	Fri Dec 15 11:32:58 2006 -0700
   104.3 @@ -113,7 +113,7 @@ static s32 ofh_xen_dom0_read(s32 chan, v
   104.4              return ret;
   104.5  
   104.6          rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_read,
   104.7 -                count, desc);
   104.8 +                        count, desc);
   104.9          if (rc <= 0) {
  104.10              return ret;
  104.11          }
  104.12 @@ -139,7 +139,7 @@ static s32 ofh_xen_dom0_write(s32 chan, 
  104.13              return ret;
  104.14  
  104.15          rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_write,
  104.16 -                count, desc);
  104.17 +                        count, desc);
  104.18          if (rc <= 0) {
  104.19              return ret;
  104.20          }
  104.21 @@ -157,8 +157,8 @@ static s32 ofh_xen_dom0_write(s32 chan, 
  104.22  static s32 ofh_xen_domu_read(s32 chan, void *buf, u32 count, s32 *actual,
  104.23                               ulong b)
  104.24  {
  104.25 -	struct xencons_interface *intf;
  104.26 -	XENCONS_RING_IDX cons, prod;
  104.27 +    struct xencons_interface *intf;
  104.28 +    XENCONS_RING_IDX cons, prod;
  104.29      s32 ret;
  104.30  
  104.31      intf = DRELA(ofh_ihp, b)->ofi_intf;
  104.32 @@ -180,8 +180,8 @@ static s32 ofh_xen_domu_read(s32 chan, v
  104.33  static s32 ofh_xen_domu_write(s32 chan, const void *buf, u32 count,
  104.34                                s32 *actual, ulong b)
  104.35  {
  104.36 -	struct xencons_interface *intf;
  104.37 -	XENCONS_RING_IDX cons, prod;
  104.38 +    struct xencons_interface *intf;
  104.39 +    XENCONS_RING_IDX cons, prod;
  104.40      s32 ret;
  104.41  
  104.42      intf = DRELA(ofh_ihp, b)->ofi_intf;
   105.1 --- a/xen/arch/powerpc/ofd_fixup.c	Fri Dec 15 10:59:33 2006 -0700
   105.2 +++ b/xen/arch/powerpc/ofd_fixup.c	Fri Dec 15 11:32:58 2006 -0700
   105.3 @@ -25,6 +25,7 @@
   105.4  #include <public/xen.h>
   105.5  #include "of-devtree.h"
   105.6  #include "oftree.h"
   105.7 +#include "rtas.h"
   105.8  
   105.9  #undef RTAS
  105.10  
  105.11 @@ -347,6 +348,15 @@ static ofdn_t ofd_xen_props(void *m, str
  105.12          val[0] =  rma_size(d->arch.rma_order) - val[1];
  105.13          ofd_prop_add(m, n, "reserved", val, sizeof (val));
  105.14  
  105.15 +        /* tell dom0 that Xen depends on it to have power control */
  105.16 +        if (!rtas_entry)
  105.17 +            ofd_prop_add(m, n, "power-control", NULL, 0);
  105.18 +
  105.19 +        /* tell dom0 where ranted pages go in the linear map */
  105.20 +        val[0] = cpu_foreign_map_order();
  105.21 +        val[1] = d->arch.foreign_mfn_count;
  105.22 +        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
  105.23 +
  105.24          n = ofd_node_add(m, n, console, sizeof (console));
  105.25          if (n > 0) {
  105.26              val[0] = 0;
  105.27 @@ -417,7 +427,7 @@ int ofd_dom0_fixup(struct domain *d, ulo
  105.28  
  105.29  
  105.30  #ifdef DEBUG
  105.31 -    ofd_walk(m, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
  105.32 +    ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
  105.33  #endif
  105.34      return 1;
  105.35  }
   106.1 --- a/xen/arch/powerpc/ofd_fixup_memory.c	Fri Dec 15 10:59:33 2006 -0700
   106.2 +++ b/xen/arch/powerpc/ofd_fixup_memory.c	Fri Dec 15 11:32:58 2006 -0700
   106.3 @@ -68,6 +68,8 @@ static ofdn_t ofd_memory_node_create(
   106.4      reg.sz = size;
   106.5      ofd_prop_add(m, n, "reg", &reg, sizeof (reg));
   106.6  
   106.7 +    printk("Dom0: %s: %016lx, %016lx\n", path, start, size);
   106.8 +
   106.9      return n;
  106.10  }
  106.11  
  106.12 @@ -86,17 +88,19 @@ static void ofd_memory_extent_nodes(void
  106.13      ulong size;
  106.14      ofdn_t n;
  106.15      struct page_extents *pe;
  106.16 +    ulong cur_pfn = 1UL << d->arch.rma_order;
  106.17  
  106.18 +    start = cur_pfn << PAGE_SHIFT;
  106.19 +    size = 0;
  106.20      list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  106.21  
  106.22 -        start = pe->pfn << PAGE_SHIFT;
  106.23 -        size = 1UL << (pe->order + PAGE_SHIFT);
  106.24 -
  106.25 -        n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
  106.26 -                                    start, size);
  106.27 -
  106.28 -        BUG_ON(n <= 0);
  106.29 +        size += 1UL << (pe->order + PAGE_SHIFT);
  106.30 +        if (pe->order != cpu_extent_order())
  106.31 +            panic("we don't handle this yet\n");
  106.32      }
  106.33 +    n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
  106.34 +                               start, size);
  106.35 +    BUG_ON(n <= 0);
  106.36  }
  106.37  
  106.38  void ofd_memory_props(void *m, struct domain *d)
   107.1 --- a/xen/arch/powerpc/papr/xlate.c	Fri Dec 15 10:59:33 2006 -0700
   107.2 +++ b/xen/arch/powerpc/papr/xlate.c	Fri Dec 15 11:32:58 2006 -0700
   107.3 @@ -19,7 +19,7 @@
   107.4   */
   107.5  
   107.6  #undef DEBUG
   107.7 -#undef DEBUG_FAIL
   107.8 +#undef DEBUG_LOW
   107.9  
  107.10  #include <xen/config.h>
  107.11  #include <xen/types.h>
  107.12 @@ -30,6 +30,17 @@
  107.13  #include <asm/papr.h>
  107.14  #include <asm/hcalls.h>
  107.15  
  107.16 +#ifdef DEBUG
  107.17 +#define DBG(fmt...) printk(fmt)
  107.18 +#else
  107.19 +#define DBG(fmt...)
  107.20 +#endif
  107.21 +#ifdef DEBUG_LOW
  107.22 +#define DBG_LOW(fmt...) printk(fmt)
  107.23 +#else
  107.24 +#define DBG_LOW(fmt...)
  107.25 +#endif
  107.26 +
  107.27  #ifdef USE_PTE_INSERT
  107.28  static inline void pte_insert(union pte volatile *pte,
  107.29          ulong vsid, ulong rpn, ulong lrpn)
  107.30 @@ -106,11 +117,8 @@ static void pte_tlbie(union pte volatile
  107.31  
  107.32  }
  107.33  
  107.34 -static void h_enter(struct cpu_user_regs *regs)
  107.35 +long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
  107.36  {
  107.37 -    ulong flags = regs->gprs[4];
  107.38 -    ulong ptex = regs->gprs[5];
  107.39 -
  107.40      union pte pte;
  107.41      union pte volatile *ppte;
  107.42      struct domain_htab *htab;
  107.43 @@ -129,14 +137,13 @@ static void h_enter(struct cpu_user_regs
  107.44  
  107.45      htab = &d->arch.htab;
  107.46      if (ptex > (1UL << htab->log_num_ptes)) {
  107.47 -        regs->gprs[3] = H_Parameter;
  107.48 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  107.49 -        return;
  107.50 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  107.51 +        return H_Parameter;
  107.52      }
  107.53  
  107.54      /* use local HPTE to avoid manual shifting & masking */
  107.55 -    pte.words.vsid = regs->gprs[6];
  107.56 -    pte.words.rpn = regs->gprs[7];
  107.57 +    pte.words.vsid = vsid;
  107.58 +    pte.words.rpn = rpn;
  107.59  
  107.60      if ( pte.bits.l ) {        /* large page? */
  107.61          /* figure out the page size for the selected large page */
  107.62 @@ -150,10 +157,9 @@ static void h_enter(struct cpu_user_regs
  107.63          }
  107.64  
  107.65          if ( lp_size >= d->arch.large_page_sizes ) {
  107.66 -            printk("%s: attempt to use unsupported lp_size %d\n",
  107.67 -                   __func__, lp_size);
  107.68 -            regs->gprs[3] = H_Parameter;
  107.69 -            return;
  107.70 +            DBG("%s: attempt to use unsupported lp_size %d\n",
  107.71 +                __func__, lp_size);
  107.72 +            return H_Parameter;
  107.73          }
  107.74  
  107.75          /* get correct pgshift value */
  107.76 @@ -168,32 +174,33 @@ static void h_enter(struct cpu_user_regs
  107.77  
  107.78      mfn = pfn2mfn(d, pfn, &mtype);
  107.79      if (mfn == INVALID_MFN) {
  107.80 -        regs->gprs[3] =  H_Parameter;
  107.81 -        return;
  107.82 +        DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn);
  107.83 +        return H_Parameter;
  107.84      }
  107.85  
  107.86 -    if (mtype == PFN_TYPE_IO) {
  107.87 +    if (mtype == PFN_TYPE_IO && !d->is_privileged) {
  107.88          /* only a privilaged dom can access outside IO space */
  107.89 -        if ( !d->is_privileged ) {
  107.90 -            regs->gprs[3] =  H_Privilege;
  107.91 -            printk("%s: unprivileged access to physical page: 0x%lx\n",
  107.92 -                   __func__, pfn);
  107.93 -            return;
  107.94 -        }
  107.95 -
  107.96 +        DBG("%s: unprivileged access to physical page: 0x%lx\n",
  107.97 +            __func__, pfn);
  107.98 +        return H_Privilege;
  107.99 +    }
 107.100 +    if (mtype == PFN_TYPE_IO) {
 107.101          if ( !((pte.bits.w == 0)
 107.102               && (pte.bits.i == 1)
 107.103               && (pte.bits.g == 1)) ) {
 107.104 -#ifdef DEBUG_FAIL
 107.105 -            printk("%s: expecting an IO WIMG "
 107.106 -                   "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
 107.107 -                   pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
 107.108 -                   pte.words.rpn);
 107.109 -#endif
 107.110 -            regs->gprs[3] =  H_Parameter;
 107.111 -            return;
 107.112 +            DBG("%s: expecting an IO WIMG "
 107.113 +                "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
 107.114 +                pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
 107.115 +                pte.words.rpn);
 107.116 +            return H_Parameter;
 107.117          }
 107.118      }
 107.119 +    if (mtype == PFN_TYPE_GNTTAB) {
 107.120 +        DBG("%s: Dom[%d] mapping grant table: 0x%lx\n",
 107.121 +            __func__, d->domain_id, pfn << PAGE_SHIFT);
 107.122 +        pte.bits.i = 0;
 107.123 +        pte.bits.g = 0;
 107.124 +    }
 107.125      /* fixup the RPN field of our local PTE copy */
 107.126      pte.bits.rpn = mfn | lp_bits;
 107.127  
 107.128 @@ -213,13 +220,13 @@ static void h_enter(struct cpu_user_regs
 107.129          BUG_ON(f == d);
 107.130  
 107.131          if (unlikely(!get_domain(f))) {
 107.132 -            regs->gprs[3] = H_Rescinded;
 107.133 -            return;
 107.134 +            DBG("%s: Rescinded, no domain: 0x%lx\n",  __func__, pfn);
 107.135 +            return H_Rescinded;
 107.136          }
 107.137          if (unlikely(!get_page(pg, f))) {
 107.138              put_domain(f);
 107.139 -            regs->gprs[3] = H_Rescinded;
 107.140 -            return;
 107.141 +            DBG("%s: Rescinded, no page: 0x%lx\n",  __func__, pfn);
 107.142 +            return H_Rescinded;
 107.143          }
 107.144      }
 107.145  
 107.146 @@ -276,17 +283,12 @@ static void h_enter(struct cpu_user_regs
 107.147                  : "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid)
 107.148                  : "memory");
 107.149  
 107.150 -            regs->gprs[3] = H_Success;
 107.151 -            regs->gprs[4] = idx;
 107.152 -
 107.153 -            return;
 107.154 +            return idx;
 107.155          }
 107.156      }
 107.157  
 107.158 -#ifdef DEBUG
 107.159      /* If the PTEG is full then no additional values are returned. */
 107.160 -    printk("%s: PTEG FULL\n", __func__);
 107.161 -#endif
 107.162 +    DBG("%s: PTEG FULL\n", __func__);
 107.163  
 107.164      if (pg != NULL)
 107.165          put_page(pg);
 107.166 @@ -294,7 +296,24 @@ static void h_enter(struct cpu_user_regs
 107.167      if (f != NULL)
 107.168          put_domain(f);
 107.169  
 107.170 -    regs->gprs[3] = H_PTEG_Full;
 107.171 +    return H_PTEG_Full;
 107.172 +}
 107.173 +
 107.174 +static void h_enter(struct cpu_user_regs *regs)
 107.175 +{
 107.176 +    ulong flags = regs->gprs[4];
 107.177 +    ulong ptex = regs->gprs[5];
 107.178 +    ulong vsid = regs->gprs[6];
 107.179 +    ulong rpn = regs->gprs[7];
 107.180 +    long ret;
 107.181 +
 107.182 +    ret = pte_enter(flags, ptex, vsid, rpn);
 107.183 +
 107.184 +    if (ret >= 0) {
 107.185 +        regs->gprs[3] = H_Success;
 107.186 +        regs->gprs[4] = ret;
 107.187 +    } else
 107.188 +        regs->gprs[3] = ret;
 107.189  }
 107.190  
 107.191  static void h_protect(struct cpu_user_regs *regs)
 107.192 @@ -308,13 +327,11 @@ static void h_protect(struct cpu_user_re
 107.193      union pte volatile *ppte;
 107.194      union pte lpte;
 107.195  
 107.196 -#ifdef DEBUG
 107.197 -    printk("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
 107.198 -           flags, ptex, avpn);
 107.199 -#endif
 107.200 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
 107.201 +            flags, ptex, avpn);
 107.202      if ( ptex > (1UL << htab->log_num_ptes) ) {
 107.203 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.204          regs->gprs[3] = H_Parameter;
 107.205 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.206          return;
 107.207      }
 107.208      ppte = &htab->map[ptex];
 107.209 @@ -324,10 +341,8 @@ static void h_protect(struct cpu_user_re
 107.210  
 107.211      /* the AVPN param occupies the bit-space of the word */
 107.212      if ( (flags & H_AVPN) && lpte.bits.avpn != avpn >> 7 ) {
 107.213 -#ifdef DEBUG_FAIL
 107.214 -        printk("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
 107.215 -                ppte, lpte.words.vsid, lpte.words.rpn);
 107.216 -#endif
 107.217 +        DBG_LOW("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
 107.218 +            ppte, lpte.words.vsid, lpte.words.rpn);
 107.219          regs->gprs[3] = H_Not_Found;
 107.220          return;
 107.221      }
 107.222 @@ -337,9 +352,7 @@ static void h_protect(struct cpu_user_re
 107.223           * we invalidate entires where the PAPR says to 0 the whole hi
 107.224           * dword, so the AVPN should catch this first */
 107.225  
 107.226 -#ifdef DEBUG_FAIL
 107.227 -        printk("%s: pte invalid\n", __func__);
 107.228 -#endif
 107.229 +        DBG("%s: pte invalid\n", __func__);
 107.230          regs->gprs[3] =  H_Not_Found;
 107.231          return;
 107.232      }
 107.233 @@ -374,7 +387,6 @@ static void h_protect(struct cpu_user_re
 107.234  
 107.235  static void h_clear_ref(struct cpu_user_regs *regs)
 107.236  {
 107.237 -    ulong flags = regs->gprs[4];
 107.238      ulong ptex = regs->gprs[5];
 107.239      struct vcpu *v = get_current();
 107.240      struct domain *d = v->domain;
 107.241 @@ -382,20 +394,20 @@ static void h_clear_ref(struct cpu_user_
 107.242      union pte volatile *pte;
 107.243      union pte lpte;
 107.244  
 107.245 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
 107.246 +            regs->gprs[4], ptex);
 107.247 +
 107.248  #ifdef DEBUG
 107.249 -    printk("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
 107.250 -           flags, ptex);
 107.251 +    if (regs->gprs[4] != 0) {
 107.252 +        DBG("WARNING: %s: "
 107.253 +            "flags are undefined and should be 0: 0x%lx\n",
 107.254 +            __func__, regs->gprs[4]);
 107.255 +    }
 107.256  #endif
 107.257  
 107.258 -    if (flags != 0) {
 107.259 -        printk("WARNING: %s: "
 107.260 -                "flags are undefined and should be 0: 0x%lx\n",
 107.261 -                __func__, flags);
 107.262 -    }
 107.263 -
 107.264      if (ptex > (1UL << htab->log_num_ptes)) {
 107.265 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.266          regs->gprs[3] = H_Parameter;
 107.267 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.268          return;
 107.269      }
 107.270      pte = &htab->map[ptex];
 107.271 @@ -417,7 +429,6 @@ static void h_clear_ref(struct cpu_user_
 107.272  
 107.273  static void h_clear_mod(struct cpu_user_regs *regs)
 107.274  {
 107.275 -    ulong flags = regs->gprs[4];
 107.276      ulong ptex = regs->gprs[5];
 107.277      struct vcpu *v = get_current();
 107.278      struct domain *d = v->domain;
 107.279 @@ -425,19 +436,20 @@ static void h_clear_mod(struct cpu_user_
 107.280      union pte volatile *pte;
 107.281      union pte lpte;
 107.282  
 107.283 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
 107.284 +          regs->gprs[4], ptex);
 107.285 +
 107.286  #ifdef DEBUG
 107.287 -    printk("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
 107.288 -           flags, ptex);
 107.289 +    if (regs->gprs[4] != 0) {
 107.290 +        DBG("WARNING: %s: "
 107.291 +            "flags are undefined and should be 0: 0x%lx\n",
 107.292 +            __func__, regs->gprs[4]);
 107.293 +    }
 107.294  #endif
 107.295 -    if (flags != 0) {
 107.296 -        printk("WARNING: %s: "
 107.297 -                "flags are undefined and should be 0: 0x%lx\n",
 107.298 -                __func__, flags);
 107.299 -    }
 107.300 -    
 107.301 +
 107.302      if (ptex > (1UL << htab->log_num_ptes)) {
 107.303 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.304          regs->gprs[3] = H_Parameter;
 107.305 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.306          return;
 107.307      }
 107.308      pte = &htab->map[ptex];
 107.309 @@ -466,63 +478,53 @@ static void h_clear_mod(struct cpu_user_
 107.310      }
 107.311  }
 107.312  
 107.313 -static void h_remove(struct cpu_user_regs *regs)
 107.314 +long pte_remove(ulong flags, ulong ptex, ulong avpn, ulong *hi, ulong *lo)
 107.315  {
 107.316 -    ulong flags = regs->gprs[4];
 107.317 -    ulong ptex = regs->gprs[5];
 107.318 -    ulong avpn = regs->gprs[6];
 107.319      struct vcpu *v = get_current();
 107.320      struct domain *d = v->domain;
 107.321      struct domain_htab *htab = &d->arch.htab;
 107.322      union pte volatile *pte;
 107.323      union pte lpte;
 107.324  
 107.325 -#ifdef DEBUG
 107.326 -    printk("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
 107.327 -           flags, ptex, avpn);
 107.328 -#endif
 107.329 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
 107.330 +            flags, ptex, avpn);
 107.331 +
 107.332      if ( ptex > (1UL << htab->log_num_ptes) ) {
 107.333 -        regs->gprs[3] = H_Parameter;
 107.334 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.335 -        return;
 107.336 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.337 +        return H_Parameter;
 107.338      }
 107.339      pte = &htab->map[ptex];
 107.340      lpte.words.vsid = pte->words.vsid;
 107.341      lpte.words.rpn = pte->words.rpn;
 107.342  
 107.343      if ((flags & H_AVPN) && lpte.bits.avpn != (avpn >> 7)) {
 107.344 -#ifdef DEBUG_FAIL
 107.345 -        printk("%s: avpn doesn not match\n", __func__);
 107.346 -#endif
 107.347 -        regs->gprs[3] = H_Not_Found;
 107.348 -        return;
 107.349 +        DBG_LOW("%s: AVPN does not match\n", __func__);
 107.350 +        return H_Not_Found;
 107.351      }
 107.352  
 107.353      if ((flags & H_ANDCOND) && ((avpn & pte->words.vsid) != 0)) {
 107.354 -#ifdef DEBUG_FAIL
 107.355 -        printk("%s: andcond does not match\n", __func__);
 107.356 -#endif
 107.357 -        regs->gprs[3] = H_Not_Found;
 107.358 -        return;
 107.359 +        DBG("%s: andcond does not match\n", __func__);
 107.360 +        return H_Not_Found;
 107.361      }
 107.362  
 107.363 -    regs->gprs[3] = H_Success;
 107.364      /* return old PTE in regs 4 and 5 */
 107.365 -    regs->gprs[4] = lpte.words.vsid;
 107.366 -    regs->gprs[5] = lpte.words.rpn;
 107.367 +    *hi = lpte.words.vsid;
 107.368 +    *lo = lpte.words.rpn;
 107.369  
 107.370 +#ifdef DEBUG_LOW
 107.371      /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */
 107.372      /* XXX - I think the spec should be questioned in this case (MFM) */
 107.373      if (lpte.bits.v == 0) {
 107.374 -        printk("%s: removing invalid entry\n", __func__);
 107.375 +        DBG_LOW("%s: removing invalid entry\n", __func__);
 107.376      }
 107.377 +#endif
 107.378  
 107.379      if (lpte.bits.v) {
 107.380          ulong mfn = lpte.bits.rpn;
 107.381          if (!cpu_io_mfn(mfn)) {
 107.382              struct page_info *pg = mfn_to_page(mfn);
 107.383              struct domain *f = page_get_owner(pg);
 107.384 -
 107.385 +            
 107.386              if (f != d) {
 107.387                  put_domain(f);
 107.388                  put_page(pg);
 107.389 @@ -536,6 +538,27 @@ static void h_remove(struct cpu_user_reg
 107.390              : "memory");
 107.391  
 107.392      pte_tlbie(&lpte, ptex);
 107.393 +
 107.394 +    return H_Success;
 107.395 +}
 107.396 +
 107.397 +static void h_remove(struct cpu_user_regs *regs)
 107.398 +{
 107.399 +    ulong flags = regs->gprs[4];
 107.400 +    ulong ptex = regs->gprs[5];
 107.401 +    ulong avpn = regs->gprs[6];
 107.402 +    ulong hi, lo;
 107.403 +    long ret;
 107.404 +
 107.405 +    ret = pte_remove(flags, ptex, avpn, &hi, &lo);
 107.406 +
 107.407 +    regs->gprs[3] = ret;
 107.408 +
 107.409 +    if (ret == H_Success) {
 107.410 +        regs->gprs[4] = hi;
 107.411 +        regs->gprs[5] = lo;
 107.412 +    }
 107.413 +    return;
 107.414  }
 107.415  
 107.416  static void h_read(struct cpu_user_regs *regs)
 107.417 @@ -547,12 +570,12 @@ static void h_read(struct cpu_user_regs 
 107.418      struct domain_htab *htab = &d->arch.htab;
 107.419      union pte volatile *pte;
 107.420  
 107.421 -	if (flags & H_READ_4)
 107.422 +    if (flags & H_READ_4)
 107.423          ptex &= ~0x3UL;
 107.424  
 107.425      if (ptex > (1UL << htab->log_num_ptes)) {
 107.426 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.427          regs->gprs[3] = H_Parameter;
 107.428 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
 107.429          return;
 107.430      }
 107.431      pte = &htab->map[ptex];
   108.1 --- a/xen/arch/powerpc/powerpc64/exceptions.S	Fri Dec 15 10:59:33 2006 -0700
   108.2 +++ b/xen/arch/powerpc/powerpc64/exceptions.S	Fri Dec 15 11:32:58 2006 -0700
   108.3 @@ -564,6 +564,22 @@ 1:
   108.4   */	
   108.5      .globl spin_start
   108.6  spin_start:
   108.7 +    /* We discovered by experiment that the ERAT must be flushed early.  */
   108.8 +    isync
   108.9 +    slbia
  108.10 +    isync
  108.11 +	
  108.12 +    /* Do a cache flush for our text, in case the loader didn't */
  108.13 +    LOADADDR(r9, _start)
  108.14 +    LOADADDR(r8, _etext)
  108.15 +4:  dcbf r0,r9
  108.16 +    icbi r0,r9
  108.17 +    addi r9,r9,0x20		/* up to a 4 way set per line */
  108.18 +    cmpld cr0,r9,r8
  108.19 +    blt	4b
  108.20 +    sync
  108.21 +    isync
  108.22 +
  108.23      /* Write our processor number as an acknowledgment that we're alive.  */
  108.24      LOADADDR(r14, __spin_ack)
  108.25      stw r3, 0(r14)
  108.26 @@ -575,7 +591,7 @@ spin_start:
  108.27      b .
  108.28      /* Find our index in the array of processor_area struct pointers.  */
  108.29  2:  LOADADDR(r14, global_cpu_table)
  108.30 -    muli r15, r3, 8
  108.31 +    mulli r15, r3, 8
  108.32      add r14, r14, r15
  108.33      /* Spin until the pointer for our processor goes valid.  */
  108.34  1:  ld r15, 0(r14)
   109.1 --- a/xen/arch/powerpc/powerpc64/io.S	Fri Dec 15 10:59:33 2006 -0700
   109.2 +++ b/xen/arch/powerpc/powerpc64/io.S	Fri Dec 15 11:32:58 2006 -0700
   109.3 @@ -23,6 +23,11 @@
   109.4  #include <asm/processor.h>
   109.5  #include <asm/percpu.h>
   109.6  
   109.7 +/* There is no reason why I can't use a tlbie, which should be less
   109.8 + * "destructive" but useing SLBIE proves to be more stable result.
   109.9 + */
  109.10 +#define INVALIDATE_ERAT_WITH_SLBIE
  109.11 +
  109.12  /* Xen runs in real mode (i.e. untranslated, MMU disabled). This avoids TLB
  109.13   * flushes and also makes it easy to access all domains' memory. However, on
  109.14   * PowerPC real mode accesses are cacheable, which is good for general
  109.15 @@ -34,12 +39,14 @@
  109.16   * make the access, then re-enable it...
  109.17   */
  109.18  
  109.19 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
  109.20  /* Not all useful assemblers understand 'tlbiel'.
  109.21   * 'addr' is a GPR containing the address being accessed.
  109.22   */
  109.23  .macro tlbiel addr
  109.24  	.long 0x7c000224 | (\addr << 11)
  109.25  .endm
  109.26 +#endif
  109.27  
  109.28  .macro DISABLE_DCACHE addr
  109.29  	mfmsr r8
  109.30 @@ -48,29 +55,53 @@
  109.31  	ori r6, r6, MSR_EE
  109.32  	andc r5, r8, r6
  109.33  	mtmsr r5
  109.34 +	sync
  109.35  
  109.36 -	/* set HID4.RM_CI */
  109.37 +#ifdef INVALIDATE_ERAT_WITH_SLBIE 
  109.38 +	/* create an slbie entry for the io setting a high order bit
  109.39 +	 * to avoid any important SLBs */
  109.40 +	extldi r0, \addr, 36, 0 
  109.41 +#endif
  109.42 +	/* setup HID4.RM_CI */
  109.43  	mfspr r9, SPRN_HID4
  109.44  	li r6, 0x100
  109.45  	sldi r6, r6, 32
  109.46 -	or r5, r9, r6
  109.47 -	tlbiel \addr /* invalidate the ERAT entry */
  109.48 -	sync
  109.49 -	mtspr SPRN_HID4, r5
  109.50 +	or r10, r9, r6
  109.51 +
  109.52 +	/* Mark the processor as "in CI mode" */
  109.53 +	li r7,0
  109.54 +	mfspr r5, SPRN_PIR
  109.55 +	li r6, MCK_CPU_STAT_CI
  109.56 +	/* store that we are in a CI routine */
  109.57 +	stb r6, MCK_CPU_STAT_BASE(r5)
  109.58 +	/* r7 = MCK_CPU_STAT_CI IO in progress */
  109.59 +	mr r7, r5
  109.60 +	lwsync
  109.61 +
  109.62 +	/* switch modes */
  109.63 +	mtspr SPRN_HID4, r10
  109.64 +	/* invalidate the ERAT entry */
  109.65 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
  109.66 +	slbie r0
  109.67 +#else
  109.68 +	tlbiel \addr
  109.69 +#endif
  109.70  	isync
  109.71  
  109.72 -	/* Mark the processor as "in CI mode" */
  109.73 -	mfspr r5, SPRN_PIR
  109.74 -	li r6, MCK_CPU_STAT_CI
  109.75 -	stb r6, MCK_CPU_STAT_BASE(r5)
  109.76 -	sync
  109.77  .endm
  109.78  
  109.79  .macro ENABLE_DCACHE addr
  109.80 -	/* re-zero HID4.RM_CI */
  109.81 +	/* r7 = 0, IO is complete */
  109.82 +	li r7, 0
  109.83 +	lwsync
  109.84 +	/* restore HID4.RM_CI */
  109.85 +	mtspr SPRN_HID4, r9
  109.86 +	/* invalidate the ERAT entry */
  109.87 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
  109.88 +	slbie r0
  109.89 +#else
  109.90  	tlbiel \addr /* invalidate the ERAT entry */
  109.91 -	sync
  109.92 -	mtspr SPRN_HID4, r9
  109.93 +#endif
  109.94  	isync
  109.95  
  109.96  	/* Mark the processor as "out of CI mode" */
  109.97 @@ -83,9 +114,13 @@
  109.98  	mtmsr r8
  109.99  .endm
 109.100  
 109.101 -/* The following assembly cannot use r8 or r9 since they hold original
 109.102 - * values of msr and hid4 repectively
 109.103 +/* The following assembly cannot use some registers since they hold original
 109.104 + * values of we need to keep
 109.105   */
 109.106 +#undef r0
 109.107 +#define r0 do_not_use_r0
 109.108 +#undef r7
 109.109 +#define r7 do_not_use_r7
 109.110  #undef r8
 109.111  #define r8 do_not_use_r8
 109.112  #undef r9
   110.1 --- a/xen/arch/powerpc/powerpc64/ppc970.c	Fri Dec 15 10:59:33 2006 -0700
   110.2 +++ b/xen/arch/powerpc/powerpc64/ppc970.c	Fri Dec 15 11:32:58 2006 -0700
   110.3 @@ -30,6 +30,7 @@
   110.4  #include <asm/powerpc64/procarea.h>
   110.5  #include <asm/powerpc64/processor.h>
   110.6  #include <asm/powerpc64/ppc970-hid.h>
   110.7 +#include "scom.h"
   110.8  
   110.9  #undef DEBUG
  110.10  #undef SERIALIZE
  110.11 @@ -38,48 +39,77 @@ struct cpu_caches cpu_caches = {
  110.12      .dline_size = 0x80,
  110.13      .log_dline_size = 7,
  110.14      .dlines_per_page = PAGE_SIZE >> 7,
  110.15 +    .isize = (64 << 10),        /* 64 KiB */
  110.16      .iline_size = 0x80,
  110.17      .log_iline_size = 7,
  110.18      .ilines_per_page = PAGE_SIZE >> 7,
  110.19  };
  110.20  
  110.21 +
  110.22 +void cpu_flush_icache(void)
  110.23 +{
  110.24 +    union hid1 hid1;
  110.25 +    ulong flags;
  110.26 +    ulong ea;
  110.27 +
  110.28 +    local_irq_save(flags);
  110.29 +
  110.30 +    /* uses special processor mode that forces a real address match on
  110.31 +     * the whole line */
  110.32 +    hid1.word = mfhid1();
  110.33 +    hid1.bits.en_icbi = 1;
  110.34 +    mthid1(hid1.word);
  110.35 +
  110.36 +    for (ea = 0; ea < cpu_caches.isize; ea += cpu_caches.iline_size)
  110.37 +        icbi(ea);
  110.38 +
  110.39 +    sync();
  110.40 +
  110.41 +    hid1.bits.en_icbi = 0;
  110.42 +    mthid1(hid1.word);
  110.43 +
  110.44 +    local_irq_restore(flags);
  110.45 +}
  110.46 +
  110.47 +
  110.48  struct rma_settings {
  110.49 -    int order;
  110.50 +    int log;
  110.51      int rmlr_0;
  110.52      int rmlr_1_2;
  110.53  };
  110.54  
  110.55 -static struct rma_settings rma_orders[] = {
  110.56 -    { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */
  110.57 -    { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
  110.58 -    { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
  110.59 -    { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */
  110.60 -    { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */
  110.61 -    { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
  110.62 +static struct rma_settings rma_logs[] = {
  110.63 +    { .log = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */
  110.64 +    { .log = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
  110.65 +    { .log = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
  110.66 +    { .log = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */
  110.67 +    { .log = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */
  110.68 +    { .log = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
  110.69  };
  110.70  
  110.71  static uint log_large_page_sizes[] = {
  110.72      4 + 20, /* (1 << 4) == 16M */
  110.73  };
  110.74  
  110.75 -static struct rma_settings *cpu_find_rma(unsigned int order)
  110.76 +static struct rma_settings *cpu_find_rma(unsigned int log)
  110.77  {
  110.78      int i;
  110.79 -    for (i = 0; i < ARRAY_SIZE(rma_orders); i++) {
  110.80 -        if (rma_orders[i].order == order)
  110.81 -            return &rma_orders[i];
  110.82 +
  110.83 +    for (i = 0; i < ARRAY_SIZE(rma_logs); i++) {
  110.84 +        if (rma_logs[i].log == log)
  110.85 +            return &rma_logs[i];
  110.86      }
  110.87      return NULL;
  110.88  }
  110.89  
  110.90  unsigned int cpu_default_rma_order_pages(void)
  110.91  {
  110.92 -    return rma_orders[0].order - PAGE_SHIFT;
  110.93 +    return rma_logs[0].log - PAGE_SHIFT;
  110.94  }
  110.95  
  110.96 -int cpu_rma_valid(unsigned int log)
  110.97 +int cpu_rma_valid(unsigned int order)
  110.98  {
  110.99 -    return cpu_find_rma(log) != NULL;
 110.100 +    return cpu_find_rma(order + PAGE_SHIFT) != NULL;
 110.101  }
 110.102  
 110.103  unsigned int cpu_large_page_orders(uint *sizes, uint max)
 110.104 @@ -163,8 +193,11 @@ void cpu_initialize(int cpuid)
 110.105      mtdec(timebase_freq);
 110.106      mthdec(timebase_freq);
 110.107  
 110.108 -    hid0.bits.nap = 1;      /* NAP */
 110.109 +    /* FIXME Do not set the NAP bit in HID0 until we have had a chance
 110.110 +     * to audit the safe halt and idle loop code. */
 110.111 +    hid0.bits.nap = 0;      /* NAP */
 110.112      hid0.bits.dpm = 1;      /* Dynamic Power Management */
 110.113 +
 110.114      hid0.bits.nhr = 1;      /* Not Hard Reset */
 110.115      hid0.bits.hdice_en = 1; /* enable HDEC */
 110.116      hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */
   111.1 --- a/xen/arch/powerpc/powerpc64/ppc970_machinecheck.c	Fri Dec 15 10:59:33 2006 -0700
   111.2 +++ b/xen/arch/powerpc/powerpc64/ppc970_machinecheck.c	Fri Dec 15 11:32:58 2006 -0700
   111.3 @@ -24,6 +24,8 @@
   111.4  #include <public/xen.h>
   111.5  #include <asm/processor.h>
   111.6  #include <asm/percpu.h>
   111.7 +#include <asm/debugger.h>
   111.8 +#include "scom.h"
   111.9  
  111.10  #define MCK_SRR1_INSN_FETCH_UNIT    0x0000000000200000 /* 42 */
  111.11  #define MCK_SRR1_LOAD_STORE         0x0000000000100000 /* 43 */
  111.12 @@ -54,6 +56,8 @@ int cpu_machinecheck(struct cpu_user_reg
  111.13      if (mck_cpu_stats[mfpir()] != 0)
  111.14          printk("While in CI IO\n");
  111.15  
  111.16 +    show_backtrace_regs(regs);
  111.17 +
  111.18      printk("SRR1: 0x%016lx\n", regs->msr);
  111.19      if (regs->msr & MCK_SRR1_INSN_FETCH_UNIT)
  111.20          printk("42: Exception caused by Instruction Fetch Unit (IFU)\n"
  111.21 @@ -67,6 +71,7 @@ int cpu_machinecheck(struct cpu_user_reg
  111.22      case 0:
  111.23          printk("0b00: Likely caused by an asynchronous machine check,\n"
  111.24                 "      see SCOM Asynchronous Machine Check Register\n");
  111.25 +        cpu_scom_AMCR();
  111.26          break;
  111.27      case MCK_SRR1_CAUSE_SLB_PAR:
  111.28          printk("0b01: Exception caused by an SLB parity error detected\n"
  111.29 @@ -116,5 +121,5 @@ int cpu_machinecheck(struct cpu_user_reg
  111.30          dump_segments(0);
  111.31      }
  111.32  
  111.33 -    return 0; /* for now lets not recover; */
  111.34 +    return 0; /* for now lets not recover */
  111.35  }
   112.1 --- a/xen/arch/powerpc/powerpc64/ppc970_scom.c	Fri Dec 15 10:59:33 2006 -0700
   112.2 +++ b/xen/arch/powerpc/powerpc64/ppc970_scom.c	Fri Dec 15 11:32:58 2006 -0700
   112.3 @@ -22,33 +22,17 @@
   112.4  #include <xen/types.h>
   112.5  #include <xen/lib.h>
   112.6  #include <xen/console.h>
   112.7 +#include <xen/errno.h>
   112.8 +#include <asm/delay.h>
   112.9 +#include <asm/processor.h>
  112.10 +#include "scom.h"
  112.11 +
  112.12 +#undef CONFIG_SCOM
  112.13  
  112.14  #define SPRN_SCOMC 276
  112.15  #define SPRN_SCOMD 277
  112.16 -
  112.17 -static inline void mtscomc(ulong scomc)
  112.18 -{
  112.19 -    __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomc), "i"(SPRN_SCOMC));
  112.20 -}
  112.21 -
  112.22 -static inline ulong mfscomc(void)
  112.23 -{
  112.24 -    ulong scomc;
  112.25 -    __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomc): "i"(SPRN_SCOMC));
  112.26 -    return scomc;
  112.27 -}
  112.28 -
  112.29 -static inline void mtscomd(ulong scomd)
  112.30 -{
  112.31 -    __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomd), "i"(SPRN_SCOMD));
  112.32 -}
  112.33 -
  112.34 -static inline ulong mfscomd(void)
  112.35 -{
  112.36 -    ulong scomd;
  112.37 -    __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomd): "i"(SPRN_SCOMD));
  112.38 -    return scomd;
  112.39 -}
  112.40 +#define SCOMC_READ 1
  112.41 +#define SCOMC_WRITE (!(SCOMC_READ))
  112.42  
  112.43  union scomc {
  112.44      struct scomc_bits {
  112.45 @@ -68,50 +52,133 @@ union scomc {
  112.46  };
  112.47  
  112.48  
  112.49 -static inline ulong read_scom(ulong addr)
  112.50 +int cpu_scom_read(uint addr, ulong *d)
  112.51  {
  112.52      union scomc c;
  112.53 -    ulong d;
  112.54 +    ulong flags;
  112.55 +
  112.56 +    /* drop the low 8bits (including parity) */
  112.57 +    addr >>= 8;
  112.58  
  112.59 -    c.word = 0;
  112.60 -    c.bits.addr = addr;
  112.61 -    c.bits.RW = 0;
  112.62 +    /* these give iface errors because the addresses are not software
  112.63 +     * accessible */
  112.64 +    BUG_ON(addr & 0x8000);
  112.65 +
  112.66 +    for (;;) {
  112.67 +        c.word = 0;
  112.68 +        c.bits.addr = addr;
  112.69 +        c.bits.RW = SCOMC_READ;
  112.70  
  112.71 -    mtscomc(c.word);
  112.72 -    d = mfscomd();
  112.73 -    c.word = mfscomc();
  112.74 -    if (c.bits.failure)
  112.75 -        panic("scom status: 0x%016lx\n", c.word);
  112.76 +        local_irq_save(flags);
  112.77 +        asm volatile (
  112.78 +            "sync         \n\t"
  112.79 +            "mtspr %2, %0 \n\t"
  112.80 +            "isync        \n\t"
  112.81 +            "mfspr %1, %3 \n\t"
  112.82 +            "isync        \n\t"
  112.83 +            "mfspr %0, %2 \n\t"
  112.84 +            "isync        \n\t"
  112.85 +            : "+r" (c.word), "=r" (*d)
  112.86 +            : "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
  112.87 +
  112.88 +        local_irq_restore(flags);
  112.89 +        /* WARNING! older 970s (pre FX) shift the bits right 1 position */
  112.90  
  112.91 -    return d;
  112.92 +        if (!c.bits.failure)
  112.93 +            return 0;
  112.94 +
  112.95 +        /* deal with errors */
  112.96 +        /* has SCOM been disabled? */
  112.97 +        if (c.bits.disabled)
  112.98 +            return -ENOSYS;
  112.99 +
 112.100 +        /* we were passed a bad addr return -1 */
 112.101 +        if (c.bits.addr_error)
 112.102 +            return -EINVAL;
 112.103 +
 112.104 +        /* this is way bad and we will checkstop soon */
 112.105 +        BUG_ON(c.bits.proto_error);
 112.106 +
 112.107 +        if (c.bits.iface_error)
 112.108 +            udelay(10);
 112.109 +    }
 112.110  }
 112.111  
 112.112 -static inline void write_scom(ulong addr, ulong val)
 112.113 +int cpu_scom_write(uint addr, ulong d)
 112.114  {
 112.115      union scomc c;
 112.116 +    ulong flags;
 112.117  
 112.118 -    c.word = 0;
 112.119 -    c.bits.addr = addr;
 112.120 -    c.bits.RW = 1;
 112.121 +    /* drop the low 8bits (including parity) */
 112.122 +    addr >>= 8;
 112.123 +
 112.124 +    /* these give iface errors because the addresses are not software
 112.125 +     * accessible */
 112.126 +    BUG_ON(addr & 0x8000);
 112.127 +
 112.128 +    for (;;) {
 112.129 +        c.word = 0;
 112.130 +        c.bits.addr = addr;
 112.131 +        c.bits.RW = SCOMC_WRITE;
 112.132  
 112.133 -    mtscomd(val);
 112.134 -    mtscomc(c.word);
 112.135 -    c.word = mfscomc();
 112.136 -    if (c.bits.failure)
 112.137 -        panic("scom status: 0x%016lx\n", c.word);
 112.138 +        local_irq_save(flags);
 112.139 +        asm volatile(
 112.140 +            "sync         \n\t"
 112.141 +            "mtspr %3, %1 \n\t"
 112.142 +            "isync        \n\t"
 112.143 +            "mtspr %2, %0 \n\t"
 112.144 +            "isync        \n\t"
 112.145 +            "mfspr %0, %2 \n\t"
 112.146 +            "isync        \n\t"
 112.147 +            : "+r" (c.word)
 112.148 +            : "r" (d), "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
 112.149 +        local_irq_restore(flags);
 112.150 +
 112.151 +        if (!c.bits.failure)
 112.152 +            return 0;
 112.153 +
 112.154 +        /* has SCOM been disabled? */
 112.155 +        if (c.bits.disabled)
 112.156 +            return -ENOSYS;
 112.157 +
 112.158 +        /* we were passed a bad addr return -1 */
 112.159 +        if (c.bits.addr_error)
 112.160 +            return -EINVAL;
 112.161 +
 112.162 +        /* this is way bad and we will checkstop soon */
 112.163 +        BUG_ON(c.bits.proto_error);
 112.164 +
 112.165 +        /* check for iface and retry */
 112.166 +        if (c.bits.iface_error)
 112.167 +            udelay(10);
 112.168 +    }
 112.169  }
 112.170  
 112.171 -#define SCOM_AMCS_REG      0x022601
 112.172 -#define SCOM_AMCS_AND_MASK 0x022700
 112.173 -#define SCOM_AMCS_OR_MASK  0x022800
 112.174 -#define SCOM_CMCE          0x030901
 112.175 -#define SCOM_PMCR          0x400801
 112.176 -
 112.177  void cpu_scom_init(void)
 112.178  {
 112.179 -#ifdef not_yet
 112.180 -    console_start_sync();
 112.181 -    printk("scom PMCR: 0x%016lx\n", read_scom(SCOM_PMCR));
 112.182 -    console_end_sync();
 112.183 +#ifdef CONFIG_SCOM
 112.184 +    ulong val;
 112.185 +    if (PVR_REV(mfpvr()) == 0x0300) {
 112.186 +        /* these address are only good for 970FX */
 112.187 +        console_start_sync();
 112.188 +        if (!cpu_scom_read(SCOM_PTSR, &val))
 112.189 +            printk("SCOM PTSR: 0x%016lx\n", val);
 112.190 +
 112.191 +        console_end_sync();
 112.192 +    }
 112.193  #endif
 112.194  }
 112.195 +
 112.196 +void cpu_scom_AMCR(void)
 112.197 +{
 112.198 +#ifdef CONFIG_SCOM
 112.199 +    ulong val;
 112.200 +
 112.201 +    if (PVR_REV(mfpvr()) == 0x0300) {
 112.202 +        /* these address are only good for 970FX */
 112.203 +        cpu_scom_read(SCOM_AMC_REG, &val);
 112.204 +        printk("SCOM AMCR: 0x%016lx\n", val);
 112.205 +    }
 112.206 +#endif
 112.207 +}
 112.208 +
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/xen/arch/powerpc/powerpc64/scom.h	Fri Dec 15 11:32:58 2006 -0700
   113.3 @@ -0,0 +1,39 @@
   113.4 +/*
   113.5 + * This program is free software; you can redistribute it and/or modify
   113.6 + * it under the terms of the GNU General Public License as published by
   113.7 + * the Free Software Foundation; either version 2 of the License, or
   113.8 + * (at your option) any later version.
   113.9 + *
  113.10 + * This program is distributed in the hope that it will be useful,
  113.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  113.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  113.13 + * GNU General Public License for more details.
  113.14 + *
  113.15 + * You should have received a copy of the GNU General Public License
  113.16 + * along with this program; if not, write to the Free Software
  113.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  113.18 + *
  113.19 + * Copyright (C) IBM Corp. 2006
  113.20 + *
  113.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
  113.22 + */
  113.23 +
  113.24 +#ifndef _ARCH_POWERPC_POWERPC64_SCOM_H_
  113.25 +#define _ARCH_POWERPC_POWERPC64_SCOM_H_
  113.26 +
  113.27 +extern void cpu_scom_init(void);
  113.28 +int cpu_scom_read(unsigned int addr, unsigned long *d);
  113.29 +int cpu_scom_write(unsigned int addr, unsigned long d);
  113.30 +void cpu_scom_AMCR(void);
  113.31 +
  113.32 +/* SCOMC addresses are 16bit but we are given 24 bits in the
  113.33 + * books. The low oerder 8 bits are some kinda parity thin and should
  113.34 + * be ignored */
  113.35 +#define SCOM_AMC_REG       0x022601
  113.36 +#define SCOM_AMC_AND_MASK  0x022700
  113.37 +#define SCOM_AMC_OR_MASK   0x022800
  113.38 +#define SCOM_CMCE          0x030901
  113.39 +#define SCOM_PMCR          0x400801
  113.40 +#define SCOM_PTSR          0x408001
  113.41 +
  113.42 +#endif
   114.1 --- a/xen/arch/powerpc/powerpc64/traps.c	Fri Dec 15 10:59:33 2006 -0700
   114.2 +++ b/xen/arch/powerpc/powerpc64/traps.c	Fri Dec 15 11:32:58 2006 -0700
   114.3 @@ -48,7 +48,3 @@ void show_registers(struct cpu_user_regs
   114.4      console_end_sync();
   114.5  }
   114.6  
   114.7 -void show_execution_state(struct cpu_user_regs *regs)
   114.8 -{
   114.9 -    show_registers(regs);
  114.10 -}
   115.1 --- a/xen/arch/powerpc/rtas.c	Fri Dec 15 10:59:33 2006 -0700
   115.2 +++ b/xen/arch/powerpc/rtas.c	Fri Dec 15 11:32:58 2006 -0700
   115.3 @@ -13,12 +13,90 @@
   115.4   * along with this program; if not, write to the Free Software
   115.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   115.6   *
   115.7 - * Copyright (C) IBM Corp. 2005
   115.8 + * Copyright (C) IBM Corp. 2006
   115.9   *
  115.10   * Authors: Jimi Xenidis <jimix@watson.ibm.com>
  115.11   */
  115.12  
  115.13  #include <xen/config.h>
  115.14 +#include <xen/init.h>
  115.15 +#include <xen/lib.h>
  115.16 +#include <xen/errno.h>
  115.17 +#include "of-devtree.h"
  115.18 +#include "rtas.h"
  115.19  
  115.20 -int rtas_halt = -1;
  115.21 -int rtas_reboot = -1;
  115.22 +static int rtas_halt_token = -1;
  115.23 +static int rtas_reboot_token = -1;
  115.24 +int rtas_entry;
  115.25 +unsigned long rtas_msr;
  115.26 +unsigned long rtas_base;
  115.27 +unsigned long rtas_end;
  115.28 +
  115.29 +struct rtas_args {
  115.30 +    int ra_token;
  115.31 +    int ra_nargs;
  115.32 +    int ra_nrets;
  115.33 +    int ra_args[10];
  115.34 +} __attribute__ ((aligned(8)));
  115.35 +
  115.36 +static int rtas_call(struct rtas_args *r)
  115.37 +{
  115.38 +    if (rtas_entry == 0)
  115.39 +        return -ENOSYS;
  115.40 +
  115.41 +    return prom_call(r, rtas_base, rtas_entry, rtas_msr);
  115.42 +}
  115.43 +
  115.44 +int __init rtas_init(void *m)
  115.45 +{
  115.46 +    static const char halt[] = "power-off";
  115.47 +    static const char reboot[] = "system-reboot";
  115.48 +    ofdn_t n;
  115.49 +
  115.50 +    if (rtas_entry == 0)
  115.51 +        return -ENOSYS;
  115.52 +
  115.53 +    n = ofd_node_find(m, "/rtas");
  115.54 +    if (n <= 0)
  115.55 +        return -ENOSYS;
  115.56 +
  115.57 +    ofd_getprop(m, n, halt,
  115.58 +                &rtas_halt_token, sizeof (rtas_halt_token));
  115.59 +    ofd_getprop(m, n, reboot,
  115.60 +                &rtas_reboot_token, sizeof (rtas_reboot_token));
  115.61 +    return 1;
  115.62 +}
  115.63 +
  115.64 +int
  115.65 +rtas_halt(void)
  115.66 +{
  115.67 +    struct rtas_args r;
  115.68 +
  115.69 +    if (rtas_halt_token == -1)
  115.70 +        return -1;
  115.71 +
  115.72 +    r.ra_token = rtas_halt_token;
  115.73 +    r.ra_nargs = 2;
  115.74 +    r.ra_nrets = 1;
  115.75 +    r.ra_args[0] = 0;
  115.76 +    r.ra_args[1] = 0;
  115.77 +
  115.78 +    return rtas_call(&r);
  115.79 +}
  115.80 +
  115.81 +int
  115.82 +rtas_reboot(void)
  115.83 +{
  115.84 +    struct rtas_args r;
  115.85 +
  115.86 +    if (rtas_reboot_token == -1)
  115.87 +        return -ENOSYS;
  115.88 +
  115.89 +    r.ra_token = rtas_reboot_token;
  115.90 +    r.ra_nargs = 2;
  115.91 +    r.ra_nrets = 1;
  115.92 +    r.ra_args[0] = 0;
  115.93 +    r.ra_args[1] = 0;
  115.94 +
  115.95 +    return rtas_call(&r);
  115.96 +}
   116.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.2 +++ b/xen/arch/powerpc/rtas.h	Fri Dec 15 11:32:58 2006 -0700
   116.3 @@ -0,0 +1,34 @@
   116.4 +/*
   116.5 + * This program is free software; you can redistribute it and/or modify
   116.6 + * it under the terms of the GNU General Public License as published by
   116.7 + * the Free Software Foundation; either version 2 of the License, or
   116.8 + * (at your option) any later version.
   116.9 + *
  116.10 + * This program is distributed in the hope that it will be useful,
  116.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  116.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  116.13 + * GNU General Public License for more details.
  116.14 + *
  116.15 + * You should have received a copy of the GNU General Public License
  116.16 + * along with this program; if not, write to the Free Software
  116.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  116.18 + *
  116.19 + * Copyright (C) IBM Corp. 2006
  116.20 + *
  116.21 + * Authors: Jimi Xenidis <jimix@us.ibm.com>
  116.22 + */
  116.23 +
  116.24 +#ifndef _ARCH_POWERPC_RTAS_H_
  116.25 +#define _ARCH_POWERPC_RTAS_H_
  116.26 +
  116.27 +extern int rtas_entry;
  116.28 +extern unsigned long rtas_msr;
  116.29 +extern unsigned long rtas_base;
  116.30 +extern unsigned long rtas_end;
  116.31 +
  116.32 +extern int prom_call(void *arg, unsigned base,
  116.33 +                     unsigned long func, unsigned long msr);
  116.34 +extern int rtas_init(void *);
  116.35 +extern int rtas_halt(void);
  116.36 +extern int rtas_reboot(void);
  116.37 +#endif
   117.1 --- a/xen/arch/powerpc/setup.c	Fri Dec 15 10:59:33 2006 -0700
   117.2 +++ b/xen/arch/powerpc/setup.c	Fri Dec 15 11:32:58 2006 -0700
   117.3 @@ -1,8 +1,8 @@
   117.4  /*
   117.5 - * This program is free software; you can redistribute it and/or modify
   117.6 - * it under the terms of the GNU General Public License as published by
   117.7 - * the Free Software Foundation; either version 2 of the License, or
   117.8 - * (at your option) any later version.
   117.9 + * This program is free software; you can redistribute it and/or
  117.10 + * modify it under the terms of the GNU General Public License as
  117.11 + * published by the Free Software Foundation; either version 2 of the
  117.12 + * License, or (at your option) any later version.
  117.13   *
  117.14   * This program is distributed in the hope that it will be useful,
  117.15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  117.16 @@ -35,8 +35,10 @@
  117.17  #include <xen/gdbstub.h>
  117.18  #include <xen/symbols.h>
  117.19  #include <xen/keyhandler.h>
  117.20 +#include <xen/numa.h>
  117.21  #include <acm/acm_hooks.h>
  117.22  #include <public/version.h>
  117.23 +#include <asm/mpic.h>
  117.24  #include <asm/processor.h>
  117.25  #include <asm/desc.h>
  117.26  #include <asm/cache.h>
  117.27 @@ -47,6 +49,7 @@
  117.28  #include "exceptions.h"
  117.29  #include "of-devtree.h"
  117.30  #include "oftree.h"
  117.31 +#include "rtas.h"
  117.32  
  117.33  #define DEBUG
  117.34  
  117.35 @@ -75,10 +78,7 @@ ulong oftree_len;
  117.36  ulong oftree_end;
  117.37  
  117.38  uint cpu_hard_id[NR_CPUS] __initdata;
  117.39 -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
  117.40 -cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
  117.41  cpumask_t cpu_present_map;
  117.42 -cpumask_t cpu_possible_map;
  117.43  
  117.44  /* XXX get this from ISA node in device tree */
  117.45  char *vgabase;
  117.46 @@ -87,6 +87,8 @@ struct ns16550_defaults ns16550;
  117.47  
  117.48  extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
  117.49  
  117.50 +static struct domain *idle_domain;
  117.51 +
  117.52  volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
  117.53  
  117.54  int is_kernel_text(unsigned long addr)
  117.55 @@ -110,12 +112,28 @@ static void __init do_initcalls(void)
  117.56      }
  117.57  }
  117.58  
  117.59 -static void hw_probe_attn(unsigned char key, struct cpu_user_regs *regs)
  117.60 +
  117.61 +void noinline __attn(void)
  117.62  {
  117.63      /* To continue the probe will step over the ATTN instruction.  The
  117.64       * NOP is there to make sure there is something sane to "step
  117.65       * over" to. */
  117.66 -    asm volatile(".long 0x00000200; nop");
  117.67 +    console_start_sync();
  117.68 +    asm volatile(".long 0x200;nop");
  117.69 +    console_end_sync();
  117.70 +}
  117.71 +
  117.72 +static void key_hw_probe_attn(unsigned char key)
  117.73 +{
  117.74 +    __attn();
  117.75 +}
  117.76 +
  117.77 +static void key_ofdump(unsigned char key)
  117.78 +{
  117.79 +    printk("ofdump:\n");
  117.80 +    /* make sure the OF devtree is good */
  117.81 +    ofd_walk((void *)oftree, "devtree", OFD_ROOT,
  117.82 +             ofd_dump_props, OFD_DUMP_ALL);
  117.83  }
  117.84  
  117.85  static void percpu_init_areas(void)
  117.86 @@ -150,8 +168,6 @@ static void percpu_free_unused_areas(voi
  117.87  
  117.88  static void __init start_of_day(void)
  117.89  {
  117.90 -    struct domain *idle_domain;
  117.91 -
  117.92      init_IRQ();
  117.93  
  117.94      scheduler_init();
  117.95 @@ -166,37 +182,20 @@ static void __init start_of_day(void)
  117.96      /* for some reason we need to set our own bit in the thread map */
  117.97      cpu_set(0, cpu_sibling_map[0]);
  117.98  
  117.99 -    percpu_free_unused_areas();
 117.100 -
 117.101 -    {
 117.102 -        /* FIXME: Xen assumes that an online CPU is a schedualable
 117.103 -         * CPU, but we just are not there yet. Remove this fragment when
 117.104 -         * scheduling processors actually works. */
 117.105 -        int cpuid;
 117.106 -
 117.107 -        printk("WARNING!: Taking all secondary CPUs offline\n");
 117.108 -
 117.109 -        for_each_online_cpu(cpuid) {
 117.110 -            if (cpuid == 0)
 117.111 -                continue;
 117.112 -            cpu_clear(cpuid, cpu_online_map);
 117.113 -        }
 117.114 -    }
 117.115 -
 117.116      initialize_keytable();
 117.117      /* Register another key that will allow for the the Harware Probe
 117.118       * to be contacted, this works with RiscWatch probes and should
 117.119       * work with Chronos and FSPs */
 117.120