ia64/xen-unstable

changeset 13021:4762d73ced42

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Thu Dec 14 08:57:36 2006 -0700 (2006-12-14)
parents ed56ef3e9716 35c724302bdd
children 2fc3392d0889
files 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	Thu Dec 14 08:54:54 2006 -0700
     1.2 +++ b/.hgignore	Thu Dec 14 08:57:36 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	Thu Dec 14 08:54:54 2006 -0700
     2.2 +++ b/config/powerpc64.mk	Thu Dec 14 08:57:36 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	Thu Dec 14 08:54:54 2006 -0700
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c	Thu Dec 14 08:57:36 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/drivers/xen/core/smpboot.c	Thu Dec 14 08:54:54 2006 -0700
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Thu Dec 14 08:57:36 2006 -0700
     4.3 @@ -110,6 +110,18 @@ set_cpu_sibling_map(int cpu)
     4.4  	cpu_data[cpu].booted_cores = 1;
     4.5  }
     4.6  
     4.7 +static void
     4.8 +remove_siblinginfo(int cpu)
     4.9 +{
    4.10 +	phys_proc_id[cpu] = BAD_APICID;
    4.11 +	cpu_core_id[cpu]  = BAD_APICID;
    4.12 +
    4.13 +	cpus_clear(cpu_sibling_map[cpu]);
    4.14 +	cpus_clear(cpu_core_map[cpu]);
    4.15 +
    4.16 +	cpu_data[cpu].booted_cores = 0;
    4.17 +}
    4.18 +
    4.19  static int xen_smp_intr_init(unsigned int cpu)
    4.20  {
    4.21  	int rc;
    4.22 @@ -358,18 +370,6 @@ static int __init initialize_cpu_present
    4.23  }
    4.24  core_initcall(initialize_cpu_present_map);
    4.25  
    4.26 -static void
    4.27 -remove_siblinginfo(int cpu)
    4.28 -{
    4.29 -	phys_proc_id[cpu] = BAD_APICID;
    4.30 -	cpu_core_id[cpu]  = BAD_APICID;
    4.31 -
    4.32 -	cpus_clear(cpu_sibling_map[cpu]);
    4.33 -	cpus_clear(cpu_core_map[cpu]);
    4.34 -
    4.35 -	cpu_data[cpu].booted_cores = 0;
    4.36 -}
    4.37 -
    4.38  int __cpu_disable(void)
    4.39  {
    4.40  	cpumask_t map = cpu_online_map;
    4.41 @@ -433,7 +433,6 @@ int __devinit __cpu_up(unsigned int cpu)
    4.42  	set_cpu_sibling_map(cpu);
    4.43  	wmb();
    4.44  
    4.45 -
    4.46  	rc = xen_smp_intr_init(cpu);
    4.47  	if (rc) {
    4.48  		remove_siblinginfo(cpu);
     5.1 --- a/tools/blktap/drivers/blktapctrl.c	Thu Dec 14 08:54:54 2006 -0700
     5.2 +++ b/tools/blktap/drivers/blktapctrl.c	Thu Dec 14 08:57:36 2006 -0700
     5.3 @@ -57,6 +57,8 @@
     5.4  #include "blktapctrl.h"
     5.5  #include "tapdisk.h"
     5.6  
     5.7 +#define PIDFILE "/var/run/blktapctrl.pid"
     5.8 +
     5.9  #define NUM_POLL_FDS 2
    5.10  #define MSG_SIZE 4096
    5.11  #define MAX_TIMEOUT 10
    5.12 @@ -622,6 +624,42 @@ static void print_drivers(void)
    5.13  		DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
    5.14  } 
    5.15  
    5.16 +static void write_pidfile(long pid)
    5.17 +{
    5.18 +	char buf[100];
    5.19 +	int len;
    5.20 +	int fd;
    5.21 +	int flags;
    5.22 +
    5.23 +	fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);
    5.24 +	if (fd == -1) {
    5.25 +		DPRINTF("Opening pid file failed (%d)\n", errno);
    5.26 +		exit(1);
    5.27 +	}
    5.28 +
    5.29 +	/* We exit silently if daemon already running. */
    5.30 +	if (lockf(fd, F_TLOCK, 0) == -1)
    5.31 +		exit(0);
    5.32 +
    5.33 +	/* Set FD_CLOEXEC, so that tapdisk doesn't get this file
    5.34 +	   descriptor. */
    5.35 +	if ((flags = fcntl(fd, F_GETFD)) == -1) {
    5.36 +		DPRINTF("F_GETFD failed (%d)\n", errno);
    5.37 +		exit(1);
    5.38 +	}
    5.39 +	flags |= FD_CLOEXEC;
    5.40 +	if (fcntl(fd, F_SETFD, flags) == -1) {
    5.41 +		DPRINTF("F_SETFD failed (%d)\n", errno);
    5.42 +		exit(1);
    5.43 +	}
    5.44 +
    5.45 +	len = sprintf(buf, "%ld\n", pid);
    5.46 +	if (write(fd, buf, len) != len) {
    5.47 +		DPRINTF("Writing pid file failed (%d)\n", errno);
    5.48 +		exit(1);
    5.49 +	}
    5.50 +}
    5.51 +
    5.52  int main(int argc, char *argv[])
    5.53  {
    5.54  	char *devname;
    5.55 @@ -681,6 +719,7 @@ int main(int argc, char *argv[])
    5.56  	ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
    5.57  
    5.58  	process = getpid();
    5.59 +	write_pidfile(process);
    5.60  	ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );
    5.61  
    5.62  	/*Static pollhooks*/
    5.63 @@ -716,3 +755,13 @@ int main(int argc, char *argv[])
    5.64  	closelog();
    5.65  	return -1;
    5.66  }
    5.67 +
    5.68 +/*
    5.69 + * Local variables:
    5.70 + *  c-file-style: "linux"
    5.71 + *  indent-tabs-mode: t
    5.72 + *  c-indent-level: 8
    5.73 + *  c-basic-offset: 8
    5.74 + *  tab-width: 8
    5.75 + * End:
    5.76 + */
     6.1 --- a/tools/examples/external-device-migrate	Thu Dec 14 08:54:54 2006 -0700
     6.2 +++ b/tools/examples/external-device-migrate	Thu Dec 14 08:57:36 2006 -0700
     6.3 @@ -60,8 +60,8 @@ function evaluate_params()
     6.4  		-step)		step=$2; shift 2;;
     6.5  		-host)		host=$2; shift 2;;
     6.6  		-domname)	domname=$2; shift 2;;
     6.7 -		-type)		type=$2; shift 2;;
     6.8 -		-subtype)	subtype=$2; shift 2;;
     6.9 +		-type)		typ=$2; shift 2;;
    6.10 +		-subtype)	stype=$2; shift 2;;
    6.11  		-recover)	recover=1; shift;;
    6.12  		-help)		ext_dev_migrate_usage; exit 0;;
    6.13  		*)		break;;
     7.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Thu Dec 14 08:54:54 2006 -0700
     7.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Thu Dec 14 08:57:36 2006 -0700
     7.3 @@ -439,7 +439,12 @@ void cpu_physical_memory_rw(target_phys_
     7.4      int l, io_index;
     7.5      uint8_t *ptr;
     7.6      uint32_t val;
     7.7 -    
     7.8 +
     7.9 +#if defined(__i386__) || defined(__x86_64__)
    7.10 +    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    7.11 +    pthread_mutex_lock(&mutex);
    7.12 +#endif
    7.13 +
    7.14      while (len > 0) {
    7.15          /* How much can we copy before the next page boundary? */
    7.16          l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
    7.17 @@ -504,6 +509,10 @@ void cpu_physical_memory_rw(target_phys_
    7.18          buf += l;
    7.19          addr += l;
    7.20      }
    7.21 +
    7.22 +#if defined(__i386__) || defined(__x86_64__)
    7.23 +    pthread_mutex_unlock(&mutex);
    7.24 +#endif
    7.25  }
    7.26  #endif
    7.27  
     8.1 --- a/tools/ioemu/vl.c	Thu Dec 14 08:54:54 2006 -0700
     8.2 +++ b/tools/ioemu/vl.c	Thu Dec 14 08:57:36 2006 -0700
     8.3 @@ -5820,8 +5820,8 @@ static int qemu_map_cache_init(unsigned 
     8.4      if (nr_pages < max_pages)
     8.5          max_pages = nr_pages;
     8.6  
     8.7 -    nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT;
     8.8 -
     8.9 +    nr_buckets   = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1;
    8.10 +    nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
    8.11      fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
    8.12  
    8.13      mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
    8.14 @@ -5857,8 +5857,7 @@ uint8_t *qemu_map_cache(target_phys_addr
    8.15  
    8.16      entry = &mapcache_entry[address_index % nr_buckets];
    8.17  
    8.18 -    if (entry->vaddr_base == NULL || entry->paddr_index != address_index)
    8.19 -    { 
    8.20 +    if (entry->vaddr_base == NULL || entry->paddr_index != address_index) {
    8.21          /* We need to remap a bucket. */
    8.22          uint8_t *vaddr_base;
    8.23          unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
     9.1 --- a/tools/libaio/src/syscall-ppc.h	Thu Dec 14 08:54:54 2006 -0700
     9.2 +++ b/tools/libaio/src/syscall-ppc.h	Thu Dec 14 08:57:36 2006 -0700
     9.3 @@ -1,3 +1,6 @@
     9.4 +#include <asm/unistd.h>
     9.5 +#include <errno.h>
     9.6 +
     9.7  #define __NR_io_setup		227
     9.8  #define __NR_io_destroy		228
     9.9  #define __NR_io_getevents	229
    9.10 @@ -9,7 +12,7 @@
    9.11   * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
    9.12   * an error return status).
    9.13   */
    9.14 -
    9.15 +#ifndef __syscall_nr
    9.16  #define __syscall_nr(nr, type, name, args...)				\
    9.17  	unsigned long __sc_ret, __sc_err;				\
    9.18  	{								\
    9.19 @@ -37,6 +40,7 @@
    9.20  	}								\
    9.21  	if (__sc_err & 0x10000000) return -((int)__sc_ret);		\
    9.22  	return (type) __sc_ret
    9.23 +#endif
    9.24  
    9.25  #define __sc_loadargs_0(name, dummy...)					\
    9.26  	__sc_0 = __NR_##name
    10.1 --- a/tools/libxc/powerpc64/Makefile	Thu Dec 14 08:54:54 2006 -0700
    10.2 +++ b/tools/libxc/powerpc64/Makefile	Thu Dec 14 08:57:36 2006 -0700
    10.3 @@ -1,4 +1,6 @@
    10.4 +GUEST_SRCS-y += powerpc64/flatdevtree.c
    10.5  GUEST_SRCS-y += powerpc64/xc_linux_build.c
    10.6 -GUEST_SRCS-y += powerpc64/flatdevtree.c
    10.7 +GUEST_SRCS-y += powerpc64/xc_prose_build.c
    10.8 +GUEST_SRCS-y += powerpc64/utils.c
    10.9  
   10.10  CTRL_SRCS-y += powerpc64/xc_memory.c
    11.1 --- a/tools/libxc/powerpc64/flatdevtree.c	Thu Dec 14 08:54:54 2006 -0700
    11.2 +++ b/tools/libxc/powerpc64/flatdevtree.c	Thu Dec 14 08:57:36 2006 -0700
    11.3 @@ -220,6 +220,29 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
    11.4  	cxt->p_anchor = cxt->pres + 16;	/* over the terminator */
    11.5  }
    11.6  
    11.7 +int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size)
    11.8 +{
    11.9 +	const struct boot_param_header *bph = bphp;
   11.10 +	u64 *p_rsvmap = (u64 *)
   11.11 +		((char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
   11.12 +	u32 i;
   11.13 +
   11.14 +	for (i = 0;; i++) {
   11.15 +		u64 addr, sz;
   11.16 +
   11.17 +		addr = be64_to_cpu(p_rsvmap[i * 2]);
   11.18 +		sz = be64_to_cpu(p_rsvmap[i * 2 + 1]);
   11.19 +		if (addr == 0 && size == 0)
   11.20 +			break;
   11.21 +		if (m == i) {
   11.22 +			p_rsvmap[i * 2] = cpu_to_be64(physaddr);
   11.23 +			p_rsvmap[i * 2 + 1] = cpu_to_be64(size);
   11.24 +			return 0;
   11.25 +		}
   11.26 +	}
   11.27 +	return -1;
   11.28 +}
   11.29 +
   11.30  void ft_begin_tree(struct ft_cxt *cxt)
   11.31  {
   11.32  	cxt->p_begin = cxt->p_anchor;
    12.1 --- a/tools/libxc/powerpc64/flatdevtree.h	Thu Dec 14 08:54:54 2006 -0700
    12.2 +++ b/tools/libxc/powerpc64/flatdevtree.h	Thu Dec 14 08:57:36 2006 -0700
    12.3 @@ -66,8 +66,10 @@ void ft_prop_str(struct ft_cxt *cxt, con
    12.4  void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
    12.5  void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
    12.6  void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
    12.7 +int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size);
    12.8  
    12.9  void ft_dump_blob(const void *bphp);
   12.10 +void ft_backtrack_node(struct ft_cxt *cxt);
   12.11  void ft_merge_blob(struct ft_cxt *cxt, void *blob);
   12.12  
   12.13  void *ft_find_node(const void *bphp, const char *srch_path);
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/libxc/powerpc64/utils.c	Thu Dec 14 08:57:36 2006 -0700
    13.3 @@ -0,0 +1,211 @@
    13.4 +/*
    13.5 + * This program is free software; you can redistribute it and/or modify
    13.6 + * it under the terms of the GNU General Public License as published by
    13.7 + * the Free Software Foundation; either version 2 of the License, or
    13.8 + * (at your option) any later version.
    13.9 + *
   13.10 + * This program is distributed in the hope that it will be useful,
   13.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.13 + * GNU General Public License for more details.
   13.14 + *
   13.15 + * You should have received a copy of the GNU General Public License
   13.16 + * along with this program; if not, write to the Free Software
   13.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   13.18 + *
   13.19 + * Copyright (C) IBM Corporation 2006
   13.20 + *
   13.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   13.22 + *          Jimi Xenidis <jimix@watson.ibm.com>
   13.23 + */
   13.24 +#include <stdio.h>
   13.25 +#include <stdint.h>
   13.26 +#include <stdlib.h>
   13.27 +#include <string.h>
   13.28 +#include <unistd.h>
   13.29 +#include <fcntl.h>
   13.30 +#include <sys/types.h>
   13.31 +#include <inttypes.h>
   13.32 +
   13.33 +#include <xen/xen.h>
   13.34 +#include <xen/memory.h>
   13.35 +#include <xc_private.h>
   13.36 +#include <xg_private.h>
   13.37 +#include <xenctrl.h>
   13.38 +
   13.39 +#include "flatdevtree_env.h"
   13.40 +#include "flatdevtree.h"
   13.41 +#include "utils.h"
   13.42 +
   13.43 +unsigned long get_rma_pages(void *devtree)
   13.44 +{
   13.45 +    void *rma;
   13.46 +    uint64_t rma_reg[2];
   13.47 +    int rc;
   13.48 +
   13.49 +    rma = ft_find_node(devtree, "/memory@0");
   13.50 +    if (rma == NULL) {
   13.51 +        DPRINTF("couldn't find /memory@0\n");
   13.52 +        return 0;
   13.53 +    }
   13.54 +    rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
   13.55 +    if (rc < 0) {
   13.56 +        DPRINTF("couldn't get /memory@0/reg\n");
   13.57 +        return 0;
   13.58 +    }
   13.59 +    if (rma_reg[0] != 0) {
   13.60 +        DPRINTF("RMA did not start at 0\n");
   13.61 +        return 0;
   13.62 +    }
   13.63 +    return rma_reg[1] >> PAGE_SHIFT;
   13.64 +}
   13.65 +
   13.66 +int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
   13.67 +		       unsigned long nr_pages)
   13.68 +{
   13.69 +    int rc;
   13.70 +    int i;
   13.71 +    xen_pfn_t *p;
   13.72 +
   13.73 +    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   13.74 +    if (*page_array == NULL) {
   13.75 +        perror("malloc");
   13.76 +        return -1;
   13.77 +    }
   13.78 +
   13.79 +    DPRINTF("xc_get_pfn_list\n");
   13.80 +    /* We know that the RMA is machine contiguous so lets just get the
   13.81 +     * first MFN and fill the rest in ourselves */
   13.82 +    rc = xc_get_pfn_list(xc_handle, domid, *page_array, 1);
   13.83 +    if (rc == -1) {
   13.84 +        perror("Could not get the page frame list");
   13.85 +        return -1;
   13.86 +    }
   13.87 +    p = *page_array;
   13.88 +    for (i = 1; i < nr_pages; i++)
   13.89 +        p[i] = p[i - 1] + 1;
   13.90 +    return 0;
   13.91 +}
   13.92 +
   13.93 +int install_image(
   13.94 +        int xc_handle,
   13.95 +        int domid,
   13.96 +        xen_pfn_t *page_array,
   13.97 +        void *image,
   13.98 +        unsigned long paddr,
   13.99 +        unsigned long size)
  13.100 +{
  13.101 +    uint8_t *img = image;
  13.102 +    int i;
  13.103 +    int rc = 0;
  13.104 +
  13.105 +    if (paddr & ~PAGE_MASK) {
  13.106 +        printf("*** unaligned address\n");
  13.107 +        return -1;
  13.108 +    }
  13.109 +
  13.110 +    for (i = 0; i < size; i += PAGE_SIZE) {
  13.111 +        void *page = img + i;
  13.112 +        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
  13.113 +        xen_pfn_t mfn = page_array[pfn];
  13.114 +
  13.115 +        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
  13.116 +        if (rc < 0) {
  13.117 +            perror("xc_copy_to_domain_page");
  13.118 +            break;
  13.119 +        }
  13.120 +    }
  13.121 +    return rc;
  13.122 +}
  13.123 +
  13.124 +void *load_file(const char *path, unsigned long *filesize)
  13.125 +{
  13.126 +    void *img;
  13.127 +    ssize_t size;
  13.128 +    int fd;
  13.129 +
  13.130 +    DPRINTF("load_file(%s)\n", path);
  13.131 +
  13.132 +    fd = open(path, O_RDONLY);
  13.133 +    if (fd < 0) {
  13.134 +        perror(path);
  13.135 +        return NULL;
  13.136 +    }
  13.137 +
  13.138 +    size = lseek(fd, 0, SEEK_END);
  13.139 +    if (size < 0) {
  13.140 +        perror(path);
  13.141 +        close(fd);
  13.142 +        return NULL;
  13.143 +    }
  13.144 +    lseek(fd, 0, SEEK_SET);
  13.145 +
  13.146 +    img = malloc(size);
  13.147 +    if (img == NULL) {
  13.148 +        perror(path);
  13.149 +        close(fd);
  13.150 +        return NULL;
  13.151 +    }
  13.152 +
  13.153 +    size = read(fd, img, size);
  13.154 +    if (size <= 0) {
  13.155 +        perror(path);
  13.156 +        close(fd);
  13.157 +        free(img);
  13.158 +        return NULL;
  13.159 +    }
  13.160 +
  13.161 +    if (filesize)
  13.162 +        *filesize = size;
  13.163 +    close(fd);
  13.164 +    return img;
  13.165 +}
  13.166 +
  13.167 +int load_elf_kernel(
  13.168 +    int xc_handle,
  13.169 +    int domid,
  13.170 +    const char *kernel_path,
  13.171 +    struct domain_setup_info *dsi,
  13.172 +    xen_pfn_t *page_array)
  13.173 +{
  13.174 +    struct load_funcs load_funcs;
  13.175 +    char *kernel_img;
  13.176 +    unsigned long kernel_size;
  13.177 +    int rc;
  13.178 +
  13.179 +    /* load the kernel ELF file */
  13.180 +    kernel_img = load_file(kernel_path, &kernel_size);
  13.181 +    if (kernel_img == NULL) {
  13.182 +        rc = -1;
  13.183 +        goto out;
  13.184 +    }
  13.185 +
  13.186 +    DPRINTF("probe_elf\n");
  13.187 +    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
  13.188 +    if (rc < 0) {
  13.189 +        rc = -1;
  13.190 +        printf("%s is not an ELF file\n", kernel_path);
  13.191 +        goto out;
  13.192 +    }
  13.193 +
  13.194 +    DPRINTF("parseimage\n");
  13.195 +    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
  13.196 +    if (rc < 0) {
  13.197 +        rc = -1;
  13.198 +        goto out;
  13.199 +    }
  13.200 +
  13.201 +    DPRINTF("loadimage\n");
  13.202 +    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
  13.203 +            page_array, dsi);
  13.204 +
  13.205 +    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
  13.206 +    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
  13.207 +    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
  13.208 +    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
  13.209 +    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
  13.210 +
  13.211 +out:
  13.212 +    free(kernel_img);
  13.213 +    return rc;
  13.214 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/libxc/powerpc64/utils.h	Thu Dec 14 08:57:36 2006 -0700
    14.3 @@ -0,0 +1,38 @@
    14.4 +/*
    14.5 + * This program is free software; you can redistribute it and/or modify
    14.6 + * it under the terms of the GNU General Public License as published by
    14.7 + * the Free Software Foundation; either version 2 of the License, or
    14.8 + * (at your option) any later version.
    14.9 + *
   14.10 + * This program is distributed in the hope that it will be useful,
   14.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.13 + * GNU General Public License for more details.
   14.14 + *
   14.15 + * You should have received a copy of the GNU General Public License
   14.16 + * along with this program; if not, write to the Free Software
   14.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   14.18 + *
   14.19 + * Copyright (C) IBM Corporation 2006
   14.20 + *
   14.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   14.22 + *          Jimi Xenidis <jimix@watson.ibm.com>
   14.23 + */
   14.24 +
   14.25 +extern unsigned long get_rma_pages(void *devtree);
   14.26 +extern int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
   14.27 +			      unsigned long nr_pages);
   14.28 +extern int install_image(int xc_handle, int domid, xen_pfn_t *page_array,
   14.29 +			 void *image, unsigned long paddr, unsigned long size);
   14.30 +extern void *load_file(const char *path, unsigned long *filesize);
   14.31 +extern int load_elf_kernel(int xc_handle, int domid,  const char *kernel_path,
   14.32 +			   struct domain_setup_info *dsi,
   14.33 +			   xen_pfn_t *page_array);
   14.34 +
   14.35 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
   14.36 +
   14.37 +#define max(x,y) ({ \
   14.38 +        const typeof(x) _x = (x);       \
   14.39 +        const typeof(y) _y = (y);       \
   14.40 +        (void) (&_x == &_y);            \
   14.41 +        _x > _y ? _x : _y; })
    15.1 --- a/tools/libxc/powerpc64/xc_linux_build.c	Thu Dec 14 08:54:54 2006 -0700
    15.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c	Thu Dec 14 08:57:36 2006 -0700
    15.3 @@ -35,61 +35,11 @@
    15.4  
    15.5  #include "flatdevtree_env.h"
    15.6  #include "flatdevtree.h"
    15.7 +#include "utils.h"
    15.8  
    15.9  #define INITRD_ADDR (24UL << 20)
   15.10  #define DEVTREE_ADDR (16UL << 20)
   15.11  
   15.12 -#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
   15.13 -
   15.14 -#define max(x,y) ({ \
   15.15 -        const typeof(x) _x = (x);       \
   15.16 -        const typeof(y) _y = (y);       \
   15.17 -        (void) (&_x == &_y);            \
   15.18 -        _x > _y ? _x : _y; })
   15.19 -
   15.20 -static void *load_file(const char *path, unsigned long *filesize)
   15.21 -{
   15.22 -    void *img;
   15.23 -    ssize_t size;
   15.24 -    int fd;
   15.25 -
   15.26 -    DPRINTF("load_file(%s)\n", path);
   15.27 -
   15.28 -    fd = open(path, O_RDONLY);
   15.29 -    if (fd < 0) {
   15.30 -        perror(path);
   15.31 -        return NULL;
   15.32 -    }
   15.33 -
   15.34 -    size = lseek(fd, 0, SEEK_END);
   15.35 -    if (size < 0) {
   15.36 -        perror(path);
   15.37 -        close(fd);
   15.38 -        return NULL;
   15.39 -    }
   15.40 -    lseek(fd, 0, SEEK_SET);
   15.41 -
   15.42 -    img = malloc(size);
   15.43 -    if (img == NULL) {
   15.44 -        perror(path);
   15.45 -        close(fd);
   15.46 -        return NULL;
   15.47 -    }
   15.48 -
   15.49 -    size = read(fd, img, size);
   15.50 -    if (size <= 0) {
   15.51 -        perror(path);
   15.52 -        close(fd);
   15.53 -        free(img);
   15.54 -        return NULL;
   15.55 -    }
   15.56 -
   15.57 -    if (filesize)
   15.58 -        *filesize = size;
   15.59 -    close(fd);
   15.60 -    return img;
   15.61 -}
   15.62 -
   15.63  static int init_boot_vcpu(
   15.64      int xc_handle,
   15.65      int domid,
   15.66 @@ -128,37 +78,6 @@ static int init_boot_vcpu(
   15.67      return rc;
   15.68  }
   15.69  
   15.70 -static int install_image(
   15.71 -        int xc_handle,
   15.72 -        int domid,
   15.73 -        xen_pfn_t *page_array,
   15.74 -        void *image,
   15.75 -        unsigned long paddr,
   15.76 -        unsigned long size)
   15.77 -{
   15.78 -    uint8_t *img = image;
   15.79 -    int i;
   15.80 -    int rc = 0;
   15.81 -
   15.82 -    if (paddr & ~PAGE_MASK) {
   15.83 -        printf("*** unaligned address\n");
   15.84 -        return -1;
   15.85 -    }
   15.86 -
   15.87 -    for (i = 0; i < size; i += PAGE_SIZE) {
   15.88 -        void *page = img + i;
   15.89 -        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   15.90 -        xen_pfn_t mfn = page_array[pfn];
   15.91 -
   15.92 -        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   15.93 -        if (rc < 0) {
   15.94 -            perror("xc_copy_to_domain_page");
   15.95 -            break;
   15.96 -        }
   15.97 -    }
   15.98 -    return rc;
   15.99 -}
  15.100 -
  15.101  static int load_devtree(
  15.102      int xc_handle,
  15.103      int domid,
  15.104 @@ -167,10 +86,10 @@ static int load_devtree(
  15.105      unsigned long devtree_addr,
  15.106      uint64_t initrd_base,
  15.107      unsigned long initrd_len,
  15.108 -    start_info_t *si,
  15.109 -    unsigned long si_addr)
  15.110 +    start_info_t *start_info __attribute__((unused)),
  15.111 +    unsigned long start_info_addr)
  15.112  {
  15.113 -    uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
  15.114 +    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
  15.115      struct boot_param_header *header;
  15.116      void *chosen;
  15.117      void *xen;
  15.118 @@ -208,9 +127,14 @@ static int load_devtree(
  15.119          return rc;
  15.120      }
  15.121  
  15.122 +    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
  15.123 +    if (rc < 0) {
  15.124 +        DPRINTF("couldn't set initrd reservation\n");
  15.125 +        return ~0UL;
  15.126 +    }
  15.127 +
  15.128      /* start-info (XXX being removed soon) */
  15.129 -    rc = ft_set_prop(&devtree, xen, "start-info",
  15.130 -            start_info, sizeof(start_info));
  15.131 +    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
  15.132      if (rc < 0) {
  15.133          DPRINTF("couldn't set /xen/start-info\n");
  15.134          return rc;
  15.135 @@ -218,93 +142,21 @@ static int load_devtree(
  15.136  
  15.137      header = devtree;
  15.138      devtree_size = header->totalsize;
  15.139 +    {
  15.140 +        static const char dtb[] = "/tmp/xc_domU.dtb";
  15.141 +        int dfd = creat(dtb, 0666);
  15.142 +        if (dfd != -1) {
  15.143 +            write(dfd, devtree, devtree_size);
  15.144 +            close(dfd);
  15.145 +        } else
  15.146 +            DPRINTF("could not open(\"%s\")\n", dtb);
  15.147 +    }
  15.148  
  15.149      DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
  15.150      return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
  15.151                         devtree_size);
  15.152  }
  15.153  
  15.154 -unsigned long spin_list[] = {
  15.155 -#if 0
  15.156 -    0x100,
  15.157 -    0x200,
  15.158 -    0x300,
  15.159 -    0x380,
  15.160 -    0x400,
  15.161 -    0x480,
  15.162 -    0x500,
  15.163 -    0x700,
  15.164 -    0x900,
  15.165 -    0xc00,
  15.166 -#endif
  15.167 -    0
  15.168 -};
  15.169 -
  15.170 -/* XXX yes, this is a hack */
  15.171 -static void hack_kernel_img(char *img)
  15.172 -{
  15.173 -    const off_t file_offset = 0x10000;
  15.174 -    unsigned long *addr = spin_list;
  15.175 -
  15.176 -    while (*addr) {
  15.177 -        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
  15.178 -        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
  15.179 -        *instruction = 0x48000000;
  15.180 -        addr++;
  15.181 -    }
  15.182 -}
  15.183 -
  15.184 -static int load_kernel(
  15.185 -    int xc_handle,
  15.186 -    int domid,
  15.187 -    const char *kernel_path,
  15.188 -    struct domain_setup_info *dsi,
  15.189 -    xen_pfn_t *page_array)
  15.190 -{
  15.191 -    struct load_funcs load_funcs;
  15.192 -    char *kernel_img;
  15.193 -    unsigned long kernel_size;
  15.194 -    int rc;
  15.195 -
  15.196 -    /* load the kernel ELF file */
  15.197 -    kernel_img = load_file(kernel_path, &kernel_size);
  15.198 -    if (kernel_img == NULL) {
  15.199 -        rc = -1;
  15.200 -        goto out;
  15.201 -    }
  15.202 -
  15.203 -    hack_kernel_img(kernel_img);
  15.204 -
  15.205 -    DPRINTF("probe_elf\n");
  15.206 -    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
  15.207 -    if (rc < 0) {
  15.208 -        rc = -1;
  15.209 -        printf("%s is not an ELF file\n", kernel_path);
  15.210 -        goto out;
  15.211 -    }
  15.212 -
  15.213 -    DPRINTF("parseimage\n");
  15.214 -    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
  15.215 -    if (rc < 0) {
  15.216 -        rc = -1;
  15.217 -        goto out;
  15.218 -    }
  15.219 -
  15.220 -    DPRINTF("loadimage\n");
  15.221 -    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
  15.222 -            page_array, dsi);
  15.223 -
  15.224 -    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
  15.225 -    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
  15.226 -    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
  15.227 -    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
  15.228 -    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
  15.229 -
  15.230 -out:
  15.231 -    free(kernel_img);
  15.232 -    return rc;
  15.233 -}
  15.234 -
  15.235  static int load_initrd(
  15.236      int xc_handle,
  15.237      int domid,
  15.238 @@ -334,49 +186,38 @@ out:
  15.239      return rc;
  15.240  }
  15.241  
  15.242 -static unsigned long create_start_info(start_info_t *si,
  15.243 +static unsigned long create_start_info(
  15.244 +	void *devtree, start_info_t *start_info,
  15.245          unsigned int console_evtchn, unsigned int store_evtchn,
  15.246 -        unsigned long nr_pages)
  15.247 +	unsigned long nr_pages, unsigned long rma_pages)
  15.248  {
  15.249 -    unsigned long si_addr;
  15.250 -
  15.251 -    memset(si, 0, sizeof(*si));
  15.252 -    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
  15.253 -
  15.254 -    si->nr_pages = nr_pages;
  15.255 -    si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
  15.256 -    si->store_mfn = si->nr_pages - 2;
  15.257 -    si->store_evtchn = store_evtchn;
  15.258 -    si->console.domU.mfn = si->nr_pages - 3;
  15.259 -    si->console.domU.evtchn = console_evtchn;
  15.260 -    si_addr = (si->nr_pages - 4) << PAGE_SHIFT;
  15.261 -
  15.262 -    return si_addr;
  15.263 -}
  15.264 -
  15.265 -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
  15.266 -                          unsigned long *nr_pages)
  15.267 -{
  15.268 +    unsigned long start_info_addr;
  15.269 +    uint64_t rma_top;
  15.270      int rc;
  15.271  
  15.272 -    DPRINTF("xc_get_tot_pages\n");
  15.273 -    *nr_pages = xc_get_tot_pages(xc_handle, domid);
  15.274 -    DPRINTF("  0x%lx\n", *nr_pages);
  15.275 +    memset(start_info, 0, sizeof(*start_info));
  15.276 +    snprintf(start_info->magic, sizeof(start_info->magic),
  15.277 +             "xen-%d.%d-powerpc64HV", 3, 0);
  15.278 +
  15.279 +    rma_top = rma_pages << PAGE_SHIFT;
  15.280 +    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
  15.281  
  15.282 -    *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
  15.283 -    if (*page_array == NULL) {
  15.284 -        perror("malloc");
  15.285 -        return -1;
  15.286 +    start_info->nr_pages = nr_pages;
  15.287 +    start_info->shared_info = rma_top - PAGE_SIZE;
  15.288 +    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
  15.289 +    start_info->store_evtchn = store_evtchn;
  15.290 +    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
  15.291 +    start_info->console.domU.evtchn = console_evtchn;
  15.292 +    start_info_addr = rma_top - 4*PAGE_SIZE;
  15.293 +
  15.294 +    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
  15.295 +    if (rc < 0) {
  15.296 +        DPRINTF("couldn't set start_info reservation\n");
  15.297 +        return ~0UL;
  15.298      }
  15.299  
  15.300 -    DPRINTF("xc_get_pfn_list\n");
  15.301 -    rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
  15.302 -    if (rc != *nr_pages) {
  15.303 -        perror("Could not get the page frame list");
  15.304 -        return -1;
  15.305 -    }
  15.306  
  15.307 -    return 0;
  15.308 +    return start_info_addr;
  15.309  }
  15.310  
  15.311  static void free_page_array(xen_pfn_t *page_array)
  15.312 @@ -388,6 +229,7 @@ static void free_page_array(xen_pfn_t *p
  15.313  
  15.314  int xc_linux_build(int xc_handle,
  15.315                     uint32_t domid,
  15.316 +                   unsigned int mem_mb,
  15.317                     const char *image_name,
  15.318                     const char *initrd_name,
  15.319                     const char *cmdline,
  15.320 @@ -399,7 +241,7 @@ int xc_linux_build(int xc_handle,
  15.321                     unsigned long *console_mfn,
  15.322                     void *devtree)
  15.323  {
  15.324 -    start_info_t si;
  15.325 +    start_info_t start_info;
  15.326      struct domain_setup_info dsi;
  15.327      xen_pfn_t *page_array = NULL;
  15.328      unsigned long nr_pages;
  15.329 @@ -407,18 +249,28 @@ int xc_linux_build(int xc_handle,
  15.330      unsigned long kern_addr;
  15.331      unsigned long initrd_base = 0;
  15.332      unsigned long initrd_len = 0;
  15.333 -    unsigned long si_addr;
  15.334 +    unsigned long start_info_addr;
  15.335 +    unsigned long rma_pages;
  15.336      int rc = 0;
  15.337  
  15.338      DPRINTF("%s\n", __func__);
  15.339  
  15.340 -    if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
  15.341 +    nr_pages = mem_mb << (20 - PAGE_SHIFT);
  15.342 +    DPRINTF("nr_pages 0x%lx\n", nr_pages);
  15.343 +
  15.344 +    rma_pages = get_rma_pages(devtree);
  15.345 +    if (rma_pages == 0) {
  15.346 +	    rc = -1;
  15.347 +	    goto out;
  15.348 +    }
  15.349 +
  15.350 +    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
  15.351          rc = -1;
  15.352          goto out;
  15.353      }
  15.354  
  15.355      DPRINTF("loading image '%s'\n", image_name);
  15.356 -    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  15.357 +    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  15.358          rc = -1;
  15.359          goto out;
  15.360      }
  15.361 @@ -434,11 +286,12 @@ int xc_linux_build(int xc_handle,
  15.362      }
  15.363  
  15.364      /* start_info stuff: about to be removed  */
  15.365 -    si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
  15.366 -    *console_mfn = page_array[si.console.domU.mfn];
  15.367 -    *store_mfn = page_array[si.store_mfn];
  15.368 -    if (install_image(xc_handle, domid, page_array, &si, si_addr,
  15.369 -                sizeof(start_info_t))) {
  15.370 +    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
  15.371 +                                        store_evtchn, nr_pages, rma_pages);
  15.372 +    *console_mfn = page_array[start_info.console.domU.mfn];
  15.373 +    *store_mfn = page_array[start_info.store_mfn];
  15.374 +    if (install_image(xc_handle, domid, page_array, &start_info,
  15.375 +                      start_info_addr, sizeof(start_info_t))) {
  15.376          rc = -1;
  15.377          goto out;
  15.378      }
  15.379 @@ -447,7 +300,8 @@ int xc_linux_build(int xc_handle,
  15.380          DPRINTF("loading flattened device tree\n");
  15.381          devtree_addr = DEVTREE_ADDR;
  15.382          if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
  15.383 -                     initrd_base, initrd_len, &si, si_addr)) {
  15.384 +                         initrd_base, initrd_len, &start_info,
  15.385 +                         start_info_addr)) {
  15.386              DPRINTF("couldn't load flattened device tree.\n");
  15.387              rc = -1;
  15.388              goto out;
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/libxc/powerpc64/xc_prose_build.c	Thu Dec 14 08:57:36 2006 -0700
    16.3 @@ -0,0 +1,323 @@
    16.4 +/*
    16.5 + * This program is free software; you can redistribute it and/or modify
    16.6 + * it under the terms of the GNU General Public License as published by
    16.7 + * the Free Software Foundation; either version 2 of the License, or
    16.8 + * (at your option) any later version.
    16.9 + *
   16.10 + * This program is distributed in the hope that it will be useful,
   16.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.13 + * GNU General Public License for more details.
   16.14 + *
   16.15 + * You should have received a copy of the GNU General Public License
   16.16 + * along with this program; if not, write to the Free Software
   16.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   16.18 + *
   16.19 + * Copyright (C) IBM Corporation 2006
   16.20 + *
   16.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   16.22 + *          Jonathan Appavoo <jappavoo@us.ibm.com>
   16.23 + */
   16.24 +
   16.25 +#include <stdio.h>
   16.26 +#include <stdint.h>
   16.27 +#include <stdlib.h>
   16.28 +#include <string.h>
   16.29 +#include <unistd.h>
   16.30 +#include <fcntl.h>
   16.31 +#include <sys/types.h>
   16.32 +#include <inttypes.h>
   16.33 +
   16.34 +#include <xen/xen.h>
   16.35 +#include <xen/memory.h>
   16.36 +#include <xc_private.h>
   16.37 +#include <xg_private.h>
   16.38 +#include <xenctrl.h>
   16.39 +
   16.40 +#include "flatdevtree_env.h"
   16.41 +#include "flatdevtree.h"
   16.42 +#include "utils.h"
   16.43 +
   16.44 +#define INITRD_ADDR (24UL << 20)
   16.45 +#define DEVTREE_ADDR (16UL << 20)
   16.46 +
   16.47 +static int init_boot_vcpu(
   16.48 +    int xc_handle,
   16.49 +    int domid,
   16.50 +    struct domain_setup_info *dsi,
   16.51 +    unsigned long devtree_addr,
   16.52 +    unsigned long kern_addr)
   16.53 +{
   16.54 +    vcpu_guest_context_t ctxt;
   16.55 +    int rc;
   16.56 +
   16.57 +    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   16.58 +    ctxt.user_regs.pc = dsi->v_kernentry;
   16.59 +    ctxt.user_regs.msr = 0;
   16.60 +    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   16.61 +    ctxt.user_regs.gprs[3] = devtree_addr;
   16.62 +    ctxt.user_regs.gprs[4] = kern_addr;
   16.63 +    ctxt.user_regs.gprs[5] = 0; /* reserved for specifying OF handler */
   16.64 +    /* There is a buggy kernel that does not zero the "local_paca", so
   16.65 +     * we must make sure this register is 0 */
   16.66 +    ctxt.user_regs.gprs[13] = 0;
   16.67 +
   16.68 +    DPRINTF("xc_vcpu_setvcpucontext:\n"
   16.69 +                 "  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
   16.70 +                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   16.71 +                 " %016"PRIx64"\n",
   16.72 +                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   16.73 +                 ctxt.user_regs.gprs[1],
   16.74 +                 ctxt.user_regs.gprs[2],
   16.75 +                 ctxt.user_regs.gprs[3],
   16.76 +                 ctxt.user_regs.gprs[4],
   16.77 +                 ctxt.user_regs.gprs[5]);
   16.78 +    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   16.79 +    if (rc < 0)
   16.80 +        perror("setdomaininfo");
   16.81 +
   16.82 +    return rc;
   16.83 +}
   16.84 +
   16.85 +static int load_devtree(
   16.86 +    int xc_handle,
   16.87 +    int domid,
   16.88 +    xen_pfn_t *page_array,
   16.89 +    void *devtree,
   16.90 +    unsigned long devtree_addr,
   16.91 +    uint64_t initrd_base,
   16.92 +    unsigned long initrd_len,
   16.93 +    start_info_t *start_info __attribute__((unused)),
   16.94 +    unsigned long start_info_addr)
   16.95 +{
   16.96 +    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
   16.97 +    struct boot_param_header *header;
   16.98 +    void *chosen;
   16.99 +    void *xen;
  16.100 +    uint64_t initrd_end = initrd_base + initrd_len;
  16.101 +    unsigned int devtree_size;
  16.102 +    int rc = 0;
  16.103 +
  16.104 +    DPRINTF("adding initrd props\n");
  16.105 +
  16.106 +    chosen = ft_find_node(devtree, "/chosen");
  16.107 +    if (chosen == NULL) {
  16.108 +        DPRINTF("couldn't find /chosen\n");
  16.109 +        return -1;
  16.110 +    }
  16.111 +
  16.112 +    xen = ft_find_node(devtree, "/xen");
  16.113 +    if (xen == NULL) {
  16.114 +        DPRINTF("couldn't find /xen\n");
  16.115 +        return -1;
  16.116 +    }
  16.117 +
  16.118 +    /* initrd-start */
  16.119 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
  16.120 +            &initrd_base, sizeof(initrd_base));
  16.121 +    if (rc < 0) {
  16.122 +        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
  16.123 +        return rc;
  16.124 +    }
  16.125 +
  16.126 +    /* initrd-end */
  16.127 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
  16.128 +            &initrd_end, sizeof(initrd_end));
  16.129 +    if (rc < 0) {
  16.130 +        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
  16.131 +        return rc;
  16.132 +    }
  16.133 +
  16.134 +    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
  16.135 +    if (rc < 0) {
  16.136 +        DPRINTF("couldn't set initrd reservation\n");
  16.137 +        return ~0UL;
  16.138 +    }
  16.139 +
  16.140 +    /* start-info (XXX being removed soon) */
  16.141 +    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
  16.142 +    if (rc < 0) {
  16.143 +        DPRINTF("couldn't set /xen/start-info\n");
  16.144 +        return rc;
  16.145 +    }
  16.146 +
  16.147 +    header = devtree;
  16.148 +    devtree_size = header->totalsize;
  16.149 +    {
  16.150 +        static const char dtb[] = "/tmp/xc_domU.dtb";
  16.151 +        int dfd = creat(dtb, 0666);
  16.152 +        if (dfd != -1) {
  16.153 +            write(dfd, devtree, devtree_size);
  16.154 +            close(dfd);
  16.155 +        } else
  16.156 +            DPRINTF("could not open(\"%s\")\n", dtb);
  16.157 +    }
  16.158 +
  16.159 +    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
  16.160 +    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
  16.161 +                       devtree_size);
  16.162 +}
  16.163 +
  16.164 +static int load_initrd(
  16.165 +    int xc_handle,
  16.166 +    int domid,
  16.167 +    xen_pfn_t *page_array,
  16.168 +    const char *initrd_path,
  16.169 +    unsigned long *base,
  16.170 +    unsigned long *len)
  16.171 +{
  16.172 +    uint8_t *initrd_img;
  16.173 +    int rc = -1;
  16.174 +
  16.175 +    /* load the initrd file */
  16.176 +    initrd_img = load_file(initrd_path, len);
  16.177 +    if (initrd_img == NULL)
  16.178 +        return -1;
  16.179 +
  16.180 +    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
  16.181 +    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
  16.182 +                *len))
  16.183 +        goto out;
  16.184 +
  16.185 +    *base = INITRD_ADDR;
  16.186 +    rc = 0;
  16.187 +
  16.188 +out:
  16.189 +    free(initrd_img);
  16.190 +    return rc;
  16.191 +}
  16.192 +
  16.193 +static unsigned long create_start_info(
  16.194 +	void *devtree, start_info_t *start_info,
  16.195 +        unsigned int console_evtchn, unsigned int store_evtchn,
  16.196 +	unsigned long nr_pages, unsigned long rma_pages, const char *cmdline)
  16.197 +{
  16.198 +    unsigned long start_info_addr;
  16.199 +    uint64_t rma_top;
  16.200 +    int rc;
  16.201 +
  16.202 +    memset(start_info, 0, sizeof(*start_info));
  16.203 +    snprintf(start_info->magic, sizeof(start_info->magic),
  16.204 +             "xen-%d.%d-powerpc64HV", 3, 0);
  16.205 +
  16.206 +    rma_top = rma_pages << PAGE_SHIFT;
  16.207 +    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
  16.208 +
  16.209 +    start_info->nr_pages = nr_pages;
  16.210 +    start_info->shared_info = rma_top - PAGE_SIZE;
  16.211 +    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
  16.212 +    start_info->store_evtchn = store_evtchn;
  16.213 +    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
  16.214 +    start_info->console.domU.evtchn = console_evtchn;
  16.215 +    strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
  16.216 +    /* just in case we truncated cmdline with strncpy add 0 at the end */
  16.217 +    start_info->cmd_line[MAX_GUEST_CMDLINE-1]=0;
  16.218 +    start_info_addr = rma_top - 4*PAGE_SIZE;
  16.219 +
  16.220 +    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
  16.221 +    if (rc < 0) {
  16.222 +        DPRINTF("couldn't set start_info reservation\n");
  16.223 +        return ~0UL;
  16.224 +    }
  16.225 +
  16.226 +    return start_info_addr;
  16.227 +}
  16.228 +
  16.229 +static void free_page_array(xen_pfn_t *page_array)
  16.230 +{
  16.231 +    free(page_array);
  16.232 +}
  16.233 +
  16.234 +int xc_prose_build(int xc_handle,
  16.235 +                   uint32_t domid,
  16.236 +                   unsigned int mem_mb,
  16.237 +                   const char *image_name,
  16.238 +                   const char *initrd_name,
  16.239 +                   const char *cmdline,
  16.240 +                   const char *features,
  16.241 +                   unsigned long flags,
  16.242 +                   unsigned int store_evtchn,
  16.243 +                   unsigned long *store_mfn,
  16.244 +                   unsigned int console_evtchn,
  16.245 +                   unsigned long *console_mfn,
  16.246 +                   void *devtree)
  16.247 +{
  16.248 +    start_info_t start_info;
  16.249 +    struct domain_setup_info dsi;
  16.250 +    xen_pfn_t *page_array = NULL;
  16.251 +    unsigned long nr_pages;
  16.252 +    unsigned long devtree_addr = 0;
  16.253 +    unsigned long kern_addr;
  16.254 +    unsigned long initrd_base = 0;
  16.255 +    unsigned long initrd_len = 0;
  16.256 +    unsigned long start_info_addr;
  16.257 +    unsigned long rma_pages;
  16.258 +    int rc = 0;
  16.259 +
  16.260 +    DPRINTF("%s\n", __func__);
  16.261 +
  16.262 +    DPRINTF("cmdline=%s\n", cmdline);
  16.263 +
  16.264 +    nr_pages = mem_mb << (20 - PAGE_SHIFT);
  16.265 +    DPRINTF("nr_pages 0x%lx\n", nr_pages);
  16.266 +
  16.267 +    rma_pages = get_rma_pages(devtree);
  16.268 +    if (rma_pages == 0) {
  16.269 +	    rc = -1;
  16.270 +	    goto out;
  16.271 +    }
  16.272 +
  16.273 +    if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
  16.274 +        rc = -1;
  16.275 +        goto out;
  16.276 +    }
  16.277 +
  16.278 +    DPRINTF("loading image '%s'\n", image_name);
  16.279 +    if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
  16.280 +        rc = -1;
  16.281 +        goto out;
  16.282 +    }
  16.283 +    kern_addr = 0;
  16.284 +
  16.285 +    if (initrd_name && initrd_name[0] != '\0') {
  16.286 +        DPRINTF("loading initrd '%s'\n", initrd_name);
  16.287 +        if (load_initrd(xc_handle, domid, page_array, initrd_name,
  16.288 +                &initrd_base, &initrd_len)) {
  16.289 +            rc = -1;
  16.290 +            goto out;
  16.291 +        }
  16.292 +    }
  16.293 +
  16.294 +    /* start_info stuff: about to be removed  */
  16.295 +    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
  16.296 +                                        store_evtchn, nr_pages,
  16.297 +					rma_pages, cmdline);
  16.298 +    *console_mfn = page_array[start_info.console.domU.mfn];
  16.299 +    *store_mfn = page_array[start_info.store_mfn];
  16.300 +    if (install_image(xc_handle, domid, page_array, &start_info,
  16.301 +                      start_info_addr, sizeof(start_info_t))) {
  16.302 +        rc = -1;
  16.303 +        goto out;
  16.304 +    }
  16.305 +
  16.306 +    if (devtree) {
  16.307 +        DPRINTF("loading flattened device tree\n");
  16.308 +        devtree_addr = DEVTREE_ADDR;
  16.309 +        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
  16.310 +                         initrd_base, initrd_len, &start_info,
  16.311 +                         start_info_addr)) {
  16.312 +            DPRINTF("couldn't load flattened device tree.\n");
  16.313 +            rc = -1;
  16.314 +            goto out;
  16.315 +        }
  16.316 +    }
  16.317 +
  16.318 +    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
  16.319 +        rc = -1;
  16.320 +        goto out;
  16.321 +    }
  16.322 +
  16.323 +out:
  16.324 +    free_page_array(page_array);
  16.325 +    return rc;
  16.326 +}
    17.1 --- a/tools/libxc/xc_linux_build.c	Thu Dec 14 08:54:54 2006 -0700
    17.2 +++ b/tools/libxc/xc_linux_build.c	Thu Dec 14 08:57:36 2006 -0700
    17.3 @@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
    17.4      }
    17.5  
    17.6      if (strstr(xen_caps, "xen-3.0-x86_32p")) {
    17.7 -        if (dsi->pae_kernel == PAEKERN_no) {
    17.8 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
    17.9 +            dsi->pae_kernel = PAEKERN_extended_cr3;
   17.10 +        } else if (dsi->pae_kernel == PAEKERN_no) {
   17.11              xc_set_error(XC_INVALID_KERNEL,
   17.12                           "Non PAE-kernel on PAE host.");
   17.13              return 0;
   17.14          }
   17.15 -    } else if (dsi->pae_kernel != PAEKERN_no) {
   17.16 -        xc_set_error(XC_INVALID_KERNEL,
   17.17 -                     "PAE-kernel on non-PAE host.");
   17.18 -        return 0;
   17.19 +    } else {
   17.20 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
   17.21 +            dsi->pae_kernel = PAEKERN_no;
   17.22 +        } else if (dsi->pae_kernel != PAEKERN_no) {
   17.23 +            xc_set_error(XC_INVALID_KERNEL,
   17.24 +                         "PAE-kernel on non-PAE host.");
   17.25 +            return 0;
   17.26 +        }
   17.27      }
   17.28  
   17.29      return 1;
    18.1 --- a/tools/libxc/xc_load_elf.c	Thu Dec 14 08:54:54 2006 -0700
    18.2 +++ b/tools/libxc/xc_load_elf.c	Thu Dec 14 08:57:36 2006 -0700
    18.3 @@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
    18.4          return -EINVAL;
    18.5      }
    18.6  
    18.7 -    /* Find the section-header strings table. */
    18.8 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
    18.9 -    {
   18.10 -        xc_set_error(XC_INVALID_KERNEL,
   18.11 -                     "ELF image has no section-header strings table (shstrtab).");
   18.12 -        return -EINVAL;
   18.13 -    }
   18.14 -    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
   18.15 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
   18.16 -    shstrtab = image + shdr->sh_offset;
   18.17 -
   18.18      dsi->__elfnote_section = NULL;
   18.19      dsi->__xen_guest_string = NULL;
   18.20  
   18.21 @@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
   18.22      /* Fall back to looking for the special '__xen_guest' section. */
   18.23      if ( dsi->__elfnote_section == NULL )
   18.24      {
   18.25 +        /* Find the section-header strings table. */
   18.26 +        if ( ehdr->e_shstrndx == SHN_UNDEF )
   18.27 +        {
   18.28 +            xc_set_error(XC_INVALID_KERNEL,
   18.29 +                         "ELF image has no section-header strings table.");
   18.30 +            return -EINVAL;
   18.31 +        }
   18.32 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
   18.33 +                            (ehdr->e_shstrndx*ehdr->e_shentsize));
   18.34 +        shstrtab = image + shdr->sh_offset;
   18.35 +
   18.36          for ( h = 0; h < ehdr->e_shnum; h++ )
   18.37          {
   18.38              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   18.39 @@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
   18.40      }
   18.41  
   18.42      /*
   18.43 +     * A "bimodal" ELF note indicates the kernel will adjust to the
   18.44 +     * current paging mode, including handling extended cr3 syntax.
   18.45       * If we have ELF notes then PAE=yes implies that we must support
   18.46       * the extended cr3 syntax. Otherwise we need to find the
   18.47       * [extended-cr3] syntax in the __xen_guest string.
   18.48 @@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
   18.49      if ( dsi->__elfnote_section )
   18.50      {
   18.51          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   18.52 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   18.53 +        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
   18.54 +            dsi->pae_kernel = PAEKERN_bimodal;
   18.55 +        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   18.56              dsi->pae_kernel = PAEKERN_extended_cr3;
   18.57  
   18.58      }
    19.1 --- a/tools/libxc/xenctrl.h	Thu Dec 14 08:54:54 2006 -0700
    19.2 +++ b/tools/libxc/xenctrl.h	Thu Dec 14 08:57:36 2006 -0700
    19.3 @@ -728,4 +728,8 @@ const char *xc_error_code_to_desc(int co
    19.4   */
    19.5  xc_error_handler xc_set_error_handler(xc_error_handler handler);
    19.6  
    19.7 +/* PowerPC specific. */
    19.8 +int xc_alloc_real_mode_area(int xc_handle,
    19.9 +                            uint32_t domid,
   19.10 +                            unsigned int log);
   19.11  #endif
    20.1 --- a/tools/libxc/xenguest.h	Thu Dec 14 08:54:54 2006 -0700
    20.2 +++ b/tools/libxc/xenguest.h	Thu Dec 14 08:57:36 2006 -0700
    20.3 @@ -122,4 +122,19 @@ int xc_set_hvm_param(
    20.4  int xc_get_hvm_param(
    20.5      int handle, domid_t dom, int param, unsigned long *value);
    20.6  
    20.7 +/* PowerPC specific. */
    20.8 +int xc_prose_build(int xc_handle,
    20.9 +                   uint32_t domid,
   20.10 +                   unsigned int mem_mb,
   20.11 +                   const char *image_name,
   20.12 +                   const char *ramdisk_name,
   20.13 +                   const char *cmdline,
   20.14 +                   const char *features,
   20.15 +                   unsigned long flags,
   20.16 +                   unsigned int store_evtchn,
   20.17 +                   unsigned long *store_mfn,
   20.18 +                   unsigned int console_evtchn,
   20.19 +                   unsigned long *console_mfn,
   20.20 +                   void *arch_args);
   20.21 +
   20.22  #endif /* XENGUEST_H */
    21.1 --- a/tools/libxc/xg_private.h	Thu Dec 14 08:54:54 2006 -0700
    21.2 +++ b/tools/libxc/xg_private.h	Thu Dec 14 08:57:36 2006 -0700
    21.3 @@ -132,6 +132,7 @@ struct domain_setup_info
    21.4  #define PAEKERN_no           0
    21.5  #define PAEKERN_yes          1
    21.6  #define PAEKERN_extended_cr3 2
    21.7 +#define PAEKERN_bimodal      3
    21.8      unsigned int  pae_kernel;
    21.9  
   21.10      unsigned int  load_symtab;
    22.1 --- a/tools/libxen/include/xen_console.h	Thu Dec 14 08:54:54 2006 -0700
    22.2 +++ b/tools/libxen/include/xen_console.h	Thu Dec 14 08:57:36 2006 -0700
    22.3 @@ -149,14 +149,14 @@ xen_console_record_opt_set_free(xen_cons
    22.4  
    22.5  
    22.6  /**
    22.7 - * Get the current state of the given console.
    22.8 + * Get a record containing the current state of the given console.
    22.9   */
   22.10  extern bool
   22.11  xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console);
   22.12  
   22.13  
   22.14  /**
   22.15 - * Get a reference to the object with the specified UUID.
   22.16 + * Get a reference to the console instance with the specified UUID.
   22.17   */
   22.18  extern bool
   22.19  xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid);
    23.1 --- a/tools/libxen/include/xen_host.h	Thu Dec 14 08:54:54 2006 -0700
    23.2 +++ b/tools/libxen/include/xen_host.h	Thu Dec 14 08:57:36 2006 -0700
    23.3 @@ -154,14 +154,14 @@ xen_host_record_opt_set_free(xen_host_re
    23.4  
    23.5  
    23.6  /**
    23.7 - * Get the current state of the given host.  !!!
    23.8 + * Get a record containing the current state of the given host.
    23.9   */
   23.10  extern bool
   23.11  xen_host_get_record(xen_session *session, xen_host_record **result, xen_host host);
   23.12  
   23.13  
   23.14  /**
   23.15 - * Get a reference to the object with the specified UUID.  !!!
   23.16 + * Get a reference to the host instance with the specified UUID.
   23.17   */
   23.18  extern bool
   23.19  xen_host_get_by_uuid(xen_session *session, xen_host *result, char *uuid);
    24.1 --- a/tools/libxen/include/xen_host_cpu.h	Thu Dec 14 08:54:54 2006 -0700
    24.2 +++ b/tools/libxen/include/xen_host_cpu.h	Thu Dec 14 08:57:36 2006 -0700
    24.3 @@ -153,14 +153,14 @@ xen_host_cpu_record_opt_set_free(xen_hos
    24.4  
    24.5  
    24.6  /**
    24.7 - * Get the current state of the given host_cpu.  !!!
    24.8 + * Get a record containing the current state of the given host_cpu.
    24.9   */
   24.10  extern bool
   24.11  xen_host_cpu_get_record(xen_session *session, xen_host_cpu_record **result, xen_host_cpu host_cpu);
   24.12  
   24.13  
   24.14  /**
   24.15 - * Get a reference to the object with the specified UUID.  !!!
   24.16 + * Get a reference to the host_cpu instance with the specified UUID.
   24.17   */
   24.18  extern bool
   24.19  xen_host_cpu_get_by_uuid(xen_session *session, xen_host_cpu *result, char *uuid);
    25.1 --- a/tools/libxen/include/xen_network.h	Thu Dec 14 08:54:54 2006 -0700
    25.2 +++ b/tools/libxen/include/xen_network.h	Thu Dec 14 08:57:36 2006 -0700
    25.3 @@ -152,14 +152,14 @@ xen_network_record_opt_set_free(xen_netw
    25.4  
    25.5  
    25.6  /**
    25.7 - * Get the current state of the given network.  !!!
    25.8 + * Get a record containing the current state of the given network.
    25.9   */
   25.10  extern bool
   25.11  xen_network_get_record(xen_session *session, xen_network_record **result, xen_network network);
   25.12  
   25.13  
   25.14  /**
   25.15 - * Get a reference to the object with the specified UUID.  !!!
   25.16 + * Get a reference to the network instance with the specified UUID.
   25.17   */
   25.18  extern bool
   25.19  xen_network_get_by_uuid(xen_session *session, xen_network *result, char *uuid);
    26.1 --- a/tools/libxen/include/xen_pif.h	Thu Dec 14 08:54:54 2006 -0700
    26.2 +++ b/tools/libxen/include/xen_pif.h	Thu Dec 14 08:57:36 2006 -0700
    26.3 @@ -155,14 +155,14 @@ xen_pif_record_opt_set_free(xen_pif_reco
    26.4  
    26.5  
    26.6  /**
    26.7 - * Get the current state of the given PIF.  !!!
    26.8 + * Get a record containing the current state of the given PIF.
    26.9   */
   26.10  extern bool
   26.11  xen_pif_get_record(xen_session *session, xen_pif_record **result, xen_pif pif);
   26.12  
   26.13  
   26.14  /**
   26.15 - * Get a reference to the object with the specified UUID.  !!!
   26.16 + * Get a reference to the PIF instance with the specified UUID.
   26.17   */
   26.18  extern bool
   26.19  xen_pif_get_by_uuid(xen_session *session, xen_pif *result, char *uuid);
    27.1 --- a/tools/libxen/include/xen_sr.h	Thu Dec 14 08:54:54 2006 -0700
    27.2 +++ b/tools/libxen/include/xen_sr.h	Thu Dec 14 08:57:36 2006 -0700
    27.3 @@ -153,14 +153,14 @@ xen_sr_record_opt_set_free(xen_sr_record
    27.4  
    27.5  
    27.6  /**
    27.7 - * Get the current state of the given SR.  !!!
    27.8 + * Get a record containing the current state of the given SR.
    27.9   */
   27.10  extern bool
   27.11  xen_sr_get_record(xen_session *session, xen_sr_record **result, xen_sr sr);
   27.12  
   27.13  
   27.14  /**
   27.15 - * Get a reference to the object with the specified UUID.  !!!
   27.16 + * Get a reference to the SR instance with the specified UUID.
   27.17   */
   27.18  extern bool
   27.19  xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid);
    28.1 --- a/tools/libxen/include/xen_user.h	Thu Dec 14 08:54:54 2006 -0700
    28.2 +++ b/tools/libxen/include/xen_user.h	Thu Dec 14 08:57:36 2006 -0700
    28.3 @@ -146,14 +146,14 @@ xen_user_record_opt_set_free(xen_user_re
    28.4  
    28.5  
    28.6  /**
    28.7 - * Get the current state of the given user.  !!!
    28.8 + * Get a record containing the current state of the given user.
    28.9   */
   28.10  extern bool
   28.11  xen_user_get_record(xen_session *session, xen_user_record **result, xen_user user);
   28.12  
   28.13  
   28.14  /**
   28.15 - * Get a reference to the object with the specified UUID.  !!!
   28.16 + * Get a reference to the user instance with the specified UUID.
   28.17   */
   28.18  extern bool
   28.19  xen_user_get_by_uuid(xen_session *session, xen_user *result, char *uuid);
    29.1 --- a/tools/libxen/include/xen_vdi.h	Thu Dec 14 08:54:54 2006 -0700
    29.2 +++ b/tools/libxen/include/xen_vdi.h	Thu Dec 14 08:57:36 2006 -0700
    29.3 @@ -159,14 +159,14 @@ xen_vdi_record_opt_set_free(xen_vdi_reco
    29.4  
    29.5  
    29.6  /**
    29.7 - * Get the current state of the given VDI.  !!!
    29.8 + * Get a record containing the current state of the given VDI.
    29.9   */
   29.10  extern bool
   29.11  xen_vdi_get_record(xen_session *session, xen_vdi_record **result, xen_vdi vdi);
   29.12  
   29.13  
   29.14  /**
   29.15 - * Get a reference to the object with the specified UUID.  !!!
   29.16 + * Get a reference to the VDI instance with the specified UUID.
   29.17   */
   29.18  extern bool
   29.19  xen_vdi_get_by_uuid(xen_session *session, xen_vdi *result, char *uuid);
    30.1 --- a/tools/libxen/include/xen_vif.h	Thu Dec 14 08:54:54 2006 -0700
    30.2 +++ b/tools/libxen/include/xen_vif.h	Thu Dec 14 08:57:36 2006 -0700
    30.3 @@ -156,14 +156,14 @@ xen_vif_record_opt_set_free(xen_vif_reco
    30.4  
    30.5  
    30.6  /**
    30.7 - * Get the current state of the given VIF.  !!!
    30.8 + * Get a record containing the current state of the given VIF.
    30.9   */
   30.10  extern bool
   30.11  xen_vif_get_record(xen_session *session, xen_vif_record **result, xen_vif vif);
   30.12  
   30.13  
   30.14  /**
   30.15 - * Get a reference to the object with the specified UUID.  !!!
   30.16 + * Get a reference to the VIF instance with the specified UUID.
   30.17   */
   30.18  extern bool
   30.19  xen_vif_get_by_uuid(xen_session *session, xen_vif *result, char *uuid);
    31.1 --- a/tools/libxen/include/xen_vm.h	Thu Dec 14 08:54:54 2006 -0700
    31.2 +++ b/tools/libxen/include/xen_vm.h	Thu Dec 14 08:57:36 2006 -0700
    31.3 @@ -79,6 +79,7 @@ typedef struct xen_vm_record
    31.4      char *name_description;
    31.5      int64_t user_version;
    31.6      bool is_a_template;
    31.7 +    bool auto_power_on;
    31.8      struct xen_host_record_opt *resident_on;
    31.9      int64_t memory_static_max;
   31.10      int64_t memory_dynamic_max;
   31.11 @@ -198,14 +199,14 @@ xen_vm_record_opt_set_free(xen_vm_record
   31.12  
   31.13  
   31.14  /**
   31.15 - * Get the current state of the given VM.  !!!
   31.16 + * Get a record containing the current state of the given VM.
   31.17   */
   31.18  extern bool
   31.19  xen_vm_get_record(xen_session *session, xen_vm_record **result, xen_vm vm);
   31.20  
   31.21  
   31.22  /**
   31.23 - * Get a reference to the object with the specified UUID.  !!!
   31.24 + * Get a reference to the VM instance with the specified UUID.
   31.25   */
   31.26  extern bool
   31.27  xen_vm_get_by_uuid(xen_session *session, xen_vm *result, char *uuid);
   31.28 @@ -277,6 +278,13 @@ xen_vm_get_is_a_template(xen_session *se
   31.29  
   31.30  
   31.31  /**
   31.32 + * Get the auto_power_on field of the given VM.
   31.33 + */
   31.34 +extern bool
   31.35 +xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm);
   31.36 +
   31.37 +
   31.38 +/**
   31.39   * Get the resident_on field of the given VM.
   31.40   */
   31.41  extern bool
   31.42 @@ -564,6 +572,13 @@ xen_vm_set_is_a_template(xen_session *se
   31.43  
   31.44  
   31.45  /**
   31.46 + * Set the auto_power_on field of the given VM.
   31.47 + */
   31.48 +extern bool
   31.49 +xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on);
   31.50 +
   31.51 +
   31.52 +/**
   31.53   * Set the memory/dynamic_max field of the given VM.
   31.54   */
   31.55  extern bool
   31.56 @@ -592,6 +607,13 @@ xen_vm_set_vcpus_params(xen_session *ses
   31.57  
   31.58  
   31.59  /**
   31.60 + * Set the VCPUs/number field of the given VM.
   31.61 + */
   31.62 +extern bool
   31.63 +xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number);
   31.64 +
   31.65 +
   31.66 +/**
   31.67   * Set the VCPUs/features/force_on field of the given VM.
   31.68   */
   31.69  extern bool
   31.70 @@ -599,6 +621,22 @@ xen_vm_set_vcpus_features_force_on(xen_s
   31.71  
   31.72  
   31.73  /**
   31.74 + * Add the given value to the VCPUs/features/force_on field of the
   31.75 + * given VM.  If the value is already in that Set, then do nothing.
   31.76 + */
   31.77 +extern bool
   31.78 +xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
   31.79 +
   31.80 +
   31.81 +/**
   31.82 + * Remove the given value from the VCPUs/features/force_on field of the
   31.83 + * given VM.  If the value is not in that Set, then do nothing.
   31.84 + */
   31.85 +extern bool
   31.86 +xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
   31.87 +
   31.88 +
   31.89 +/**
   31.90   * Set the VCPUs/features/force_off field of the given VM.
   31.91   */
   31.92  extern bool
   31.93 @@ -606,6 +644,22 @@ xen_vm_set_vcpus_features_force_off(xen_
   31.94  
   31.95  
   31.96  /**
   31.97 + * Add the given value to the VCPUs/features/force_off field of the
   31.98 + * given VM.  If the value is already in that Set, then do nothing.
   31.99 + */
  31.100 +extern bool
  31.101 +xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  31.102 +
  31.103 +
  31.104 +/**
  31.105 + * Remove the given value from the VCPUs/features/force_off field of
  31.106 + * the given VM.  If the value is not in that Set, then do nothing.
  31.107 + */
  31.108 +extern bool
  31.109 +xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value);
  31.110 +
  31.111 +
  31.112 +/**
  31.113   * Set the actions/after_shutdown field of the given VM.
  31.114   */
  31.115  extern bool
  31.116 @@ -817,12 +871,4 @@ extern bool
  31.117  xen_vm_get_all(xen_session *session, struct xen_vm_set **result);
  31.118  
  31.119  
  31.120 -/**
  31.121 - * Destroy the specified VM.  The VM is completely removed from the system.
  31.122 - * This function can only be called when the VM is in the Halted State.
  31.123 - */
  31.124 -extern bool
  31.125 -xen_vm_destroy(xen_session *session, xen_vm vm);
  31.126 -
  31.127 -
  31.128  #endif
    32.1 --- a/tools/libxen/include/xen_vtpm.h	Thu Dec 14 08:54:54 2006 -0700
    32.2 +++ b/tools/libxen/include/xen_vtpm.h	Thu Dec 14 08:57:36 2006 -0700
    32.3 @@ -151,14 +151,14 @@ xen_vtpm_record_opt_set_free(xen_vtpm_re
    32.4  
    32.5  
    32.6  /**
    32.7 - * Get the current state of the given VTPM.  !!!
    32.8 + * Get a record containing the current state of the given VTPM.
    32.9   */
   32.10  extern bool
   32.11  xen_vtpm_get_record(xen_session *session, xen_vtpm_record **result, xen_vtpm vtpm);
   32.12  
   32.13  
   32.14  /**
   32.15 - * Get a reference to the object with the specified UUID.  !!!
   32.16 + * Get a reference to the VTPM instance with the specified UUID.
   32.17   */
   32.18  extern bool
   32.19  xen_vtpm_get_by_uuid(xen_session *session, xen_vtpm *result, char *uuid);
    33.1 --- a/tools/libxen/src/xen_vm.c	Thu Dec 14 08:54:54 2006 -0700
    33.2 +++ b/tools/libxen/src/xen_vm.c	Thu Dec 14 08:57:36 2006 -0700
    33.3 @@ -67,6 +67,9 @@ static const struct_member xen_vm_record
    33.4          { .key = "is_a_template",
    33.5            .type = &abstract_type_bool,
    33.6            .offset = offsetof(xen_vm_record, is_a_template) },
    33.7 +        { .key = "auto_power_on",
    33.8 +          .type = &abstract_type_bool,
    33.9 +          .offset = offsetof(xen_vm_record, auto_power_on) },
   33.10          { .key = "resident_on",
   33.11            .type = &abstract_type_ref,
   33.12            .offset = offsetof(xen_vm_record, resident_on) },
   33.13 @@ -399,6 +402,22 @@ xen_vm_get_is_a_template(xen_session *se
   33.14  
   33.15  
   33.16  bool
   33.17 +xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm)
   33.18 +{
   33.19 +    abstract_value param_values[] =
   33.20 +        {
   33.21 +            { .type = &abstract_type_string,
   33.22 +              .u.string_val = vm }
   33.23 +        };
   33.24 +
   33.25 +    abstract_type result_type = abstract_type_bool;
   33.26 +
   33.27 +    XEN_CALL_("VM.get_auto_power_on");
   33.28 +    return session->ok;
   33.29 +}
   33.30 +
   33.31 +
   33.32 +bool
   33.33  xen_vm_get_resident_on(xen_session *session, xen_host *result, xen_vm vm)
   33.34  {
   33.35      abstract_value param_values[] =
   33.36 @@ -1082,6 +1101,22 @@ xen_vm_set_is_a_template(xen_session *se
   33.37  
   33.38  
   33.39  bool
   33.40 +xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on)
   33.41 +{
   33.42 +    abstract_value param_values[] =
   33.43 +        {
   33.44 +            { .type = &abstract_type_string,
   33.45 +              .u.string_val = vm },
   33.46 +            { .type = &abstract_type_bool,
   33.47 +              .u.bool_val = auto_power_on }
   33.48 +        };
   33.49 +
   33.50 +    xen_call_(session, "VM.set_auto_power_on", param_values, 2, NULL, NULL);
   33.51 +    return session->ok;
   33.52 +}
   33.53 +
   33.54 +
   33.55 +bool
   33.56  xen_vm_set_memory_dynamic_max(xen_session *session, xen_vm vm, int64_t dynamic_max)
   33.57  {
   33.58      abstract_value param_values[] =
   33.59 @@ -1146,6 +1181,22 @@ xen_vm_set_vcpus_params(xen_session *ses
   33.60  
   33.61  
   33.62  bool
   33.63 +xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number)
   33.64 +{
   33.65 +    abstract_value param_values[] =
   33.66 +        {
   33.67 +            { .type = &abstract_type_string,
   33.68 +              .u.string_val = vm },
   33.69 +            { .type = &abstract_type_int,
   33.70 +              .u.int_val = number }
   33.71 +        };
   33.72 +
   33.73 +    xen_call_(session, "VM.set_VCPUs_number", param_values, 2, NULL, NULL);
   33.74 +    return session->ok;
   33.75 +}
   33.76 +
   33.77 +
   33.78 +bool
   33.79  xen_vm_set_vcpus_features_force_on(xen_session *session, xen_vm vm, struct xen_cpu_feature_set *force_on)
   33.80  {
   33.81      abstract_value param_values[] =
   33.82 @@ -1162,6 +1213,38 @@ xen_vm_set_vcpus_features_force_on(xen_s
   33.83  
   33.84  
   33.85  bool
   33.86 +xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
   33.87 +{
   33.88 +    abstract_value param_values[] =
   33.89 +        {
   33.90 +            { .type = &abstract_type_string,
   33.91 +              .u.string_val = vm },
   33.92 +            { .type = &xen_cpu_feature_abstract_type_,
   33.93 +              .u.string_val = xen_cpu_feature_to_string(value) }
   33.94 +        };
   33.95 +
   33.96 +    xen_call_(session, "VM.add_VCPUs_features_force_on", param_values, 2, NULL, NULL);
   33.97 +    return session->ok;
   33.98 +}
   33.99 +
  33.100 +
  33.101 +bool
  33.102 +xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  33.103 +{
  33.104 +    abstract_value param_values[] =
  33.105 +        {
  33.106 +            { .type = &abstract_type_string,
  33.107 +              .u.string_val = vm },
  33.108 +            { .type = &xen_cpu_feature_abstract_type_,
  33.109 +              .u.string_val = xen_cpu_feature_to_string(value) }
  33.110 +        };
  33.111 +
  33.112 +    xen_call_(session, "VM.remove_VCPUs_features_force_on", param_values, 2, NULL, NULL);
  33.113 +    return session->ok;
  33.114 +}
  33.115 +
  33.116 +
  33.117 +bool
  33.118  xen_vm_set_vcpus_features_force_off(xen_session *session, xen_vm vm, struct xen_cpu_feature_set *force_off)
  33.119  {
  33.120      abstract_value param_values[] =
  33.121 @@ -1178,6 +1261,38 @@ xen_vm_set_vcpus_features_force_off(xen_
  33.122  
  33.123  
  33.124  bool
  33.125 +xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  33.126 +{
  33.127 +    abstract_value param_values[] =
  33.128 +        {
  33.129 +            { .type = &abstract_type_string,
  33.130 +              .u.string_val = vm },
  33.131 +            { .type = &xen_cpu_feature_abstract_type_,
  33.132 +              .u.string_val = xen_cpu_feature_to_string(value) }
  33.133 +        };
  33.134 +
  33.135 +    xen_call_(session, "VM.add_VCPUs_features_force_off", param_values, 2, NULL, NULL);
  33.136 +    return session->ok;
  33.137 +}
  33.138 +
  33.139 +
  33.140 +bool
  33.141 +xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum xen_cpu_feature value)
  33.142 +{
  33.143 +    abstract_value param_values[] =
  33.144 +        {
  33.145 +            { .type = &abstract_type_string,
  33.146 +              .u.string_val = vm },
  33.147 +            { .type = &xen_cpu_feature_abstract_type_,
  33.148 +              .u.string_val = xen_cpu_feature_to_string(value) }
  33.149 +        };
  33.150 +
  33.151 +    xen_call_(session, "VM.remove_VCPUs_features_force_off", param_values, 2, NULL, NULL);
  33.152 +    return session->ok;
  33.153 +}
  33.154 +
  33.155 +
  33.156 +bool
  33.157  xen_vm_set_actions_after_shutdown(xen_session *session, xen_vm vm, enum xen_on_normal_exit after_shutdown)
  33.158  {
  33.159      abstract_value param_values[] =
  33.160 @@ -1268,7 +1383,7 @@ xen_vm_set_platform_std_vga(xen_session 
  33.161                .u.bool_val = std_vga }
  33.162          };
  33.163  
  33.164 -    xen_call_(session, "VM.set_platform_std_vga", param_values, 2, NULL, NULL);
  33.165 +    xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
  33.166      return session->ok;
  33.167  }
  33.168  
  33.169 @@ -1444,7 +1559,7 @@ xen_vm_set_otherconfig(xen_session *sess
  33.170                .u.set_val = (arbitrary_set *)otherconfig }
  33.171          };
  33.172  
  33.173 -    xen_call_(session, "VM.set_otherconfig", param_values, 2, NULL, NULL);
  33.174 +    xen_call_(session, "VM.set_otherConfig", param_values, 2, NULL, NULL);
  33.175      return session->ok;
  33.176  }
  33.177  
    34.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Dec 14 08:54:54 2006 -0700
    34.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Dec 14 08:57:36 2006 -0700
    34.3 @@ -919,6 +919,68 @@ static PyObject *dom_op(XcObject *self, 
    34.4      return zero;
    34.5  }
    34.6  
    34.7 +#ifdef __powerpc__
    34.8 +static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
    34.9 +                                           PyObject *args,
   34.10 +                                           PyObject *kwds)
   34.11 +{
   34.12 +    uint32_t dom;
   34.13 +    unsigned int log;
   34.14 +
   34.15 +    static char *kwd_list[] = { "dom", "log", NULL };
   34.16 +
   34.17 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
   34.18 +                                      &dom, &log) )
   34.19 +        return NULL;
   34.20 +
   34.21 +    if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
   34.22 +        return PyErr_SetFromErrno(xc_error);
   34.23 +
   34.24 +    Py_INCREF(zero);
   34.25 +    return zero;
   34.26 +}
   34.27 +
   34.28 +static PyObject *pyxc_prose_build(XcObject *self,
   34.29 +                                  PyObject *args,
   34.30 +                                  PyObject *kwds)
   34.31 +{
   34.32 +    uint32_t dom;
   34.33 +    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
   34.34 +    int flags = 0;
   34.35 +    int store_evtchn, console_evtchn;
   34.36 +    unsigned long store_mfn = 0;
   34.37 +    unsigned long console_mfn = 0;
   34.38 +    void *arch_args = NULL;
   34.39 +    int unused;
   34.40 +
   34.41 +    static char *kwd_list[] = { "dom", "store_evtchn",
   34.42 +                                "console_evtchn", "image",
   34.43 +                                /* optional */
   34.44 +                                "ramdisk", "cmdline", "flags",
   34.45 +                                "features", "arch_args", NULL };
   34.46 +
   34.47 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
   34.48 +                                      &dom, &store_evtchn,
   34.49 +                                      &console_evtchn, &image,
   34.50 +                                      /* optional */
   34.51 +                                      &ramdisk, &cmdline, &flags,
   34.52 +                                      &features, &arch_args, &unused) )
   34.53 +        return NULL;
   34.54 +
   34.55 +    if ( xc_prose_build(self->xc_handle, dom, image,
   34.56 +                        ramdisk, cmdline, features, flags,
   34.57 +                        store_evtchn, &store_mfn,
   34.58 +                        console_evtchn, &console_mfn,
   34.59 +                        arch_args) != 0 ) {
   34.60 +        if (!errno)
   34.61 +             errno = EINVAL;
   34.62 +        return PyErr_SetFromErrno(xc_error);
   34.63 +    }
   34.64 +    return Py_BuildValue("{s:i,s:i}", 
   34.65 +                         "store_mfn", store_mfn,
   34.66 +                         "console_mfn", console_mfn);
   34.67 +}
   34.68 +#endif /* powerpc */
   34.69  
   34.70  static PyMethodDef pyxc_methods[] = {
   34.71      { "handle",
   34.72 @@ -1225,6 +1287,27 @@ static PyMethodDef pyxc_methods[] = {
   34.73        " dom        [int]: Domain whose time offset is being set.\n"
   34.74        "Returns: [int] 0 on success; -1 on error.\n" },
   34.75  
   34.76 +#ifdef __powerpc__
   34.77 +    { "arch_alloc_real_mode_area", 
   34.78 +      (PyCFunction)pyxc_alloc_real_mode_area, 
   34.79 +      METH_VARARGS | METH_KEYWORDS, "\n"
   34.80 +      "Allocate a domain's real mode area.\n"
   34.81 +      " dom [int]: Identifier of domain.\n"
   34.82 +      " log [int]: Specifies the area's size.\n"
   34.83 +      "Returns: [int] 0 on success; -1 on error.\n" },
   34.84 +
   34.85 +    { "arch_prose_build", 
   34.86 +      (PyCFunction)pyxc_prose_build, 
   34.87 +      METH_VARARGS | METH_KEYWORDS, "\n"
   34.88 +      "Build a new Linux guest OS.\n"
   34.89 +      " dom     [int]:      Identifier of domain to build into.\n"
   34.90 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
   34.91 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
   34.92 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   34.93 +      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
   34.94 +      "Returns: [int] 0 on success; -1 on error.\n" },
   34.95 +#endif /* __powerpc */
   34.96 +
   34.97      { NULL, NULL, 0, NULL }
   34.98  };
   34.99  
    35.1 --- a/tools/python/xen/xend/FlatDeviceTree.py	Thu Dec 14 08:54:54 2006 -0700
    35.2 +++ b/tools/python/xen/xend/FlatDeviceTree.py	Thu Dec 14 08:57:36 2006 -0700
    35.3 @@ -22,6 +22,10 @@ import sys
    35.4  import struct
    35.5  import stat
    35.6  import re
    35.7 +import glob
    35.8 +import math
    35.9 +
   35.10 +_host_devtree_root = '/proc/device-tree'
   35.11  
   35.12  _OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
   35.13  _OF_DT_BEGIN_NODE = 0x1
   35.14 @@ -33,8 +37,10 @@ def _bincat(seq, separator=''):
   35.15      '''Concatenate the contents of seq into a bytestream.'''
   35.16      strs = []
   35.17      for item in seq:
   35.18 -        if type(item) == type(0):
   35.19 +        if isinstance(item, int):
   35.20              strs.append(struct.pack(">I", item))
   35.21 +        elif isinstance(item, long):
   35.22 +            strs.append(struct.pack(">Q", item))
   35.23          else:
   35.24              try:
   35.25                  strs.append(item.to_bin())
   35.26 @@ -231,38 +237,51 @@ class Tree(_Node):
   35.27          header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
   35.28          return _pad(header.to_bin(), 8) + payload
   35.29  
   35.30 -_host_devtree_root = '/proc/device-tree'
   35.31 -def _getprop(propname):
   35.32 -    '''Extract a property from the system's device tree.'''
   35.33 -    f = file(os.path.join(_host_devtree_root, propname), 'r')
   35.34 +def _readfile(fullpath):
   35.35 +    '''Return full contents of a file.'''
   35.36 +    f = file(fullpath, 'r')
   35.37      data = f.read()
   35.38      f.close()
   35.39      return data
   35.40  
   35.41 +def _find_first_cpu(dirpath):
   35.42 +    '''Find the first node of type 'cpu' in a directory tree.'''
   35.43 +    cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
   35.44 +    for node in cpulist:
   35.45 +        try:
   35.46 +            data = _readfile(os.path.join(node, 'device_type'))
   35.47 +        except IOError:
   35.48 +            continue
   35.49 +        if 'cpu' in data:
   35.50 +            return node
   35.51 +    raise IOError("couldn't find any CPU nodes under " + dirpath)
   35.52 +
   35.53  def _copynode(node, dirpath, propfilter):
   35.54 -    '''Extract all properties from a node in the system's device tree.'''
   35.55 +    '''Copy all properties and children nodes from a directory tree.'''
   35.56      dirents = os.listdir(dirpath)
   35.57      for dirent in dirents:
   35.58          fullpath = os.path.join(dirpath, dirent)
   35.59          st = os.lstat(fullpath)
   35.60          if stat.S_ISDIR(st.st_mode):
   35.61              child = node.addnode(dirent)
   35.62 -            _copytree(child, fullpath, propfilter)
   35.63 +            _copynode(child, fullpath, propfilter)
   35.64          elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
   35.65 -            node.addprop(dirent, _getprop(fullpath))
   35.66 -
   35.67 -def _copytree(node, dirpath, propfilter):
   35.68 -    path = os.path.join(_host_devtree_root, dirpath)
   35.69 -    _copynode(node, path, propfilter)
   35.70 +            node.addprop(dirent, _readfile(fullpath))
   35.71  
   35.72  def build(imghandler):
   35.73      '''Construct a device tree by combining the domain's configuration and
   35.74      the host's device tree.'''
   35.75      root = Tree()
   35.76  
   35.77 -    # 4 pages: start_info, console, store, shared_info
   35.78 +    # 1st reseravtion entry used for start_info, console, store, shared_info
   35.79      root.reserve(0x3ffc000, 0x4000)
   35.80  
   35.81 +    # 2nd reservation enrty used for initrd, later on when we load the
   35.82 +    # initrd we may fill this in with zeroes which signifies the end
   35.83 +    # of the reservation map.  So as to avoid adding a zero map now we
   35.84 +    # put some bogus yet sensible numbers here.
   35.85 +    root.reserve(0x1000000, 0x1000)
   35.86 +
   35.87      root.addprop('device_type', 'chrp-but-not-really\0')
   35.88      root.addprop('#size-cells', 2)
   35.89      root.addprop('#address-cells', 2)
   35.90 @@ -270,35 +289,52 @@ def build(imghandler):
   35.91      root.addprop('compatible', 'Momentum,Maple\0')
   35.92  
   35.93      xen = root.addnode('xen')
   35.94 -    xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
   35.95 +    xen.addprop('start-info', long(0x3ffc000), long(0x1000))
   35.96      xen.addprop('version', 'Xen-3.0-unstable\0')
   35.97 -    xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
   35.98 +    xen.addprop('reg', long(imghandler.vm.domid), long(0))
   35.99      xen.addprop('domain-name', imghandler.vm.getName() + '\0')
  35.100      xencons = xen.addnode('console')
  35.101      xencons.addprop('interrupts', 1, 0)
  35.102  
  35.103 -    # XXX split out RMA node
  35.104 -    mem = root.addnode('memory@0')
  35.105 +    # add memory nodes
  35.106      totalmem = imghandler.vm.getMemoryTarget() * 1024
  35.107 -    mem.addprop('reg', 0, 0, 0, totalmem)
  35.108 -    mem.addprop('device_type', 'memory\0')
  35.109 +    rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
  35.110 +    rma_bytes = 1 << rma_log
  35.111 +
  35.112 +    # RMA node
  35.113 +    rma = root.addnode('memory@0')
  35.114 +    rma.addprop('reg', long(0), long(rma_bytes))
  35.115 +    rma.addprop('device_type', 'memory\0')
  35.116  
  35.117 +    # all the rest in a single node
  35.118 +    remaining = totalmem - rma_bytes
  35.119 +    if remaining > 0:
  35.120 +        mem = root.addnode('memory@1')
  35.121 +        mem.addprop('reg', long(rma_bytes), long(remaining))
  35.122 +        mem.addprop('device_type', 'memory\0')
  35.123 +
  35.124 +    # add CPU nodes
  35.125      cpus = root.addnode('cpus')
  35.126      cpus.addprop('smp-enabled')
  35.127      cpus.addprop('#size-cells', 0)
  35.128      cpus.addprop('#address-cells', 1)
  35.129  
  35.130      # Copy all properties the system firmware gave us, except for 'linux,'
  35.131 -    # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are
  35.132 -    # identical...
  35.133 +    # properties, from the first CPU node in the device tree. Do this once for
  35.134 +    # every vcpu. Hopefully all cpus are identical...
  35.135      cpu0 = None
  35.136 +    cpu0path = _find_first_cpu(_host_devtree_root)
  35.137      def _nolinuxprops(fullpath):
  35.138          return not os.path.basename(fullpath).startswith('linux,')
  35.139      for i in range(imghandler.vm.getVCpuCount()):
  35.140 -        cpu = cpus.addnode('PowerPC,970@0')
  35.141 -        _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops)
  35.142 -        # and then overwrite what we need to
  35.143 -        pft_size = imghandler.vm.info.get('pft-size', 0x14)
  35.144 +        # create new node and copy all properties
  35.145 +        cpu = cpus.addnode('PowerPC,970@%d' % i)
  35.146 +        _copynode(cpu, cpu0path, _nolinuxprops)
  35.147 +
  35.148 +        # overwrite what we need to
  35.149 +        shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
  35.150 +        shadow_mb_log = int(math.log(shadow_mb, 2))
  35.151 +        pft_size = shadow_mb_log + 20
  35.152          cpu.setprop('ibm,pft-size', 0, pft_size)
  35.153  
  35.154          # set default CPU
  35.155 @@ -307,13 +343,13 @@ def build(imghandler):
  35.156  
  35.157      chosen = root.addnode('chosen')
  35.158      chosen.addprop('cpu', cpu0.get_phandle())
  35.159 -    chosen.addprop('memory', mem.get_phandle())
  35.160 +    chosen.addprop('memory', rma.get_phandle())
  35.161      chosen.addprop('linux,stdout-path', '/xen/console\0')
  35.162      chosen.addprop('interrupt-controller', xen.get_phandle())
  35.163      chosen.addprop('bootargs', imghandler.cmdline + '\0')
  35.164      # xc_linux_load.c will overwrite these 64-bit properties later
  35.165 -    chosen.addprop('linux,initrd-start', 0, 0)
  35.166 -    chosen.addprop('linux,initrd-end', 0, 0)
  35.167 +    chosen.addprop('linux,initrd-start', long(0))
  35.168 +    chosen.addprop('linux,initrd-end', long(0))
  35.169  
  35.170      if 1:
  35.171          f = file('/tmp/domU.dtb', 'w')
    36.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Dec 14 08:54:54 2006 -0700
    36.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Dec 14 08:57:36 2006 -0700
    36.3 @@ -591,7 +591,9 @@ class XendDomain:
    36.4          try:
    36.5              self.domains_lock.acquire()
    36.6              result = [d.get_uuid() for d in self.domains.values()]
    36.7 -            result += self.managed_domains.keys()
    36.8 +            for d in self.managed_domains.keys():
    36.9 +                if d not in result:
   36.10 +                    result.append(d)
   36.11              return result
   36.12          finally:
   36.13              self.domains_lock.release()
    37.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Dec 14 08:54:54 2006 -0700
    37.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Dec 14 08:57:36 2006 -0700
    37.3 @@ -167,7 +167,7 @@ def recreate(info, priv):
    37.4  
    37.5      @param xeninfo: Parsed configuration
    37.6      @type  xeninfo: Dictionary
    37.7 -    @param priv: TODO, unknown, something to do with memory
    37.8 +    @param priv: Is a privileged domain (Dom 0)
    37.9      @type  priv: bool
   37.10  
   37.11      @rtype:  XendDomainInfo
   37.12 @@ -381,7 +381,7 @@ class XendDomainInfo:
   37.13          @type    dompath: string
   37.14          @keyword augment: Augment given info with xenstored VM info
   37.15          @type    augment: bool
   37.16 -        @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
   37.17 +        @keyword priv: Is a privileged domain (Dom 0)
   37.18          @type    priv: bool
   37.19          @keyword resume: Is this domain being resumed?
   37.20          @type    resume: bool
   37.21 @@ -563,7 +563,7 @@ class XendDomainInfo:
   37.22          for devclass in XendDevices.valid_devices():
   37.23              self.getDeviceController(devclass).waitForDevices()
   37.24  
   37.25 -    def destroyDevice(self, deviceClass, devid):
   37.26 +    def destroyDevice(self, deviceClass, devid, force=None):
   37.27          try:
   37.28              devid = int(devid)
   37.29          except ValueError:
   37.30 @@ -578,7 +578,7 @@ class XendDomainInfo:
   37.31                      devid = entry
   37.32                      break
   37.33                  
   37.34 -        return self.getDeviceController(deviceClass).destroyDevice(devid)
   37.35 +        return self.getDeviceController(deviceClass).destroyDevice(devid, force)
   37.36  
   37.37  
   37.38  
   37.39 @@ -647,6 +647,8 @@ class XendDomainInfo:
   37.40          if priv:
   37.41              augment_entries.remove('memory')
   37.42              augment_entries.remove('maxmem')
   37.43 +            augment_entries.remove('vcpus')
   37.44 +            augment_entries.remove('vcpu_avail')
   37.45  
   37.46          vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
   37.47                                           for k in augment_entries])
   37.48 @@ -664,6 +666,14 @@ class XendDomainInfo:
   37.49                  else:
   37.50                      self.info[arg] = val
   37.51  
   37.52 +        # For dom0, we ignore any stored value for the vcpus fields, and
   37.53 +        # read the current value from Xen instead.  This allows boot-time
   37.54 +        # settings to take precedence over any entries in the store.
   37.55 +        if priv:
   37.56 +            xeninfo = dom_get(self.domid)
   37.57 +            self.info['vcpus_number'] = xeninfo['online_vcpus']
   37.58 +            self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
   37.59 +
   37.60          # read image value
   37.61          image_sxp = self._readVm('image')
   37.62          if image_sxp:
   37.63 @@ -896,6 +906,10 @@ class XendDomainInfo:
   37.64          """Get this domain's target memory size, in KB."""
   37.65          return self.info['memory_static_min'] * 1024
   37.66  
   37.67 +    def getMemoryMaximum(self):
   37.68 +        """Get this domain's maximum memory size, in KB."""
   37.69 +        return self.info['memory_static_max'] * 1024
   37.70 +
   37.71      def getResume(self):
   37.72          return str(self._resume)
   37.73  
   37.74 @@ -1363,9 +1377,9 @@ class XendDomainInfo:
   37.75              # Use architecture- and image-specific calculations to determine
   37.76              # the various headrooms necessary, given the raw configured
   37.77              # values. maxmem, memory, and shadow are all in KiB.
   37.78 -            maxmem = self.image.getRequiredAvailableMemory(
   37.79 +            memory = self.image.getRequiredAvailableMemory(
   37.80                  self.info['memory_static_min'] * 1024)
   37.81 -            memory = self.image.getRequiredAvailableMemory(
   37.82 +            maxmem = self.image.getRequiredAvailableMemory(
   37.83                  self.info['memory_static_max'] * 1024)
   37.84              shadow = self.image.getRequiredShadowMemory(
   37.85                  self.info['shadow_memory'] * 1024,
   37.86 @@ -1727,7 +1741,7 @@ class XendDomainInfo:
   37.87              raise VmError("VM name '%s' already exists%s" %
   37.88                            (name,
   37.89                             dom.domid is not None and
   37.90 -                           ("as domain %s" % str(dom.domid)) or ""))
   37.91 +                           (" as domain %s" % str(dom.domid)) or ""))
   37.92          
   37.93  
   37.94      def update(self, info = None, refresh = True):
   37.95 @@ -2031,7 +2045,7 @@ class XendDomainInfo:
   37.96          if not dev_uuid:
   37.97              raise XendError('Failed to create device')
   37.98          
   37.99 -        if self.state in (DOM_STATE_HALTED,):
  37.100 +        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
  37.101              sxpr = self.info.device_sxpr(dev_uuid)
  37.102              devid = self.getDeviceController('vif').createDevice(sxpr)
  37.103              raise XendError("Device creation failed")
    38.1 --- a/tools/python/xen/xend/image.py	Thu Dec 14 08:54:54 2006 -0700
    38.2 +++ b/tools/python/xen/xend/image.py	Thu Dec 14 08:57:36 2006 -0700
    38.3 @@ -145,6 +145,14 @@ class ImageHandler:
    38.4          add headroom where necessary."""
    38.5          return self.getRequiredAvailableMemory(self.vm.getMemoryTarget())
    38.6  
    38.7 +    def getRequiredMaximumReservation(self):
    38.8 +        """@param mem_kb The maximum possible memory, in KiB.
    38.9 +        @return The corresponding required amount of memory to be free, also
   38.10 +        in KiB. This is normally the same as getRequiredAvailableMemory, but
   38.11 +        architecture- or image-specific code may override this to
   38.12 +        add headroom where necessary."""
   38.13 +        return self.getRequiredAvailableMemory(self.vm.getMemoryMaximum())
   38.14 +
   38.15      def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   38.16          """@param shadow_mem_kb The configured shadow memory, in KiB.
   38.17          @param maxmem_kb The configured maxmem, in KiB.
   38.18 @@ -235,6 +243,60 @@ class PPC_LinuxImageHandler(LinuxImageHa
   38.19                                features       = self.vm.getFeatures(),
   38.20                                arch_args      = devtree.to_bin())
   38.21  
   38.22 +    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   38.23 +        """@param shadow_mem_kb The configured shadow memory, in KiB.
   38.24 +        @param maxmem_kb The configured maxmem, in KiB.
   38.25 +        @return The corresponding required amount of shadow memory, also in
   38.26 +        KiB.
   38.27 +        PowerPC currently uses "shadow memory" to refer to the hash table."""
   38.28 +        return max(maxmem_kb / 64, shadow_mem_kb)
   38.29 +
   38.30 +
   38.31 +class PPC_ProseImageHandler(LinuxImageHandler):
   38.32 +
   38.33 +    ostype = "prose"
   38.34 +
   38.35 +    def configure(self, imageConfig, deviceConfig):
   38.36 +        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
   38.37 +        self.imageConfig = imageConfig
   38.38 +
   38.39 +    def buildDomain(self):
   38.40 +        store_evtchn = self.vm.getStorePort()
   38.41 +        console_evtchn = self.vm.getConsolePort()
   38.42 +
   38.43 +        mem_mb = self.getRequiredInitialReservation() / 1024
   38.44 +
   38.45 +        log.debug("dom            = %d", self.vm.getDomid())
   38.46 +        log.debug("memsize        = %d", mem_mb)
   38.47 +        log.debug("image          = %s", self.kernel)
   38.48 +        log.debug("store_evtchn   = %d", store_evtchn)
   38.49 +        log.debug("console_evtchn = %d", console_evtchn)
   38.50 +        log.debug("cmdline        = %s", self.cmdline)
   38.51 +        log.debug("ramdisk        = %s", self.ramdisk)
   38.52 +        log.debug("vcpus          = %d", self.vm.getVCpuCount())
   38.53 +        log.debug("features       = %s", self.vm.getFeatures())
   38.54 +
   38.55 +        devtree = FlatDeviceTree.build(self)
   38.56 +
   38.57 +        return xc.arch_prose_build(dom            = self.vm.getDomid(),
   38.58 +                                   memsize        = mem_mb,
   38.59 +                                   image          = self.kernel,
   38.60 +                                   store_evtchn   = store_evtchn,
   38.61 +                                   console_evtchn = console_evtchn,
   38.62 +                                   cmdline        = self.cmdline,
   38.63 +                                   ramdisk        = self.ramdisk,
   38.64 +                                   features       = self.vm.getFeatures(),
   38.65 +                                   arch_args      = devtree.to_bin())
   38.66 +
   38.67 +    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   38.68 +        """@param shadow_mem_kb The configured shadow memory, in KiB.
   38.69 +        @param maxmem_kb The configured maxmem, in KiB.
   38.70 +        @return The corresponding required amount of shadow memory, also in
   38.71 +        KiB.
   38.72 +        PowerPC currently uses "shadow memory" to refer to the hash table."""
   38.73 +        return max(maxmem_kb / 64, shadow_mem_kb)
   38.74 +
   38.75 +
   38.76  class HVMImageHandler(ImageHandler):
   38.77  
   38.78      ostype = "hvm"
   38.79 @@ -539,6 +601,9 @@ class X86_HVM_ImageHandler(HVMImageHandl
   38.80      def getRequiredInitialReservation(self):
   38.81          return self.vm.getMemoryTarget()
   38.82  
   38.83 +    def getRequiredMaximumReservation(self):
   38.84 +        return self.vm.getMemoryMaximum()
   38.85 +
   38.86      def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
   38.87          # 256 pages (1MB) per vcpu,
   38.88          # plus 1 page per MiB of RAM for the P2M map,
   38.89 @@ -553,13 +618,14 @@ class X86_Linux_ImageHandler(LinuxImageH
   38.90      def buildDomain(self):
   38.91          # set physical mapping limit
   38.92          # add an 8MB slack to balance backend allocations.
   38.93 -        mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
   38.94 +        mem_kb = self.getRequiredMaximumReservation() + (8 * 1024)
   38.95          xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
   38.96          return LinuxImageHandler.buildDomain(self)
   38.97  
   38.98  _handlers = {
   38.99      "powerpc": {
  38.100          "linux": PPC_LinuxImageHandler,
  38.101 +        "prose": PPC_ProseImageHandler,
  38.102      },
  38.103      "ia64": {
  38.104          "linux": LinuxImageHandler,
    39.1 --- a/tools/python/xen/xend/server/DevController.py	Thu Dec 14 08:54:54 2006 -0700
    39.2 +++ b/tools/python/xen/xend/server/DevController.py	Thu Dec 14 08:57:36 2006 -0700
    39.3 @@ -19,13 +19,15 @@
    39.4  from threading import Event
    39.5  import types
    39.6  
    39.7 -from xen.xend import sxp
    39.8 +from xen.xend import sxp, XendRoot
    39.9  from xen.xend.XendError import VmError
   39.10  from xen.xend.XendLogging import log
   39.11  
   39.12  from xen.xend.xenstore.xstransact import xstransact, complete
   39.13  from xen.xend.xenstore.xswatch import xswatch
   39.14  
   39.15 +import os
   39.16 +
   39.17  DEVICE_CREATE_TIMEOUT = 100
   39.18  HOTPLUG_STATUS_NODE = "hotplug-status"
   39.19  HOTPLUG_ERROR_NODE  = "hotplug-error"
   39.20 @@ -48,6 +50,8 @@ xenbusState = {
   39.21      'Closed'       : 6,
   39.22      }
   39.23  
   39.24 +xroot = XendRoot.instance()
   39.25 +
   39.26  xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys())))
   39.27  
   39.28  
   39.29 @@ -191,7 +195,7 @@ class DevController:
   39.30          raise VmError('%s devices may not be reconfigured' % self.deviceClass)
   39.31  
   39.32  
   39.33 -    def destroyDevice(self, devid):
   39.34 +    def destroyDevice(self, devid, force):
   39.35          """Destroy the specified device.
   39.36  
   39.37          @param devid The device ID, or something device-specific from which
   39.38 @@ -212,6 +216,13 @@ class DevController:
   39.39          self.writeBackend(devid, 'online', "0")
   39.40          self.writeBackend(devid, 'state', str(xenbusState['Closing']))
   39.41  
   39.42 +        if force:
   39.43 +            frontpath = self.frontendPath(devid)
   39.44 +            backpath = xstransact.Read(frontpath, "backend")
   39.45 +            if backpath:
   39.46 +                xstransact.Remove(backpath)
   39.47 +            xstransact.Remove(frontpath)
   39.48 +
   39.49  
   39.50      def configurations(self):
   39.51          return map(self.configuration, self.deviceIDs())
   39.52 @@ -313,6 +324,16 @@ class DevController:
   39.53                        Make sure that the migration has finished and only
   39.54                        then return from the call.
   39.55          """
   39.56 +        tool = xroot.get_external_migration_tool()
   39.57 +        if tool:
   39.58 +            log.info("Calling external migration tool for step %d" % step)
   39.59 +            fd = os.popen("%s -type %s -step %d -host %s -domname %s" %
   39.60 +                          (tool, self.deviceClass, step, dst, domName))
   39.61 +            for line in fd:
   39.62 +                log.info(line.rstrip())
   39.63 +            rc = fd.close()
   39.64 +            if rc:
   39.65 +                raise VmError('Migration tool returned %d' % (rc >> 8))
   39.66          return 0
   39.67  
   39.68  
   39.69 @@ -320,6 +341,16 @@ class DevController:
   39.70          """ Recover from device migration. The given step was the
   39.71              last one that was successfully executed.
   39.72          """
   39.73 +        tool = xroot.get_external_migration_tool()
   39.74 +        if tool:
   39.75 +            log.info("Calling external migration tool")
   39.76 +            fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" %
   39.77 +                          (tool, self.deviceClass, step, dst, domName))
   39.78 +            for line in fd:
   39.79 +                log.info(line.rstrip())
   39.80 +            rc = fd.close()
   39.81 +            if rc:
   39.82 +                raise VmError('Migration tool returned %d' % (rc >> 8))
   39.83          return 0
   39.84  
   39.85  
    40.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Dec 14 08:54:54 2006 -0700
    40.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Dec 14 08:57:36 2006 -0700
    40.3 @@ -133,7 +133,7 @@ class BlkifController(DevController):
    40.4  
    40.5          return config
    40.6  
    40.7 -    def destroyDevice(self, devid):
    40.8 +    def destroyDevice(self, devid, force):
    40.9          """@see DevController.destroyDevice"""
   40.10  
   40.11          # If we are given a device name, then look up the device ID from it,
   40.12 @@ -142,13 +142,13 @@ class BlkifController(DevController):
   40.13          # superclass's method.
   40.14  
   40.15          try:
   40.16 -            DevController.destroyDevice(self, int(devid))
   40.17 +            DevController.destroyDevice(self, int(devid), force)
   40.18          except ValueError:
   40.19              devid_end = type(devid) is str and devid.split('/')[-1] or None
   40.20  
   40.21              for i in self.deviceIDs():
   40.22                  d = self.readBackend(i, 'dev')
   40.23                  if d == devid or (devid_end and d == devid_end):
   40.24 -                    DevController.destroyDevice(self, i)
   40.25 +                    DevController.destroyDevice(self, i, force)
   40.26                      return
   40.27              raise VmError("Device %s not connected" % devid)
    41.1 --- a/tools/python/xen/xm/main.py	Thu Dec 14 08:54:54 2006 -0700
    41.2 +++ b/tools/python/xen/xm/main.py	Thu Dec 14 08:57:36 2006 -0700
    41.3 @@ -142,14 +142,14 @@ SUBCOMMAND_HELP = {
    41.4                          'Create a new virtual block device.'),
    41.5      'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
    41.6                          'Change block device configuration'),
    41.7 -    'block-detach'  :  ('<Domain> <DevId>',
    41.8 +    'block-detach'  :  ('<Domain> <DevId> [-f|--force]',
    41.9                          'Destroy a domain\'s virtual block device.'),
   41.10      'block-list'    :  ('<Domain> [--long]',
   41.11                          'List virtual block devices for a domain.'),
   41.12      'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
   41.13                          '[--mac=<mac>]',
   41.14                          'Create a new virtual network device.'),
   41.15 -    'network-detach':  ('<Domain> <DevId>',
   41.16 +    'network-detach':  ('<Domain> <DevId> [-f|--force]',
   41.17                          'Destroy a domain\'s virtual network device.'),
   41.18      'network-list'  :  ('<Domain> [--long]',
   41.19                          'List virtual network interfaces for a domain.'),
   41.20 @@ -1493,16 +1493,24 @@ def xm_network_attach(args):
   41.21  
   41.22  
   41.23  def detach(args, command, deviceClass):
   41.24 -    arg_check(args, command, 2)
   41.25 +    arg_check(args, command, 2, 3)
   41.26  
   41.27      dom = args[0]
   41.28      dev = args[1]
   41.29 +    try:
   41.30 +        force = args[2]
   41.31 +        if (force != "--force") and (force != "-f"):
   41.32 +            print "Ignoring option %s"%(force)
   41.33 +            force = None
   41.34 +    except IndexError:
   41.35 +        force = None
   41.36  
   41.37 -    server.xend.domain.destroyDevice(dom, deviceClass, dev)
   41.38 +    server.xend.domain.destroyDevice(dom, deviceClass, dev, force)
   41.39  
   41.40  
   41.41  def xm_block_detach(args):
   41.42      detach(args, 'block-detach', 'vbd')
   41.43 +    detach(args, 'block-detach', 'tap')
   41.44  
   41.45  
   41.46  def xm_network_detach(args):
    42.1 --- a/tools/xenstore/xenstored_domain.c	Thu Dec 14 08:54:54 2006 -0700
    42.2 +++ b/tools/xenstore/xenstored_domain.c	Thu Dec 14 08:57:36 2006 -0700
    42.3 @@ -459,6 +459,8 @@ static int dom0_init(void)
    42.4  		return -1;
    42.5  
    42.6  	dom0 = new_domain(NULL, 0, port); 
    42.7 +	if (dom0 == NULL)
    42.8 +		return -1;
    42.9  
   42.10  	dom0->interface = xenbus_map();
   42.11  	if (dom0->interface == NULL)
    43.1 --- a/xen/arch/powerpc/Makefile	Thu Dec 14 08:54:54 2006 -0700
    43.2 +++ b/xen/arch/powerpc/Makefile	Thu Dec 14 08:57:36 2006 -0700
    43.3 @@ -9,10 +9,10 @@ obj-y += audit.o
    43.4  obj-y += backtrace.o
    43.5  obj-y += bitops.o
    43.6  obj-y += boot_of.o
    43.7 +obj-y += cmdline.o
    43.8  obj-y += dart.o
    43.9  obj-y += dart_u3.o
   43.10  obj-y += dart_u4.o
   43.11 -obj-y += delay.o
   43.12  obj-y += domctl.o
   43.13  obj-y += domain_build.o
   43.14  obj-y += domain.o
   43.15 @@ -22,11 +22,12 @@ obj-y += float.o
   43.16  obj-y += hcalls.o
   43.17  obj-y += iommu.o
   43.18  obj-y += irq.o
   43.19 -obj-y += mambo.o
   43.20 +obj-y += systemsim.o
   43.21  obj-y += memory.o
   43.22  obj-y += mm.o
   43.23  obj-y += mpic.o
   43.24  obj-y += mpic_init.o
   43.25 +obj-y += numa.o
   43.26  obj-y += of-devtree.o
   43.27  obj-y += of-devwalk.o
   43.28  obj-y += ofd_fixup.o
   43.29 @@ -36,6 +37,7 @@ obj-y += rtas.o
   43.30  obj-y += setup.o
   43.31  obj-y += shadow.o
   43.32  obj-y += smp.o
   43.33 +obj-y += smpboot.o
   43.34  obj-y += smp-tbsync.o
   43.35  obj-y += sysctl.o
   43.36  obj-y += time.o
   43.37 @@ -57,11 +59,6 @@ PPC_C_WARNINGS += -Wundef -Wmissing-prot
   43.38  PPC_C_WARNINGS += -Wshadow
   43.39  CFLAGS += $(PPC_C_WARNINGS)
   43.40  
   43.41 -LINK=0x400000
   43.42 -boot32_link_base = $(LINK)
   43.43 -xen_link_offset  = 100
   43.44 -xen_link_base    = $(patsubst %000,%$(xen_link_offset),$(LINK))
   43.45 -
   43.46  #
   43.47  # The following flags are fed to gcc in order to link several
   43.48  # objects into a single ELF segment and to not link in any additional
   43.49 @@ -72,34 +69,39 @@ OMAGIC = -N -nodefaultlibs -nostartfiles
   43.50  firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
   43.51  	$(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
   43.52  
   43.53 -firmware_image: firmware
   43.54 +firmware_image.bin: firmware
   43.55  	$(CROSS_COMPILE)objcopy --output-target=binary $< $@
   43.56  
   43.57 -firmware_image.o: firmware_image
   43.58 -	$(CROSS_COMPILE)objcopy --input-target=binary \
   43.59 -		--output-target=elf64-powerpc \
   43.60 -		--binary-architecture=powerpc \
   43.61 -		--redefine-sym _binary_$<_start=$(@:%.o=%)_start \
   43.62 -		--redefine-sym _binary_$<_end=$(@:%.o=%)_end \
   43.63 -		--redefine-sym _binary_$<_size=$(@:%.o=%)_size  $< $@
   43.64 -
   43.65  #
   43.66  # Hacks for included C files
   43.67  #
   43.68  irq.o: ../x86/irq.c
   43.69  physdev.o: ../x86/physdev.c
   43.70 +numa.o: ../x86/numa.c
   43.71  
   43.72  HDRS += $(wildcard *.h)
   43.73  
   43.74 +ifneq ($(CMDLINE),)
   43.75  # The first token in the arguments will be silently dropped.
   43.76 -IMAGENAME = xen
   43.77 -CMDLINE = ""
   43.78 -boot_of.o: CFLAGS += -DCMDLINE="\"$(IMAGENAME) $(CMDLINE)\""
   43.79 +FULL_CMDLINE := xen $(CMDLINE)
   43.80 +endif
   43.81  
   43.82 -start.o: boot/start.S
   43.83 -	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
   43.84 +ifeq ($(wildcard cmdline.dep),)
   43.85 +cmdline.dep:
   43.86 +	echo $(FULL_CMDLINE) > cmdline.dep
   43.87 +else
   43.88 +ifneq ($(FULL_CMDLINE),$(shell cat cmdline.dep))
   43.89 +cmdline.dep::
   43.90 +	echo $(FULL_CMDLINE) > cmdline.dep
   43.91 +else
   43.92 +cmdline.dep:
   43.93 +endif
   43.94 +endif
   43.95  
   43.96 -TARGET_OPTS = $(OMAGIC) -Wl,-Ttext,$(xen_link_base),-T,xen.lds
   43.97 +cmdline.o: cmdline.dep
   43.98 +cmdline.o: CFLAGS += -DCMDLINE="\"$(FULL_CMDLINE)\""
   43.99 +
  43.100 +TARGET_OPTS = $(OMAGIC) -Wl,-T,xen.lds
  43.101  TARGET_OPTS += start.o $(ALL_OBJS)
  43.102  
  43.103  .xen-syms: start.o $(ALL_OBJS) xen.lds
  43.104 @@ -122,22 +124,10 @@ xen-syms.o: xen-syms.S
  43.105  $(TARGET)-syms: start.o $(ALL_OBJS) xen-syms.o xen.lds
  43.106  	$(CC) $(CFLAGS) $(TARGET_OPTS) xen-syms.o -o $@
  43.107  
  43.108 -$(TARGET).bin: $(TARGET)-syms
  43.109 -	$(CROSS_COMPILE)objcopy --output-target=binary $< $@
  43.110 -
  43.111 -$(TARGET).bin.o: $(TARGET).bin
  43.112 -	$(CROSS_COMPILE)objcopy --input-target=binary \
  43.113 -		--output-target=elf32-powerpc \
  43.114 -		--binary-architecture=powerpc  $< $@
  43.115 -
  43.116 -boot32.o: boot/boot32.S
  43.117 -	$(CC) -m32 -Wa,-a32,-mppc64bridge \
  43.118 -		-D__ASSEMBLY__ -D__BRIDGE64__ $(CFLAGS) -c $< -o $@
  43.119 -
  43.120 -$(TARGET): boot32.o $(TARGET).bin.o
  43.121 -	$(CC) -m32 -N -Wl,-melf32ppclinux -static -nostdlib \
  43.122 -		-Wl,-Ttext,$(boot32_link_base)  -Wl,-Tdata,$(xen_link_base) \
  43.123 -		$(CFLAGS) $^ -o $@
  43.124 +# our firmware only loads 32-bit ELF files
  43.125 +OCPYFLAGS := --input-target=elf64-powerpc --output-target=elf32-powerpc
  43.126 +$(TARGET): $(TARGET)-syms
  43.127 +	$(CROSS_COMPILE)objcopy $(OCPYFLAGS) $^ $@
  43.128  
  43.129  asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
  43.130  	$(CC) $(CFLAGS) -S -o $@ $<
  43.131 @@ -150,4 +140,5 @@ dom0.bin: $(DOM0_IMAGE)
  43.132  
  43.133  clean::
  43.134  	$(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean
  43.135 -	rm -f firmware firmware_image dom0.bin .xen-syms
  43.136 +	rm -f firmware firmware_image.bin dom0.bin .xen-syms xen-syms.S \
  43.137 +		xen.lds asm-offsets.s cmdline.dep
    44.1 --- a/xen/arch/powerpc/backtrace.c	Thu Dec 14 08:54:54 2006 -0700
    44.2 +++ b/xen/arch/powerpc/backtrace.c	Thu Dec 14 08:57:36 2006 -0700
    44.3 @@ -14,6 +14,7 @@
    44.4  #include <xen/console.h>
    44.5  #include <xen/sched.h>
    44.6  #include <xen/symbols.h>
    44.7 +#include <asm/debugger.h>
    44.8  
    44.9  static char namebuf[KSYM_NAME_LEN+1];
   44.10  
   44.11 @@ -192,6 +193,19 @@ void show_backtrace(ulong sp, ulong lr, 
   44.12      console_end_sync();
   44.13  }
   44.14  
   44.15 +void show_backtrace_regs(struct cpu_user_regs *regs)
   44.16 +{
   44.17 +    console_start_sync();
   44.18 +    
   44.19 +    show_registers(regs);
   44.20 +    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
   44.21 +    printk("hid4 0x%016lx\n", regs->hid4);
   44.22 +    printk("---[ backtrace ]---\n");
   44.23 +    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
   44.24 +
   44.25 +    console_end_sync();
   44.26 +}
   44.27 +
   44.28  void __warn(char *file, int line)
   44.29  {
   44.30      ulong sp;
   44.31 @@ -202,9 +216,19 @@ void __warn(char *file, int line)
   44.32  
   44.33      sp = (ulong)__builtin_frame_address(0);
   44.34      lr = (ulong)__builtin_return_address(0);
   44.35 +    backtrace(sp, lr, lr);
   44.36  
   44.37 -    backtrace(sp, lr, lr);
   44.38      console_end_sync();
   44.39  }
   44.40  
   44.41 -    
   44.42 +void dump_execution_state(void)
   44.43 +{
   44.44 +    struct vcpu *v = current;
   44.45 +    struct cpu_user_regs *regs = &v->arch.ctxt;
   44.46 +
   44.47 +    show_registers(regs);
   44.48 +    if (regs->msr & MSR_HV) {
   44.49 +        printk("In Xen:\n");
   44.50 +        show_backtrace(regs->gprs[1], regs->pc, regs->lr);
   44.51 +    }
   44.52 +}
    45.1 --- a/xen/arch/powerpc/bitops.c	Thu Dec 14 08:54:54 2006 -0700
    45.2 +++ b/xen/arch/powerpc/bitops.c	Thu Dec 14 08:57:36 2006 -0700
    45.3 @@ -12,42 +12,42 @@
    45.4   * @size: The maximum size to search
    45.5   */
    45.6  unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
    45.7 -			    unsigned long offset)
    45.8 +                            unsigned long offset)
    45.9  {
   45.10 -	const unsigned long *p = addr + BITOP_WORD(offset);
   45.11 -	unsigned long result = offset & ~(BITS_PER_LONG-1);
   45.12 -	unsigned long tmp;
   45.13 +    const unsigned long *p = addr + BITOP_WORD(offset);
   45.14 +    unsigned long result = offset & ~(BITS_PER_LONG-1);
   45.15 +    unsigned long tmp;
   45.16  
   45.17 -	if (offset >= size)
   45.18 -		return size;
   45.19 -	size -= result;
   45.20 -	offset %= BITS_PER_LONG;
   45.21 -	if (offset) {
   45.22 -		tmp = *(p++);
   45.23 -		tmp &= (~0UL << offset);
   45.24 -		if (size < BITS_PER_LONG)
   45.25 -			goto found_first;
   45.26 -		if (tmp)
   45.27 -			goto found_middle;
   45.28 -		size -= BITS_PER_LONG;
   45.29 -		result += BITS_PER_LONG;
   45.30 -	}
   45.31 -	while (size & ~(BITS_PER_LONG-1)) {
   45.32 -		if ((tmp = *(p++)))
   45.33 -			goto found_middle;
   45.34 -		result += BITS_PER_LONG;
   45.35 -		size -= BITS_PER_LONG;
   45.36 -	}
   45.37 -	if (!size)
   45.38 -		return result;
   45.39 -	tmp = *p;
   45.40 +    if (offset >= size)
   45.41 +        return size;
   45.42 +    size -= result;
   45.43 +    offset %= BITS_PER_LONG;
   45.44 +    if (offset) {
   45.45 +        tmp = *(p++);
   45.46 +        tmp &= (~0UL << offset);
   45.47 +        if (size < BITS_PER_LONG)
   45.48 +            goto found_first;
   45.49 +        if (tmp)
   45.50 +            goto found_middle;
   45.51 +        size -= BITS_PER_LONG;
   45.52 +        result += BITS_PER_LONG;
   45.53 +    }
   45.54 +    while (size & ~(BITS_PER_LONG-1)) {
   45.55 +        if ((tmp = *(p++)))
   45.56 +            goto found_middle;
   45.57 +        result += BITS_PER_LONG;
   45.58 +        size -= BITS_PER_LONG;
   45.59 +    }
   45.60 +    if (!size)
   45.61 +        return result;
   45.62 +    tmp = *p;
   45.63  
   45.64  found_first:
   45.65 -	tmp &= (~0UL >> (BITS_PER_LONG - size));
   45.66 -	if (tmp == 0UL)		/* Are any bits set? */
   45.67 -		return result + size;	/* Nope. */
   45.68 +    tmp &= (~0UL >> (BITS_PER_LONG - size));
   45.69 +    if (tmp == 0UL)        /* Are any bits set? */
   45.70 +        return result + size;    /* Nope. */
   45.71  found_middle:
   45.72 -	return result + __ffs(tmp);
   45.73 +    return result + __ffs(tmp);
   45.74  }
   45.75  
   45.76  /*
   45.77 @@ -55,40 +55,40 @@ found_middle:
   45.78   * Linus' asm-alpha/bitops.h.
   45.79   */
   45.80  unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
   45.81 -				 unsigned long offset)
   45.82 +                                 unsigned long offset)
   45.83  {
   45.84 -	const unsigned long *p = addr + BITOP_WORD(offset);
   45.85 -	unsigned long result = offset & ~(BITS_PER_LONG-1);
   45.86 -	unsigned long tmp;
   45.87 +    const unsigned long *p = addr + BITOP_WORD(offset);
   45.88 +    unsigned long result = offset & ~(BITS_PER_LONG-1);
   45.89 +    unsigned long tmp;
   45.90  
   45.91 -	if (offset >= size)
   45.92 -		return size;
   45.93 -	size -= result;
   45.94 -	offset %= BITS_PER_LONG;
   45.95 -	if (offset) {
   45.96 -		tmp = *(p++);
   45.97 -		tmp |= ~0UL >> (BITS_PER_LONG - offset);
   45.98 -		if (size < BITS_PER_LONG)
   45.99 -			goto found_first;
  45.100 -		if (~tmp)
  45.101 -			goto found_middle;
  45.102 -		size -= BITS_PER_LONG;
  45.103 -		result += BITS_PER_LONG;
  45.104 -	}
  45.105 -	while (size & ~(BITS_PER_LONG-1)) {
  45.106 -		if (~(tmp = *(p++)))
  45.107 -			goto found_middle;
  45.108 -		result += BITS_PER_LONG;
  45.109 -		size -= BITS_PER_LONG;
  45.110 -	}
  45.111 -	if (!size)
  45.112 -		return result;
  45.113 -	tmp = *p;
  45.114 +    if (offset >= size)
  45.115 +        return size;
  45.116 +    size -= result;
  45.117 +    offset %= BITS_PER_LONG;
  45.118 +    if (offset) {
  45.119 +        tmp = *(p++);
  45.120 +        tmp |= ~0UL >> (BITS_PER_LONG - offset);
  45.121 +        if (size < BITS_PER_LONG)
  45.122 +            goto found_first;
  45.123 +        if (~tmp)
  45.124 +            goto found_middle;
  45.125 +        size -= BITS_PER_LONG;
  45.126 +        result += BITS_PER_LONG;
  45.127 +    }
  45.128 +    while (size & ~(BITS_PER_LONG-1)) {
  45.129 +        if (~(tmp = *(p++)))
  45.130 +            goto found_middle;
  45.131 +        result += BITS_PER_LONG;
  45.132 +        size -= BITS_PER_LONG;
  45.133 +    }
  45.134 +    if (!size)
  45.135 +        return result;
  45.136 +    tmp = *p;
  45.137  
  45.138  found_first:
  45.139 -	tmp |= ~0UL << size;
  45.140 -	if (tmp == ~0UL)	/* Are any bits zero? */
  45.141 -		return result + size;	/* Nope. */
  45.142 +    tmp |= ~0UL << size;
  45.143 +    if (tmp == ~0UL)    /* Are any bits zero? */
  45.144 +        return result + size;    /* Nope. */
  45.145  found_middle:
  45.146 -	return result + ffz(tmp);
  45.147 +    return result + ffz(tmp);
  45.148  }
    46.1 --- a/xen/arch/powerpc/boot/boot32.S	Thu Dec 14 08:54:54 2006 -0700
    46.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.3 @@ -1,75 +0,0 @@
    46.4 -/*
    46.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    46.6 - *
    46.7 - * This program is free software; you can redistribute it and/or modify
    46.8 - * it under the terms of the GNU General Public License as published by
    46.9 - * the Free Software Foundation; either version 2 of the License, or
   46.10 - * (at your option) any later version.
   46.11 - * 
   46.12 - * This program is distributed in the hope that it will be useful,
   46.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.15 - * GNU General Public License for more details.
   46.16 - * 
   46.17 - * You should have received a copy of the GNU General Public License
   46.18 - * along with this program; if not, write to the Free Software
   46.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   46.20 - *
   46.21 - */
   46.22 -	
   46.23 -### 32 bit strapping code so Of will like us
   46.24 -	.section	".text"
   46.25 -	.align 3
   46.26 -	.globl _start
   46.27 -		
   46.28 -_start:
   46.29 -	## Double word align the MSR value below
   46.30 -	nop
   46.31 -	bl _real_start
   46.32 -	## static value for MSR
   46.33 -	.llong 0x9000000000001000
   46.34 -
   46.35 -	## see also docs/reference/ppc/msr.txt
   46.36 -##bit C  Hex               Name Desc
   46.37 -##  0 63 80000000 00000000 SF   64-bit Mode
   46.38 -##  3 60 10000000 00000000 HV   Hypervisor State iff PR = 0 in hypervisor state.
   46.39 -## 51 12 00000000 00001000 ME   Machine Check Enable
   46.40 -
   46.41 -_real_start:		
   46.42 -	# pass the original msr as argument to hype_init
   46.43 -	mfmsr   8
   46.44 -
   46.45 -	## Set PC
   46.46 -	li	21, 0
   46.47 -	oris	21, 21, _hype64@h
   46.48 -	ori	21, 21, _hype64@l
   46.49 -#ifdef __BRIDGE64__
   46.50 -	## In 64bit we use rfid to switch from 32bit to 64 bit
   46.51 -	mtsrr0	21
   46.52 -
   46.53 -	## Set MSR
   46.54 -	mflr	21
   46.55 -	ld	22, 0(21)
   46.56 -	mtsrr1	22
   46.57 -	bl __leap
   46.58 -	/* should never return */
   46.59 -	trap
   46.60 -__leap:		
   46.61 -	rfid
   46.62 -#else
   46.63 -	mtctr 21
   46.64 -	bctrl
   46.65 -	/* should never return */
   46.66 -	trap
   46.67 -#endif
   46.68 -
   46.69 -	
   46.70 -_real_end:
   46.71 -	.data
   46.72 -	.align 3
   46.73 -	## Hypervisor starts here, at the first data address
   46.74 -	## linker magic positions _hype64 0x100 after _start
   46.75 -	## hype/ppc64/Makefile.isa 
   46.76 -_hype64:		
   46.77 -
   46.78 -
    47.1 --- a/xen/arch/powerpc/boot/start.S	Thu Dec 14 08:54:54 2006 -0700
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,51 +0,0 @@
    47.4 -/*
    47.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    47.6 - *
    47.7 - * This program is free software; you can redistribute it and/or modify
    47.8 - * it under the terms of the GNU General Public License as published by
    47.9 - * the Free Software Foundation; either version 2 of the License, or
   47.10 - * (at your option) any later version.
   47.11 - * 
   47.12 - * This program is distributed in the hope that it will be useful,
   47.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.15 - * GNU General Public License for more details.
   47.16 - * 
   47.17 - * You should have received a copy of the GNU General Public License
   47.18 - * along with this program; if not, write to the Free Software
   47.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   47.20 - *
   47.21 - */
   47.22 -
   47.23 -#include <asm/config.h>
   47.24 -#include <asm/processor.h>
   47.25 -#include <asm/page.h>
   47.26 -
   47.27 -    .globl _start
   47.28 -_start:
   47.29 -    /* load up the stack */
   47.30 -    SET_REG_TO_LABEL(r1, cpu0_stack)
   47.31 -
   47.32 -    /* call the init function */
   47.33 -    LOADADDR(r21,__start_xen_ppc)
   47.34 -
   47.35 -#ifdef __PPC64__
   47.36 -    ld r2, 8(r21)
   47.37 -    ld r21, 0(r21)
   47.38 -#endif
   47.39 -    mtctr r21
   47.40 -    bctrl
   47.41 -    /* should never return */
   47.42 -    trap
   47.43 -
   47.44 -    /* Note! GDB 6.3 makes the very stupid assumption that PC > SP means we are
   47.45 -     * in a Linux signal trampoline, and it begins groping for a struct
   47.46 -     * rt_sigframe on the stack. Naturally, this fails miserably for our
   47.47 -     * backtrace. To work around this behavior, we must make certain that our
   47.48 -     * stack is always above our text, e.g. in the data section. */
   47.49 -    .data /* DO NOT REMOVE; see GDB note above */
   47.50 -    .align 4
   47.51 -cpu0_stack_bottom:
   47.52 -    .space STACK_SIZE
   47.53 -cpu0_stack:
   47.54 -    .space STACK_FRAME_OVERHEAD
    48.1 --- a/xen/arch/powerpc/boot_of.c	Thu Dec 14 08:54:54 2006 -0700
    48.2 +++ b/xen/arch/powerpc/boot_of.c	Thu Dec 14 08:57:36 2006 -0700
    48.3 @@ -16,6 +16,7 @@
    48.4   * Copyright (C) IBM Corp. 2005, 2006
    48.5   *
    48.6   * Authors: Jimi Xenidis <jimix@watson.ibm.com>
    48.7 + *          Hollis Blanchard <hollisb@us.ibm.com>
    48.8   */
    48.9  
   48.10  #include <xen/config.h>
   48.11 @@ -32,6 +33,7 @@
   48.12  #include "exceptions.h"
   48.13  #include "of-devtree.h"
   48.14  #include "oftree.h"
   48.15 +#include "rtas.h"
   48.16  
   48.17  /* Secondary processors use this for handshaking with main processor.  */
   48.18  volatile unsigned int __spin_ack;
   48.19 @@ -39,15 +41,16 @@ volatile unsigned int __spin_ack;
   48.20  static ulong of_vec;
   48.21  static ulong of_msr;
   48.22  static int of_out;
   48.23 -static char bootargs[256];
   48.24 +static ulong eomem;
   48.25  
   48.26 -#define COMMAND_LINE_SIZE 512
   48.27 -static char builtin_cmdline[COMMAND_LINE_SIZE]
   48.28 -    __attribute__((section("__builtin_cmdline"))) = CMDLINE;
   48.29 +#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)
   48.30 +static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);
   48.31  
   48.32 +extern char builtin_cmdline[];
   48.33  extern struct ns16550_defaults ns16550;
   48.34  
   48.35  #undef OF_DEBUG
   48.36 +#undef OF_DEBUG_LOW
   48.37  
   48.38  #ifdef OF_DEBUG
   48.39  #define DBG(args...) of_printf(args)
   48.40 @@ -55,6 +58,12 @@ extern struct ns16550_defaults ns16550;
   48.41  #define DBG(args...)
   48.42  #endif
   48.43  
   48.44 +#ifdef OF_DEBUG_LOW
   48.45 +#define DBG_LOW(args...) of_printf(args)
   48.46 +#else
   48.47 +#define DBG_LOW(args...)
   48.48 +#endif
   48.49 +
   48.50  #define of_panic(MSG...) \
   48.51      do { of_printf(MSG); of_printf("\nHANG\n"); for (;;); } while (0)
   48.52  
   48.53 @@ -68,7 +77,6 @@ struct of_service {
   48.54  static int bof_chosen;
   48.55  
   48.56  static struct of_service s;
   48.57 -extern s32 prom_call(void *arg, ulong rtas_base, ulong func, ulong msr);
   48.58  
   48.59  static int __init of_call(
   48.60      const char *service, u32 nargs, u32 nrets, s32 rets[], ...)
   48.61 @@ -78,7 +86,6 @@ static int __init of_call(
   48.62      if (of_vec != 0) {
   48.63          va_list args;
   48.64          int i;
   48.65 -
   48.66          memset(&s, 0, sizeof (s));
   48.67          s.ofs_service = (ulong)service;
   48.68          s.ofs_nargs = nargs;
   48.69 @@ -189,7 +196,7 @@ static int __init of_finddevice(const ch
   48.70          DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]);
   48.71          return OF_FAILURE;
   48.72      }
   48.73 -    DBG("finddevice %s -> %d\n",devspec, rets[0]);
   48.74 +    DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]);
   48.75      return rets[0];
   48.76  }
   48.77  
   48.78 @@ -200,11 +207,11 @@ static int __init of_getprop(int ph, con
   48.79      of_call("getprop", 4, 1, rets, ph, name, buf, buflen);
   48.80  
   48.81      if (rets[0] == OF_FAILURE) {
   48.82 -        DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
   48.83 +        DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name);
   48.84          return OF_FAILURE;
   48.85      }
   48.86  
   48.87 -    DBG("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
   48.88 +    DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
   48.89      return rets[0];
   48.90  }
   48.91  
   48.92 @@ -220,7 +227,7 @@ static int __init of_setprop(
   48.93          return OF_FAILURE;
   48.94      }
   48.95  
   48.96 -    DBG("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
   48.97 +    DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
   48.98      return rets[0];
   48.99  }
  48.100  
  48.101 @@ -232,7 +239,7 @@ static int __init of_getchild(int ph)
  48.102      int rets[1] = { OF_FAILURE };
  48.103  
  48.104      of_call("child", 1, 1, rets, ph);
  48.105 -    DBG("getchild 0x%x -> 0x%x\n", ph, rets[0]);
  48.106 +    DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]);
  48.107  
  48.108      return rets[0];
  48.109  }
  48.110 @@ -245,7 +252,7 @@ static int __init of_getpeer(int ph)
  48.111      int rets[1] = { OF_FAILURE };
  48.112  
  48.113      of_call("peer", 1, 1, rets, ph);
  48.114 -    DBG("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
  48.115 +    DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
  48.116  
  48.117      return rets[0];
  48.118  }
  48.119 @@ -259,7 +266,7 @@ static int __init of_getproplen(int ph, 
  48.120          DBG("getproplen 0x%x %s -> FAILURE\n", ph, name);
  48.121          return OF_FAILURE;
  48.122      }
  48.123 -    DBG("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
  48.124 +    DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
  48.125      return rets[0];
  48.126  }
  48.127  
  48.128 @@ -272,7 +279,7 @@ static int __init of_package_to_path(int
  48.129          DBG("%s 0x%x -> FAILURE\n", __func__, ph);
  48.130          return OF_FAILURE;
  48.131      }
  48.132 -    DBG("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
  48.133 +    DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
  48.134      if (rets[0] <= buflen)
  48.135          buffer[rets[0]] = '\0';
  48.136      return rets[0];
  48.137 @@ -289,7 +296,7 @@ static int __init of_nextprop(int ph, co
  48.138          return OF_FAILURE;
  48.139      }
  48.140  
  48.141 -    DBG("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
  48.142 +    DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
  48.143      return rets[0];
  48.144  }
  48.145  
  48.146 @@ -336,7 +343,7 @@ static int __init of_claim(u32 virt, u32
  48.147          return OF_FAILURE;
  48.148      }
  48.149  
  48.150 -    DBG("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,
  48.151 +    DBG_LOW("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,
  48.152          rets[0]);
  48.153      return rets[0];
  48.154  }
  48.155 @@ -358,29 +365,194 @@ static int __init of_getparent(int ph)
  48.156  
  48.157      of_call("parent", 1, 1, rets, ph);
  48.158  
  48.159 -    DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
  48.160 +    DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]);
  48.161 +    return rets[0];
  48.162 +}
  48.163 +
  48.164 +static int __init of_open(const char *devspec)
  48.165 +{
  48.166 +    int rets[1] = { OF_FAILURE };
  48.167 +
  48.168 +    of_call("open", 1, 1, rets, devspec);
  48.169      return rets[0];
  48.170  }
  48.171  
  48.172 -static void boot_of_probemem(multiboot_info_t *mbi)
  48.173 +static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells)
  48.174 +{
  48.175 +    int rc;
  48.176 +    uint pg;
  48.177 +    uint a[64];
  48.178 +    int tst;
  48.179 +    u64 start;
  48.180 +    u64 size;
  48.181 +
  48.182 +    rc = of_getprop(m, "available", a, sizeof (a));
  48.183 +    if (rc > 0) {
  48.184 +        int l =  rc / sizeof(a[0]);
  48.185 +        int r = 0;
  48.186 +
  48.187 +#ifdef OF_DEBUG
  48.188 +        { 
  48.189 +            int i;
  48.190 +            of_printf("avail:\n");
  48.191 +            for (i = 0; i < l; i += 4)
  48.192 +                of_printf("  0x%x%x, 0x%x%x\n",
  48.193 +                          a[i], a[i + 1],
  48.194 +                          a[i + 2] ,a[i + 3]);
  48.195 +        }
  48.196 +#endif
  48.197 +            
  48.198 +        pg = 0;
  48.199 +        while (pg < MEM_AVAILABLE_PAGES && r < l) {
  48.200 +            ulong end;
  48.201 +
  48.202 +            start = a[r++];
  48.203 +            if (addr_cells == 2 && (r < l) )
  48.204 +                start = (start << 32) | a[r++];
  48.205 +            
  48.206 +            size = a[r++];
  48.207 +            if (size_cells == 2 && (r < l) )
  48.208 +                size = (size << 32) | a[r++];
  48.209 +                
  48.210 +            end = ALIGN_DOWN(start + size, PAGE_SIZE);
  48.211 +
  48.212 +            start = ALIGN_UP(start, PAGE_SIZE);
  48.213 +
  48.214 +            DBG("%s: marking 0x%x - 0x%lx\n", __func__,
  48.215 +                pg << PAGE_SHIFT, start);
  48.216 +
  48.217 +            start >>= PAGE_SHIFT;
  48.218 +            while (pg < MEM_AVAILABLE_PAGES && pg < start) {
  48.219 +                set_bit(pg, mem_available_pages);
  48.220 +                pg++;
  48.221 +            }
  48.222 +
  48.223 +            pg = end  >> PAGE_SHIFT;
  48.224 +        }
  48.225 +    }
  48.226 +
  48.227 +    /* Now make sure we mark our own memory */
  48.228 +    pg =  (ulong)_start >> PAGE_SHIFT;
  48.229 +    start = (ulong)_end >> PAGE_SHIFT;
  48.230 +
  48.231 +    DBG("%s: marking 0x%x - 0x%lx\n", __func__,
  48.232 +        pg << PAGE_SHIFT, start << PAGE_SHIFT);
  48.233 +
  48.234 +    /* Lets try and detect if our image has stepped on something. It
  48.235 +     * is possible that FW has already subtracted our image from
  48.236 +     * available memory so we must make sure that the previous bits
  48.237 +     * are the same for the whole image */
  48.238 +    tst = test_and_set_bit(pg, mem_available_pages);
  48.239 +    ++pg;
  48.240 +    while (pg <= start) {
  48.241 +        if (test_and_set_bit(pg, mem_available_pages) != tst)
  48.242 +            of_panic("%s: pg :0x%x of our image is different\n",
  48.243 +                     __func__, pg);
  48.244 +        ++pg;
  48.245 +    }
  48.246 +
  48.247 +    DBG("%s: marking 0x%x - 0x%x\n", __func__,
  48.248 +        0 << PAGE_SHIFT, 3 << PAGE_SHIFT);
  48.249 +    /* First for pages (where the vectors are) should be left alone as well */
  48.250 +    set_bit(0, mem_available_pages);
  48.251 +    set_bit(1, mem_available_pages);
  48.252 +    set_bit(2, mem_available_pages);
  48.253 +    set_bit(3, mem_available_pages);
  48.254 +}
  48.255 +
  48.256 +#ifdef BOOT_OF_FREE
  48.257 +/* this is here in case we ever need a free call at a later date */
  48.258 +static void boot_of_free(ulong addr, ulong size)
  48.259 +{
  48.260 +    ulong bits;
  48.261 +    ulong pos;
  48.262 +    ulong i;
  48.263 +
  48.264 +    size = ALIGN_UP(size, PAGE_SIZE);
  48.265 +    bits = size >> PAGE_SHIFT;
  48.266 +    pos = addr >> PAGE_SHIFT;
  48.267 +
  48.268 +    for (i = 0; i < bits; i++) {
  48.269 +        if (!test_and_clear_bit(pos + i, mem_available_pages))
  48.270 +            of_panic("%s: pg :0x%lx was never allocated\n",
  48.271 +                     __func__, pos + i);
  48.272 +    }
  48.273 +}
  48.274 +#endif
  48.275 +
  48.276 +static ulong boot_of_alloc(ulong size)
  48.277 +{
  48.278 +    ulong bits;
  48.279 +    ulong pos;
  48.280 +
  48.281 +    if (size == 0)
  48.282 +        return 0;
  48.283 +
  48.284 +    DBG("%s(0x%lx)\n", __func__, size);
  48.285 +
  48.286 +    size = ALIGN_UP(size, PAGE_SIZE);
  48.287 +    bits = size >> PAGE_SHIFT;
  48.288 +    pos = 0;
  48.289 +    for (;;) {
  48.290 +        ulong i;
  48.291 +
  48.292 +        pos = find_next_zero_bit(mem_available_pages,
  48.293 +                                 MEM_AVAILABLE_PAGES, pos);
  48.294 +        DBG("%s: found start bit at: 0x%lx\n", __func__, pos);
  48.295 +
  48.296 +        /* found nothing */
  48.297 +        if ((pos + bits) > MEM_AVAILABLE_PAGES) {
  48.298 +            of_printf("%s: allocation of size: 0x%lx failed\n",
  48.299 +                     __func__, size);
  48.300 +            return 0;
  48.301 +        }
  48.302 +
  48.303 +        /* find a set that fits */
  48.304 +        DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos);
  48.305 +
  48.306 +        i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);  
  48.307 +        if (i - pos >= bits) {
  48.308 +            uint addr = pos << PAGE_SHIFT;
  48.309 +
  48.310 +            /* make sure OF is happy with our choice */
  48.311 +            if (of_claim(addr, size, 0) != OF_FAILURE) {
  48.312 +                for (i = 0; i < bits; i++)
  48.313 +                    set_bit(pos + i, mem_available_pages);
  48.314 +
  48.315 +                DBG("%s: 0x%lx is good returning 0x%x\n",
  48.316 +                    __func__, pos, addr);
  48.317 +                return addr;
  48.318 +            }
  48.319 +            /* if OF did not like the address then simply start from
  48.320 +             * the next bit */
  48.321 +            i = 1;
  48.322 +        }
  48.323 +
  48.324 +        pos = pos + i;
  48.325 +    }
  48.326 +}
  48.327 +
  48.328 +static ulong boot_of_mem_init(void)
  48.329  {
  48.330      int root;
  48.331      int p;
  48.332 -    u32 addr_cells = 1;
  48.333 -    u32 size_cells = 1;
  48.334      int rc;
  48.335 -    int mcount = 0;
  48.336 -    static memory_map_t mmap[16];
  48.337 +    uint addr_cells;
  48.338 +    uint size_cells;
  48.339  
  48.340      root = of_finddevice("/");
  48.341      p = of_getchild(root);
  48.342  
  48.343      /* code is writen to assume sizes of 1 */
  48.344 -    of_getprop(root, "#address-cells", &addr_cells, sizeof (addr_cells));
  48.345 -    of_getprop(root, "#size-cells", &size_cells, sizeof (size_cells));
  48.346 +    of_getprop(root, "#address-cells", &addr_cells,
  48.347 +               sizeof (addr_cells));
  48.348 +    of_getprop(root, "#size-cells", &size_cells,
  48.349 +               sizeof (size_cells));
  48.350      DBG("%s: address_cells=%d  size_cells=%d\n",
  48.351                      __func__, addr_cells, size_cells);
  48.352 -    
  48.353 +
  48.354 +    /* We do ream memory discovery later, for now we only want to find
  48.355 +     * the first LMB */
  48.356      do {
  48.357          const char memory[] = "memory";
  48.358          char type[32];
  48.359 @@ -389,82 +561,69 @@ static void boot_of_probemem(multiboot_i
  48.360  
  48.361          of_getprop(p, "device_type", type, sizeof (type));
  48.362          if (strncmp(type, memory, sizeof (memory)) == 0) {
  48.363 -            u32 reg[48];  
  48.364 -            u32 al, ah, ll, lh;
  48.365 +            uint reg[48];  
  48.366 +            u64 start;
  48.367 +            u64 size;
  48.368              int r;
  48.369 +            int l;
  48.370  
  48.371              rc = of_getprop(p, "reg", reg, sizeof (reg));
  48.372              if (rc == OF_FAILURE) {
  48.373                  of_panic("no reg property for memory node: 0x%x.\n", p);
  48.374              }
  48.375 -            int l = rc/sizeof(u32); /* number reg element */
  48.376 +
  48.377 +            l = rc / sizeof(reg[0]); /* number reg element */
  48.378              DBG("%s: number of bytes in property 'reg' %d\n",
  48.379                              __func__, rc);
  48.380              
  48.381              r = 0;
  48.382              while (r < l) {
  48.383 -                al = ah = ll = lh = 0;
  48.384 -                if (addr_cells == 2) {
  48.385 -                    ah = reg[r++];
  48.386 -                    if (r >= l)
  48.387 -                        break;  /* partial line.  Skip  */
  48.388 -                    al = reg[r++];
  48.389 -                    if (r >= l)
  48.390 -                        break;  /* partial line.  Skip */
  48.391 -                } else {
  48.392 -                    al = reg[r++];
  48.393 -                    if (r >= l)
  48.394 -                        break;  /* partial line.  Skip */
  48.395 -                }
  48.396 -                if (size_cells == 2) {
  48.397 -                    lh = reg[r++];
  48.398 -                    if (r >= l)
  48.399 -                        break;  /* partial line.  Skip */
  48.400 -                    ll = reg[r++];
  48.401 -                } else {
  48.402 -                    ll = reg[r++];
  48.403 +                start = reg[r++];
  48.404 +                if (addr_cells == 2 && (r < l) )
  48.405 +                    start = (start << 32) | reg[r++];
  48.406 +
  48.407 +                if (r >= l)
  48.408 +                    break;  /* partial line.  Skip */
  48.409 +
  48.410 +                if (start > 0) {
  48.411 +                    /* this is not the first LMB so we skip it */
  48.412 +                    break;
  48.413                  }
  48.414  
  48.415 -                if ((ll != 0) || (lh != 0)) {
  48.416 -                    mmap[mcount].size = 20; /* - size field */
  48.417 -                    mmap[mcount].type = 1; /* Regular ram */
  48.418 -                    mmap[mcount].length_high = lh;
  48.419 -                    mmap[mcount].length_low = ll;
  48.420 -                    mmap[mcount].base_addr_high = ah;
  48.421 -                    mmap[mcount].base_addr_low = al;
  48.422 -                    of_printf("%s: memory 0x%016lx[0x%08lx]\n",
  48.423 -                      __func__,
  48.424 -                      (u64)(((u64)mmap[mcount].base_addr_high << 32)
  48.425 -                            | mmap[mcount].base_addr_low),
  48.426 -                      (u64)(((u64)mmap[mcount].length_high << 32)
  48.427 -                            | mmap[mcount].length_low));
  48.428 -                    ++mcount;
  48.429 -                }
  48.430 +                size = reg[r++];
  48.431 +                if (size_cells == 2 && (r < l) )
  48.432 +                    size = (size << 32) | reg[r++];
  48.433 +                
  48.434 +                if (r > l)
  48.435 +                    break;  /* partial line.  Skip */
  48.436 +
  48.437 +                boot_of_alloc_init(p, addr_cells, size_cells);
  48.438 +                
  48.439 +                eomem = size;
  48.440 +                return size;
  48.441              }
  48.442          }
  48.443          p = of_getpeer(p);
  48.444      } while (p != OF_FAILURE && p != 0);
  48.445  
  48.446 -    if (mcount > 0) {
  48.447 -        mbi->flags |= MBI_MEMMAP;
  48.448 -        mbi->mmap_length = sizeof (mmap[0]) * mcount;
  48.449 -        mbi->mmap_addr = (ulong)mmap;
  48.450 -    }
  48.451 +    return 0;
  48.452  }
  48.453  
  48.454  static void boot_of_bootargs(multiboot_info_t *mbi)
  48.455  {
  48.456      int rc;
  48.457  
  48.458 -    rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
  48.459 -    if (rc == OF_FAILURE || bootargs[0] == '\0') {
  48.460 -        strlcpy(bootargs, builtin_cmdline, sizeof(bootargs));
  48.461 +    if (builtin_cmdline[0] == '\0') {
  48.462 +        rc = of_getprop(bof_chosen, "bootargs", builtin_cmdline,
  48.463 +                CONFIG_CMDLINE_SIZE);
  48.464 +        if (rc > CONFIG_CMDLINE_SIZE)
  48.465 +            of_panic("bootargs[] not big enough for /chosen/bootargs\n");
  48.466      }
  48.467  
  48.468      mbi->flags |= MBI_CMDLINE;
  48.469 -    mbi->cmdline = (u32)bootargs;
  48.470 +    mbi->cmdline = (ulong)builtin_cmdline;
  48.471  
  48.472 -    of_printf("bootargs = %s\n", bootargs);
  48.473 +    of_printf("bootargs = %s\n", builtin_cmdline);
  48.474  }
  48.475  
  48.476  static int save_props(void *m, ofdn_t n, int pkg)
  48.477 @@ -500,7 +659,8 @@ static int save_props(void *m, ofdn_t n,
  48.478                      of_panic("obj array not big enough for 0x%x\n", sz);
  48.479                  }
  48.480                  actual = of_getprop(pkg, name, obj, sz);
  48.481 -                if (actual > sz) of_panic("obj too small");
  48.482 +                if (actual > sz)
  48.483 +                    of_panic("obj too small");
  48.484              }
  48.485  
  48.486              if (strncmp(name, name_str, sizeof(name_str)) == 0) {
  48.487 @@ -512,7 +672,8 @@ static int save_props(void *m, ofdn_t n,
  48.488              }
  48.489  
  48.490              pos = ofd_prop_add(m, n, name, obj, actual);
  48.491 -            if (pos == 0) of_panic("prop_create");
  48.492 +            if (pos == 0)
  48.493 +                of_panic("prop_create");
  48.494          }
  48.495  
  48.496          result = of_nextprop(pkg, name, name);
  48.497 @@ -536,10 +697,12 @@ retry:
  48.498  
  48.499      if (pnext != 0) {
  48.500          sz = of_package_to_path(pnext, path, psz);
  48.501 -        if (sz == OF_FAILURE) of_panic("bad path\n");
  48.502 +        if (sz == OF_FAILURE)
  48.503 +            of_panic("bad path\n");
  48.504  
  48.505          nnext = ofd_node_child_create(m, n, path, sz);
  48.506 -        if (nnext == 0) of_panic("out of mem\n");
  48.507 +        if (nnext == 0)
  48.508 +            of_panic("out of mem\n");
  48.509  
  48.510          do_pkg(m, nnext, pnext, path, psz);
  48.511      }
  48.512 @@ -551,7 +714,8 @@ retry:
  48.513          sz = of_package_to_path(pnext, path, psz);
  48.514  
  48.515          nnext = ofd_node_peer_create(m, n, path, sz);
  48.516 -        if (nnext <= 0) of_panic("out of space in OFD tree.\n");
  48.517 +        if (nnext <= 0)
  48.518 +            of_panic("out of space in OFD tree.\n");
  48.519  
  48.520          n = nnext;
  48.521          p = pnext;
  48.522 @@ -559,7 +723,7 @@ retry:
  48.523      }
  48.524  }
  48.525  
  48.526 -static int pkg_save(void *mem)
  48.527 +static long pkg_save(void *mem)
  48.528  {
  48.529      int root;
  48.530      char path[256];
  48.531 @@ -570,11 +734,12 @@ static int pkg_save(void *mem)
  48.532  
  48.533      /* get root */
  48.534      root = of_getpeer(0);
  48.535 -    if (root == OF_FAILURE) of_panic("no root package\n");
  48.536 +    if (root == OF_FAILURE)
  48.537 +        of_panic("no root package\n");
  48.538  
  48.539      do_pkg(mem, OFD_ROOT, root, path, sizeof(path));
  48.540  
  48.541 -    r = (((ofdn_t *)mem)[1] + 1) * sizeof (u64);
  48.542 +    r = ofd_size(mem);
  48.543  
  48.544      of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r);
  48.545  
  48.546 @@ -604,7 +769,8 @@ static int boot_of_fixup_refs(void *mem)
  48.547              char ofpath[256];
  48.548  
  48.549              path = ofd_node_path(mem, c);
  48.550 -            if (path == NULL) of_panic("no path to found prop: %s\n", name);
  48.551 +            if (path == NULL)
  48.552 +                of_panic("no path to found prop: %s\n", name);
  48.553  
  48.554              rp = of_finddevice(path);
  48.555              if (rp == OF_FAILURE)
  48.556 @@ -629,13 +795,15 @@ static int boot_of_fixup_refs(void *mem)
  48.557                           "ref 0x%x\n", name, path, rp, ref);
  48.558  
  48.559              dp = ofd_node_find(mem, ofpath);
  48.560 -            if (dp <= 0) of_panic("no ofd node for OF node[0x%x]: %s\n",
  48.561 -                                  ref, ofpath);
  48.562 +            if (dp <= 0)
  48.563 +                of_panic("no ofd node for OF node[0x%x]: %s\n",
  48.564 +                         ref, ofpath);
  48.565  
  48.566              ref = dp;
  48.567  
  48.568              upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref));
  48.569 -            if (upd <= 0) of_panic("update failed: %s\n", name);
  48.570 +            if (upd <= 0)
  48.571 +                of_panic("update failed: %s\n", name);
  48.572  
  48.573  #ifdef DEBUG
  48.574              of_printf("%s: %s/%s -> %s\n", __func__,
  48.575 @@ -658,7 +826,8 @@ static int boot_of_fixup_chosen(void *me
  48.576      char ofpath[256];
  48.577  
  48.578      ch = of_finddevice("/chosen");
  48.579 -    if (ch == OF_FAILURE) of_panic("/chosen not found\n");
  48.580 +    if (ch == OF_FAILURE)
  48.581 +        of_panic("/chosen not found\n");
  48.582  
  48.583      rc = of_getprop(ch, "cpu", &val, sizeof (val));
  48.584  
  48.585 @@ -667,16 +836,19 @@ static int boot_of_fixup_chosen(void *me
  48.586  
  48.587          if (rc > 0) {
  48.588              dn = ofd_node_find(mem, ofpath);
  48.589 -            if (dn <= 0) of_panic("no node for: %s\n", ofpath);
  48.590 +            if (dn <= 0)
  48.591 +                of_panic("no node for: %s\n", ofpath);
  48.592  
  48.593              ofd_boot_cpu = dn;
  48.594              val = dn;
  48.595  
  48.596              dn = ofd_node_find(mem, "/chosen");
  48.597 -            if (dn <= 0) of_panic("no /chosen node\n");
  48.598 +            if (dn <= 0)
  48.599 +                of_panic("no /chosen node\n");
  48.600  
  48.601              dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val));
  48.602 -            if (dc <= 0) of_panic("could not fix /chosen/cpu\n");
  48.603 +            if (dc <= 0)
  48.604 +                of_panic("could not fix /chosen/cpu\n");
  48.605              rc = 1;
  48.606          } else {
  48.607              of_printf("*** can't find path to booting cpu, "
  48.608 @@ -687,56 +859,6 @@ static int boot_of_fixup_chosen(void *me
  48.609      return rc;
  48.610  }
  48.611  
  48.612 -static ulong space_base;
  48.613 -
  48.614 -/*
  48.615 - * The following function is necessary because we cannot depend on all
  48.616 - * FW to actually allocate us any space, so we look for it _hoping_
  48.617 - * that at least is will fail if we try to claim something that
  48.618 - * belongs to FW.  This hope does not seem to be true on some version
  48.619 - * of PIBS.
  48.620 - */
  48.621 -static ulong find_space(u32 size, u32 align, multiboot_info_t *mbi)
  48.622 -{
  48.623 -    memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr);
  48.624 -    ulong eomem = ((u64)map->length_high << 32) | (u64)map->length_low;
  48.625 -    ulong base;
  48.626 -
  48.627 -    if (size == 0)
  48.628 -        return 0;
  48.629 -
  48.630 -    if (align == 0)
  48.631 -        of_panic("cannot call %s() with align of 0\n", __func__);
  48.632 -
  48.633 -#ifdef BROKEN_CLAIM_WORKAROUND
  48.634 -    {
  48.635 -        static int broken_claim;
  48.636 -        if (!broken_claim) {
  48.637 -            /* just try and claim it to the FW chosen address */
  48.638 -            base = of_claim(0, size, align);
  48.639 -            if (base != OF_FAILURE)
  48.640 -                return base;
  48.641 -            of_printf("%s: Firmware does not allocate memory for you\n",
  48.642 -                      __func__);
  48.643 -            broken_claim = 1;
  48.644 -        }
  48.645 -    }
  48.646 -#endif
  48.647 -
  48.648 -    of_printf("%s base=0x%016lx  eomem=0x%016lx  size=0x%08x  align=0x%x\n",
  48.649 -                    __func__, space_base, eomem, size, align);
  48.650 -    base = ALIGN_UP(space_base, PAGE_SIZE);
  48.651 -
  48.652 -    while ((base + size) < rma_size(cpu_default_rma_order_pages())) {
  48.653 -        if (of_claim(base, size, 0) != OF_FAILURE) {
  48.654 -            space_base = base + size;
  48.655 -            return base;
  48.656 -        }
  48.657 -        base += (PAGE_SIZE >  align) ? PAGE_SIZE : align;
  48.658 -    }
  48.659 -    of_panic("Cannot find memory in the RMA\n");
  48.660 -}
  48.661 -
  48.662  /* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges
  48.663   * property.  The values are bad, and it doesn't even have the
  48.664   * right number of cells. */
  48.665 @@ -798,8 +920,10 @@ static int __init boot_of_serial(void *o
  48.666              of_panic("package-to-path failed\n");
  48.667  
  48.668          rc = of_getprop(p, "device_type", type, sizeof (type));
  48.669 -        if (rc == OF_FAILURE)
  48.670 -            of_panic("fetching device type failed\n");
  48.671 +        if (rc == OF_FAILURE) {
  48.672 +            of_printf("%s: fetching type of `%s' failed\n", __func__, buf);
  48.673 +            continue;
  48.674 +        }
  48.675  
  48.676          if (strcmp(type, "serial") != 0)
  48.677              continue;
  48.678 @@ -855,17 +979,104 @@ static int __init boot_of_serial(void *o
  48.679      return 1;
  48.680  }
  48.681  
  48.682 -static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
  48.683 +static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi)
  48.684  {
  48.685 -    static module_t mods[3];
  48.686 +    int rtas_node;
  48.687 +    int rtas_instance;
  48.688 +    uint size = 0;
  48.689 +    int res[2];
  48.690 +    int mem;
  48.691 +    int ret;
  48.692 +
  48.693 +    rtas_node = of_finddevice("/rtas");
  48.694 +
  48.695 +    if (rtas_node <= 0) {
  48.696 +        of_printf("No RTAS, Xen has no power control\n");
  48.697 +        return 0;
  48.698 +    }
  48.699 +    of_getprop(rtas_node, "rtas-size", &size, sizeof (size));
  48.700 +    if (size == 0) {
  48.701 +        of_printf("RTAS, has no size\n");
  48.702 +        return 0;
  48.703 +    }
  48.704 +
  48.705 +    rtas_instance = of_open("/rtas");
  48.706 +    if (rtas_instance == OF_FAILURE) {
  48.707 +        of_printf("RTAS, could not open\n");
  48.708 +        return 0;
  48.709 +    }
  48.710 +
  48.711 +    size = ALIGN_UP(size, PAGE_SIZE);
  48.712 +    
  48.713 +    mem = boot_of_alloc(size);
  48.714 +    if (mem == 0)
  48.715 +        of_panic("Could not allocate RTAS tree\n");
  48.716 +
  48.717 +    of_printf("instantiating RTAS at: 0x%x\n", mem);
  48.718 +
  48.719 +    ret = of_call("call-method", 3, 2, res,
  48.720 +                  "instantiate-rtas", rtas_instance, mem);
  48.721 +    if (ret == OF_FAILURE) {
  48.722 +        of_printf("RTAS, could not open\n");
  48.723 +        return 0;
  48.724 +    }
  48.725 +    
  48.726 +    rtas_entry = res[1];
  48.727 +    rtas_base = mem;
  48.728 +    rtas_end = mem + size;
  48.729 +    rtas_msr = of_msr;
  48.730 +
  48.731 +    mod->mod_start = rtas_base;
  48.732 +    mod->mod_end = rtas_end;
  48.733 +    return 1;
  48.734 +}
  48.735 +
  48.736 +static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
  48.737 +{
  48.738      void *oft;
  48.739      ulong oft_sz = 48 * PAGE_SIZE;
  48.740 +
  48.741 +    /* snapshot the tree */
  48.742 +    oft = (void *)boot_of_alloc(oft_sz);
  48.743 +    if (oft == NULL)
  48.744 +        of_panic("Could not allocate OFD tree\n");
  48.745 +
  48.746 +    of_printf("creating oftree at: 0x%p\n", oft);
  48.747 +    of_test("package-to-path");
  48.748 +    oft = ofd_create(oft, oft_sz);
  48.749 +    pkg_save(oft);
  48.750 +
  48.751 +    if (ofd_size(oft) > oft_sz)
  48.752 +         of_panic("Could not fit all of native devtree\n");
  48.753 +
  48.754 +    boot_of_fixup_refs(oft);
  48.755 +    boot_of_fixup_chosen(oft);
  48.756 +
  48.757 +    if (ofd_size(oft) > oft_sz)
  48.758 +         of_panic("Could not fit all devtree fixups\n");
  48.759 +
  48.760 +    ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2);
  48.761 +
  48.762 +    mod->mod_start = (ulong)oft;
  48.763 +    mod->mod_end = mod->mod_start + oft_sz;
  48.764 +    of_printf("%s: devtree mod @ 0x%016x - 0x%016x\n", __func__,
  48.765 +              mod->mod_start, mod->mod_end);
  48.766 +
  48.767 +    return oft;
  48.768 +}
  48.769 +
  48.770 +static void * __init boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
  48.771 +{
  48.772 +    static module_t mods[4];
  48.773      ulong mod0_start;
  48.774      ulong mod0_size;
  48.775 -    static const char sepr[] = " -- ";
  48.776 +    static const char * sepr[] = {" -- ", " || "};
  48.777 +    int sepr_index;
  48.778      extern char dom0_start[] __attribute__ ((weak));
  48.779      extern char dom0_size[] __attribute__ ((weak));
  48.780 -    const char *p;
  48.781 +    const char *p = NULL;
  48.782 +    int mod;
  48.783 +    void *oft;
  48.784  
  48.785      if ((r3 > 0) && (r4 > 0)) {
  48.786          /* was it handed to us in registers ? */
  48.787 @@ -908,57 +1119,50 @@ static void boot_of_module(ulong r3, ulo
  48.788          of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
  48.789      }
  48.790  
  48.791 -    space_base = (ulong)_end;
  48.792 -    mods[0].mod_start = mod0_start;
  48.793 -    mods[0].mod_end = mod0_start + mod0_size;
  48.794 +    mod = 0;
  48.795 +    mods[mod].mod_start = mod0_start;
  48.796 +    mods[mod].mod_end = mod0_start + mod0_size;
  48.797  
  48.798 -    of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__,
  48.799 -              mods[0].mod_start, mods[0].mod_end);
  48.800 -    p = strstr((char *)(ulong)mbi->cmdline, sepr);
  48.801 -    if (p != NULL) {
  48.802 -        p += sizeof (sepr) - 1;
  48.803 -        mods[0].string = (u32)(ulong)p;
  48.804 -        of_printf("%s: mod[0].string: %s\n", __func__, p);
  48.805 +    of_printf("%s: dom0 mod @ 0x%016x[0x%x]\n", __func__,
  48.806 +              mods[mod].mod_start, mods[mod].mod_end);
  48.807 +
  48.808 +    /* look for delimiter: "--" or "||" */
  48.809 +    for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index++){
  48.810 +        p = strstr((char *)(ulong)mbi->cmdline, sepr[sepr_index]);
  48.811 +        if (p != NULL)
  48.812 +            break;
  48.813      }
  48.814  
  48.815 -    /* snapshot the tree */
  48.816 -    oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
  48.817 -    if (oft == 0)
  48.818 -        of_panic("Could not allocate OFD tree\n");
  48.819 -
  48.820 -    of_printf("creating oft\n");
  48.821 -    of_test("package-to-path");
  48.822 -    oft = ofd_create(oft, oft_sz);
  48.823 -    pkg_save(oft);
  48.824 -
  48.825 -    if (ofd_size(oft) > oft_sz)
  48.826 -         of_panic("Could not fit all of native devtree\n");
  48.827 +    if (p != NULL) {
  48.828 +        /* Xen proper should never know about the dom0 args.  */
  48.829 +        *(char *)p = '\0';
  48.830 +        p += strlen(sepr[sepr_index]);
  48.831 +        mods[mod].string = (u32)(ulong)p;
  48.832 +        of_printf("%s: dom0 mod string: %s\n", __func__, p);
  48.833 +    }
  48.834  
  48.835 -    boot_of_fixup_refs(oft);
  48.836 -    boot_of_fixup_chosen(oft);
  48.837 -
  48.838 -    if (ofd_size(oft) > oft_sz)
  48.839 -         of_panic("Could not fit all devtree fixups\n");
  48.840 +    ++mod;
  48.841 +    if (boot_of_rtas(&mods[mod], mbi))
  48.842 +        ++mod;
  48.843  
  48.844 -    ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
  48.845 +    oft = boot_of_devtree(&mods[mod], mbi);
  48.846 +    if (oft == NULL)
  48.847 +        of_panic("%s: boot_of_devtree failed\n", __func__);
  48.848  
  48.849 -    mods[1].mod_start = (ulong)oft;
  48.850 -    mods[1].mod_end = mods[1].mod_start + oft_sz;
  48.851 -    of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
  48.852 -              mods[1].mod_start, mods[1].mod_end);
  48.853 -
  48.854 +    ++mod;
  48.855  
  48.856      mbi->flags |= MBI_MODULES;
  48.857 -    mbi->mods_count = 2;
  48.858 +    mbi->mods_count = mod;
  48.859      mbi->mods_addr = (u32)mods;
  48.860  
  48.861 -    boot_of_serial(oft);
  48.862 +    return oft;
  48.863  }
  48.864  
  48.865  static int __init boot_of_cpus(void)
  48.866  {
  48.867 -    int cpus_node;
  48.868 -    int cpu_node, bootcpu_node, logical;
  48.869 +    int cpus_node, cpu_node;
  48.870 +    int bootcpu_instance, bootcpu_node;
  48.871 +    int logical;
  48.872      int result;
  48.873      s32 cpuid;
  48.874      u32 cpu_clock[2];
  48.875 @@ -967,9 +1171,13 @@ static int __init boot_of_cpus(void)
  48.876      /* Look up which CPU we are running on right now and get all info
  48.877       * from there */
  48.878      result = of_getprop(bof_chosen, "cpu",
  48.879 -                        &bootcpu_node, sizeof (bootcpu_node));
  48.880 +                        &bootcpu_instance, sizeof (bootcpu_instance));
  48.881      if (result == OF_FAILURE)
  48.882 -        of_panic("Failed to look up boot cpu\n");
  48.883 +        of_panic("Failed to look up boot cpu instance\n");
  48.884 +
  48.885 +    bootcpu_node = of_instance_to_package(bootcpu_instance);
  48.886 +    if (result == OF_FAILURE)
  48.887 +        of_panic("Failed to look up boot cpu package\n");
  48.888  
  48.889      cpu_node = bootcpu_node;
  48.890  
  48.891 @@ -1070,15 +1278,12 @@ static int __init boot_of_cpus(void)
  48.892      return 1;
  48.893  }
  48.894  
  48.895 -static int __init boot_of_rtas(void)
  48.896 -{
  48.897 -    return 1;
  48.898 -}
  48.899 -
  48.900  multiboot_info_t __init *boot_of_init(
  48.901          ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
  48.902  {
  48.903      static multiboot_info_t mbi;
  48.904 +    void *oft;
  48.905 +    int r;
  48.906  
  48.907      of_vec = vec;
  48.908      of_msr = orig_msr;
  48.909 @@ -1098,18 +1303,20 @@ multiboot_info_t __init *boot_of_init(
  48.910              r3, r4, vec, r6, r7, orig_msr);
  48.911  
  48.912      if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
  48.913 -        of_printf("Hmm.. OF[0x%lx] seems to have stepped on our image "
  48.914 -                "that ranges: %p .. %p.\n HANG!\n",
  48.915 +        of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
  48.916 +                "that ranges: %p .. %p.\n",
  48.917                  vec, _start, _end);
  48.918      }
  48.919      of_printf("%s: _start %p _end %p 0x%lx\n", __func__, _start, _end, r6);
  48.920  
  48.921      boot_of_fix_maple();
  48.922 -    boot_of_probemem(&mbi);
  48.923 +    r = boot_of_mem_init();
  48.924 +    if (r == 0)
  48.925 +        of_panic("failure to initialize memory allocator");
  48.926      boot_of_bootargs(&mbi);
  48.927 -    boot_of_module(r3, r4, &mbi);
  48.928 +    oft = boot_of_module(r3, r4, &mbi);
  48.929      boot_of_cpus();
  48.930 -    boot_of_rtas();
  48.931 +    boot_of_serial(oft);
  48.932  
  48.933      /* end of OF */
  48.934      of_printf("Quiescing Open Firmware ...\n");
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/xen/arch/powerpc/cmdline.c	Thu Dec 14 08:57:36 2006 -0700
    49.3 @@ -0,0 +1,24 @@
    49.4 +/*
    49.5 + * This program is free software; you can redistribute it and/or modify
    49.6 + * it under the terms of the GNU General Public License as published by
    49.7 + * the Free Software Foundation; either version 2 of the License, or
    49.8 + * (at your option) any later version.
    49.9 + *
   49.10 + * This program is distributed in the hope that it will be useful,
   49.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.13 + * GNU General Public License for more details.
   49.14 + *
   49.15 + * You should have received a copy of the GNU General Public License
   49.16 + * along with this program; if not, write to the Free Software
   49.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   49.18 + *
   49.19 + * Copyright (C) IBM Corp. 2006
   49.20 + *
   49.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   49.22 + */
   49.23 +
   49.24 +#include <asm/config.h>
   49.25 +
   49.26 +char builtin_cmdline[CONFIG_CMDLINE_SIZE] 
   49.27 +        __attribute__((section("__builtin_cmdline"))) = CMDLINE;
    50.1 --- a/xen/arch/powerpc/crash.c	Thu Dec 14 08:54:54 2006 -0700
    50.2 +++ b/xen/arch/powerpc/crash.c	Thu Dec 14 08:57:36 2006 -0700
    50.3 @@ -1,5 +1,6 @@
    50.4  #include <xen/lib.h>       /* for printk() used in stub */
    50.5  #include <xen/types.h>
    50.6 +#include <xen/kexec.h>
    50.7  #include <public/kexec.h>
    50.8  
    50.9  void machine_crash_shutdown(void)
    51.1 --- a/xen/arch/powerpc/dart.c	Thu Dec 14 08:54:54 2006 -0700
    51.2 +++ b/xen/arch/powerpc/dart.c	Thu Dec 14 08:57:36 2006 -0700
    51.3 @@ -60,8 +60,8 @@ union dart_entry {
    51.4      u32 de_word;
    51.5      struct {
    51.6          u32 de_v:1;             /* valid */
    51.7 -        u32 de_rp:1;             /* read protected*/
    51.8 -        u32 de_wp:1;             /* write protected*/
    51.9 +        u32 de_rp:1;             /* read protected */
   51.10 +        u32 de_wp:1;             /* write protected */
   51.11          u32 _de_res:5;
   51.12          u32 de_ppn:24;         /* 24 bit Physical Page Number
   51.13                                   * representing address [28:51] */
   51.14 @@ -98,7 +98,6 @@ static u32 dart_encode(int perm, ulong r
   51.15      if (perm & DART_WRITE) {
   51.16          e.de_bits.de_wp = 0;
   51.17      }
   51.18 -
   51.19      return e.de_word;
   51.20  }
   51.21  
   51.22 @@ -190,10 +189,8 @@ static int find_dart(struct dart_info *d
   51.23      ofdn_t n;
   51.24      char compat[128];
   51.25  
   51.26 -
   51.27 -    if (on_mambo()) {
   51.28 -        /* mambo has no dart */
   51.29 -        DBG("%s: Mambo does not support a dart\n", __func__);
   51.30 +    if (on_systemsim()) {
   51.31 +        DBG("%s: systemsim does not support a dart\n", __func__);
   51.32          return -1;
   51.33      }
   51.34  
   51.35 @@ -263,7 +260,7 @@ static int init_dart(void)
   51.36  
   51.37      /* Linux uses a dummy page, filling "empty" DART entries with a
   51.38         reference to this page to capture stray DMA's */
   51.39 -    dummy_page = (ulong)alloc_xenheap_pages(1);
   51.40 +    dummy_page = (ulong)alloc_xenheap_pages(0);
   51.41      clear_page((void *)dummy_page);
   51.42      dummy_page >>= PAGE_SHIFT;
   51.43  
    52.1 --- a/xen/arch/powerpc/dart_u4.c	Thu Dec 14 08:54:54 2006 -0700
    52.2 +++ b/xen/arch/powerpc/dart_u4.c	Thu Dec 14 08:57:36 2006 -0700
    52.3 @@ -19,6 +19,7 @@
    52.4   */
    52.5  
    52.6  #undef DEBUG
    52.7 +#define INVALIDATE_ALL
    52.8  
    52.9  #include <xen/config.h>
   52.10  #include <xen/types.h>
   52.11 @@ -123,9 +124,14 @@ static void u4_inv_all(void)
   52.12  
   52.13  static void u4_inv_entry(ulong pgn)
   52.14  {
   52.15 +#ifdef INVALIDATE_ALL
   52.16 +    return u4_inv_all();
   52.17 +#else
   52.18      union dart_ctl dc;
   52.19      ulong retries = 0;
   52.20  
   52.21 +    return u4_inv_all();
   52.22 +
   52.23      dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
   52.24      dc.dc_bits.dc_ilpn = pgn;
   52.25      dc.dc_bits.dc_ione = 1;
   52.26 @@ -139,6 +145,7 @@ static void u4_inv_entry(ulong pgn)
   52.27          if (retries > 1000000)
   52.28              panic("WAY! too long\n");
   52.29      } while (dc.dc_bits.dc_ione != 0);
   52.30 +#endif
   52.31  }
   52.32  
   52.33  static struct dart_ops u4_ops = {
    53.1 --- a/xen/arch/powerpc/delay.c	Thu Dec 14 08:54:54 2006 -0700
    53.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.3 @@ -1,37 +0,0 @@
    53.4 -/*
    53.5 - * This program is free software; you can redistribute it and/or modify
    53.6 - * it under the terms of the GNU General Public License as published by
    53.7 - * the Free Software Foundation; either version 2 of the License, or
    53.8 - * (at your option) any later version.
    53.9 - *
   53.10 - * This program is distributed in the hope that it will be useful,
   53.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   53.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   53.13 - * GNU General Public License for more details.
   53.14 - *
   53.15 - * You should have received a copy of the GNU General Public License
   53.16 - * along with this program; if not, write to the Free Software
   53.17 - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   53.18 - *
   53.19 - * Copyright (C) IBM Corp. 2005
   53.20 - *
   53.21 - * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   53.22 - */
   53.23 -
   53.24 -#include <xen/config.h>
   53.25 -#include <xen/delay.h>
   53.26 -#include <xen/time.h>
   53.27 -#include <asm/processor.h>
   53.28 -
   53.29 -void udelay(unsigned long usecs)
   53.30 -{
   53.31 -    ulong ticks = usecs * ticks_per_usec;
   53.32 -    ulong s;
   53.33 -    ulong e;
   53.34 -
   53.35 -    s = get_timebase();
   53.36 -    do {
   53.37 -        asm volatile("or 1,1,1"); /* also puts the thread to low priority */
   53.38 -        e = get_timebase();
   53.39 -    } while ((e-s) < ticks);
   53.40 -}
    54.1 --- a/xen/arch/powerpc/domain.c	Thu Dec 14 08:54:54 2006 -0700
    54.2 +++ b/xen/arch/powerpc/domain.c	Thu Dec 14 08:57:36 2006 -0700
    54.3 @@ -33,6 +33,8 @@
    54.4  #include <asm/htab.h>
    54.5  #include <asm/current.h>
    54.6  #include <asm/hcalls.h>
    54.7 +#include "rtas.h"
    54.8 +#include "exceptions.h"
    54.9  
   54.10  #define next_arg(fmt, args) ({                                              \
   54.11      unsigned long __arg;                                                    \
   54.12 @@ -46,7 +48,6 @@
   54.13      }                                                                       \
   54.14      __arg;                                                                  \
   54.15  })
   54.16 -extern void idle_loop(void);
   54.17  
   54.18  unsigned long hypercall_create_continuation(unsigned int op,
   54.19          const char *format, ...)
   54.20 @@ -87,26 +88,44 @@ int arch_domain_create(struct domain *d)
   54.21  
   54.22      INIT_LIST_HEAD(&d->arch.extent_list);
   54.23  
   54.24 +    d->arch.foreign_mfn_count = 1024;
   54.25 +    d->arch.foreign_mfns = xmalloc_array(uint, d->arch.foreign_mfn_count);
   54.26 +    BUG_ON(d->arch.foreign_mfns == NULL);
   54.27 +
   54.28 +    memset(d->arch.foreign_mfns, -1, d->arch.foreign_mfn_count * sizeof(uint));
   54.29 +
   54.30      return 0;
   54.31  }
   54.32  
   54.33  void arch_domain_destroy(struct domain *d)
   54.34  {
   54.35      shadow_teardown(d);
   54.36 +    /* shared_info is part of the RMA so no need to release it */
   54.37  }
   54.38  
   54.39 +static void machine_fail(const char *s)
   54.40 +{
   54.41 +    printk("%s failed, manual powercycle required!\n", s);
   54.42 +    for (;;)
   54.43 +        sleep();
   54.44 +}
   54.45  void machine_halt(void)
   54.46  {
   54.47      printk("machine_halt called: spinning....\n");
   54.48      console_start_sync();
   54.49 -    while(1);
   54.50 +    printk("%s called\n", __func__);
   54.51 +    rtas_halt();
   54.52 +
   54.53 +    machine_fail(__func__);
   54.54  }
   54.55  
   54.56  void machine_restart(char * __unused)
   54.57  {
   54.58      printk("machine_restart called: spinning....\n");
   54.59      console_start_sync();
   54.60 -    while(1);
   54.61 +    printk("%s called\n", __func__);
   54.62 +    rtas_reboot();
   54.63 +    machine_fail(__func__);
   54.64  }
   54.65  
   54.66  struct vcpu *alloc_vcpu_struct(void)
   54.67 @@ -222,6 +241,7 @@ void context_switch(struct vcpu *prev, s
   54.68  
   54.69      mtsdr1(next->domain->arch.htab.sdr1);
   54.70      local_flush_tlb(); /* XXX maybe flush_tlb_mask? */
   54.71 +    cpu_flush_icache();
   54.72  
   54.73      if (is_idle_vcpu(next)) {
   54.74          reset_stack_and_jump(idle_loop);
   54.75 @@ -278,8 +298,10 @@ static void relinquish_memory(struct dom
   54.76  
   54.77  void domain_relinquish_resources(struct domain *d)
   54.78  {
   54.79 +    relinquish_memory(d, &d->xenpage_list);
   54.80      relinquish_memory(d, &d->page_list);
   54.81      free_extents(d);
   54.82 +    xfree(d->arch.foreign_mfns);
   54.83      return;
   54.84  }
   54.85  
   54.86 @@ -291,7 +313,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
   54.87  {
   54.88  }
   54.89  
   54.90 -extern void sleep(void);
   54.91  static void safe_halt(void)
   54.92  {
   54.93      int cpu = smp_processor_id();
    55.1 --- a/xen/arch/powerpc/domain_build.c	Thu Dec 14 08:54:54 2006 -0700
    55.2 +++ b/xen/arch/powerpc/domain_build.c	Thu Dec 14 08:57:36 2006 -0700
    55.3 @@ -178,8 +178,7 @@ int construct_dom0(struct domain *d,
    55.4          shadow_set_allocation(d, opt_dom0_shadow, &preempt);
    55.5      } while (preempt);
    55.6      if (shadow_get_allocation(d) == 0)
    55.7 -        panic("shadow allocation failed 0x%x < 0x%x\n",
    55.8 -              shadow_get_allocation(d), opt_dom0_shadow);
    55.9 +        panic("shadow allocation failed: %dMib\n", opt_dom0_shadow);
   55.10  
   55.11      ASSERT( image_len < rma_sz );
   55.12  
    56.1 --- a/xen/arch/powerpc/domctl.c	Thu Dec 14 08:54:54 2006 -0700
    56.2 +++ b/xen/arch/powerpc/domctl.c	Thu Dec 14 08:57:36 2006 -0700
    56.3 @@ -96,14 +96,14 @@ long arch_do_domctl(struct xen_domctl *d
    56.4      case XEN_DOMCTL_real_mode_area:
    56.5      {
    56.6          struct domain *d;
    56.7 -        unsigned int log = domctl->u.real_mode_area.log;
    56.8 +        unsigned int order = domctl->u.real_mode_area.log - PAGE_SHIFT;
    56.9  
   56.10          ret = -ESRCH;
   56.11          d = find_domain_by_id(domctl->domain);
   56.12          if (d != NULL) {
   56.13              ret = -EINVAL;
   56.14 -            if (cpu_rma_valid(log))
   56.15 -                ret = allocate_rma(d, log - PAGE_SHIFT);
   56.16 +            if (cpu_rma_valid(order))
   56.17 +                ret = allocate_rma(d, order);
   56.18              put_domain(d);
   56.19          }
   56.20      }
    57.1 --- a/xen/arch/powerpc/exceptions.c	Thu Dec 14 08:54:54 2006 -0700
    57.2 +++ b/xen/arch/powerpc/exceptions.c	Thu Dec 14 08:57:36 2006 -0700
    57.3 @@ -25,8 +25,10 @@
    57.4  #include <xen/serial.h>
    57.5  #include <xen/gdbstub.h>
    57.6  #include <xen/console.h>
    57.7 +#include <xen/shutdown.h>
    57.8  #include <asm/time.h>
    57.9  #include <asm/processor.h>
   57.10 +#include <asm/debugger.h>
   57.11  
   57.12  #undef DEBUG
   57.13  
   57.14 @@ -56,25 +58,19 @@ void do_dec(struct cpu_user_regs *regs)
   57.15  
   57.16  void program_exception(struct cpu_user_regs *regs, unsigned long cookie)
   57.17  {
   57.18 -#ifdef CRASH_DEBUG
   57.19 -    __trap_to_gdb(regs, cookie);
   57.20 -#else /* CRASH_DEBUG */
   57.21 -    int recover = 0;
   57.22 -
   57.23 -    console_start_sync();
   57.24 +    if (cookie == 0x200) {
   57.25 +        if (cpu_machinecheck(regs))
   57.26 +            return;
   57.27  
   57.28 -    show_registers(regs);
   57.29 -    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
   57.30 -    printk("hid4 0x%016lx\n", regs->hid4);
   57.31 -    printk("---[ backtrace ]---\n");
   57.32 -    show_backtrace(regs->gprs[1], regs->lr, regs->pc);
   57.33 +        printk("%s: machine check\n", __func__);
   57.34 +    } else {
   57.35 +#ifdef CRASH_DEBUG
   57.36 +        if (__trap_to_gdb(regs, cookie) == 0)
   57.37 +            return;
   57.38 +#endif /* CRASH_DEBUG */
   57.39  
   57.40 -    if (cookie == 0x200)
   57.41 -        recover = cpu_machinecheck(regs);
   57.42 -
   57.43 -    if (!recover)
   57.44 -        panic("%s: 0x%lx\n", __func__, cookie);
   57.45 -
   57.46 -    console_end_sync();
   57.47 -#endif /* CRASH_DEBUG */
   57.48 +        printk("%s: type: 0x%lx\n", __func__, cookie);
   57.49 +        show_backtrace_regs(regs);
   57.50 +    }
   57.51 +    machine_halt();
   57.52  }
    58.1 --- a/xen/arch/powerpc/exceptions.h	Thu Dec 14 08:54:54 2006 -0700
    58.2 +++ b/xen/arch/powerpc/exceptions.h	Thu Dec 14 08:57:36 2006 -0700
    58.3 @@ -43,13 +43,14 @@ extern void program_exception(
    58.4      struct cpu_user_regs *regs, unsigned long cookie);
    58.5  
    58.6  extern long xen_hvcall_jump(struct cpu_user_regs *regs, ulong address);
    58.7 -extern void *mambo_memset(void *, int, ulong);
    58.8 -extern void *mambo_memcpy(void *, const void *, ulong);
    58.9 +
   58.10 +extern void sleep(void);
   58.11 +extern void idle_loop(void);
   58.12  
   58.13  extern ulong *__hypercall_table[];
   58.14  
   58.15  extern char exception_vectors[];
   58.16  extern char exception_vectors_end[];
   58.17  extern int spin_start[];
   58.18 -extern int secondary_cpu_init(int cpuid, unsigned long r4);
   58.19 +extern void secondary_cpu_init(int cpuid, unsigned long r4);
   58.20  #endif
    59.1 --- a/xen/arch/powerpc/external.c	Thu Dec 14 08:54:54 2006 -0700
    59.2 +++ b/xen/arch/powerpc/external.c	Thu Dec 14 08:57:36 2006 -0700
    59.3 @@ -82,7 +82,14 @@ void do_external(struct cpu_user_regs *r
    59.4  
    59.5      vec = xen_mpic_get_irq(regs);
    59.6  
    59.7 -    if (vec != -1) {
    59.8 +    if (irq_desc[vec].status & IRQ_PER_CPU) {
    59.9 +        /* x86 do_IRQ does not respect the per cpu flag.  */
   59.10 +        irq_desc_t *desc = &irq_desc[vec];
   59.11 +        regs->entry_vector = vec;
   59.12 +        desc->handler->ack(vec);
   59.13 +        desc->action->handler(vector_to_irq(vec), desc->action->dev_id, regs);
   59.14 +        desc->handler->end(vec);
   59.15 +    } else if (vec != -1) {
   59.16          DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
   59.17          regs->entry_vector = vec;
   59.18          do_IRQ(regs);
   59.19 @@ -253,3 +260,24 @@ int ioapic_guest_write(unsigned long phy
   59.20      BUG_ON(val != val);
   59.21      return 0;
   59.22  }
   59.23 +
   59.24 +void send_IPI_mask(cpumask_t mask, int vector)
   59.25 +{
   59.26 +    unsigned int cpus;
   59.27 +    int const bits = 8 * sizeof(cpus);
   59.28 +
   59.29 +    switch(vector) {
   59.30 +    case CALL_FUNCTION_VECTOR:
   59.31 +    case EVENT_CHECK_VECTOR:
   59.32 +        break;
   59.33 +    default:
   59.34 +        BUG();
   59.35 +        return;
   59.36 +    }
   59.37 +
   59.38 +    BUG_ON(NR_CPUS > bits);
   59.39 +    BUG_ON(fls(mask.bits[0]) > bits);
   59.40 +
   59.41 +    cpus = mask.bits[0];
   59.42 +    mpic_send_ipi(vector, cpus);
   59.43 +}
    60.1 --- a/xen/arch/powerpc/gdbstub.c	Thu Dec 14 08:54:54 2006 -0700
    60.2 +++ b/xen/arch/powerpc/gdbstub.c	Thu Dec 14 08:57:36 2006 -0700
    60.3 @@ -25,6 +25,7 @@
    60.4  #include <asm/msr.h>
    60.5  #include <asm/bitops.h>
    60.6  #include <asm/cache.h>
    60.7 +#include <asm/debugger.h>
    60.8  #include <asm/processor.h>
    60.9  
   60.10  asm(".globl trap_instruction\n"
    61.1 --- a/xen/arch/powerpc/iommu.c	Thu Dec 14 08:54:54 2006 -0700
    61.2 +++ b/xen/arch/powerpc/iommu.c	Thu Dec 14 08:57:36 2006 -0700
    61.3 @@ -32,6 +32,12 @@
    61.4  #include "tce.h"
    61.5  #include "iommu.h"
    61.6  
    61.7 +#ifdef DEBUG
    61.8 +#define DBG(fmt...) printk(fmt)
    61.9 +#else
   61.10 +#define DBG(fmt...)
   61.11 +#endif
   61.12 +
   61.13  struct iommu_funcs {
   61.14      int (*iommu_put)(ulong, union tce);
   61.15  };
   61.16 @@ -46,17 +52,31 @@ int iommu_put(u32 buid, ulong ioba, unio
   61.17      struct domain *d = v->domain;
   61.18  
   61.19      if (buid < iommu_phbs_num && iommu_phbs[buid].iommu_put != NULL) {
   61.20 -        ulong pfn;
   61.21 +        ulong gmfn;
   61.22          ulong mfn;
   61.23          int mtype;
   61.24  
   61.25 -        pfn = tce.tce_bits.tce_rpn;
   61.26 -        mfn = pfn2mfn(d, pfn, &mtype);
   61.27 +        gmfn = tce.tce_bits.tce_rpn;
   61.28 +
   61.29 +        
   61.30 +        mfn = pfn2mfn(d, gmfn, &mtype);
   61.31          if (mfn != INVALID_MFN) {
   61.32 -#ifdef DEBUG
   61.33 -            printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
   61.34 -                   ioba, pfn, mfn);
   61.35 -#endif
   61.36 +            switch (mtype) {
   61.37 +            case PFN_TYPE_RMA:
   61.38 +            case PFN_TYPE_LOGICAL:
   61.39 +                break;
   61.40 +            case PFN_TYPE_FOREIGN:
   61.41 +                DBG("%s: assigning to Foriegn page: "
   61.42 +                    "gmfn: 0x%lx mfn: 0x%lx\n",  __func__, gmfn, mfn);
   61.43 +                break;
   61.44 +            default:
   61.45 +                printk("%s: unsupported type[%d]: gmfn: 0x%lx mfn: 0x%lx\n",
   61.46 +                       __func__, mtype, gmfn, mfn);
   61.47 +                return -1;
   61.48 +            break;
   61.49 +            }
   61.50 +            DBG("%s: ioba=0x%lx gmfn=0x%lx mfn=0x%lx\n", __func__,
   61.51 +                ioba, gmfn, mfn);
   61.52              tce.tce_bits.tce_rpn = mfn;
   61.53              return iommu_phbs[buid].iommu_put(ioba, tce);
   61.54          }
    62.1 --- a/xen/arch/powerpc/machine_kexec.c	Thu Dec 14 08:54:54 2006 -0700
    62.2 +++ b/xen/arch/powerpc/machine_kexec.c	Thu Dec 14 08:57:36 2006 -0700
    62.3 @@ -1,5 +1,6 @@
    62.4  #include <xen/lib.h>       /* for printk() used in stubs */
    62.5  #include <xen/types.h>
    62.6 +#include <xen/kexec.h>
    62.7  #include <public/kexec.h>
    62.8  
    62.9  int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
   62.10 @@ -13,11 +14,6 @@ void machine_kexec_unload(int type, int 
   62.11      printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   62.12  }
   62.13  
   62.14 -void machine_kexec(xen_kexec_image_t *image)
   62.15 -{
   62.16 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   62.17 -}
   62.18 -
   62.19  void machine_reboot_kexec(xen_kexec_image_t *image)
   62.20  {
   62.21      printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    63.1 --- a/xen/arch/powerpc/mambo.S	Thu Dec 14 08:54:54 2006 -0700
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,64 +0,0 @@
    63.4 -/*
    63.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    63.6 - *
    63.7 - * This program is free software; you can redistribute it and/or modify
    63.8 - * it under the terms of the GNU General Public License as published by
    63.9 - * the Free Software Foundation; either version 2 of the License, or
   63.10 - * (at your option) any later version.
   63.11 - * 
   63.12 - * This program is distributed in the hope that it will be useful,
   63.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.15 - * GNU General Public License for more details.
   63.16 - * 
   63.17 - * You should have received a copy of the GNU General Public License
   63.18 - * along with this program; if not, write to the Free Software
   63.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   63.20 - *
   63.21 - */
   63.22 -
   63.23 -#include <asm/config.h>
   63.24 -#include <asm/processor.h>
   63.25 -
   63.26 -_GLOBAL(mambo_callthru)
   63.27 -	.long 0x000eaeb0
   63.28 -	blr
   63.29 -
   63.30 -_GLOBAL(mambo_write)
   63.31 -	mr	r5, r4
   63.32 -	mr	r4, r3
   63.33 -	li	r3, 0		# Write console code
   63.34 -	
   63.35 -	li	r6, 0
   63.36 -	/* need to fix return value */
   63.37 -	mflr	r7
   63.38 -	bl	_ENTRY(mambo_callthru)
   63.39 -	mtlr	r7
   63.40 -	mr	r3, r5
   63.41 -	blr
   63.42 -
   63.43 -_GLOBAL(mambo_memset)
   63.44 -	mr	r6, r5
   63.45 -	mr	r5, r4
   63.46 -	mr	r4, r3
   63.47 -	li	r3, 0x47	# memset
   63.48 -	/* need to fix return value */
   63.49 -	mflr	r7
   63.50 -	bl	_ENTRY(mambo_callthru)
   63.51 -	mtlr	r7
   63.52 -	mr	r3, r4
   63.53 -	blr
   63.54 -
   63.55 -_GLOBAL(mambo_memcpy)
   63.56 -	mr	r6, r5
   63.57 -	mr	r5, r4
   63.58 -	mr	r4, r3
   63.59 -	li	r3, 0x45 # memcpy
   63.60 -	/* need to fix return value */
   63.61 -	mflr	r7
   63.62 -	bl	_ENTRY(mambo_callthru)
   63.63 -	mtlr	r7
   63.64 -	mr	r3, r4
   63.65 -	blr
   63.66 -
   63.67 -	
    64.1 --- a/xen/arch/powerpc/memory.c	Thu Dec 14 08:54:54 2006 -0700
    64.2 +++ b/xen/arch/powerpc/memory.c	Thu Dec 14 08:57:36 2006 -0700
    64.3 @@ -20,10 +20,31 @@
    64.4   */
    64.5  #include <xen/sched.h>
    64.6  #include <xen/mm.h>
    64.7 +#include <xen/numa.h>
    64.8  #include "of-devtree.h"
    64.9  #include "oftree.h"
   64.10 +#include "rtas.h"
   64.11 +
   64.12 +#undef DEBUG
   64.13 +#ifdef DEBUG
   64.14 +#define DBG(fmt...) printk(fmt)
   64.15 +#else
   64.16 +#define DBG(fmt...)
   64.17 +#endif
   64.18 +
   64.19 +/*
   64.20 + * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
   64.21 + * page_info table and allocation bitmap.
   64.22 + */
   64.23 +static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
   64.24 +integer_param("xenheap_megabytes", opt_xenheap_megabytes);
   64.25  
   64.26  unsigned long xenheap_phys_end;
   64.27 +static uint nr_pages;
   64.28 +static ulong xenheap_size;
   64.29 +static ulong save_start;
   64.30 +static ulong save_end;
   64.31 +
   64.32  struct membuf {
   64.33      ulong start;
   64.34      ulong size;
   64.35 @@ -36,15 +57,20 @@ static ulong free_xenheap(ulong start, u
   64.36      start = ALIGN_UP(start, PAGE_SIZE);
   64.37      end = ALIGN_DOWN(end, PAGE_SIZE);
   64.38  
   64.39 -    printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
   64.40 +    DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
   64.41  
   64.42 -    if (oftree <= end && oftree >= start) {
   64.43 -        printk("%s:     Go around the devtree: 0x%lx - 0x%lx\n",
   64.44 -               __func__, oftree, oftree_end);
   64.45 -        init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE));
   64.46 -        init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end);
   64.47 +    /* need to do this better */
   64.48 +    if (save_start <= end && save_start >= start) {
   64.49 +        DBG("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
   64.50 +               __func__, save_start, save_end);
   64.51 +        init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
   64.52 +        xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
   64.53 +
   64.54 +        init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
   64.55 +        xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
   64.56      } else {
   64.57          init_xenheap_pages(start, end);
   64.58 +        xenheap_size += end - start;
   64.59      }
   64.60  
   64.61      return ALIGN_UP(end, PAGE_SIZE);
   64.62 @@ -57,8 +83,10 @@ static void set_max_page(struct membuf *
   64.63      for (i = 0; i < entries; i++) {
   64.64          ulong end_page;
   64.65  
   64.66 +        printk("  %016lx: %016lx\n", mb[i].start, mb[i].size);
   64.67 +        nr_pages += mb[i].size >> PAGE_SHIFT;
   64.68 +
   64.69          end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
   64.70 -
   64.71          if (end_page > max_page)
   64.72              max_page = end_page;
   64.73      }
   64.74 @@ -71,11 +99,11 @@ static void heap_init(struct membuf *mb,
   64.75      ulong start_blk;
   64.76      ulong end_blk = 0;
   64.77  
   64.78 -	for (i = 0; i < entries; i++) {
   64.79 -	    start_blk = mb[i].start;
   64.80 -	    end_blk = start_blk + mb[i].size;
   64.81 +    for (i = 0; i < entries; i++) {
   64.82 +        start_blk = mb[i].start;
   64.83 +        end_blk = start_blk + mb[i].size;
   64.84  
   64.85 -	    if (start_blk < xenheap_phys_end) {
   64.86 +        if (start_blk < xenheap_phys_end) {
   64.87              if (xenheap_phys_end > end_blk) {
   64.88                  panic("xenheap spans LMB\n");
   64.89              }
   64.90 @@ -87,7 +115,7 @@ static void heap_init(struct membuf *mb,
   64.91  
   64.92          init_boot_pages(start_blk, end_blk);
   64.93          total_pages += (end_blk - start_blk) >> PAGE_SHIFT;
   64.94 -	}
   64.95 +    }
   64.96  }
   64.97  
   64.98  static void ofd_walk_mem(void *m, walk_mem_fn fn)
   64.99 @@ -123,7 +151,7 @@ static void setup_xenheap(module_t *mod,
  64.100      for (i = 0; i < mcount; i++) {
  64.101          u32 s;
  64.102  
  64.103 -        if(mod[i].mod_end == mod[i].mod_start)
  64.104 +        if (mod[i].mod_end == mod[i].mod_start)
  64.105              continue;
  64.106  
  64.107          s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
  64.108 @@ -149,19 +177,42 @@ static void setup_xenheap(module_t *mod,
  64.109  void memory_init(module_t *mod, int mcount)
  64.110  {
  64.111      ulong eomem;
  64.112 -    ulong heap_start, heap_size;
  64.113 -
  64.114 -    printk("Physical RAM map:\n");
  64.115 +    ulong heap_start;
  64.116 +    ulong xh_pages;
  64.117  
  64.118      /* lets find out how much memory there is and set max_page */
  64.119      max_page = 0;
  64.120 +    printk("Physical RAM map:\n");
  64.121      ofd_walk_mem((void *)oftree, set_max_page);
  64.122      eomem = max_page << PAGE_SHIFT;
  64.123  
  64.124      if (eomem == 0){
  64.125          panic("ofd_walk_mem() failed\n");
  64.126      }
  64.127 -    printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
  64.128 +
  64.129 +    /* find the portion of memory we need to keep safe */
  64.130 +    save_start = oftree;
  64.131 +    save_end = oftree_end;
  64.132 +    if (rtas_base) {
  64.133 +        if (save_start > rtas_base)
  64.134 +            save_start = rtas_base;
  64.135 +        if (save_end < rtas_end)
  64.136 +            save_end = rtas_end;
  64.137 +    }
  64.138 +
  64.139 +    /* minimum heap has to reach to the end of all Xen required memory */
  64.140 +    xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
  64.141 +    xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
  64.142 +
  64.143 +    /* While we are allocating HTABS from The Xen Heap we need it to
  64.144 +     * be larger */
  64.145 +    xh_pages  += nr_pages >> 5;
  64.146 +
  64.147 +    xenheap_phys_end = xh_pages << PAGE_SHIFT;
  64.148 +    printk("End of Xen Area: %luMiB (%luKiB)\n",
  64.149 +           xenheap_phys_end >> 20, xenheap_phys_end >> 10);
  64.150 +
  64.151 +    printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
  64.152  
  64.153      /* Architecturally the first 4 pages are exception hendlers, we
  64.154       * will also be copying down some code there */
  64.155 @@ -185,22 +236,23 @@ void memory_init(module_t *mod, int mcou
  64.156          panic("total_pages > max_page: 0x%lx > 0x%lx\n",
  64.157                total_pages, max_page);
  64.158  
  64.159 -    printk("total_pages: 0x%016lx\n", total_pages);
  64.160 +    DBG("total_pages: 0x%016lx\n", total_pages);
  64.161  
  64.162      init_frametable();
  64.163 +
  64.164 +    numa_initmem_init(0, max_page);
  64.165 +
  64.166      end_boot_allocator();
  64.167  
  64.168      /* Add memory between the beginning of the heap and the beginning
  64.169 -     * of out text */
  64.170 +     * of our text */
  64.171      free_xenheap(heap_start, (ulong)_start);
  64.172 -
  64.173 -    heap_size = xenheap_phys_end - heap_start;
  64.174 -    printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
  64.175 -
  64.176      setup_xenheap(mod, mcount);
  64.177 +    printk("Xen Heap: %luMiB (%luKiB)\n",
  64.178 +           xenheap_size >> 20, xenheap_size >> 10);
  64.179  
  64.180      eomem = avail_domheap_pages();
  64.181 -    printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
  64.182 +    printk("Dom Heap: %luMiB (%luKiB)\n",
  64.183             (eomem << PAGE_SHIFT) >> 20,
  64.184             (eomem << PAGE_SHIFT) >> 10);
  64.185  }
    65.1 --- a/xen/arch/powerpc/mm.c	Thu Dec 14 08:54:54 2006 -0700
    65.2 +++ b/xen/arch/powerpc/mm.c	Thu Dec 14 08:57:36 2006 -0700
    65.3 @@ -25,9 +25,9 @@
    65.4  #include <xen/kernel.h>
    65.5  #include <xen/sched.h>
    65.6  #include <xen/perfc.h>
    65.7 -#include <asm/misc.h>
    65.8  #include <asm/init.h>
    65.9  #include <asm/page.h>
   65.10 +#include <asm/string.h>
   65.11  
   65.12  #ifdef VERBOSE
   65.13  #define MEM_LOG(_f, _a...)                                  \
   65.14 @@ -42,18 +42,129 @@ struct page_info *frame_table;
   65.15  unsigned long max_page;
   65.16  unsigned long total_pages;
   65.17  
   65.18 +void __init init_frametable(void)
   65.19 +{
   65.20 +    unsigned long p;
   65.21 +    unsigned long nr_pages;
   65.22 +    int i;
   65.23 +
   65.24 +    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
   65.25 +
   65.26 +    p = alloc_boot_pages(nr_pages, 1);
   65.27 +    if (p == 0)
   65.28 +        panic("Not enough memory for frame table\n");
   65.29 +
   65.30 +    frame_table = (struct page_info *)(p << PAGE_SHIFT);
   65.31 +    for (i = 0; i < nr_pages; i += 1)
   65.32 +        clear_page((void *)((p + i) << PAGE_SHIFT));
   65.33 +}
   65.34 +
   65.35 +void share_xen_page_with_guest(
   65.36 +    struct page_info *page, struct domain *d, int readonly)
   65.37 +{
   65.38 +    if ( page_get_owner(page) == d )
   65.39 +        return;
   65.40 +
   65.41 +    /* this causes us to leak pages in the Domain and reuslts in
   65.42 +     * Zombie domains, I think we are missing a piece, until we find
   65.43 +     * it we disable the following code */
   65.44 +    set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
   65.45 +
   65.46 +    spin_lock(&d->page_alloc_lock);
   65.47 +
   65.48 +    /* The incremented type count pins as writable or read-only. */
   65.49 +    page->u.inuse.type_info  = (readonly ? PGT_none : PGT_writable_page);
   65.50 +    page->u.inuse.type_info |= PGT_validated | 1;
   65.51 +
   65.52 +    page_set_owner(page, d);
   65.53 +    wmb(); /* install valid domain ptr before updating refcnt. */
   65.54 +    ASSERT(page->count_info == 0);
   65.55 +    page->count_info |= PGC_allocated | 1;
   65.56 +
   65.57 +    if ( unlikely(d->xenheap_pages++ == 0) )
   65.58 +        get_knownalive_domain(d);
   65.59 +    list_add_tail(&page->list, &d->xenpage_list);
   65.60 +
   65.61 +    spin_unlock(&d->page_alloc_lock);
   65.62 +}
   65.63 +
   65.64 +void share_xen_page_with_privileged_guests(
   65.65 +    struct page_info *page, int readonly)
   65.66 +{
   65.67 +        unimplemented();
   65.68 +}
   65.69 +
   65.70 +static ulong foreign_to_mfn(struct domain *d, ulong pfn)
   65.71 +{
   65.72 +
   65.73 +    pfn -= 1UL << cpu_foreign_map_order();
   65.74 +
   65.75 +    BUG_ON(pfn >= d->arch.foreign_mfn_count);
   65.76 +
   65.77 +    return d->arch.foreign_mfns[pfn];
   65.78 +}
   65.79 +
   65.80 +static int set_foreign(struct domain *d, ulong pfn, ulong mfn)
   65.81 +{
   65.82 +    pfn -= 1UL << cpu_foreign_map_order();
   65.83 +
   65.84 +    BUG_ON(pfn >= d->arch.foreign_mfn_count);
   65.85 +    d->arch.foreign_mfns[pfn] = mfn;
   65.86 +
   65.87 +    return 0;
   65.88 +}
   65.89 +
   65.90 +static int create_grant_va_mapping(
   65.91 +    unsigned long va, unsigned long frame, struct vcpu *v)
   65.92 +{
   65.93 +    if (v->domain->domain_id != 0) {
   65.94 +        printk("only Dom0 can map a grant entry\n");
   65.95 +        BUG();
   65.96 +        return GNTST_permission_denied;
   65.97 +    }
   65.98 +    set_foreign(v->domain, va >> PAGE_SHIFT, frame);
   65.99 +    return GNTST_okay;
  65.100 +}
  65.101 +
  65.102 +static int destroy_grant_va_mapping(
  65.103 +    unsigned long addr, unsigned long frame, struct domain *d)
  65.104 +{
  65.105 +    if (d->domain_id != 0) {
  65.106 +        printk("only Dom0 can map a grant entry\n");
  65.107 +        BUG();
  65.108 +        return GNTST_permission_denied;
  65.109 +    }
  65.110 +    set_foreign(d, addr >> PAGE_SHIFT, ~0UL);
  65.111 +    return GNTST_okay;
  65.112 +}
  65.113 +
  65.114  int create_grant_host_mapping(
  65.115      unsigned long addr, unsigned long frame, unsigned int flags)
  65.116  {
  65.117 -    panic("%s called\n", __func__);
  65.118 -    return 1;
  65.119 +    if (flags & GNTMAP_application_map) {
  65.120 +        printk("%s: GNTMAP_application_map not supported\n", __func__);
  65.121 +        BUG();
  65.122 +        return GNTST_general_error;
  65.123 +    }
  65.124 +    if (flags & GNTMAP_contains_pte) {
  65.125 +        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
  65.126 +        BUG();
  65.127 +        return GNTST_general_error;
  65.128 +    }
  65.129 +    return create_grant_va_mapping(addr, frame, current);
  65.130  }
  65.131  
  65.132  int destroy_grant_host_mapping(
  65.133      unsigned long addr, unsigned long frame, unsigned int flags)
  65.134  {
  65.135 -    panic("%s called\n", __func__);
  65.136 -    return 1;
  65.137 +    if (flags & GNTMAP_contains_pte) {
  65.138 +        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
  65.139 +        BUG();
  65.140 +        return GNTST_general_error;
  65.141 +    }
  65.142 +
  65.143 +    /* may have force the remove here */
  65.144 +    return destroy_grant_va_mapping(addr, frame, current->domain);
  65.145  }
  65.146  
  65.147  int steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
  65.148 @@ -139,7 +250,7 @@ int get_page_type(struct page_info *page
  65.149          {
  65.150              return 0;
  65.151          }
  65.152 -        if ( unlikely(!(x & PGT_validated)) )
  65.153 +        else if ( unlikely(!(x & PGT_validated)) )
  65.154          {
  65.155              /* Someone else is updating validation of this page. Wait... */
  65.156              while ( (y = page->u.inuse.type_info) == x )
  65.157 @@ -158,25 +269,6 @@ int get_page_type(struct page_info *page
  65.158      return 1;
  65.159  }
  65.160  
  65.161 -void __init init_frametable(void)
  65.162 -{
  65.163 -    unsigned long p;
  65.164 -    unsigned long nr_pages;
  65.165 -    int i;
  65.166 -
  65.167 -    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
  65.168 -    nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT)));
  65.169 -    
  65.170 -
  65.171 -    p = alloc_boot_pages(nr_pages, 1);
  65.172 -    if (p == 0)
  65.173 -        panic("Not enough memory for frame table\n");
  65.174 -
  65.175 -    frame_table = (struct page_info *)(p << PAGE_SHIFT);
  65.176 -    for (i = 0; i < nr_pages; i += 1)
  65.177 -        clear_page((void *)((p + i) << PAGE_SHIFT));
  65.178 -}
  65.179 -
  65.180  long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
  65.181  {
  65.182      printk("%s: no PPC specific memory ops\n", __func__);
  65.183 @@ -185,29 +277,28 @@ long arch_memory_op(int op, XEN_GUEST_HA
  65.184  
  65.185  extern void copy_page(void *dp, void *sp)
  65.186  {
  65.187 -    if (on_mambo()) {
  65.188 -        extern void *mambo_memcpy(void *,const void *,__kernel_size_t);
  65.189 -        mambo_memcpy(dp, sp, PAGE_SIZE);
  65.190 +    if (on_systemsim()) {
  65.191 +        systemsim_memcpy(dp, sp, PAGE_SIZE);
  65.192      } else {
  65.193          memcpy(dp, sp, PAGE_SIZE);
  65.194      }
  65.195  }
  65.196  
  65.197 +/* XXX should probably replace with faster data structure */
  65.198  static uint add_extent(struct domain *d, struct page_info *pg, uint order)
  65.199  {
  65.200      struct page_extents *pe;
  65.201  
  65.202      pe = xmalloc(struct page_extents);
  65.203      if (pe == NULL)
  65.204 -        return 0;
  65.205 +        return -ENOMEM;
  65.206  
  65.207      pe->pg = pg;
  65.208      pe->order = order;
  65.209 -    pe->pfn = page_to_mfn(pg);
  65.210  
  65.211      list_add_tail(&pe->pe_list, &d->arch.extent_list);
  65.212  
  65.213 -    return pe->pfn;
  65.214 +    return 0;
  65.215  }
  65.216  
  65.217  void free_extents(struct domain *d)
  65.218 @@ -246,7 +337,7 @@ uint allocate_extents(struct domain *d, 
  65.219          if (pg == NULL)
  65.220              return total_nrpages;
  65.221  
  65.222 -        if (add_extent(d, pg, ext_order) == 0) {
  65.223 +        if (add_extent(d, pg, ext_order) < 0) {
  65.224              free_domheap_pages(pg, ext_order);
  65.225              return total_nrpages;
  65.226          }
  65.227 @@ -299,6 +390,7 @@ int allocate_rma(struct domain *d, unsig
  65.228  
  65.229      return 0;
  65.230  }
  65.231 +
  65.232  void free_rma_check(struct page_info *page)
  65.233  {
  65.234      if (test_bit(_PGC_page_RMA, &page->count_info) &&
  65.235 @@ -306,7 +398,6 @@ void free_rma_check(struct page_info *pa
  65.236          panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
  65.237  }
  65.238  
  65.239 -
  65.240  ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
  65.241  {
  65.242      ulong rma_base_mfn = page_to_mfn(d->arch.rma_page);
  65.243 @@ -314,9 +405,17 @@ ulong pfn2mfn(struct domain *d, ulong pf
  65.244      struct page_extents *pe;
  65.245      ulong mfn = INVALID_MFN;
  65.246      int t = PFN_TYPE_NONE;
  65.247 +    ulong foreign_map_pfn = 1UL << cpu_foreign_map_order();
  65.248  
  65.249      /* quick tests first */
  65.250 -    if (d->is_privileged && cpu_io_mfn(pfn)) {
  65.251 +    if (pfn & foreign_map_pfn) {
  65.252 +        t = PFN_TYPE_FOREIGN;
  65.253 +        mfn = foreign_to_mfn(d, pfn);
  65.254 +    } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) {
  65.255 +        /* Its a grant table access */
  65.256 +        t = PFN_TYPE_GNTTAB;
  65.257 +        mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
  65.258 +    } else if (d->is_privileged && cpu_io_mfn(pfn)) {
  65.259          t = PFN_TYPE_IO;
  65.260          mfn = pfn;
  65.261      } else {
  65.262 @@ -324,17 +423,32 @@ ulong pfn2mfn(struct domain *d, ulong pf
  65.263              t = PFN_TYPE_RMA;
  65.264              mfn = pfn + rma_base_mfn;
  65.265          } else {
  65.266 -            list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  65.267 -                uint end_pfn = pe->pfn + (1 << pe->order);
  65.268 +            ulong cur_pfn = rma_size_mfn;
  65.269  
  65.270 -                if (pfn >= pe->pfn && pfn < end_pfn) {
  65.271 +            list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  65.272 +                uint pe_pages = 1UL << pe->order;
  65.273 +                uint end_pfn = cur_pfn + pe_pages;
  65.274 +
  65.275 +                if (pfn >= cur_pfn && pfn < end_pfn) {
  65.276                      t = PFN_TYPE_LOGICAL;
  65.277 -                    mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
  65.278 +                    mfn = page_to_mfn(pe->pg) + (pfn - cur_pfn);
  65.279                      break;
  65.280                  }
  65.281 +                cur_pfn += pe_pages;
  65.282              }
  65.283          }
  65.284 -        BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d);
  65.285 +#ifdef DEBUG
  65.286 +        if (t != PFN_TYPE_NONE &&
  65.287 +            (d->domain_flags & DOMF_dying) &&
  65.288 +            page_get_owner(mfn_to_page(mfn)) != d) {
  65.289 +            printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
  65.290 +                   __func__, t,
  65.291 +                   page_get_owner(mfn_to_page(mfn))->domain_id,
  65.292 +                   page_get_owner(mfn_to_page(mfn)),
  65.293 +                   d->domain_id, d);
  65.294 +            BUG();
  65.295 +        }
  65.296 +#endif
  65.297      }
  65.298  
  65.299      if (t == PFN_TYPE_NONE) {
  65.300 @@ -368,6 +482,42 @@ ulong pfn2mfn(struct domain *d, ulong pf
  65.301      return mfn;
  65.302  }
  65.303  
  65.304 +unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
  65.305 +{
  65.306 +    struct page_extents *pe;
  65.307 +    ulong cur_pfn;
  65.308 +    ulong gnttab_mfn;
  65.309 +    ulong rma_mfn;
  65.310 +
  65.311 +    /* grant? */
  65.312 +    gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0);
  65.313 +    if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES))
  65.314 +        return max_page + (mfn - gnttab_mfn);
  65.315 +
  65.316 +    /* IO? */
  65.317 +    if (d->is_privileged && cpu_io_mfn(mfn))
  65.318 +        return mfn;
  65.319 +
  65.320 +    rma_mfn = page_to_mfn(d->arch.rma_page);
  65.321 +    if (mfn >= rma_mfn &&
  65.322 +        mfn < (rma_mfn + (1 << d->arch.rma_order)))
  65.323 +        return mfn - rma_mfn;
  65.324 +
  65.325 +    /* Extent? */
  65.326 +    cur_pfn = 1UL << d->arch.rma_order;
  65.327 +    list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
  65.328 +        uint pe_pages = 1UL << pe->order;
  65.329 +        uint b_mfn = page_to_mfn(pe->pg);
  65.330 +        uint e_mfn = b_mfn + pe_pages;
  65.331 +
  65.332 +        if (mfn >= b_mfn && mfn < e_mfn) {
  65.333 +            return cur_pfn + (mfn - b_mfn);
  65.334 +        }
  65.335 +        cur_pfn += pe_pages;
  65.336 +    }
  65.337 +    return INVALID_M2P_ENTRY;
  65.338 +}
  65.339 +
  65.340  void guest_physmap_add_page(
  65.341      struct domain *d, unsigned long gpfn, unsigned long mfn)
  65.342  {
  65.343 @@ -382,3 +532,10 @@ void shadow_drop_references(
  65.344      struct domain *d, struct page_info *page)
  65.345  {
  65.346  }
  65.347 +
  65.348 +int arch_domain_add_extent(struct domain *d, struct page_info *page, int order)
  65.349 +{
  65.350 +    if (add_extent(d, page, order) < 0)
  65.351 +        return -ENOMEM;
  65.352 +    return 0;
  65.353 +}
    66.1 --- a/xen/arch/powerpc/mpic.c	Thu Dec 14 08:54:54 2006 -0700
    66.2 +++ b/xen/arch/powerpc/mpic.c	Thu Dec 14 08:57:36 2006 -0700
    66.3 @@ -15,22 +15,18 @@
    66.4  /* XXX Xen hacks ... */
    66.5  /* make this generic */
    66.6  
    66.7 -#define le32_to_cpu(x) \
    66.8 -({ \
    66.9 -	__u32 __x = (x); \
   66.10 -	((__u32)( \
   66.11 -		(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
   66.12 -		(((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) | \
   66.13 -		(((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) | \
   66.14 -		(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
   66.15 -})
   66.16 +#define le32_to_cpu(x)                                          \
   66.17 +    ({                                                          \
   66.18 +        __u32 __x = (x);                                        \
   66.19 +        ((__u32)(                                               \
   66.20 +             (((__u32)(__x) & (__u32)0x000000ffUL) << 24) |     \
   66.21 +             (((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) |     \
   66.22 +             (((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) |     \
   66.23 +             (((__u32)(__x) & (__u32)0xff000000UL) >> 24) ));   \
   66.24 +    })
   66.25  
   66.26  
   66.27  #define alloc_bootmem(x) xmalloc_bytes(x)
   66.28 -#define request_irq(irq, handler, f, devname, dev_id) \
   66.29 -    panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
   66.30 -
   66.31 -typedef int irqreturn_t;
   66.32  
   66.33  #define IRQ_NONE	(0)
   66.34  #define IRQ_HANDLED	(1)
   66.35 @@ -97,11 +93,6 @@ typedef int irqreturn_t;
   66.36  #include <asm/mpic.h>
   66.37  #include <asm/smp.h>
   66.38  
   66.39 -static inline void smp_message_recv(int msg, struct pt_regs *regs)
   66.40 -{
   66.41 -    return;
   66.42 -}
   66.43 -
   66.44  #ifdef DEBUG
   66.45  #define DBG(fmt...) printk(fmt)
   66.46  #else
   66.47 @@ -126,7 +117,7 @@ static DEFINE_SPINLOCK(mpic_lock);
   66.48  
   66.49  
   66.50  static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
   66.51 -			    unsigned int reg)
   66.52 +                             unsigned int reg)
   66.53  {
   66.54  	if (be)
   66.55  		return in_be32(base + (reg >> 2));
   66.56 @@ -135,7 +126,7 @@ static inline u32 _mpic_read(unsigned in
   66.57  }
   66.58  
   66.59  static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
   66.60 -			      unsigned int reg, u32 value)
   66.61 +                               unsigned int reg, u32 value)
   66.62  {
   66.63  	if (be)
   66.64  		out_be32(base + (reg >> 2), value);
   66.65 @@ -186,17 +177,17 @@ static inline u32 _mpic_irq_read(struct 
   66.66  	unsigned int	idx = src_no & mpic->isu_mask;
   66.67  
   66.68  	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
   66.69 -			  reg + (idx * MPIC_IRQ_STRIDE));
   66.70 +                      reg + (idx * MPIC_IRQ_STRIDE));
   66.71  }
   66.72  
   66.73  static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
   66.74 -				   unsigned int reg, u32 value)
   66.75 +                                   unsigned int reg, u32 value)
   66.76  {
   66.77  	unsigned int	isu = src_no >> mpic->isu_shift;
   66.78  	unsigned int	idx = src_no & mpic->isu_mask;
   66.79  
   66.80  	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
   66.81 -		    reg + (idx * MPIC_IRQ_STRIDE), value);
   66.82 +                reg + (idx * MPIC_IRQ_STRIDE), value);
   66.83  }
   66.84  
   66.85  #define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
   66.86 @@ -261,7 +252,7 @@ static inline void mpic_ht_end_irq(struc
   66.87  }
   66.88  
   66.89  static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
   66.90 -				      unsigned int irqflags)
   66.91 +                                      unsigned int irqflags)
   66.92  {
   66.93  	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
   66.94  	unsigned long flags;
   66.95 @@ -284,7 +275,7 @@ static void mpic_startup_ht_interrupt(st
   66.96  }
   66.97  
   66.98  static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
   66.99 -				       unsigned int irqflags)
  66.100 +                                       unsigned int irqflags)
  66.101  {
  66.102  	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
  66.103  	unsigned long flags;
  66.104 @@ -305,7 +296,7 @@ static void mpic_shutdown_ht_interrupt(s
  66.105  }
  66.106  
  66.107  static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
  66.108 -				    unsigned int devfn, u32 vdid)
  66.109 +                                    unsigned int devfn, u32 vdid)
  66.110  {
  66.111  	int i, irq, n;
  66.112  	u8 __iomem *base;
  66.113 @@ -485,8 +476,8 @@ static void mpic_enable_irq(unsigned int
  66.114  	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
  66.115  
  66.116  	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
  66.117 -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
  66.118 -		       ~MPIC_VECPRI_MASK);
  66.119 +                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
  66.120 +                   ~MPIC_VECPRI_MASK);
  66.121  
  66.122  	/* make sure mask gets to controller before we return to user */
  66.123  	do {
  66.124 @@ -532,8 +523,8 @@ static void mpic_disable_irq(unsigned in
  66.125  	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
  66.126  
  66.127  	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
  66.128 -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
  66.129 -		       MPIC_VECPRI_MASK);
  66.130 +                   mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
  66.131 +                   MPIC_VECPRI_MASK);
  66.132  
  66.133  	/* make sure mask gets to controller before we return to user */
  66.134  	do {
  66.135 @@ -623,7 +614,7 @@ static void mpic_set_affinity(unsigned i
  66.136  	cpus_and(tmp, cpumask, cpu_online_map);
  66.137  
  66.138  	mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
  66.139 -		       mpic_physmask(cpus_addr(tmp)[0]));	
  66.140 +                   mpic_physmask(cpus_addr(tmp)[0]));	
  66.141  }
  66.142  
  66.143  
  66.144 @@ -633,14 +624,14 @@ static void mpic_set_affinity(unsigned i
  66.145  
  66.146  
  66.147  struct mpic * __init mpic_alloc(unsigned long phys_addr,
  66.148 -				unsigned int flags,
  66.149 -				unsigned int isu_size,
  66.150 -				unsigned int irq_offset,
  66.151 -				unsigned int irq_count,
  66.152 -				unsigned int ipi_offset,
  66.153 -				unsigned char *senses,
  66.154 -				unsigned int senses_count,
  66.155 -				const char *name)
  66.156 +                                unsigned int flags,
  66.157 +                                unsigned int isu_size,
  66.158 +                                unsigned int irq_offset,
  66.159 +                                unsigned int irq_count,
  66.160 +                                unsigned int ipi_offset,
  66.161 +                                unsigned char *senses,
  66.162 +                                unsigned int senses_count,
  66.163 +                                const char *name)
  66.164  {
  66.165  	struct mpic	*mpic;
  66.166  	u32		reg;
  66.167 @@ -687,8 +678,8 @@ struct mpic * __init mpic_alloc(unsigned
  66.168  	/* Reset */
  66.169  	if (flags & MPIC_WANTS_RESET) {
  66.170  		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
  66.171 -			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  66.172 -			   | MPIC_GREG_GCONF_RESET);
  66.173 +                   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  66.174 +                   | MPIC_GREG_GCONF_RESET);
  66.175  		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  66.176  		       & MPIC_GREG_GCONF_RESET)
  66.177  			mb();
  66.178 @@ -700,15 +691,15 @@ struct mpic * __init mpic_alloc(unsigned
  66.179  	 */
  66.180  	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
  66.181  	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
  66.182 -			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
  66.183 +                      >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
  66.184  	if (isu_size == 0)
  66.185  		mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
  66.186 -				     >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
  66.187 +                             >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
  66.188  
  66.189  	/* Map the per-CPU registers */
  66.190  	for (i = 0; i < mpic->num_cpus; i++) {
  66.191  		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
  66.192 -					   i * MPIC_CPU_STRIDE, 0x1000);
  66.193 +                                   i * MPIC_CPU_STRIDE, 0x1000);
  66.194  		BUG_ON(mpic->cpuregs[i] == NULL);
  66.195  	}
  66.196  
  66.197 @@ -716,7 +707,7 @@ struct mpic * __init mpic_alloc(unsigned
  66.198  	if (mpic->isu_size == 0) {
  66.199  		mpic->isu_size = mpic->num_sources;
  66.200  		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
  66.201 -					MPIC_IRQ_STRIDE * mpic->isu_size);
  66.202 +                                MPIC_IRQ_STRIDE * mpic->isu_size);
  66.203  		BUG_ON(mpic->isus[0] == NULL);
  66.204  	}
  66.205  	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
  66.206 @@ -752,7 +743,7 @@ struct mpic * __init mpic_alloc(unsigned
  66.207  }
  66.208  
  66.209  void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
  66.210 -			    unsigned long phys_addr)
  66.211 +                            unsigned long phys_addr)
  66.212  {
  66.213  	unsigned int isu_first = isu_num * mpic->isu_size;
  66.214  
  66.215 @@ -764,7 +755,7 @@ void __init mpic_assign_isu(struct mpic 
  66.216  }
  66.217  
  66.218  void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
  66.219 -			       void *data)
  66.220 +                               void *data)
  66.221  {
  66.222  	struct mpic *mpic = mpic_find(irq, NULL);
  66.223  	unsigned long flags;
  66.224 @@ -799,20 +790,20 @@ void __init mpic_init(struct mpic *mpic)
  66.225  	/* Initialize timers: just disable them all */
  66.226  	for (i = 0; i < 4; i++) {
  66.227  		mpic_write(mpic->tmregs,
  66.228 -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
  66.229 +                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
  66.230  		mpic_write(mpic->tmregs,
  66.231 -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
  66.232 -			   MPIC_VECPRI_MASK |
  66.233 -			   (MPIC_VEC_TIMER_0 + i));
  66.234 +                   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
  66.235 +                   MPIC_VECPRI_MASK |
  66.236 +                   (MPIC_VEC_TIMER_0 + i));
  66.237  	}
  66.238  
  66.239  	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
  66.240  	mpic_test_broken_ipi(mpic);
  66.241  	for (i = 0; i < 4; i++) {
  66.242  		mpic_ipi_write(i,
  66.243 -			       MPIC_VECPRI_MASK |
  66.244 -			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
  66.245 -			       (MPIC_VEC_IPI_0 + i));
  66.246 +                       MPIC_VECPRI_MASK |
  66.247 +                       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
  66.248 +                       (MPIC_VEC_IPI_0 + i));
  66.249  #ifdef CONFIG_SMP
  66.250  		if (!(mpic->flags & MPIC_PRIMARY))
  66.251  			continue;
  66.252 @@ -859,7 +850,7 @@ void __init mpic_init(struct mpic *mpic)
  66.253  #ifdef CONFIG_MPIC_BROKEN_U3
  66.254  			if (mpic_is_ht_interrupt(mpic, i)) {
  66.255  				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
  66.256 -					    MPIC_VECPRI_POLARITY_MASK);
  66.257 +                            MPIC_VECPRI_POLARITY_MASK);
  66.258  				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
  66.259  			}
  66.260  #else
  66.261 @@ -873,7 +864,7 @@ void __init mpic_init(struct mpic *mpic)
  66.262  		/* init hw */
  66.263  		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
  66.264  		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  66.265 -			       1 << hard_smp_processor_id());
  66.266 +                       1 << hard_smp_processor_id());
  66.267  
  66.268  		/* init linux descriptors */
  66.269  		if (i < mpic->irq_count) {
  66.270 @@ -887,8 +878,8 @@ void __init mpic_init(struct mpic *mpic)
  66.271  
  66.272  	/* Disable 8259 passthrough */
  66.273  	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
  66.274 -		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  66.275 -		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
  66.276 +               mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
  66.277 +               | MPIC_GREG_GCONF_8259_PTHROU_DIS);
  66.278  
  66.279  	/* Set current processor priority to 0 */
  66.280  	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
  66.281 @@ -908,12 +899,12 @@ void mpic_irq_set_priority(unsigned int 
  66.282  		reg = mpic_ipi_read(irq - mpic->ipi_offset) &
  66.283  			~MPIC_VECPRI_PRIORITY_MASK;
  66.284  		mpic_ipi_write(irq - mpic->ipi_offset,
  66.285 -			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  66.286 +                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  66.287  	} else {
  66.288  		reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
  66.289  			& ~MPIC_VECPRI_PRIORITY_MASK;
  66.290  		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
  66.291 -			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  66.292 +                       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
  66.293  	}
  66.294  	spin_unlock_irqrestore(&mpic_lock, flags);
  66.295  }
  66.296 @@ -956,7 +947,7 @@ void mpic_setup_this_cpu(void)
  66.297  	if (distribute_irqs) {
  66.298  	 	for (i = 0; i < mpic->num_sources ; i++)
  66.299  			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  66.300 -				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
  66.301 +                           mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
  66.302  	}
  66.303  
  66.304  	/* Set current processor priority to 0 */
  66.305 @@ -1001,7 +992,7 @@ void mpic_teardown_this_cpu(int secondar
  66.306  	/* let the mpic know we don't want intrs.  */
  66.307  	for (i = 0; i < mpic->num_sources ; i++)
  66.308  		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
  66.309 -			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
  66.310 +                       mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
  66.311  
  66.312  	/* Set current processor priority to max */
  66.313  	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
  66.314 @@ -1021,7 +1012,7 @@ void mpic_send_ipi(unsigned int ipi_no, 
  66.315  #endif
  66.316  
  66.317  	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
  66.318 -		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
  66.319 +                   mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
  66.320  }
  66.321  
  66.322  int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
  66.323 @@ -1049,7 +1040,7 @@ int mpic_get_one_irq(struct mpic *mpic, 
  66.324  		return irq + mpic->irq_offset;
  66.325  	}
  66.326  #ifdef DEBUG_IPI
  66.327 -       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
  66.328 +    DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
  66.329  #endif
  66.330  	return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
  66.331  }
  66.332 @@ -1075,13 +1066,13 @@ void mpic_request_ipis(void)
  66.333  
  66.334  	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
  66.335  	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
  66.336 -		    "IPI0 (call function)", mpic);
  66.337 +                "IPI0 (call function)", mpic);
  66.338  	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
  66.339 -		   "IPI1 (reschedule)", mpic);
  66.340 +                "IPI1 (reschedule)", mpic);
  66.341  	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
  66.342 -		   "IPI2 (unused)", mpic);
  66.343 +                "IPI2 (unused)", mpic);
  66.344  	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
  66.345 -		   "IPI3 (debugger break)", mpic);
  66.346 +                "IPI3 (debugger break)", mpic);
  66.347  
  66.348  	printk("IPIs requested... \n");
  66.349  }
    67.1 --- a/xen/arch/powerpc/mpic_init.c	Thu Dec 14 08:54:54 2006 -0700
    67.2 +++ b/xen/arch/powerpc/mpic_init.c	Thu Dec 14 08:57:36 2006 -0700
    67.3 @@ -22,6 +22,7 @@
    67.4  #include <xen/init.h>
    67.5  #include <xen/lib.h>
    67.6  #include <asm/mpic.h>
    67.7 +#include <errno.h>
    67.8  #include "mpic_init.h"
    67.9  #include "oftree.h"
   67.10  #include "of-devtree.h"
   67.11 @@ -74,7 +75,7 @@ static unsigned long reg2(void *oft_p, o
   67.12      rc = ofd_getprop(oft_p, c, "reg", &isa_reg, sizeof(isa_reg));
   67.13  
   67.14      DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
   67.15 -                    isa_reg.address, isa_reg.size);
   67.16 +        isa_reg.address, isa_reg.size);
   67.17      return isa_reg.address;
   67.18  }
   67.19  
   67.20 @@ -92,7 +93,7 @@ static unsigned long reg1(void *oft_p, o
   67.21      rc = ofd_getprop(oft_p, c, "reg", &reg, sizeof(reg));
   67.22  
   67.23      DBG("%s: reg property address=0x%08x  size=0x%08x\n", __func__,
   67.24 -                        reg.address, reg.size);
   67.25 +        reg.address, reg.size);
   67.26      return reg.address;
   67.27  }
   67.28  
   67.29 @@ -173,15 +174,15 @@ static unsigned long find_ranges_addr_fr
   67.30          break;
   67.31      case 2:
   67.32          ranges_addr = (((u64)ranges[ranges_i]) << 32) |
   67.33 -                      ranges[ranges_i + 1];
   67.34 +            ranges[ranges_i + 1];
   67.35          break;
   67.36      case 3:  /* the G5 case, how to squeeze 96 bits into 64 */
   67.37          ranges_addr = (((u64)ranges[ranges_i+1]) << 32) |
   67.38 -                      ranges[ranges_i + 2];
   67.39 +            ranges[ranges_i + 2];
   67.40          break;
   67.41      case 4:
   67.42          ranges_addr = (((u64)ranges[ranges_i+2]) << 32) |
   67.43 -                      ranges[ranges_i + 4];
   67.44 +            ranges[ranges_i + 4];
   67.45          break;
   67.46      default:
   67.47          PANIC("#address-cells out of range\n");
   67.48 @@ -266,7 +267,7 @@ static int find_mpic_canonical_probe(voi
   67.49       * We select the one without an 'interrupt' property.
   67.50       */
   67.51      c = ofd_node_find_by_prop(oft_p, OFD_ROOT, "device_type", mpic_type,
   67.52 -                                        sizeof(mpic_type));
   67.53 +                              sizeof(mpic_type));
   67.54      while (c > 0) {
   67.55          int int_len;
   67.56          int good_mpic;
   67.57 @@ -358,6 +359,42 @@ static struct hw_interrupt_type *share_m
   67.58  
   67.59  #endif
   67.60  
   67.61 +static unsigned int mpic_startup_ipi(unsigned int irq)
   67.62 +{
   67.63 +    mpic->hc_ipi.enable(irq);
   67.64 +    return 0;
   67.65 +}
   67.66 +
   67.67 +int request_irq(unsigned int irq,
   67.68 +                irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
   67.69 +                unsigned long irqflags, const char * devname, void *dev_id)
   67.70 +{
   67.71 +    int retval;
   67.72 +    struct irqaction *action;
   67.73 +    void (*func)(int, void *, struct cpu_user_regs *);
   67.74 +
   67.75 +    action = xmalloc(struct irqaction);
   67.76 +    if (!action) {
   67.77 +        BUG();
   67.78 +        return -ENOMEM;
   67.79 +    }
   67.80 +
   67.81 +    /* Xen's handler prototype is slightly different than Linux's.  */
   67.82 +    func = (void (*)(int, void *, struct cpu_user_regs *))handler;
   67.83 +
   67.84 +    action->handler = func;
   67.85 +    action->name = devname;
   67.86 +    action->dev_id = dev_id;
   67.87 +
   67.88 +    retval = setup_irq(irq, action);
   67.89 +    if (retval) {
   67.90 +        BUG();
   67.91 +        xfree(action);
   67.92 +    }
   67.93 +
   67.94 +    return retval;
   67.95 +}
   67.96 +
   67.97  struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
   67.98  {
   67.99      unsigned int isu_size;
  67.100 @@ -397,6 +434,11 @@ struct hw_interrupt_type *xen_mpic_init(
  67.101      hit = share_mpic(&mpic->hc_irq, xen_irq);
  67.102  
  67.103      printk("%s: success\n", __func__);
  67.104 +
  67.105 +    mpic->hc_ipi.ack = xen_irq->ack;
  67.106 +    mpic->hc_ipi.startup = mpic_startup_ipi;
  67.107 +    mpic_request_ipis();
  67.108 +
  67.109      return hit;
  67.110  }
  67.111  
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/xen/arch/powerpc/numa.c	Thu Dec 14 08:57:36 2006 -0700
    68.3 @@ -0,0 +1,1 @@
    68.4 +#include "../x86/numa.c"
    69.1 --- a/xen/arch/powerpc/of-devtree.h	Thu Dec 14 08:54:54 2006 -0700
    69.2 +++ b/xen/arch/powerpc/of-devtree.h	Thu Dec 14 08:57:36 2006 -0700
    69.3 @@ -33,15 +33,15 @@ enum {
    69.4  union of_pci_hi {
    69.5      u32 word;
    69.6      struct {
    69.7 -        u32	opa_n: 1; /* relocatable */
    69.8 -        u32	opa_p: 1; /* prefetchable */
    69.9 -        u32	opa_t: 1; /* aliased */
   69.10 +        u32 opa_n: 1; /* relocatable */
   69.11 +        u32 opa_p: 1; /* prefetchable */
   69.12 +        u32 opa_t: 1; /* aliased */
   69.13          u32 _opa_res: 3;
   69.14 -        u32	opa: 2; /* space code */
   69.15 +        u32 opa: 2; /* space code */
   69.16          u32  opa_b: 8; /* bus number */
   69.17 -        u32	opa_d: 5; /* device number */
   69.18 -        u32	opa_f: 3; /* function number */
   69.19 -        u32	opa_r: 8; /* register number */
   69.20 +        u32 opa_d: 5; /* device number */
   69.21 +        u32 opa_f: 3; /* function number */
   69.22 +        u32 opa_r: 8; /* register number */
   69.23      } bits;
   69.24  };
   69.25  
   69.26 @@ -79,9 +79,9 @@ struct reg_property32 {
   69.27  typedef s32 ofdn_t;
   69.28  
   69.29  #define OFD_ROOT 1
   69.30 -#define OFD_DUMP_NAMES	0x1
   69.31 -#define OFD_DUMP_VALUES	0x2
   69.32 -#define OFD_DUMP_ALL	(OFD_DUMP_VALUES|OFD_DUMP_NAMES)
   69.33 +#define OFD_DUMP_NAMES 0x1
   69.34 +#define OFD_DUMP_VALUES 0x2
   69.35 +#define OFD_DUMP_ALL (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
   69.36  
   69.37  extern void *ofd_create(void *mem, size_t sz);
   69.38  extern ofdn_t ofd_node_parent(void *mem, ofdn_t n);
   69.39 @@ -90,9 +90,9 @@ extern ofdn_t ofd_node_child(void *mem, 
   69.40  extern const char *ofd_node_path(void *mem, ofdn_t p);
   69.41  extern int ofd_node_to_path(void *mem, ofdn_t p, void *buf, size_t sz);
   69.42  extern ofdn_t ofd_node_child_create(void *mem, ofdn_t parent,
   69.43 -				    const char *path, size_t pathlen);
   69.44 +                                    const char *path, size_t pathlen);
   69.45  extern ofdn_t ofd_node_peer_create(void *mem, ofdn_t sibling,
   69.46 -				   const char *path, size_t pathlen);
   69.47 +                                   const char *path, size_t pathlen);
   69.48  extern ofdn_t ofd_node_find(void *mem, const char *devspec);
   69.49  extern ofdn_t ofd_node_add(void *m, ofdn_t n, const char *path, size_t sz);
   69.50  extern int ofd_node_prune(void *m, ofdn_t n);
   69.51 @@ -102,23 +102,23 @@ extern ofdn_t ofd_node_io(void *mem, ofd
   69.52  extern ofdn_t ofd_nextprop(void *mem, ofdn_t n, const char *prev, char *name);
   69.53  extern ofdn_t ofd_prop_find(void *mem, ofdn_t n, const char *name);
   69.54  extern int ofd_getprop(void *mem, ofdn_t n, const char *name,
   69.55 -			void *buf, size_t sz);
   69.56 +                       void *buf, size_t sz);
   69.57  extern int ofd_getproplen(void *mem, ofdn_t n, const char *name);
   69.58  
   69.59  extern int ofd_setprop(void *mem, ofdn_t n, const char *name,
   69.60 -			const void *buf, size_t sz);
   69.61 +                       const void *buf, size_t sz);
   69.62  extern void ofd_prop_remove(void *mem, ofdn_t node, ofdn_t prop);
   69.63  extern ofdn_t ofd_prop_add(void *mem, ofdn_t n, const char *name,
   69.64 -			   const void *buf, size_t sz);
   69.65 +                           const void *buf, size_t sz);
   69.66  extern ofdn_t ofd_io_create(void *m, ofdn_t node, u64 open);
   69.67  extern u32 ofd_io_open(void *mem, ofdn_t n);
   69.68  extern void ofd_io_close(void *mem, ofdn_t n);
   69.69  
   69.70  
   69.71 -typedef void (*walk_fn)(void *m, ofdn_t p, int arg);
   69.72 -extern void ofd_dump_props(void *m, ofdn_t p, int dump);
   69.73 +typedef void (*walk_fn)(void *m, const char *pre, ofdn_t p, int arg);
   69.74 +extern void ofd_dump_props(void *m, const char *pre, ofdn_t p, int dump);
   69.75  
   69.76 -extern void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg);
   69.77 +extern void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg);
   69.78  
   69.79  
   69.80  /* Recursively look up #address_cells and #size_cells properties */
   69.81 @@ -129,10 +129,10 @@ extern size_t ofd_size(void *mem);
   69.82  extern size_t ofd_space(void *mem);
   69.83  
   69.84  extern void ofd_prop_print(const char *head, const char *path,
   69.85 -			   const char *name, const char *prop, size_t sz);
   69.86 +                           const char *name, const char *prop, size_t sz);
   69.87  
   69.88  extern ofdn_t ofd_node_find_by_prop(void *mem, ofdn_t n, const char *name,
   69.89 -				    const void *val, size_t sz);
   69.90 +                                    const void *val, size_t sz);
   69.91  extern ofdn_t ofd_node_find_next(void *mem, ofdn_t n);
   69.92  extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n);
   69.93  extern void ofd_init(int (*write)(const char *, size_t len));
    70.1 --- a/xen/arch/powerpc/of-devwalk.c	Thu Dec 14 08:54:54 2006 -0700
    70.2 +++ b/xen/arch/powerpc/of-devwalk.c	Thu Dec 14 08:57:36 2006 -0700
    70.3 @@ -80,7 +80,7 @@ void ofd_prop_print(
    70.4  #endif
    70.5  }
    70.6  
    70.7 -void ofd_dump_props(void *mem, ofdn_t n, int dump)
    70.8 +void ofd_dump_props(void *mem, const char *pre, ofdn_t n, int dump)
    70.9  {
   70.10      ofdn_t p;
   70.11      char name[128];
   70.12 @@ -95,7 +95,7 @@ void ofd_dump_props(void *mem, ofdn_t n,
   70.13      }
   70.14  
   70.15      if (dump & OFD_DUMP_NAMES) {
   70.16 -        printk("of_walk: %s: phandle 0x%x\n", path, n);
   70.17 +        printk("%s: %s: phandle 0x%x\n", pre, path, n);
   70.18      }
   70.19  
   70.20      p = ofd_nextprop(mem, n, NULL, name);
   70.21 @@ -106,30 +106,30 @@ void ofd_dump_props(void *mem, ofdn_t n,
   70.22          }
   70.23  
   70.24          if ( dump & OFD_DUMP_VALUES ) {
   70.25 -            ofd_prop_print("of_walk", path, name, prop, sz);
   70.26 +            ofd_prop_print(pre, path, name, prop, sz);
   70.27          }
   70.28  
   70.29          p = ofd_nextprop(mem, n, name, name);
   70.30      }
   70.31  }
   70.32  
   70.33 -void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg)
   70.34 +void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg)
   70.35  {
   70.36      ofdn_t n;
   70.37  
   70.38      if ( fn != NULL ) {
   70.39 -        (*fn)(m, p, arg);
   70.40 +        (*fn)(m, pre, p, arg);
   70.41      }
   70.42  
   70.43      /* child */
   70.44      n = ofd_node_child(m, p);
   70.45      if ( n != 0 ) {
   70.46 -        ofd_walk(m, n, fn, arg);
   70.47 +        ofd_walk(m, pre, n, fn, arg);
   70.48      }
   70.49  
   70.50      /* peer */
   70.51      n = ofd_node_peer(m, p);
   70.52      if ( n != 0 ) {
   70.53 -        ofd_walk(m, n, fn, arg);
   70.54 +        ofd_walk(m, pre, n, fn, arg);
   70.55      }
   70.56  }
    71.1 --- a/xen/arch/powerpc/of_handler/console.c	Thu Dec 14 08:54:54 2006 -0700
    71.2 +++ b/xen/arch/powerpc/of_handler/console.c	Thu Dec 14 08:57:36 2006 -0700
    71.3 @@ -113,7 +113,7 @@ static s32 ofh_xen_dom0_read(s32 chan, v
    71.4              return ret;
    71.5  
    71.6          rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_read,
    71.7 -                count, desc);
    71.8 +                        count, desc);
    71.9          if (rc <= 0) {
   71.10              return ret;
   71.11          }
   71.12 @@ -139,7 +139,7 @@ static s32 ofh_xen_dom0_write(s32 chan, 
   71.13              return ret;
   71.14  
   71.15          rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_write,
   71.16 -                count, desc);
   71.17 +                        count, desc);
   71.18          if (rc <= 0) {
   71.19              return ret;
   71.20          }
   71.21 @@ -157,8 +157,8 @@ static s32 ofh_xen_dom0_write(s32 chan, 
   71.22  static s32 ofh_xen_domu_read(s32 chan, void *buf, u32 count, s32 *actual,
   71.23                               ulong b)
   71.24  {
   71.25 -	struct xencons_interface *intf;
   71.26 -	XENCONS_RING_IDX cons, prod;
   71.27 +    struct xencons_interface *intf;
   71.28 +    XENCONS_RING_IDX cons, prod;
   71.29      s32 ret;
   71.30  
   71.31      intf = DRELA(ofh_ihp, b)->ofi_intf;
   71.32 @@ -180,8 +180,8 @@ static s32 ofh_xen_domu_read(s32 chan, v
   71.33  static s32 ofh_xen_domu_write(s32 chan, const void *buf, u32 count,
   71.34                                s32 *actual, ulong b)
   71.35  {
   71.36 -	struct xencons_interface *intf;
   71.37 -	XENCONS_RING_IDX cons, prod;
   71.38 +    struct xencons_interface *intf;
   71.39 +    XENCONS_RING_IDX cons, prod;
   71.40      s32 ret;
   71.41  
   71.42      intf = DRELA(ofh_ihp, b)->ofi_intf;
    72.1 --- a/xen/arch/powerpc/ofd_fixup.c	Thu Dec 14 08:54:54 2006 -0700
    72.2 +++ b/xen/arch/powerpc/ofd_fixup.c	Thu Dec 14 08:57:36 2006 -0700
    72.3 @@ -25,6 +25,7 @@
    72.4  #include <public/xen.h>
    72.5  #include "of-devtree.h"
    72.6  #include "oftree.h"
    72.7 +#include "rtas.h"
    72.8  
    72.9  #undef RTAS
   72.10  
   72.11 @@ -347,6 +348,15 @@ static ofdn_t ofd_xen_props(void *m, str
   72.12          val[0] =  rma_size(d->arch.rma_order) - val[1];
   72.13          ofd_prop_add(m, n, "reserved", val, sizeof (val));
   72.14  
   72.15 +        /* tell dom0 that Xen depends on it to have power control */
   72.16 +        if (!rtas_entry)
   72.17 +            ofd_prop_add(m, n, "power-control", NULL, 0);
   72.18 +
   72.19 +        /* tell dom0 where ranted pages go in the linear map */
   72.20 +        val[0] = cpu_foreign_map_order();
   72.21 +        val[1] = d->arch.foreign_mfn_count;
   72.22 +        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
   72.23 +
   72.24          n = ofd_node_add(m, n, console, sizeof (console));
   72.25          if (n > 0) {
   72.26              val[0] = 0;
   72.27 @@ -417,7 +427,7 @@ int ofd_dom0_fixup(struct domain *d, ulo
   72.28  
   72.29  
   72.30  #ifdef DEBUG
   72.31 -    ofd_walk(m, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
   72.32 +    ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
   72.33  #endif
   72.34      return 1;
   72.35  }
    73.1 --- a/xen/arch/powerpc/ofd_fixup_memory.c	Thu Dec 14 08:54:54 2006 -0700
    73.2 +++ b/xen/arch/powerpc/ofd_fixup_memory.c	Thu Dec 14 08:57:36 2006 -0700
    73.3 @@ -68,6 +68,8 @@ static ofdn_t ofd_memory_node_create(
    73.4      reg.sz = size;
    73.5      ofd_prop_add(m, n, "reg", &reg, sizeof (reg));
    73.6  
    73.7 +    printk("Dom0: %s: %016lx, %016lx\n", path, start, size);
    73.8 +
    73.9      return n;
   73.10  }
   73.11  
   73.12 @@ -86,17 +88,19 @@ static void ofd_memory_extent_nodes(void
   73.13      ulong size;
   73.14      ofdn_t n;
   73.15      struct page_extents *pe;
   73.16 +    ulong cur_pfn = 1UL << d->arch.rma_order;
   73.17  
   73.18 +    start = cur_pfn << PAGE_SHIFT;
   73.19 +    size = 0;
   73.20      list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
   73.21  
   73.22 -        start = pe->pfn << PAGE_SHIFT;
   73.23 -        size = 1UL << (pe->order + PAGE_SHIFT);
   73.24 -
   73.25 -        n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
   73.26 -                                    start, size);
   73.27 -
   73.28 -        BUG_ON(n <= 0);
   73.29 +        size += 1UL << (pe->order + PAGE_SHIFT);
   73.30 +        if (pe->order != cpu_extent_order())
   73.31 +            panic("we don't handle this yet\n");
   73.32      }
   73.33 +    n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
   73.34 +                               start, size);
   73.35 +    BUG_ON(n <= 0);
   73.36  }
   73.37  
   73.38  void ofd_memory_props(void *m, struct domain *d)
    74.1 --- a/xen/arch/powerpc/papr/xlate.c	Thu Dec 14 08:54:54 2006 -0700
    74.2 +++ b/xen/arch/powerpc/papr/xlate.c	Thu Dec 14 08:57:36 2006 -0700
    74.3 @@ -19,7 +19,7 @@
    74.4   */
    74.5  
    74.6  #undef DEBUG
    74.7 -#undef DEBUG_FAIL
    74.8 +#undef DEBUG_LOW
    74.9  
   74.10  #include <xen/config.h>
   74.11  #include <xen/types.h>
   74.12 @@ -30,6 +30,17 @@
   74.13  #include <asm/papr.h>
   74.14  #include <asm/hcalls.h>
   74.15  
   74.16 +#ifdef DEBUG
   74.17 +#define DBG(fmt...) printk(fmt)
   74.18 +#else
   74.19 +#define DBG(fmt...)
   74.20 +#endif
   74.21 +#ifdef DEBUG_LOW
   74.22 +#define DBG_LOW(fmt...) printk(fmt)
   74.23 +#else
   74.24 +#define DBG_LOW(fmt...)
   74.25 +#endif
   74.26 +
   74.27  #ifdef USE_PTE_INSERT
   74.28  static inline void pte_insert(union pte volatile *pte,
   74.29          ulong vsid, ulong rpn, ulong lrpn)
   74.30 @@ -106,11 +117,8 @@ static void pte_tlbie(union pte volatile
   74.31  
   74.32  }
   74.33  
   74.34 -static void h_enter(struct cpu_user_regs *regs)
   74.35 +long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
   74.36  {
   74.37 -    ulong flags = regs->gprs[4];
   74.38 -    ulong ptex = regs->gprs[5];
   74.39 -
   74.40      union pte pte;
   74.41      union pte volatile *ppte;
   74.42      struct domain_htab *htab;
   74.43 @@ -129,14 +137,13 @@ static void h_enter(struct cpu_user_regs
   74.44  
   74.45      htab = &d->arch.htab;
   74.46      if (ptex > (1UL << htab->log_num_ptes)) {
   74.47 -        regs->gprs[3] = H_Parameter;
   74.48 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
   74.49 -        return;
   74.50 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
   74.51 +        return H_Parameter;
   74.52      }
   74.53  
   74.54      /* use local HPTE to avoid manual shifting & masking */
   74.55 -    pte.words.vsid = regs->gprs[6];
   74.56 -    pte.words.rpn = regs->gprs[7];
   74.57 +    pte.words.vsid = vsid;
   74.58 +    pte.words.rpn = rpn;
   74.59  
   74.60      if ( pte.bits.l ) {        /* large page? */
   74.61          /* figure out the page size for the selected large page */
   74.62 @@ -150,10 +157,9 @@ static void h_enter(struct cpu_user_regs
   74.63          }
   74.64  
   74.65          if ( lp_size >= d->arch.large_page_sizes ) {
   74.66 -            printk("%s: attempt to use unsupported lp_size %d\n",
   74.67 -                   __func__, lp_size);
   74.68 -            regs->gprs[3] = H_Parameter;
   74.69 -            return;
   74.70 +            DBG("%s: attempt to use unsupported lp_size %d\n",
   74.71 +                __func__, lp_size);
   74.72 +            return H_Parameter;
   74.73          }
   74.74  
   74.75          /* get correct pgshift value */
   74.76 @@ -168,32 +174,33 @@ static void h_enter(struct cpu_user_regs
   74.77  
   74.78      mfn = pfn2mfn(d, pfn, &mtype);
   74.79      if (mfn == INVALID_MFN) {
   74.80 -        regs->gprs[3] =  H_Parameter;
   74.81 -        return;
   74.82 +        DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn);
   74.83 +        return H_Parameter;
   74.84      }
   74.85  
   74.86 -    if (mtype == PFN_TYPE_IO) {
   74.87 +    if (mtype == PFN_TYPE_IO && !d->is_privileged) {
   74.88          /* only a privilaged dom can access outside IO space */
   74.89 -        if ( !d->is_privileged ) {
   74.90 -            regs->gprs[3] =  H_Privilege;
   74.91 -            printk("%s: unprivileged access to physical page: 0x%lx\n",
   74.92 -                   __func__, pfn);
   74.93 -            return;
   74.94 -        }
   74.95 -
   74.96 +        DBG("%s: unprivileged access to physical page: 0x%lx\n",
   74.97 +            __func__, pfn);
   74.98 +        return H_Privilege;
   74.99 +    }
  74.100 +    if (mtype == PFN_TYPE_IO) {
  74.101          if ( !((pte.bits.w == 0)
  74.102               && (pte.bits.i == 1)
  74.103               && (pte.bits.g == 1)) ) {
  74.104 -#ifdef DEBUG_FAIL
  74.105 -            printk("%s: expecting an IO WIMG "
  74.106 -                   "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
  74.107 -                   pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
  74.108 -                   pte.words.rpn);
  74.109 -#endif
  74.110 -            regs->gprs[3] =  H_Parameter;
  74.111 -            return;
  74.112 +            DBG("%s: expecting an IO WIMG "
  74.113 +                "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
  74.114 +                pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
  74.115 +                pte.words.rpn);
  74.116 +            return H_Parameter;
  74.117          }
  74.118      }
  74.119 +    if (mtype == PFN_TYPE_GNTTAB) {
  74.120 +        DBG("%s: Dom[%d] mapping grant table: 0x%lx\n",
  74.121 +            __func__, d->domain_id, pfn << PAGE_SHIFT);
  74.122 +        pte.bits.i = 0;
  74.123 +        pte.bits.g = 0;
  74.124 +    }
  74.125      /* fixup the RPN field of our local PTE copy */
  74.126      pte.bits.rpn = mfn | lp_bits;
  74.127  
  74.128 @@ -213,13 +220,13 @@ static void h_enter(struct cpu_user_regs
  74.129          BUG_ON(f == d);
  74.130  
  74.131          if (unlikely(!get_domain(f))) {
  74.132 -            regs->gprs[3] = H_Rescinded;
  74.133 -            return;
  74.134 +            DBG("%s: Rescinded, no domain: 0x%lx\n",  __func__, pfn);
  74.135 +            return H_Rescinded;
  74.136          }
  74.137          if (unlikely(!get_page(pg, f))) {
  74.138              put_domain(f);
  74.139 -            regs->gprs[3] = H_Rescinded;
  74.140 -            return;
  74.141 +            DBG("%s: Rescinded, no page: 0x%lx\n",  __func__, pfn);
  74.142 +            return H_Rescinded;
  74.143          }
  74.144      }
  74.145  
  74.146 @@ -276,17 +283,12 @@ static void h_enter(struct cpu_user_regs
  74.147                  : "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid)
  74.148                  : "memory");
  74.149  
  74.150 -            regs->gprs[3] = H_Success;
  74.151 -            regs->gprs[4] = idx;
  74.152 -
  74.153 -            return;
  74.154 +            return idx;
  74.155          }
  74.156      }
  74.157  
  74.158 -#ifdef DEBUG
  74.159      /* If the PTEG is full then no additional values are returned. */
  74.160 -    printk("%s: PTEG FULL\n", __func__);
  74.161 -#endif
  74.162 +    DBG("%s: PTEG FULL\n", __func__);
  74.163  
  74.164      if (pg != NULL)
  74.165          put_page(pg);
  74.166 @@ -294,7 +296,24 @@ static void h_enter(struct cpu_user_regs
  74.167      if (f != NULL)
  74.168          put_domain(f);
  74.169  
  74.170 -    regs->gprs[3] = H_PTEG_Full;
  74.171 +    return H_PTEG_Full;
  74.172 +}
  74.173 +
  74.174 +static void h_enter(struct cpu_user_regs *regs)
  74.175 +{
  74.176 +    ulong flags = regs->gprs[4];
  74.177 +    ulong ptex = regs->gprs[5];
  74.178 +    ulong vsid = regs->gprs[6];
  74.179 +    ulong rpn = regs->gprs[7];
  74.180 +    long ret;
  74.181 +
  74.182 +    ret = pte_enter(flags, ptex, vsid, rpn);
  74.183 +
  74.184 +    if (ret >= 0) {
  74.185 +        regs->gprs[3] = H_Success;
  74.186 +        regs->gprs[4] = ret;
  74.187 +    } else
  74.188 +        regs->gprs[3] = ret;
  74.189  }
  74.190  
  74.191  static void h_protect(struct cpu_user_regs *regs)
  74.192 @@ -308,13 +327,11 @@ static void h_protect(struct cpu_user_re
  74.193      union pte volatile *ppte;
  74.194      union pte lpte;
  74.195  
  74.196 -#ifdef DEBUG
  74.197 -    printk("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
  74.198 -           flags, ptex, avpn);
  74.199 -#endif
  74.200 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
  74.201 +            flags, ptex, avpn);
  74.202      if ( ptex > (1UL << htab->log_num_ptes) ) {
  74.203 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.204          regs->gprs[3] = H_Parameter;
  74.205 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.206          return;
  74.207      }
  74.208      ppte = &htab->map[ptex];
  74.209 @@ -324,10 +341,8 @@ static void h_protect(struct cpu_user_re
  74.210  
  74.211      /* the AVPN param occupies the bit-space of the word */
  74.212      if ( (flags & H_AVPN) && lpte.bits.avpn != avpn >> 7 ) {
  74.213 -#ifdef DEBUG_FAIL
  74.214 -        printk("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
  74.215 -                ppte, lpte.words.vsid, lpte.words.rpn);
  74.216 -#endif
  74.217 +        DBG_LOW("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
  74.218 +            ppte, lpte.words.vsid, lpte.words.rpn);
  74.219          regs->gprs[3] = H_Not_Found;
  74.220          return;
  74.221      }
  74.222 @@ -337,9 +352,7 @@ static void h_protect(struct cpu_user_re
  74.223           * we invalidate entires where the PAPR says to 0 the whole hi
  74.224           * dword, so the AVPN should catch this first */
  74.225  
  74.226 -#ifdef DEBUG_FAIL
  74.227 -        printk("%s: pte invalid\n", __func__);
  74.228 -#endif
  74.229 +        DBG("%s: pte invalid\n", __func__);
  74.230          regs->gprs[3] =  H_Not_Found;
  74.231          return;
  74.232      }
  74.233 @@ -374,7 +387,6 @@ static void h_protect(struct cpu_user_re
  74.234  
  74.235  static void h_clear_ref(struct cpu_user_regs *regs)
  74.236  {
  74.237 -    ulong flags = regs->gprs[4];
  74.238      ulong ptex = regs->gprs[5];
  74.239      struct vcpu *v = get_current();
  74.240      struct domain *d = v->domain;
  74.241 @@ -382,20 +394,20 @@ static void h_clear_ref(struct cpu_user_
  74.242      union pte volatile *pte;
  74.243      union pte lpte;
  74.244  
  74.245 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
  74.246 +            regs->gprs[4], ptex);
  74.247 +
  74.248  #ifdef DEBUG
  74.249 -    printk("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
  74.250 -           flags, ptex);
  74.251 +    if (regs->gprs[4] != 0) {
  74.252 +        DBG("WARNING: %s: "
  74.253 +            "flags are undefined and should be 0: 0x%lx\n",
  74.254 +            __func__, regs->gprs[4]);
  74.255 +    }
  74.256  #endif
  74.257  
  74.258 -    if (flags != 0) {
  74.259 -        printk("WARNING: %s: "
  74.260 -                "flags are undefined and should be 0: 0x%lx\n",
  74.261 -                __func__, flags);
  74.262 -    }
  74.263 -
  74.264      if (ptex > (1UL << htab->log_num_ptes)) {
  74.265 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.266          regs->gprs[3] = H_Parameter;
  74.267 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.268          return;
  74.269      }
  74.270      pte = &htab->map[ptex];
  74.271 @@ -417,7 +429,6 @@ static void h_clear_ref(struct cpu_user_
  74.272  
  74.273  static void h_clear_mod(struct cpu_user_regs *regs)
  74.274  {
  74.275 -    ulong flags = regs->gprs[4];
  74.276      ulong ptex = regs->gprs[5];
  74.277      struct vcpu *v = get_current();
  74.278      struct domain *d = v->domain;
  74.279 @@ -425,19 +436,20 @@ static void h_clear_mod(struct cpu_user_
  74.280      union pte volatile *pte;
  74.281      union pte lpte;
  74.282  
  74.283 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
  74.284 +          regs->gprs[4], ptex);
  74.285 +
  74.286  #ifdef DEBUG
  74.287 -    printk("%s: flags: 0x%lx ptex: 0x%lx\n", __func__,
  74.288 -           flags, ptex);
  74.289 +    if (regs->gprs[4] != 0) {
  74.290 +        DBG("WARNING: %s: "
  74.291 +            "flags are undefined and should be 0: 0x%lx\n",
  74.292 +            __func__, regs->gprs[4]);
  74.293 +    }
  74.294  #endif
  74.295 -    if (flags != 0) {
  74.296 -        printk("WARNING: %s: "
  74.297 -                "flags are undefined and should be 0: 0x%lx\n",
  74.298 -                __func__, flags);
  74.299 -    }
  74.300 -    
  74.301 +
  74.302      if (ptex > (1UL << htab->log_num_ptes)) {
  74.303 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.304          regs->gprs[3] = H_Parameter;
  74.305 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.306          return;
  74.307      }
  74.308      pte = &htab->map[ptex];
  74.309 @@ -466,63 +478,53 @@ static void h_clear_mod(struct cpu_user_
  74.310      }
  74.311  }
  74.312  
  74.313 -static void h_remove(struct cpu_user_regs *regs)
  74.314 +long pte_remove(ulong flags, ulong ptex, ulong avpn, ulong *hi, ulong *lo)
  74.315  {
  74.316 -    ulong flags = regs->gprs[4];
  74.317 -    ulong ptex = regs->gprs[5];
  74.318 -    ulong avpn = regs->gprs[6];
  74.319      struct vcpu *v = get_current();
  74.320      struct domain *d = v->domain;
  74.321      struct domain_htab *htab = &d->arch.htab;
  74.322      union pte volatile *pte;
  74.323      union pte lpte;
  74.324  
  74.325 -#ifdef DEBUG
  74.326 -    printk("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
  74.327 -           flags, ptex, avpn);
  74.328 -#endif
  74.329 +    DBG_LOW("%s: flags: 0x%lx ptex: 0x%lx avpn: 0x%lx\n", __func__,
  74.330 +            flags, ptex, avpn);
  74.331 +
  74.332      if ( ptex > (1UL << htab->log_num_ptes) ) {
  74.333 -        regs->gprs[3] = H_Parameter;
  74.334 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.335 -        return;
  74.336 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.337 +        return H_Parameter;
  74.338      }
  74.339      pte = &htab->map[ptex];
  74.340      lpte.words.vsid = pte->words.vsid;
  74.341      lpte.words.rpn = pte->words.rpn;
  74.342  
  74.343      if ((flags & H_AVPN) && lpte.bits.avpn != (avpn >> 7)) {
  74.344 -#ifdef DEBUG_FAIL
  74.345 -        printk("%s: avpn doesn not match\n", __func__);
  74.346 -#endif
  74.347 -        regs->gprs[3] = H_Not_Found;
  74.348 -        return;
  74.349 +        DBG_LOW("%s: AVPN does not match\n", __func__);
  74.350 +        return H_Not_Found;
  74.351      }
  74.352  
  74.353      if ((flags & H_ANDCOND) && ((avpn & pte->words.vsid) != 0)) {
  74.354 -#ifdef DEBUG_FAIL
  74.355 -        printk("%s: andcond does not match\n", __func__);
  74.356 -#endif
  74.357 -        regs->gprs[3] = H_Not_Found;
  74.358 -        return;
  74.359 +        DBG("%s: andcond does not match\n", __func__);
  74.360 +        return H_Not_Found;
  74.361      }
  74.362  
  74.363 -    regs->gprs[3] = H_Success;
  74.364      /* return old PTE in regs 4 and 5 */
  74.365 -    regs->gprs[4] = lpte.words.vsid;
  74.366 -    regs->gprs[5] = lpte.words.rpn;
  74.367 +    *hi = lpte.words.vsid;
  74.368 +    *lo = lpte.words.rpn;
  74.369  
  74.370 +#ifdef DEBUG_LOW
  74.371      /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */
  74.372      /* XXX - I think the spec should be questioned in this case (MFM) */
  74.373      if (lpte.bits.v == 0) {
  74.374 -        printk("%s: removing invalid entry\n", __func__);
  74.375 +        DBG_LOW("%s: removing invalid entry\n", __func__);
  74.376      }
  74.377 +#endif
  74.378  
  74.379      if (lpte.bits.v) {
  74.380          ulong mfn = lpte.bits.rpn;
  74.381          if (!cpu_io_mfn(mfn)) {
  74.382              struct page_info *pg = mfn_to_page(mfn);
  74.383              struct domain *f = page_get_owner(pg);
  74.384 -
  74.385 +            
  74.386              if (f != d) {
  74.387                  put_domain(f);
  74.388                  put_page(pg);
  74.389 @@ -536,6 +538,27 @@ static void h_remove(struct cpu_user_reg
  74.390              : "memory");
  74.391  
  74.392      pte_tlbie(&lpte, ptex);
  74.393 +
  74.394 +    return H_Success;
  74.395 +}
  74.396 +
  74.397 +static void h_remove(struct cpu_user_regs *regs)
  74.398 +{
  74.399 +    ulong flags = regs->gprs[4];
  74.400 +    ulong ptex = regs->gprs[5];
  74.401 +    ulong avpn = regs->gprs[6];
  74.402 +    ulong hi, lo;
  74.403 +    long ret;
  74.404 +
  74.405 +    ret = pte_remove(flags, ptex, avpn, &hi, &lo);
  74.406 +
  74.407 +    regs->gprs[3] = ret;
  74.408 +
  74.409 +    if (ret == H_Success) {
  74.410 +        regs->gprs[4] = hi;
  74.411 +        regs->gprs[5] = lo;
  74.412 +    }
  74.413 +    return;
  74.414  }
  74.415  
  74.416  static void h_read(struct cpu_user_regs *regs)
  74.417 @@ -547,12 +570,12 @@ static void h_read(struct cpu_user_regs 
  74.418      struct domain_htab *htab = &d->arch.htab;
  74.419      union pte volatile *pte;
  74.420  
  74.421 -	if (flags & H_READ_4)
  74.422 +    if (flags & H_READ_4)
  74.423          ptex &= ~0x3UL;
  74.424  
  74.425      if (ptex > (1UL << htab->log_num_ptes)) {
  74.426 +        DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.427          regs->gprs[3] = H_Parameter;
  74.428 -        printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
  74.429          return;
  74.430      }
  74.431      pte = &htab->map[ptex];
    75.1 --- a/xen/arch/powerpc/powerpc64/exceptions.S	Thu Dec 14 08:54:54 2006 -0700
    75.2 +++ b/xen/arch/powerpc/powerpc64/exceptions.S	Thu Dec 14 08:57:36 2006 -0700
    75.3 @@ -564,6 +564,22 @@ 1:
    75.4   */	
    75.5      .globl spin_start
    75.6  spin_start:
    75.7 +    /* We discovered by experiment that the ERAT must be flushed early.  */
    75.8 +    isync
    75.9 +    slbia
   75.10 +    isync
   75.11 +	
   75.12 +    /* Do a cache flush for our text, in case the loader didn't */
   75.13 +    LOADADDR(r9, _start)
   75.14 +    LOADADDR(r8, _etext)
   75.15 +4:  dcbf r0,r9
   75.16 +    icbi r0,r9
   75.17 +    addi r9,r9,0x20		/* up to a 4 way set per line */
   75.18 +    cmpld cr0,r9,r8
   75.19 +    blt	4b
   75.20 +    sync
   75.21 +    isync
   75.22 +
   75.23      /* Write our processor number as an acknowledgment that we're alive.  */
   75.24      LOADADDR(r14, __spin_ack)
   75.25      stw r3, 0(r14)
   75.26 @@ -575,7 +591,7 @@ spin_start:
   75.27      b .
   75.28      /* Find our index in the array of processor_area struct pointers.  */
   75.29  2:  LOADADDR(r14, global_cpu_table)
   75.30 -    muli r15, r3, 8
   75.31 +    mulli r15, r3, 8
   75.32      add r14, r14, r15
   75.33      /* Spin until the pointer for our processor goes valid.  */
   75.34  1:  ld r15, 0(r14)
    76.1 --- a/xen/arch/powerpc/powerpc64/io.S	Thu Dec 14 08:54:54 2006 -0700
    76.2 +++ b/xen/arch/powerpc/powerpc64/io.S	Thu Dec 14 08:57:36 2006 -0700
    76.3 @@ -23,6 +23,11 @@
    76.4  #include <asm/processor.h>
    76.5  #include <asm/percpu.h>
    76.6  
    76.7 +/* There is no reason why I can't use a tlbie, which should be less
    76.8 + * "destructive" but useing SLBIE proves to be more stable result.
    76.9 + */
   76.10 +#define INVALIDATE_ERAT_WITH_SLBIE
   76.11 +
   76.12  /* Xen runs in real mode (i.e. untranslated, MMU disabled). This avoids TLB
   76.13   * flushes and also makes it easy to access all domains' memory. However, on
   76.14   * PowerPC real mode accesses are cacheable, which is good for general
   76.15 @@ -34,12 +39,14 @@
   76.16   * make the access, then re-enable it...
   76.17   */
   76.18  
   76.19 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
   76.20  /* Not all useful assemblers understand 'tlbiel'.
   76.21   * 'addr' is a GPR containing the address being accessed.
   76.22   */
   76.23  .macro tlbiel addr
   76.24  	.long 0x7c000224 | (\addr << 11)
   76.25  .endm
   76.26 +#endif
   76.27  
   76.28  .macro DISABLE_DCACHE addr
   76.29  	mfmsr r8
   76.30 @@ -48,29 +55,53 @@
   76.31  	ori r6, r6, MSR_EE
   76.32  	andc r5, r8, r6
   76.33  	mtmsr r5
   76.34 +	sync
   76.35  
   76.36 -	/* set HID4.RM_CI */
   76.37 +#ifdef INVALIDATE_ERAT_WITH_SLBIE 
   76.38 +	/* create an slbie entry for the io setting a high order bit
   76.39 +	 * to avoid any important SLBs */
   76.40 +	extldi r0, \addr, 36, 0 
   76.41 +#endif
   76.42 +	/* setup HID4.RM_CI */
   76.43  	mfspr r9, SPRN_HID4
   76.44  	li r6, 0x100
   76.45  	sldi r6, r6, 32
   76.46 -	or r5, r9, r6
   76.47 -	tlbiel \addr /* invalidate the ERAT entry */
   76.48 -	sync
   76.49 -	mtspr SPRN_HID4, r5
   76.50 +	or r10, r9, r6
   76.51 +
   76.52 +	/* Mark the processor as "in CI mode" */
   76.53 +	li r7,0
   76.54 +	mfspr r5, SPRN_PIR
   76.55 +	li r6, MCK_CPU_STAT_CI
   76.56 +	/* store that we are in a CI routine */
   76.57 +	stb r6, MCK_CPU_STAT_BASE(r5)
   76.58 +	/* r7 = MCK_CPU_STAT_CI IO in progress */
   76.59 +	mr r7, r5
   76.60 +	lwsync
   76.61 +
   76.62 +	/* switch modes */
   76.63 +	mtspr SPRN_HID4, r10
   76.64 +	/* invalidate the ERAT entry */
   76.65 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
   76.66 +	slbie r0
   76.67 +#else
   76.68 +	tlbiel \addr
   76.69 +#endif
   76.70  	isync
   76.71  
   76.72 -	/* Mark the processor as "in CI mode" */
   76.73 -	mfspr r5, SPRN_PIR
   76.74 -	li r6, MCK_CPU_STAT_CI
   76.75 -	stb r6, MCK_CPU_STAT_BASE(r5)
   76.76 -	sync
   76.77  .endm
   76.78  
   76.79  .macro ENABLE_DCACHE addr
   76.80 -	/* re-zero HID4.RM_CI */
   76.81 +	/* r7 = 0, IO is complete */
   76.82 +	li r7, 0
   76.83 +	lwsync
   76.84 +	/* restore HID4.RM_CI */
   76.85 +	mtspr SPRN_HID4, r9
   76.86 +	/* invalidate the ERAT entry */
   76.87 +#ifdef INVALIDATE_ERAT_WITH_SLBIE
   76.88 +	slbie r0
   76.89 +#else
   76.90  	tlbiel \addr /* invalidate the ERAT entry */
   76.91 -	sync
   76.92 -	mtspr SPRN_HID4, r9
   76.93 +#endif
   76.94  	isync
   76.95  
   76.96  	/* Mark the processor as "out of CI mode" */
   76.97 @@ -83,9 +114,13 @@
   76.98  	mtmsr r8
   76.99  .endm
  76.100  
  76.101 -/* The following assembly cannot use r8 or r9 since they hold original
  76.102 - * values of msr and hid4 repectively
  76.103 +/* The following assembly cannot use some registers since they hold original
  76.104 + * values of we need to keep
  76.105   */
  76.106 +#undef r0
  76.107 +#define r0 do_not_use_r0
  76.108 +#undef r7
  76.109 +#define r7 do_not_use_r7
  76.110  #undef r8
  76.111  #define r8 do_not_use_r8
  76.112  #undef r9
    77.1 --- a/xen/arch/powerpc/powerpc64/ppc970.c	Thu Dec 14 08:54:54 2006 -0700
    77.2 +++ b/xen/arch/powerpc/powerpc64/ppc970.c	Thu Dec 14 08:57:36 2006 -0700
    77.3 @@ -30,6 +30,7 @@
    77.4  #include <asm/powerpc64/procarea.h>
    77.5  #include <asm/powerpc64/processor.h>
    77.6  #include <asm/powerpc64/ppc970-hid.h>
    77.7 +#include "scom.h"
    77.8  
    77.9  #undef DEBUG
   77.10  #undef SERIALIZE
   77.11 @@ -38,48 +39,77 @@ struct cpu_caches cpu_caches = {
   77.12      .dline_size = 0x80,
   77.13      .log_dline_size = 7,
   77.14      .dlines_per_page = PAGE_SIZE >> 7,
   77.15 +    .isize = (64 << 10),        /* 64 KiB */
   77.16      .iline_size = 0x80,
   77.17      .log_iline_size = 7,
   77.18      .ilines_per_page = PAGE_SIZE >> 7,
   77.19  };
   77.20  
   77.21 +
   77.22 +void cpu_flush_icache(void)
   77.23 +{
   77.24 +    union hid1 hid1;
   77.25 +    ulong flags;
   77.26 +    ulong ea;
   77.27 +
   77.28 +    local_irq_save(flags);
   77.29 +
   77.30 +    /* uses special processor mode that forces a real address match on
   77.31 +     * the whole line */
   77.32 +    hid1.word = mfhid1();
   77.33 +    hid1.bits.en_icbi = 1;
   77.34 +    mthid1(hid1.word);
   77.35 +
   77.36 +    for (ea = 0; ea < cpu_caches.isize; ea += cpu_caches.iline_size)
   77.37 +        icbi(ea);
   77.38 +
   77.39 +    sync();
   77.40 +
   77.41 +    hid1.bits.en_icbi = 0;
   77.42 +    mthid1(hid1.word);
   77.43 +
   77.44 +    local_irq_restore(flags);
   77.45 +}
   77.46 +
   77.47 +
   77.48  struct rma_settings {
   77.49 -    int order;
   77.50 +    int log;
   77.51      int rmlr_0;
   77.52      int rmlr_1_2;
   77.53  };
   77.54  
   77.55 -static struct rma_settings rma_orders[] = {
   77.56 -    { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */
   77.57 -    { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
   77.58 -    { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
   77.59 -    { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */
   77.60 -    { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */
   77.61 -    { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
   77.62 +static struct rma_settings rma_logs[] = {
   77.63 +    { .log = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */
   77.64 +    { .log = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
   77.65 +    { .log = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
   77.66 +    { .log = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */
   77.67 +    { .log = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */
   77.68 +    { .log = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
   77.69  };
   77.70  
   77.71  static uint log_large_page_sizes[] = {
   77.72      4 + 20, /* (1 << 4) == 16M */
   77.73  };
   77.74  
   77.75 -static struct rma_settings *cpu_find_rma(unsigned int order)
   77.76 +static struct rma_settings *cpu_find_rma(unsigned int log)
   77.77  {
   77.78      int i;
   77.79 -    for (i = 0; i < ARRAY_SIZE(rma_orders); i++) {
   77.80 -        if (rma_orders[i].order == order)
   77.81 -            return &rma_orders[i];
   77.82 +
   77.83 +    for (i = 0; i < ARRAY_SIZE(rma_logs); i++) {
   77.84 +        if (rma_logs[i].log == log)
   77.85 +            return &rma_logs[i];
   77.86      }
   77.87      return NULL;
   77.88  }
   77.89  
   77.90  unsigned int cpu_default_rma_order_pages(void)
   77.91  {
   77.92 -    return rma_orders[0].order - PAGE_SHIFT;
   77.93 +    return rma_logs[0].log - PAGE_SHIFT;
   77.94  }
   77.95  
   77.96 -int cpu_rma_valid(unsigned int log)
   77.97 +int cpu_rma_valid(unsigned int order)
   77.98  {
   77.99 -    return cpu_find_rma(log) != NULL;
  77.100 +    return cpu_find_rma(order + PAGE_SHIFT) != NULL;
  77.101  }
  77.102  
  77.103  unsigned int cpu_large_page_orders(uint *sizes, uint max)
  77.104 @@ -163,8 +193,11 @@ void cpu_initialize(int cpuid)
  77.105      mtdec(timebase_freq);
  77.106      mthdec(timebase_freq);
  77.107  
  77.108 -    hid0.bits.nap = 1;      /* NAP */
  77.109 +    /* FIXME Do not set the NAP bit in HID0 until we have had a chance
  77.110 +     * to audit the safe halt and idle loop code. */
  77.111 +    hid0.bits.nap = 0;      /* NAP */
  77.112      hid0.bits.dpm = 1;      /* Dynamic Power Management */
  77.113 +
  77.114      hid0.bits.nhr = 1;      /* Not Hard Reset */
  77.115      hid0.bits.hdice_en = 1; /* enable HDEC */
  77.116      hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */
    78.1 --- a/xen/arch/powerpc/powerpc64/ppc970_machinecheck.c	Thu Dec 14 08:54:54 2006 -0700
    78.2 +++ b/xen/arch/powerpc/powerpc64/ppc970_machinecheck.c	Thu Dec 14 08:57:36 2006 -0700
    78.3 @@ -24,6 +24,8 @@
    78.4  #include <public/xen.h>
    78.5  #include <asm/processor.h>
    78.6  #include <asm/percpu.h>
    78.7 +#include <asm/debugger.h>
    78.8 +#include "scom.h"
    78.9  
   78.10  #define MCK_SRR1_INSN_FETCH_UNIT    0x0000000000200000 /* 42 */
   78.11  #define MCK_SRR1_LOAD_STORE         0x0000000000100000 /* 43 */
   78.12 @@ -54,6 +56,8 @@ int cpu_machinecheck(struct cpu_user_reg
   78.13      if (mck_cpu_stats[mfpir()] != 0)
   78.14          printk("While in CI IO\n");
   78.15  
   78.16 +    show_backtrace_regs(regs);
   78.17 +
   78.18      printk("SRR1: 0x%016lx\n", regs->msr);
   78.19      if (regs->msr & MCK_SRR1_INSN_FETCH_UNIT)
   78.20          printk("42: Exception caused by Instruction Fetch Unit (IFU)\n"
   78.21 @@ -67,6 +71,7 @@ int cpu_machinecheck(struct cpu_user_reg
   78.22      case 0:
   78.23          printk("0b00: Likely caused by an asynchronous machine check,\n"
   78.24                 "      see SCOM Asynchronous Machine Check Register\n");
   78.25 +        cpu_scom_AMCR();
   78.26          break;
   78.27      case MCK_SRR1_CAUSE_SLB_PAR:
   78.28          printk("0b01: Exception caused by an SLB parity error detected\n"
   78.29 @@ -116,5 +121,5 @@ int cpu_machinecheck(struct cpu_user_reg
   78.30          dump_segments(0);
   78.31      }
   78.32  
   78.33 -    return 0; /* for now lets not recover; */
   78.34 +    return 0; /* for now lets not recover */
   78.35  }
    79.1 --- a/xen/arch/powerpc/powerpc64/ppc970_scom.c	Thu Dec 14 08:54:54 2006 -0700
    79.2 +++ b/xen/arch/powerpc/powerpc64/ppc970_scom.c	Thu Dec 14 08:57:36 2006 -0700
    79.3 @@ -22,33 +22,17 @@
    79.4  #include <xen/types.h>
    79.5  #include <xen/lib.h>
    79.6  #include <xen/console.h>
    79.7 +#include <xen/errno.h>
    79.8 +#include <asm/delay.h>
    79.9 +#include <asm/processor.h>
   79.10 +#include "scom.h"
   79.11 +
   79.12 +#undef CONFIG_SCOM
   79.13  
   79.14  #define SPRN_SCOMC 276
   79.15  #define SPRN_SCOMD 277
   79.16 -
   79.17 -static inline void mtscomc(ulong scomc)
   79.18 -{
   79.19 -    __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomc), "i"(SPRN_SCOMC));
   79.20 -}
   79.21 -
   79.22 -static inline ulong mfscomc(void)
   79.23 -{
   79.24 -    ulong scomc;
   79.25 -    __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomc): "i"(SPRN_SCOMC));
   79.26 -    return scomc;
   79.27 -}
   79.28 -
   79.29 -static inline void mtscomd(ulong scomd)
   79.30 -{
   79.31 -    __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomd), "i"(SPRN_SCOMD));
   79.32 -}
   79.33 -
   79.34 -static inline ulong mfscomd(void)
   79.35 -{
   79.36 -    ulong scomd;
   79.37 -    __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomd): "i"(SPRN_SCOMD));
   79.38 -    return scomd;
   79.39 -}
   79.40 +#define SCOMC_READ 1
   79.41 +#define SCOMC_WRITE (!(SCOMC_READ))
   79.42  
   79.43  union scomc {
   79.44      struct scomc_bits {
   79.45 @@ -68,50 +52,133 @@ union scomc {
   79.46  };
   79.47  
   79.48  
   79.49 -static inline ulong read_scom(ulong addr)
   79.50 +int cpu_scom_read(uint addr, ulong *d)
   79.51  {
   79.52      union scomc c;
   79.53 -    ulong d;
   79.54 +    ulong flags;
   79.55 +
   79.56 +    /* drop the low 8bits (including parity) */
   79.57 +    addr >>= 8;
   79.58  
   79.59 -    c.word = 0;
   79.60 -    c.bits.addr = addr;
   79.61 -    c.bits.RW = 0;
   79.62 +    /* these give iface errors because the addresses are not software
   79.63 +     * accessible */
   79.64 +    BUG_ON(addr & 0x8000);
   79.65 +
   79.66 +    for (;;) {
   79.67 +        c.word = 0;
   79.68 +        c.bits.addr = addr;
   79.69 +        c.bits.RW = SCOMC_READ;
   79.70  
   79.71 -    mtscomc(c.word);
   79.72 -    d = mfscomd();
   79.73 -    c.word = mfscomc();
   79.74 -    if (c.bits.failure)
   79.75 -        panic("scom status: 0x%016lx\n", c.word);
   79.76 +        local_irq_save(flags);
   79.77 +        asm volatile (
   79.78 +            "sync         \n\t"
   79.79 +            "mtspr %2, %0 \n\t"
   79.80 +            "isync        \n\t"
   79.81 +            "mfspr %1, %3 \n\t"
   79.82 +            "isync        \n\t"
   79.83 +            "mfspr %0, %2 \n\t"
   79.84 +            "isync        \n\t"
   79.85 +            : "+r" (c.word), "=r" (*d)
   79.86 +            : "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
   79.87 +
   79.88 +        local_irq_restore(flags);
   79.89 +        /* WARNING! older 970s (pre FX) shift the bits right 1 position */
   79.90  
   79.91 -    return d;
   79.92 +        if (!c.bits.failure)
   79.93 +            return 0;
   79.94 +
   79.95 +        /* deal with errors */
   79.96 +        /* has SCOM been disabled? */
   79.97 +        if (c.bits.disabled)
   79.98 +            return -ENOSYS;
   79.99 +
  79.100 +        /* we were passed a bad addr return -1 */
  79.101 +        if (c.bits.addr_error)
  79.102 +            return -EINVAL;
  79.103 +
  79.104 +        /* this is way bad and we will checkstop soon */
  79.105 +        BUG_ON(c.bits.proto_error);
  79.106 +
  79.107 +        if (c.bits.iface_error)
  79.108 +            udelay(10);
  79.109 +    }
  79.110  }
  79.111  
  79.112 -static inline void write_scom(ulong addr, ulong val)
  79.113 +int cpu_scom_write(uint addr, ulong d)
  79.114  {
  79.115      union scomc c;
  79.116 +    ulong flags;
  79.117  
  79.118 -    c.word = 0;
  79.119 -    c.bits.addr = addr;
  79.120 -    c.bits.RW = 1;
  79.121 +    /* drop the low 8bits (including parity) */
  79.122 +    addr >>= 8;
  79.123 +
  79.124 +    /* these give iface errors because the addresses are not software
  79.125 +     * accessible */
  79.126 +    BUG_ON(addr & 0x8000);
  79.127 +
  79.128 +    for (;;) {
  79.129 +        c.word = 0;
  79.130 +        c.bits.addr = addr;
  79.131 +        c.bits.RW = SCOMC_WRITE;
  79.132  
  79.133 -    mtscomd(val);
  79.134 -    mtscomc(c.word);
  79.135 -    c.word = mfscomc();
  79.136 -    if (c.bits.failure)
  79.137 -        panic("scom status: 0x%016lx\n", c.word);
  79.138 +        local_irq_save(flags);
  79.139 +        asm volatile(
  79.140 +            "sync         \n\t"
  79.141 +            "mtspr %3, %1 \n\t"
  79.142 +            "isync        \n\t"
  79.143 +            "mtspr %2, %0 \n\t"
  79.144 +            "isync        \n\t"
  79.145 +            "mfspr %0, %2 \n\t"
  79.146 +            "isync        \n\t"
  79.147 +            : "+r" (c.word)
  79.148 +            : "r" (d), "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
  79.149 +        local_irq_restore(flags);
  79.150 +
  79.151 +        if (!c.bits.failure)
  79.152 +            return 0;
  79.153 +
  79.154 +        /* has SCOM been disabled? */
  79.155 +        if (c.bits.disabled)
  79.156 +            return -ENOSYS;
  79.157 +
  79.158 +        /* we were passed a bad addr return -1 */
  79.159 +        if (c.bits.addr_error)
  79.160 +            return -EINVAL;
  79.161 +
  79.162 +        /* this is way bad and we will checkstop soon */
  79.163 +        BUG_ON(c.bits.proto_error);
  79.164 +
  79.165 +        /* check for iface and retry */
  79.166 +        if (c.bits.iface_error)
  79.167 +            udelay(10);
  79.168 +    }
  79.169  }
  79.170  
  79.171 -#define SCOM_AMCS_REG      0x022601
  79.172 -#define SCOM_AMCS_AND_MASK 0x022700
  79.173 -#define SCOM_AMCS_OR_MASK  0x022800
  79.174 -#define SCOM_CMCE          0x030901
  79.175 -#define SCOM_PMCR          0x400801
  79.176 -
  79.177  void cpu_scom_init(void)
  79.178  {
  79.179 -#ifdef not_yet
  79.180 -    console_start_sync();
  79.181 -    printk("scom PMCR: 0x%016lx\n", read_scom(SCOM_PMCR));
  79.182 -    console_end_sync();
  79.183 +#ifdef CONFIG_SCOM
  79.184 +    ulong val;
  79.185 +    if (PVR_REV(mfpvr()) == 0x0300) {
  79.186 +        /* these address are only good for 970FX */
  79.187 +        console_start_sync();
  79.188 +        if (!cpu_scom_read(SCOM_PTSR, &val))
  79.189 +            printk("SCOM PTSR: 0x%016lx\n", val);
  79.190 +
  79.191 +        console_end_sync();
  79.192 +    }
  79.193  #endif
  79.194  }
  79.195 +
  79.196 +void cpu_scom_AMCR(void)
  79.197 +{
  79.198 +#ifdef CONFIG_SCOM
  79.199 +    ulong val;
  79.200 +
  79.201 +    if (PVR_REV(mfpvr()) == 0x0300) {
  79.202 +        /* these address are only good for 970FX */
  79.203 +        cpu_scom_read(SCOM_AMC_REG, &val);
  79.204 +        printk("SCOM AMCR: 0x%016lx\n", val);
  79.205 +    }
  79.206 +#endif
  79.207 +}
  79.208 +
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/xen/arch/powerpc/powerpc64/scom.h	Thu Dec 14 08:57:36 2006 -0700
    80.3 @@ -0,0 +1,39 @@
    80.4 +/*
    80.5 + * This program is free software; you can redistribute it and/or modify
    80.6 + * it under the terms of the GNU General Public License as published by
    80.7 + * the Free Software Foundation; either version 2 of the License, or
    80.8 + * (at your option) any later version.
    80.9 + *
   80.10 + * This program is distributed in the hope that it will be useful,
   80.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   80.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   80.13 + * GNU General Public License for more details.
   80.14 + *
   80.15 + * You should have received a copy of the GNU General Public License
   80.16 + * along with this program; if not, write to the Free Software
   80.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   80.18 + *
   80.19 + * Copyright (C) IBM Corp. 2006
   80.20 + *
   80.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   80.22 + */
   80.23 +
   80.24 +#ifndef _ARCH_POWERPC_POWERPC64_SCOM_H_
   80.25 +#define _ARCH_POWERPC_POWERPC64_SCOM_H_
   80.26 +
   80.27 +extern void cpu_scom_init(void);
   80.28 +int cpu_scom_read(unsigned int addr, unsigned long *d);
   80.29 +int cpu_scom_write(unsigned int addr, unsigned long d);
   80.30 +void cpu_scom_AMCR(void);
   80.31 +
   80.32 +/* SCOMC addresses are 16bit but we are given 24 bits in the
   80.33 + * books. The low oerder 8 bits are some kinda parity thin and should
   80.34 + * be ignored */
   80.35 +#define SCOM_AMC_REG       0x022601
   80.36 +#define SCOM_AMC_AND_MASK  0x022700
   80.37 +#define SCOM_AMC_OR_MASK   0x022800
   80.38 +#define SCOM_CMCE          0x030901
   80.39 +#define SCOM_PMCR          0x400801
   80.40 +#define SCOM_PTSR          0x408001
   80.41 +
   80.42 +#endif
    81.1 --- a/xen/arch/powerpc/powerpc64/traps.c	Thu Dec 14 08:54:54 2006 -0700
    81.2 +++ b/xen/arch/powerpc/powerpc64/traps.c	Thu Dec 14 08:57:36 2006 -0700
    81.3 @@ -48,7 +48,3 @@ void show_registers(struct cpu_user_regs
    81.4      console_end_sync();
    81.5  }
    81.6  
    81.7 -void show_execution_state(struct cpu_user_regs *regs)
    81.8 -{
    81.9 -    show_registers(regs);
   81.10 -}
    82.1 --- a/xen/arch/powerpc/rtas.c	Thu Dec 14 08:54:54 2006 -0700
    82.2 +++ b/xen/arch/powerpc/rtas.c	Thu Dec 14 08:57:36 2006 -0700
    82.3 @@ -13,12 +13,90 @@
    82.4   * along with this program; if not, write to the Free Software
    82.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    82.6   *
    82.7 - * Copyright (C) IBM Corp. 2005
    82.8 + * Copyright (C) IBM Corp. 2006
    82.9   *
   82.10   * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   82.11   */
   82.12  
   82.13  #include <xen/config.h>
   82.14 +#include <xen/init.h>
   82.15 +#include <xen/lib.h>
   82.16 +#include <xen/errno.h>
   82.17 +#include "of-devtree.h"
   82.18 +#include "rtas.h"
   82.19  
   82.20 -int rtas_halt = -1;
   82.21 -int rtas_reboot = -1;
   82.22 +static int rtas_halt_token = -1;
   82.23 +static int rtas_reboot_token = -1;
   82.24 +int rtas_entry;
   82.25 +unsigned long rtas_msr;
   82.26 +unsigned long rtas_base;
   82.27 +unsigned long rtas_end;
   82.28 +
   82.29 +struct rtas_args {
   82.30 +    int ra_token;
   82.31 +    int ra_nargs;
   82.32 +    int ra_nrets;
   82.33 +    int ra_args[10];
   82.34 +} __attribute__ ((aligned(8)));
   82.35 +
   82.36 +static int rtas_call(struct rtas_args *r)
   82.37 +{
   82.38 +    if (rtas_entry == 0)
   82.39 +        return -ENOSYS;
   82.40 +
   82.41 +    return prom_call(r, rtas_base, rtas_entry, rtas_msr);
   82.42 +}
   82.43 +
   82.44 +int __init rtas_init(void *m)
   82.45 +{
   82.46 +    static const char halt[] = "power-off";
   82.47 +    static const char reboot[] = "system-reboot";
   82.48 +    ofdn_t n;
   82.49 +
   82.50 +    if (rtas_entry == 0)
   82.51 +        return -ENOSYS;
   82.52 +
   82.53 +    n = ofd_node_find(m, "/rtas");
   82.54 +    if (n <= 0)
   82.55 +        return -ENOSYS;
   82.56 +
   82.57 +    ofd_getprop(m, n, halt,
   82.58 +                &rtas_halt_token, sizeof (rtas_halt_token));
   82.59 +    ofd_getprop(m, n, reboot,
   82.60 +                &rtas_reboot_token, sizeof (rtas_reboot_token));
   82.61 +    return 1;
   82.62 +}
   82.63 +
   82.64 +int
   82.65 +rtas_halt(void)
   82.66 +{
   82.67 +    struct rtas_args r;
   82.68 +
   82.69 +    if (rtas_halt_token == -1)
   82.70 +        return -1;
   82.71 +
   82.72 +    r.ra_token = rtas_halt_token;
   82.73 +    r.ra_nargs = 2;
   82.74 +    r.ra_nrets = 1;
   82.75 +    r.ra_args[0] = 0;
   82.76 +    r.ra_args[1] = 0;
   82.77 +
   82.78 +    return rtas_call(&r);
   82.79 +}
   82.80 +
   82.81 +int
   82.82 +rtas_reboot(void)
   82.83 +{
   82.84 +    struct rtas_args r;
   82.85 +
   82.86 +    if (rtas_reboot_token == -1)
   82.87 +        return -ENOSYS;
   82.88 +
   82.89 +    r.ra_token = rtas_reboot_token;
   82.90 +    r.ra_nargs = 2;
   82.91 +    r.ra_nrets = 1;
   82.92 +    r.ra_args[0] = 0;
   82.93 +    r.ra_args[1] = 0;
   82.94 +
   82.95 +    return rtas_call(&r);
   82.96 +}
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/xen/arch/powerpc/rtas.h	Thu Dec 14 08:57:36 2006 -0700
    83.3 @@ -0,0 +1,34 @@
    83.4 +/*
    83.5 + * This program is free software; you can redistribute it and/or modify
    83.6 + * it under the terms of the GNU General Public License as published by
    83.7 + * the Free Software Foundation; either version 2 of the License, or
    83.8 + * (at your option) any later version.
    83.9 + *
   83.10 + * This program is distributed in the hope that it will be useful,
   83.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   83.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   83.13 + * GNU General Public License for more details.
   83.14 + *
   83.15 + * You should have received a copy of the GNU General Public License
   83.16 + * along with this program; if not, write to the Free Software
   83.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   83.18 + *
   83.19 + * Copyright (C) IBM Corp. 2006
   83.20 + *
   83.21 + * Authors: Jimi Xenidis <jimix@us.ibm.com>
   83.22 + */
   83.23 +
   83.24 +#ifndef _ARCH_POWERPC_RTAS_H_
   83.25 +#define _ARCH_POWERPC_RTAS_H_
   83.26 +
   83.27 +extern int rtas_entry;
   83.28 +extern unsigned long rtas_msr;
   83.29 +extern unsigned long rtas_base;
   83.30 +extern unsigned long rtas_end;
   83.31 +
   83.32 +extern int prom_call(void *arg, unsigned base,
   83.33 +                     unsigned long func, unsigned long msr);
   83.34 +extern int rtas_init(void *);
   83.35 +extern int rtas_halt(void);
   83.36 +extern int rtas_reboot(void);
   83.37 +#endif
    84.1 --- a/xen/arch/powerpc/setup.c	Thu Dec 14 08:54:54 2006 -0700
    84.2 +++ b/xen/arch/powerpc/setup.c	Thu Dec 14 08:57:36 2006 -0700
    84.3 @@ -1,8 +1,8 @@
    84.4  /*
    84.5 - * This program is free software; you can redistribute it and/or modify
    84.6 - * it under the terms of the GNU General Public License as published by
    84.7 - * the Free Software Foundation; either version 2 of the License, or
    84.8 - * (at your option) any later version.
    84.9 + * This program is free software; you can redistribute it and/or
   84.10 + * modify it under the terms of the GNU General Public License as
   84.11 + * published by the Free Software Foundation; either version 2 of the
   84.12 + * License, or (at your option) any later version.
   84.13   *
   84.14   * This program is distributed in the hope that it will be useful,
   84.15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   84.16 @@ -35,8 +35,10 @@
   84.17  #include <xen/gdbstub.h>
   84.18  #include <xen/symbols.h>
   84.19  #include <xen/keyhandler.h>
   84.20 +#include <xen/numa.h>
   84.21  #include <acm/acm_hooks.h>
   84.22  #include <public/version.h>
   84.23 +#include <asm/mpic.h>
   84.24  #include <asm/processor.h>
   84.25  #include <asm/desc.h>
   84.26  #include <asm/cache.h>
   84.27 @@ -47,6 +49,7 @@
   84.28  #include "exceptions.h"
   84.29  #include "of-devtree.h"
   84.30  #include "oftree.h"
   84.31 +#include "rtas.h"
   84.32  
   84.33  #define DEBUG
   84.34  
   84.35 @@ -75,10 +78,7 @@ ulong oftree_len;
   84.36  ulong oftree_end;
   84.37  
   84.38  uint cpu_hard_id[NR_CPUS] __initdata;
   84.39 -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
   84.40 -cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
   84.41  cpumask_t cpu_present_map;
   84.42 -cpumask_t cpu_possible_map;
   84.43  
   84.44  /* XXX get this from ISA node in device tree */
   84.45  char *vgabase;
   84.46 @@ -87,6 +87,8 @@ struct ns16550_defaults ns16550;
   84.47  
   84.48  extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
   84.49  
   84.50 +static struct domain *idle_domain;
   84.51 +
   84.52  volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
   84.53  
   84.54  int is_kernel_text(unsigned long addr)
   84.55 @@ -110,12 +112,28 @@ static void __init do_initcalls(void)
   84.56      }
   84.57  }
   84.58  
   84.59 -static void hw_probe_attn(unsigned char key, struct cpu_user_regs *regs)
   84.60 +
   84.61 +void noinline __attn(void)
   84.62  {
   84.63      /* To continue the probe will step over the ATTN instruction.  The
   84.64       * NOP is there to make sure there is something sane to "step
   84.65       * over" to. */
   84.66 -    asm volatile(".long 0x00000200; nop");
   84.67 +    console_start_sync();
   84.68 +    asm volatile(".long 0x200;nop");
   84.69 +    console_end_sync();
   84.70 +}
   84.71 +
   84.72 +static void key_hw_probe_attn(unsigned char key)
   84.73 +{
   84.74 +    __attn();
   84.75 +}
   84.76 +
   84.77 +static void key_ofdump(unsigned char key)
   84.78 +{
   84.79 +    printk("ofdump:\n");
   84.80 +    /* make sure the OF devtree is good */
   84.81 +    ofd_walk((void *)oftree, "devtree", OFD_ROOT,
   84.82 +             ofd_dump_props, OFD_DUMP_ALL);
   84.83  }
   84.84  
   84.85  static void percpu_init_areas(void)
   84.86 @@ -150,8 +168,6 @@ static void percpu_free_unused_areas(voi
   84.87  
   84.88  static void __init start_of_day(void)
   84.89  {
   84.90 -    struct domain *idle_domain;
   84.91 -
   84.92      init_IRQ();
   84.93  
   84.94      scheduler_init();
   84.95 @@ -166,37 +182,20 @@ static void __init start_of_day(void)
   84.96      /* for some reason we need to set our own bit in the thread map */
   84.97      cpu_set(0, cpu_sibling_map[0]);
   84.98  
   84.99 -    percpu_free_unused_areas();
  84.100 -
  84.101 -    {
  84.102 -        /* FIXME: Xen assumes that an online CPU is a schedualable
  84.103 -         * CPU, but we just are not there yet. Remove this fragment when
  84.104 -         * scheduling processors actually works. */
  84.105 -        int cpuid;
  84.106 -
  84.107 -        printk("WARNING!: Taking all secondary CPUs offline\n");
  84.108 -
  84.109 -        for_each_online_cpu(cpuid) {
  84.110 -            if (cpuid == 0)
  84.111 -                continue;
  84.112 -            cpu_clear(cpuid, cpu_online_map);
  84.113 -        }
  84.114 -    }
  84.115 -
  84.116      initialize_keytable();
  84.117      /* Register another key that will allow for the the Harware Probe
  84.118       * to be contacted, this works with RiscWatch probes and should
  84.119       * work with Chronos and FSPs */
  84.120 -    register_irq_keyhandler('^', hw_probe_attn,   "Trap to Hardware Probe");
  84.121 +    register_keyhandler('^', key_hw_probe_attn, "Trap to Hardware Probe");
  84.122 +
  84.123 +    /* allow the dumping of the devtree */
  84.124 +    register_keyhandler('D', key_ofdump , "Dump OF Devtree");
  84.125  
  84.126      timer_init();
  84.127      serial_init_postirq();
  84.128      do_initcalls();
  84.129 -    schedulers_start();
  84.130  }
  84.131  
  84.132 -extern void idle_loop(void);
  84.133 -
  84.134  void startup_cpu_idle_loop(void)
  84.135  {
  84.136      struct vcpu *v = current;
  84.137 @@ -209,6 +208,15 @@ void startup_cpu_idle_loop(void)
  84.138      reset_stack_and_jump(idle_loop);
  84.139  }
  84.140  
  84.141 +/* The boot_pa is enough "parea" for the boot CPU to get thru
  84.142 + * initialization, it will ultimately get replaced later */
  84.143 +static __init void init_boot_cpu(void)
  84.144 +{
  84.145 +    static struct processor_area boot_pa;
  84.146 +    boot_pa.whoami = 0;
  84.147 +    parea = &boot_pa;
  84.148 +}    
  84.149 +
  84.150  static void init_parea(int cpuid)
  84.151  {
  84.152      /* Be careful not to shadow the global variable.  */
  84.153 @@ -227,6 +235,7 @@ static void init_parea(int cpuid)
  84.154      pa->whoami = cpuid;
  84.155      pa->hard_id = cpu_hard_id[cpuid];
  84.156      pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);
  84.157 +    mb();
  84.158  
  84.159      /* This store has the effect of invoking secondary_cpu_init.  */
  84.160      global_cpu_table[cpuid] = pa;
  84.161 @@ -248,18 +257,34 @@ static int kick_secondary_cpus(int maxcp
  84.162          /* wait for it */
  84.163          while (!cpu_online(cpuid))
  84.164              cpu_relax();
  84.165 +
  84.166 +        numa_set_node(cpuid, 0);
  84.167 +        numa_add_cpu(cpuid);
  84.168      }
  84.169  
  84.170      return 0;
  84.171  }
  84.172  
  84.173  /* This is the first C code that secondary processors invoke.  */
  84.174 -int secondary_cpu_init(int cpuid, unsigned long r4)
  84.175 +void secondary_cpu_init(int cpuid, unsigned long r4)
  84.176  {
  84.177 +    struct vcpu *vcpu;
  84.178 +
  84.179      cpu_initialize(cpuid);
  84.180      smp_generic_take_timebase();
  84.181 +
  84.182 +    /* If we are online, we must be able to ACK IPIs.  */
  84.183 +    mpic_setup_this_cpu();
  84.184      cpu_set(cpuid, cpu_online_map);
  84.185 -    while(1);
  84.186 +
  84.187 +    vcpu = alloc_vcpu(idle_domain, cpuid, cpuid);
  84.188 +    BUG_ON(vcpu == NULL);
  84.189 +
  84.190 +    set_current(idle_domain->vcpu[cpuid]);
  84.191 +    idle_vcpu[cpuid] = current;
  84.192 +    startup_cpu_idle_loop();
  84.193 +
  84.194 +    panic("should never get here\n");
  84.195  }
  84.196  
  84.197  static void __init __start_xen(multiboot_info_t *mbi)
  84.198 @@ -278,6 +303,9 @@ static void __init __start_xen(multiboot
  84.199      if ((mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0))
  84.200          cmdline_parse(__va((ulong)mbi->cmdline));
  84.201  
  84.202 +    /* we need to be able to identify this CPU early on */
  84.203 +    init_boot_cpu();
  84.204 +
  84.205      /* We initialise the serial devices very early so we can get debugging. */
  84.206      ns16550.io_base = 0x3f8;
  84.207      ns16550_init(0, &ns16550);
  84.208 @@ -286,22 +314,14 @@ static void __init __start_xen(multiboot
  84.209      serial_init_preirq();
  84.210  
  84.211      init_console();
  84.212 -#ifdef CONSOLE_SYNC
  84.213 +    /* let synchronize until we really get going */
  84.214      console_start_sync();
  84.215 -#endif
  84.216 -
  84.217 -    /* we give the first RMA to the hypervisor */
  84.218 -    xenheap_phys_end = rma_size(cpu_default_rma_order_pages());
  84.219  
  84.220      /* Check that we have at least one Multiboot module. */
  84.221      if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) {
  84.222          panic("FATAL ERROR: Require at least one Multiboot module.\n");
  84.223      }
  84.224  
  84.225 -    if (!(mbi->flags & MBI_MEMMAP)) {
  84.226 -        panic("FATAL ERROR: Bootloader provided no memory information.\n");
  84.227 -    }
  84.228 -
  84.229      /* OF dev tree is the last module */
  84.230      oftree = mod[mbi->mods_count-1].mod_start;
  84.231      oftree_end = mod[mbi->mods_count-1].mod_end;
  84.232 @@ -312,14 +332,18 @@ static void __init __start_xen(multiboot
  84.233      mod[mbi->mods_count-1].mod_end = 0;
  84.234      --mbi->mods_count;
  84.235  
  84.236 +    if (rtas_entry) {
  84.237 +        rtas_init((void *)oftree);
  84.238 +        /* remove rtas module from consideration */
  84.239 +        mod[mbi->mods_count-1].mod_start = 0;
  84.240 +        mod[mbi->mods_count-1].mod_end = 0;
  84.241 +        --mbi->mods_count;
  84.242 +    }
  84.243      memory_init(mod, mbi->mods_count);
  84.244  
  84.245  #ifdef OF_DEBUG
  84.246 -    printk("ofdump:\n");
  84.247 -    /* make sure the OF devtree is good */
  84.248 -    ofd_walk((void *)oftree, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
  84.249 +    key_ofdump(0);
  84.250  #endif
  84.251 -
  84.252      percpu_init_areas();
  84.253  
  84.254      init_parea(0);
  84.255 @@ -331,6 +355,10 @@ static void __init __start_xen(multiboot
  84.256          debugger_trap_immediate();
  84.257  #endif
  84.258  
  84.259 +    start_of_day();
  84.260 +
  84.261 +    mpic_setup_this_cpu();
  84.262 +
  84.263      /* Deal with secondary processors.  */
  84.264      if (opt_nosmp || ofd_boot_cpu == -1) {
  84.265          printk("nosmp: leaving secondary processors spinning forever\n");
  84.266 @@ -339,7 +367,11 @@ static void __init __start_xen(multiboot
  84.267          kick_secondary_cpus(max_cpus);
  84.268      }
  84.269  
  84.270 -    start_of_day();
  84.271 +    /* Secondary processors must be online before we call this.  */
  84.272 +    schedulers_start();
  84.273 +
  84.274 +    /* This cannot be called before secondary cpus are marked online.  */
  84.275 +    percpu_free_unused_areas();
  84.276  
  84.277      /* Create initial domain 0. */
  84.278      dom0 = domain_create(0, 0);
  84.279 @@ -383,10 +415,10 @@ static void __init __start_xen(multiboot
  84.280      }
  84.281  
  84.282      init_xenheap_pages(ALIGN_UP(dom0_start, PAGE_SIZE),
  84.283 -                 ALIGN_DOWN(dom0_start + dom0_len, PAGE_SIZE));
  84.284 +                       ALIGN_DOWN(dom0_start + dom0_len, PAGE_SIZE));
  84.285      if (initrd_start)
  84.286          init_xenheap_pages(ALIGN_UP(initrd_start, PAGE_SIZE),
  84.287 -                     ALIGN_DOWN(initrd_start + initrd_len, PAGE_SIZE));
  84.288 +                           ALIGN_DOWN(initrd_start + initrd_len, PAGE_SIZE));
  84.289  
  84.290      init_trace_bufs();
  84.291  
  84.292 @@ -395,8 +427,12 @@ static void __init __start_xen(multiboot
  84.293      /* Hide UART from DOM0 if we're using it */
  84.294      serial_endboot();
  84.295  
  84.296 +    console_end_sync();
  84.297 +
  84.298      domain_unpause_by_systemcontroller(dom0);
  84.299 -
  84.300 +#ifdef DEBUG_IPI
  84.301 +    ipi_torture_test();
  84.302 +#endif
  84.303      startup_cpu_idle_loop();
  84.304  }
  84.305  
  84.306 @@ -414,7 +450,7 @@ void __init __start_xen_ppc(
  84.307  
  84.308      } else {
  84.309          /* booted by someone else that hopefully has a trap handler */
  84.310 -        trap();
  84.311 +        __builtin_trap();
  84.312      }
  84.313  
  84.314      __start_xen(mbi);
    85.1 --- a/xen/arch/powerpc/shadow.c	Thu Dec 14 08:54:54 2006 -0700
    85.2 +++ b/xen/arch/powerpc/shadow.c	Thu Dec 14 08:57:36 2006 -0700
    85.3 @@ -101,9 +101,6 @@ unsigned int shadow_set_allocation(struc
    85.4  
    85.5      addr = htab_alloc(d, order);
    85.6  
    85.7 -    printk("%s: ibm,fpt-size should be: 0x%x\n", __func__,
    85.8 -           d->arch.htab.log_num_ptes + LOG_PTE_SIZE);
    85.9 -
   85.10      if (addr == 0)
   85.11          return -ENOMEM;
   85.12  
   85.13 @@ -115,8 +112,8 @@ unsigned int shadow_set_allocation(struc
   85.14  }
   85.15  
   85.16  int shadow_domctl(struct domain *d, 
   85.17 -				  xen_domctl_shadow_op_t *sc,
   85.18 -				  XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
   85.19 +                  xen_domctl_shadow_op_t *sc,
   85.20 +                  XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
   85.21  {
   85.22      if ( unlikely(d == current->domain) )
   85.23      {
    86.1 --- a/xen/arch/powerpc/smp.c	Thu Dec 14 08:54:54 2006 -0700
    86.2 +++ b/xen/arch/powerpc/smp.c	Thu Dec 14 08:57:36 2006 -0700
    86.3 @@ -13,15 +13,18 @@
    86.4   * along with this program; if not, write to the Free Software
    86.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    86.6   *
    86.7 - * Copyright (C) IBM Corp. 2005
    86.8 + * Copyright (C) IBM Corp. 2005,2006
    86.9   *
   86.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
   86.11 + * Authors: Amos Waterland <apw@us.ibm.com>
   86.12   */
   86.13  
   86.14 -#include <asm/misc.h>
   86.15  #include <xen/cpumask.h>
   86.16  #include <xen/smp.h>
   86.17  #include <asm/flushtlb.h>
   86.18 +#include <asm/debugger.h>
   86.19 +#include <asm/mpic.h>
   86.20 +#include <asm/mach-default/irq_vectors.h>
   86.21  
   86.22  int smp_num_siblings = 1;
   86.23  int smp_num_cpus = 1;
   86.24 @@ -29,26 +32,57 @@ int ht_per_core = 1;
   86.25  
   86.26  void __flush_tlb_mask(cpumask_t mask, unsigned long addr)
   86.27  {
   86.28 -    unimplemented();
   86.29 +    if (cpu_isset(smp_processor_id(), mask)) {
   86.30 +        cpu_clear(smp_processor_id(), mask);
   86.31 +        if (cpus_empty(mask)) {
   86.32 +            /* only local */
   86.33 +            if (addr == FLUSH_ALL_ADDRS)
   86.34 +                local_flush_tlb();
   86.35 +            else
   86.36 +                local_flush_tlb_one(addr);
   86.37 +            return;
   86.38 +        }
   86.39 +    }
   86.40 +    /* if we are still here and the mask is non-empty, then we need to
   86.41 +     * flush other TLBs so we flush em all */
   86.42 +    if (!cpus_empty(mask))
   86.43 +        unimplemented();
   86.44  }
   86.45  
   86.46 -void smp_send_event_check_mask(cpumask_t cpu_mask)
   86.47 +void smp_send_event_check_mask(cpumask_t mask)
   86.48  {
   86.49 -    unimplemented();
   86.50 +    cpu_clear(smp_processor_id(), mask);
   86.51 +    if (!cpus_empty(mask))
   86.52 +        send_IPI_mask(mask, EVENT_CHECK_VECTOR);
   86.53  }
   86.54  
   86.55 -int smp_call_function(void (*func) (void *info), void *info, int unused,
   86.56 -        int wait)
   86.57 +
   86.58 +int smp_call_function(void (*func) (void *info), void *info, int retry,
   86.59 +                      int wait)
   86.60  {
   86.61 -    unimplemented();
   86.62 -    return 0;
   86.63 +    cpumask_t allbutself = cpu_online_map;
   86.64 +    cpu_clear(smp_processor_id(), allbutself);
   86.65 +
   86.66 +    return on_selected_cpus(allbutself, func, info, retry, wait);
   86.67  }
   86.68  
   86.69  void smp_send_stop(void)
   86.70  {
   86.71 -    unimplemented();
   86.72 +    BUG();
   86.73  }
   86.74  
   86.75 +struct call_data_struct {
   86.76 +    void (*func) (void *info);
   86.77 +    void *info;
   86.78 +    int wait;
   86.79 +    atomic_t started;
   86.80 +    atomic_t finished;
   86.81 +    cpumask_t selected;
   86.82 +};
   86.83 +
   86.84 +static DEFINE_SPINLOCK(call_lock);
   86.85 +static struct call_data_struct call_data;
   86.86 +
   86.87  int on_selected_cpus(
   86.88      cpumask_t selected,
   86.89      void (*func) (void *info),
   86.90 @@ -56,5 +90,125 @@ int on_selected_cpus(
   86.91      int retry,
   86.92      int wait)
   86.93  {
   86.94 -    return 0;
   86.95 +    int retval = 0, nr_cpus = cpus_weight(selected);
   86.96 +    unsigned long start, stall = SECONDS(1);
   86.97 +
   86.98 +    spin_lock(&call_lock);
   86.99 +
  86.100 +    call_data.func = func;
  86.101 +    call_data.info = info;
  86.102 +    call_data.wait = wait;
  86.103 +    atomic_set(&call_data.started, 0);
  86.104 +    atomic_set(&call_data.finished, 0);
  86.105 +    mb();
  86.106 +
  86.107 +    send_IPI_mask(selected, CALL_FUNCTION_VECTOR);
  86.108 +
  86.109 +    /* We always wait for an initiation ACK from remote CPU.  */
  86.110 +    for (start = NOW(); atomic_read(&call_data.started) != nr_cpus; ) {
  86.111 +        if (NOW() > start + stall) {
  86.112 +            printk("IPI start stall: %d ACKS to %d SYNS\n", 
  86.113 +                   atomic_read(&call_data.started), nr_cpus);
  86.114 +            start = NOW();
  86.115 +        }
  86.116 +    }
  86.117 +
  86.118 +    /* If told to, we wait for a completion ACK from remote CPU.  */
  86.119 +    if (wait) {
  86.120 +        for (start = NOW(); atomic_read(&call_data.finished) != nr_cpus; ) {
  86.121 +            if (NOW() > start + stall) {
  86.122 +                printk("IPI finish stall: %d ACKS to %d SYNS\n", 
  86.123 +                       atomic_read(&call_data.finished), nr_cpus);
  86.124 +                start = NOW();
  86.125 +            }
  86.126 +        }
  86.127 +    }
  86.128 +
  86.129 +    spin_unlock(&call_lock);
  86.130 +
  86.131 +    return retval;
  86.132 +}
  86.133 +
  86.134 +void smp_call_function_interrupt(struct cpu_user_regs *regs)
  86.135 +{
  86.136 +
  86.137 +    void (*func)(void *info) = call_data.func;
  86.138 +    void *info = call_data.info;
  86.139 +    int wait = call_data.wait;
  86.140 +
  86.141 +    atomic_inc(&call_data.started);
  86.142 +    mb();
  86.143 +    (*func)(info);
  86.144 +    mb();
  86.145 +
  86.146 +    if (wait)
  86.147 +        atomic_inc(&call_data.finished);
  86.148 +
  86.149 +    return;
  86.150  }
  86.151 +
  86.152 +void smp_event_check_interrupt(void)
  86.153 +{
  86.154 +    /* We are knocked out of NAP state at least.  */
  86.155 +    return;
  86.156 +}
  86.157 +
  86.158 +void smp_message_recv(int msg, struct cpu_user_regs *regs)
  86.159 +{
  86.160 +    switch(msg) {
  86.161 +    case CALL_FUNCTION_VECTOR:
  86.162 +        smp_call_function_interrupt(regs);
  86.163 +        break;
  86.164 +    case EVENT_CHECK_VECTOR:
  86.165 +        smp_event_check_interrupt();
  86.166 +        break;
  86.167 +    default:
  86.168 +        BUG();
  86.169 +        break;
  86.170 +    }
  86.171 +}
  86.172 +
  86.173 +#ifdef DEBUG_IPI
  86.174 +static void debug_ipi_ack(void *info)
  86.175 +{
  86.176 +    if (info) {
  86.177 +        unsigned long start, stall = SECONDS(5);
  86.178 +        for (start = NOW(); NOW() < start + stall; );
  86.179 +        printk("IPI recv on cpu #%d: %s\n", smp_processor_id(), (char *)info);
  86.180 +    }
  86.181 +    return;
  86.182 +}
  86.183 +
  86.184 +void ipi_torture_test(void)
  86.185 +{
  86.186 +    int cpu;
  86.187 +    unsigned long before, after, delta;
  86.188 +    unsigned long min = ~0, max = 0, mean = 0, sum = 0, trials = 0;
  86.189 +    cpumask_t mask;
  86.190 +
  86.191 +    cpus_clear(mask);
  86.192 +
  86.193 +    while (trials < 1000000) {
  86.194 +        for_each_online_cpu(cpu) {
  86.195 +            cpu_set(cpu, mask);
  86.196 +            before = mftb();
  86.197 +            on_selected_cpus(mask, debug_ipi_ack, NULL, 1, 1);
  86.198 +            after = mftb();
  86.199 +            cpus_clear(mask);
  86.200 +
  86.201 +            delta = after - before;
  86.202 +            if (delta > max) max = delta;
  86.203 +            if (delta < min) min = delta;
  86.204 +            sum += delta;
  86.205 +            trials++;
  86.206 +        }
  86.207 +    }
  86.208 +
  86.209 +    mean = tb_to_ns(sum / trials);
  86.210 +
  86.211 +    printk("IPI latency: min = %ld ticks, max = %ld ticks, mean = %ldns\n",
  86.212 +           min, max, mean);
  86.213 +
  86.214 +    smp_call_function(debug_ipi_ack, "Hi", 0, 1);
  86.215 +}
  86.216 +#endif
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/xen/arch/powerpc/smpboot.c	Thu Dec 14 08:57:36 2006 -0700
    87.3 @@ -0,0 +1,29 @@
    87.4 +
    87.5 +#include <xen/config.h>
    87.6 +#include <xen/init.h>
    87.7 +#include <xen/types.h>
    87.8 +#include <xen/cpumask.h>
    87.9 +#include <asm/cache.h>
   87.10 +
   87.11 +/* representing HT siblings of each logical CPU */
   87.12 +cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
   87.13 +EXPORT_SYMBOL(cpu_sibling_map);
   87.14 +
   87.15 +/* representing HT and core siblings of each logical CPU */
   87.16 +cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
   87.17 +EXPORT_SYMBOL(cpu_core_map);
   87.18 +
   87.19 +/* bitmap of online cpus */
   87.20 +cpumask_t cpu_online_map __read_mostly;
   87.21 +EXPORT_SYMBOL(cpu_online_map);
   87.22 +
   87.23 +
   87.24 +#ifdef CONFIG_HOTPLUG_CPU
   87.25 +cpumask_t cpu_possible_map = CPU_MASK_ALL;
   87.26 +#else
   87.27 +cpumask_t cpu_possible_map;
   87.28 +#endif
   87.29 +EXPORT_SYMBOL(cpu_possible_map);
   87.30 +
   87.31 +u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0xff };
   87.32 +EXPORT_SYMBOL(x86_cpu_to_apicid);
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/xen/arch/powerpc/start.S	Thu Dec 14 08:57:36 2006 -0700
    88.3 @@ -0,0 +1,62 @@
    88.4 +/*
    88.5 + * This program is free software; you can redistribute it and/or modify
    88.6 + * it under the terms of the GNU General Public License as published by
    88.7 + * the Free Software Foundation; either version 2 of the License, or
    88.8 + * (at your option) any later version.
    88.9 + * 
   88.10 + * This program is distributed in the hope that it will be useful,
   88.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   88.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   88.13 + * GNU General Public License for more details.
   88.14 + * 
   88.15 + * You should have received a copy of the GNU General Public License
   88.16 + * along with this program; if not, write to the Free Software
   88.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   88.18 + *
   88.19 + * Copyright (C) 2005, 2006 IBM Corp.
   88.20 + *
   88.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   88.22 + *          Hollis Blanchard <hollisb@us.ibm.com>
   88.23 + *
   88.24 + */
   88.25 +
   88.26 +#include <asm/config.h>
   88.27 +#include <asm/msr.h>
   88.28 +#include <asm/processor.h>
   88.29 +#include <asm/page.h>
   88.30 +
   88.31 +    .globl _start
   88.32 +_start:
   88.33 +    /* pass the original MSR along */
   88.34 +    mfmsr r8
   88.35 +
   88.36 +    /* set initial MSR */
   88.37 +    li r22, 0
   88.38 +    ori r22, r22, (MSR_SF | MSR_HV) >> 48
   88.39 +    sldi r22, r22, 48
   88.40 +    mtmsrd r22
   88.41 +
   88.42 +_start64:
   88.43 +    /* load up the stack */
   88.44 +    SET_REG_TO_LABEL(r1, cpu0_stack)
   88.45 +
   88.46 +    /* call the init function */
   88.47 +    LOADADDR(r21,__start_xen_ppc)
   88.48 +    ld r2, 8(r21)
   88.49 +    ld r21, 0(r21)
   88.50 +    mtctr r21
   88.51 +    bctrl
   88.52 +    /* should never return */
   88.53 +    trap
   88.54 +
   88.55 +    /* Note! GDB 6.3 makes the very stupid assumption that PC > SP means we are
   88.56 +     * in a Linux signal trampoline, and it begins groping for a struct
   88.57 +     * rt_sigframe on the stack. Naturally, this fails miserably for our
   88.58 +     * backtrace. To work around this behavior, we must make certain that our
   88.59 +     * stack is always above our text, e.g. in the data section. */
   88.60 +    .data /* DO NOT REMOVE; see GDB note above */
   88.61 +    .align 4
   88.62 +cpu0_stack_bottom:
   88.63 +    .space STACK_SIZE
   88.64 +cpu0_stack:
   88.65 +    .space STACK_FRAME_OVERHEAD
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/xen/arch/powerpc/systemsim.S	Thu Dec 14 08:57:36 2006 -0700
    89.3 @@ -0,0 +1,64 @@
    89.4 +/*
    89.5 + * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    89.6 + *
    89.7 + * This program is free software; you can redistribute it and/or modify
    89.8 + * it under the terms of the GNU General Public License as published by
    89.9 + * the Free Software Foundation; either version 2 of the License, or
   89.10 + * (at your option) any later version.
   89.11 + * 
   89.12 + * This program is distributed in the hope that it will be useful,
   89.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   89.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   89.15 + * GNU General Public License for more details.
   89.16 + * 
   89.17 + * You should have received a copy of the GNU General Public License
   89.18 + * along with this program; if not, write to the Free Software
   89.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   89.20 + *
   89.21 + */
   89.22 +
   89.23 +#include <asm/config.h>
   89.24 +#include <asm/processor.h>
   89.25 +
   89.26 +_GLOBAL(systemsim_callthru)
   89.27 +	.long 0x000eaeb0
   89.28 +	blr
   89.29 +
   89.30 +_GLOBAL(systemsim_write)
   89.31 +	mr	r5, r4
   89.32 +	mr	r4, r3
   89.33 +	li	r3, 0		# Write console code
   89.34 +	
   89.35 +	li	r6, 0
   89.36 +	/* need to fix return value */
   89.37 +	mflr	r7
   89.38 +	bl	_ENTRY(systemsim_callthru)
   89.39 +	mtlr	r7
   89.40 +	mr	r3, r5
   89.41 +	blr
   89.42 +
   89.43 +_GLOBAL(systemsim_memset)
   89.44 +	mr	r6, r5
   89.45 +	mr	r5, r4
   89.46 +	mr	r4, r3
   89.47 +	li	r3, 0x47	# memset
   89.48 +	/* need to fix return value */
   89.49 +	mflr	r7
   89.50 +	bl	_ENTRY(systemsim_callthru)
   89.51 +	mtlr	r7
   89.52 +	mr	r3, r4
   89.53 +	blr
   89.54 +
   89.55 +_GLOBAL(systemsim_memcpy)
   89.56 +	mr	r6, r5
   89.57 +	mr	r5, r4
   89.58 +	mr	r4, r3
   89.59 +	li	r3, 0x45 # memcpy
   89.60 +	/* need to fix return value */
   89.61 +	mflr	r7
   89.62 +	bl	_ENTRY(systemsim_callthru)
   89.63 +	mtlr	r7
   89.64 +	mr	r3, r4
   89.65 +	blr
   89.66 +
   89.67 +	
    90.1 --- a/xen/arch/powerpc/time.c	Thu Dec 14 08:54:54 2006 -0700
    90.2 +++ b/xen/arch/powerpc/time.c	Thu Dec 14 08:57:36 2006 -0700
    90.3 @@ -25,7 +25,7 @@
    90.4  #include <xen/sched.h>
    90.5  #include <asm/processor.h>
    90.6  #include <asm/current.h>
    90.7 -#include <asm/misc.h>
    90.8 +#include <asm/debugger.h>
    90.9  
   90.10  #define Dprintk(x...) printk(x)
   90.11  
   90.12 @@ -93,5 +93,4 @@ void do_settime(unsigned long secs, unsi
   90.13  
   90.14  void update_vcpu_system_time(struct vcpu *v)
   90.15  {
   90.16 -    unimplemented();
   90.17  }
    91.1 --- a/xen/arch/powerpc/usercopy.c	Thu Dec 14 08:54:54 2006 -0700
    91.2 +++ b/xen/arch/powerpc/usercopy.c	Thu Dec 14 08:57:36 2006 -0700
    91.3 @@ -18,267 +18,33 @@
    91.4   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    91.5   */
    91.6  
    91.7 -#include <xen/config.h>
    91.8 -#include <xen/mm.h>
    91.9  #include <xen/sched.h>
   91.10 +#include <xen/lib.h>
   91.11  #include <asm/current.h>
   91.12 -#include <asm/uaccess.h>
   91.13 -#include <public/xen.h>
   91.14 -#include <public/xencomm.h>
   91.15 -
   91.16 -#undef DEBUG
   91.17 -#ifdef DEBUG
   91.18 -static int xencomm_debug = 1; /* extremely verbose */
   91.19 -#else
   91.20 -#define xencomm_debug 0
   91.21 -#endif
   91.22 +#include <asm/page.h>
   91.23 +#include <asm/debugger.h>
   91.24  
   91.25  /* XXX need to return error, not panic, if domain passed a bad pointer */
   91.26 -static unsigned long paddr_to_maddr(unsigned long paddr)
   91.27 +unsigned long paddr_to_maddr(unsigned long paddr)
   91.28  {
   91.29      struct vcpu *v = get_current();
   91.30      struct domain *d = v->domain;
   91.31 -    int mtype;
   91.32 -    ulong pfn;
   91.33 +    ulong gpfn;
   91.34      ulong offset;
   91.35      ulong pa = paddr;
   91.36  
   91.37      offset = pa & ~PAGE_MASK;
   91.38 -    pfn = pa >> PAGE_SHIFT;
   91.39 +    gpfn = pa >> PAGE_SHIFT;
   91.40  
   91.41 -    pa = pfn2mfn(d, pfn, &mtype);
   91.42 +    pa = gmfn_to_mfn(d, gpfn);
   91.43      if (pa == INVALID_MFN) {
   91.44          printk("%s: Dom:%d bad paddr: 0x%lx\n",
   91.45                 __func__, d->domain_id, paddr);
   91.46          return 0;
   91.47      }
   91.48 -    switch (mtype) {
   91.49 -    case PFN_TYPE_RMA:
   91.50 -    case PFN_TYPE_LOGICAL:
   91.51 -        break;
   91.52  
   91.53 -    case PFN_TYPE_FOREIGN:
   91.54 -        /* I don't think this should ever happen, but I suppose it
   91.55 -         * could be possible */
   91.56 -        printk("%s: Dom:%d paddr: 0x%lx type: FOREIGN\n",
   91.57 -               __func__, d->domain_id, paddr);
   91.58 -        WARN();
   91.59 -        break;
   91.60 -
   91.61 -    case PFN_TYPE_IO:
   91.62 -    default:
   91.63 -        printk("%s: Dom:%d paddr: 0x%lx bad type: 0x%x\n",
   91.64 -               __func__, d->domain_id, paddr, mtype);
   91.65 -        WARN();
   91.66 -        return 0;
   91.67 -    }
   91.68      pa <<= PAGE_SHIFT;
   91.69      pa |= offset;
   91.70  
   91.71      return pa;
   91.72  }
   91.73 -
   91.74 -/**
   91.75 - * xencomm_copy_from_guest: Copy a block of data from domain space.
   91.76 - * @to:   Machine address.
   91.77 - * @from: Physical address to a xencomm buffer descriptor.
   91.78 - * @n:    Number of bytes to copy.
   91.79 - * @skip: Number of bytes from the start to skip.
   91.80 - *
   91.81 - * Copy data from domain to hypervisor.
   91.82 - *
   91.83 - * Returns number of bytes that could not be copied.
   91.84 - * On success, this will be zero.
   91.85 - */
   91.86 -unsigned long
   91.87 -xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
   91.88 -        unsigned int skip)
   91.89 -{
   91.90 -    struct xencomm_desc *desc;
   91.91 -    unsigned int from_pos = 0;
   91.92 -    unsigned int to_pos = 0;
   91.93 -    unsigned int i = 0;
   91.94 -
   91.95 -    /* first we need to access the descriptor */
   91.96 -    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
   91.97 -    if (desc == NULL)
   91.98 -        return n;
   91.99 -
  91.100 -    if (desc->magic != XENCOMM_MAGIC) {
  91.101 -        printk("%s: error: %p magic was 0x%x\n",
  91.102 -               __func__, desc, desc->magic);
  91.103 -        return n;
  91.104 -    }
  91.105 -
  91.106 -    /* iterate through the descriptor, copying up to a page at a time */
  91.107 -    while ((to_pos < n) && (i < desc->nr_addrs)) {
  91.108 -        unsigned long src_paddr = desc->address[i];
  91.109 -        unsigned int pgoffset;
  91.110 -        unsigned int chunksz;
  91.111 -        unsigned int chunk_skip;
  91.112 -
  91.113 -        if (src_paddr == XENCOMM_INVALID) {
  91.114 -            i++;
  91.115 -            continue;
  91.116 -        }
  91.117 -
  91.118 -        pgoffset = src_paddr % PAGE_SIZE;
  91.119 -        chunksz = PAGE_SIZE - pgoffset;
  91.120 -
  91.121 -        chunk_skip = min(chunksz, skip);
  91.122 -        from_pos += chunk_skip;
  91.123 -        chunksz -= chunk_skip;
  91.124 -        skip -= chunk_skip;
  91.125 -
  91.126 -        if (skip == 0) {
  91.127 -            unsigned long src_maddr;
  91.128 -            unsigned long dest = (unsigned long)to + to_pos;
  91.129 -            unsigned int bytes = min(chunksz, n - to_pos);
  91.130 -
  91.131 -            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
  91.132 -            if (src_maddr == 0)
  91.133 -                return n - to_pos;
  91.134 -
  91.135 -            if (xencomm_debug)
  91.136 -                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
  91.137 -            memcpy((void *)dest, (void *)src_maddr, bytes);
  91.138 -            from_pos += bytes;
  91.139 -            to_pos += bytes;
  91.140 -        }
  91.141 -
  91.142 -        i++;
  91.143 -    }
  91.144 -
  91.145 -    return n - to_pos;
  91.146 -}
  91.147 -
  91.148 -/**
  91.149 - * xencomm_copy_to_guest: Copy a block of data to domain space.
  91.150 - * @to:     Physical address to xencomm buffer descriptor.
  91.151 - * @from:   Machine address.
  91.152 - * @n:      Number of bytes to copy.
  91.153 - * @skip: Number of bytes from the start to skip.
  91.154 - *
  91.155 - * Copy data from hypervisor to domain.
  91.156 - *
  91.157 - * Returns number of bytes that could not be copied.
  91.158 - * On success, this will be zero.
  91.159 - */
  91.160 -unsigned long
  91.161 -xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
  91.162 -        unsigned int skip)
  91.163 -{
  91.164 -    struct xencomm_desc *desc;
  91.165 -    unsigned int from_pos = 0;
  91.166 -    unsigned int to_pos = 0;
  91.167 -    unsigned int i = 0;
  91.168 -
  91.169 -    /* first we need to access the descriptor */
  91.170 -    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
  91.171 -    if (desc == NULL)
  91.172 -        return n;
  91.173 -
  91.174 -    if (desc->magic != XENCOMM_MAGIC) {
  91.175 -        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
  91.176 -        return n;
  91.177 -    }
  91.178 -
  91.179 -    /* iterate through the descriptor, copying up to a page at a time */
  91.180 -    while ((from_pos < n) && (i < desc->nr_addrs)) {
  91.181 -        unsigned long dest_paddr = desc->address[i];
  91.182 -        unsigned int pgoffset;
  91.183 -        unsigned int chunksz;
  91.184 -        unsigned int chunk_skip;
  91.185 -
  91.186 -        if (dest_paddr == XENCOMM_INVALID) {
  91.187 -            i++;
  91.188 -            continue;
  91.189 -        }
  91.190 -
  91.191 -        pgoffset = dest_paddr % PAGE_SIZE;
  91.192 -        chunksz = PAGE_SIZE - pgoffset;
  91.193 -
  91.194 -        chunk_skip = min(chunksz, skip);
  91.195 -        to_pos += chunk_skip;
  91.196 -        chunksz -= chunk_skip;
  91.197 -        skip -= chunk_skip;
  91.198 -
  91.199 -        if (skip == 0) {
  91.200 -            unsigned long dest_maddr;
  91.201 -            unsigned long source = (unsigned long)from + from_pos;
  91.202 -            unsigned int bytes = min(chunksz, n - from_pos);
  91.203 -
  91.204 -            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
  91.205 -            if (dest_maddr == 0)
  91.206 -                return -1;
  91.207 -
  91.208 -            if (xencomm_debug)
  91.209 -                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
  91.210 -            memcpy((void *)dest_maddr, (void *)source, bytes);
  91.211 -            from_pos += bytes;
  91.212 -            to_pos += bytes;
  91.213 -        }
  91.214 -
  91.215 -        i++;
  91.216 -    }
  91.217 -
  91.218 -    return n - from_pos;
  91.219 -}
  91.220 -
  91.221 -/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
  91.222 - * exhausted pages to XENCOMM_INVALID. */
  91.223 -int xencomm_add_offset(void *handle, unsigned int bytes)
  91.224 -{
  91.225 -    struct xencomm_desc *desc;
  91.226 -    int i = 0;
  91.227 -
  91.228 -    /* first we need to access the descriptor */
  91.229 -    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
  91.230 -    if (desc == NULL)
  91.231 -        return -1;
  91.232 -
  91.233 -    if (desc->magic != XENCOMM_MAGIC) {
  91.234 -        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
  91.235 -        return -1;
  91.236 -    }
  91.237 -
  91.238 -    /* iterate through the descriptor incrementing addresses */
  91.239 -    while ((bytes > 0) && (i < desc->nr_addrs)) {
  91.240 -        unsigned long dest_paddr = desc->address[i];
  91.241 -        unsigned int pgoffset;
  91.242 -        unsigned int chunksz;
  91.243 -        unsigned int chunk_skip;
  91.244 -
  91.245 -        if (dest_paddr == XENCOMM_INVALID) {
  91.246 -            i++;
  91.247 -            continue;
  91.248 -        }
  91.249 -
  91.250 -        pgoffset = dest_paddr % PAGE_SIZE;
  91.251 -        chunksz = PAGE_SIZE - pgoffset;
  91.252 -
  91.253 -        chunk_skip = min(chunksz, bytes);
  91.254 -        if (chunk_skip == chunksz) {
  91.255 -            /* exhausted this page */
  91.256 -            desc->address[i] = XENCOMM_INVALID;
  91.257 -        } else {
  91.258 -            desc->address[i] += chunk_skip;
  91.259 -        }
  91.260 -        bytes -= chunk_skip;
  91.261 -
  91.262 -	i++;
  91.263 -    }
  91.264 -    return 0;
  91.265 -}
  91.266 -
  91.267 -int xencomm_handle_is_null(void *ptr)
  91.268 -{
  91.269 -    struct xencomm_desc *desc;
  91.270 -
  91.271 -    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
  91.272 -    if (desc == NULL)
  91.273 -        return 1;
  91.274 -
  91.275 -    return (desc->nr_addrs == 0);
  91.276 -}
  91.277 -
    92.1 --- a/xen/arch/powerpc/xen.lds.S	Thu Dec 14 08:54:54 2006 -0700
    92.2 +++ b/xen/arch/powerpc/xen.lds.S	Thu Dec 14 08:57:36 2006 -0700
    92.3 @@ -12,12 +12,12 @@ SEARCH_DIR("=/usr/local/lib64"); SEARCH_
    92.4     __DYNAMIC = 0;    */
    92.5  PHDRS
    92.6  {
    92.7 -  text PT_LOAD FILEHDR PHDRS;
    92.8 +  text PT_LOAD;
    92.9  }   
   92.10  SECTIONS
   92.11  {
   92.12 +  . = 0x00400000;
   92.13    /* Read-only sections, merged into text segment: */
   92.14 -  PROVIDE (__executable_start = 0x10000000); . = 0x10000000 + SIZEOF_HEADERS;
   92.15    .interp         : { *(.interp) } :text
   92.16    .hash           : { *(.hash) }
   92.17    .dynsym         : { *(.dynsym) }
   92.18 @@ -111,8 +111,6 @@ SECTIONS
   92.19      SORT(CONSTRUCTORS)
   92.20    }
   92.21  
   92.22 -  /* Xen addition */
   92.23 -
   92.24    . = ALIGN(32);
   92.25    __setup_start = .;
   92.26    .setup.init : { *(.setup.init) }
   92.27 @@ -131,8 +129,6 @@ SECTIONS
   92.28    . = ALIGN(STACK_SIZE);
   92.29    __per_cpu_end = .;
   92.30  
   92.31 -  /* end Xen addition */
   92.32 -
   92.33    .data1          : { *(.data1) }
   92.34    .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   92.35    .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
    93.1 --- a/xen/arch/x86/crash.c	Thu Dec 14 08:54:54 2006 -0700
    93.2 +++ b/xen/arch/x86/crash.c	Thu Dec 14 08:57:36 2006 -0700
    93.3 @@ -58,9 +58,9 @@ static int crash_nmi_callback(struct cpu
    93.4  static void smp_send_nmi_allbutself(void)
    93.5  {
    93.6      cpumask_t allbutself = cpu_online_map;
    93.7 -
    93.8      cpu_clear(smp_processor_id(), allbutself);
    93.9 -    send_IPI_mask(allbutself, APIC_DM_NMI);
   93.10 +    if ( !cpus_empty(allbutself) )
   93.11 +        send_IPI_mask(allbutself, APIC_DM_NMI);
   93.12  }
   93.13  
   93.14  static void nmi_shootdown_cpus(void)
    94.1 --- a/xen/arch/x86/domain_build.c	Thu Dec 14 08:54:54 2006 -0700
    94.2 +++ b/xen/arch/x86/domain_build.c	Thu Dec 14 08:57:36 2006 -0700
    94.3 @@ -321,8 +321,11 @@ int construct_dom0(struct domain *d,
    94.4      if ( (rc = parseelfimage(&dsi)) != 0 )
    94.5          return rc;
    94.6  
    94.7 -    dom0_pae = (dsi.pae_kernel != PAEKERN_no);
    94.8      xen_pae  = (CONFIG_PAGING_LEVELS == 3);
    94.9 +    if (dsi.pae_kernel == PAEKERN_bimodal)
   94.10 +        dom0_pae = xen_pae; 
   94.11 +    else
   94.12 +        dom0_pae = (dsi.pae_kernel != PAEKERN_no);
   94.13      if ( dom0_pae != xen_pae )
   94.14      {
   94.15          printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n",
   94.16 @@ -330,7 +333,8 @@ int construct_dom0(struct domain *d,
   94.17          return -EINVAL;
   94.18      }
   94.19  
   94.20 -    if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 )
   94.21 +    if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 ||
   94.22 +            dsi.pae_kernel == PAEKERN_bimodal) )
   94.23              set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
   94.24  
   94.25      if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
    95.1 --- a/xen/arch/x86/mm.c	Thu Dec 14 08:54:54 2006 -0700
    95.2 +++ b/xen/arch/x86/mm.c	Thu Dec 14 08:57:36 2006 -0700
    95.3 @@ -2951,7 +2951,17 @@ long arch_memory_op(int op, XEN_GUEST_HA
    95.4          guest_physmap_add_page(d, xatp.gpfn, mfn);
    95.5  
    95.6          UNLOCK_BIGLOCK(d);
    95.7 -        
    95.8 +
    95.9 +        /* If we're doing FAST_FAULT_PATH, then shadow mode may have
   95.10 +           cached the fact that this is an mmio region in the shadow
   95.11 +           page tables.  Blow the tables away to remove the cache.
   95.12 +           This is pretty heavy handed, but this is a rare operation
   95.13 +           (it might happen a dozen times during boot and then never
   95.14 +           again), so it doesn't matter too much. */
   95.15 +        shadow_lock(d);
   95.16 +        shadow_blow_tables(d);
   95.17 +        shadow_unlock(d);
   95.18 +
   95.19          put_domain(d);
   95.20  
   95.21          break;
    96.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Dec 14 08:54:54 2006 -0700
    96.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Dec 14 08:57:36 2006 -0700
    96.3 @@ -791,7 +791,7 @@ void shadow_prealloc(struct domain *d, u
    96.4  
    96.5  /* Deliberately free all the memory we can: this will tear down all of
    96.6   * this domain's shadows */
    96.7 -static void shadow_blow_tables(struct domain *d) 
    96.8 +void shadow_blow_tables(struct domain *d) 
    96.9  {
   96.10      struct list_head *l, *t;
   96.11      struct shadow_page_info *sp;
   96.12 @@ -3123,7 +3123,7 @@ static int shadow_log_dirty_op(
   96.13   out:
   96.14      shadow_unlock(d);
   96.15      domain_unpause(d);
   96.16 -    return 0;
   96.17 +    return rv;
   96.18  }
   96.19  
   96.20  
    97.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Dec 14 08:54:54 2006 -0700
    97.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Dec 14 08:57:36 2006 -0700
    97.3 @@ -3488,6 +3488,9 @@ sh_update_cr3(struct vcpu *v)
    97.4                                         ? SH_type_l2h_shadow 
    97.5                                         : SH_type_l2_shadow);
    97.6              }
    97.7 +            else
    97.8 +                /* The guest is not present: clear out the shadow. */
    97.9 +                sh_set_toplevel_shadow(v, i, _mfn(INVALID_MFN), 0); 
   97.10          }
   97.11      }
   97.12  #elif GUEST_PAGING_LEVELS == 4
    98.1 --- a/xen/arch/x86/numa.c	Thu Dec 14 08:54:54 2006 -0700
    98.2 +++ b/xen/arch/x86/numa.c	Thu Dec 14 08:57:36 2006 -0700
    98.3 @@ -214,7 +214,7 @@ void __init numa_initmem_init(unsigned l
    98.4  
    98.5  __cpuinit void numa_add_cpu(int cpu)
    98.6  {
    98.7 -	set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
    98.8 +	cpu_set(cpu, node_to_cpumask[cpu_to_node(cpu)]);
    98.9  } 
   98.10  
   98.11  void __cpuinit numa_set_node(int cpu, int node)
    99.1 --- a/xen/common/Makefile	Thu Dec 14 08:54:54 2006 -0700
    99.2 +++ b/xen/common/Makefile	Thu Dec 14 08:57:36 2006 -0700
    99.3 @@ -32,5 +32,7 @@ obj-$(perfc)       += perfc.o
    99.4  obj-$(crash_debug) += gdbstub.o
    99.5  obj-$(xenoprof)    += xenoprof.o
    99.6  
    99.7 +obj-$(CONFIG_XENCOMM) += xencomm.o
    99.8 +
    99.9  # Object file contains changeset and compiler information.
   99.10  version.o: $(BASEDIR)/include/xen/compile.h
   100.1 --- a/xen/common/domain.c	Thu Dec 14 08:54:54 2006 -0700
   100.2 +++ b/xen/common/domain.c	Thu Dec 14 08:57:36 2006 -0700
   100.3 @@ -238,7 +238,11 @@ void domain_kill(struct domain *d)
   100.4  
   100.5  void __domain_crash(struct domain *d)
   100.6  {
   100.7 -    if ( d == current->domain )
   100.8 +    if ( test_bit(_DOMF_shutdown, &d->domain_flags) )
   100.9 +    {
  100.10 +        /* Print nothing: the domain is already shutting down. */
  100.11 +    }
  100.12 +    else if ( d == current->domain )
  100.13      {
  100.14          printk("Domain %d (vcpu#%d) crashed on cpu#%d:\n",
  100.15                 d->domain_id, current->vcpu_id, smp_processor_id());
  100.16 @@ -346,18 +350,27 @@ void domain_destroy(struct domain *d)
  100.17      send_guest_global_virq(dom0, VIRQ_DOM_EXC);
  100.18  }
  100.19  
  100.20 -void vcpu_pause(struct vcpu *v)
  100.21 +static void vcpu_pause_setup(struct vcpu *v)
  100.22  {
  100.23 -    ASSERT(v != current);
  100.24 -
  100.25      spin_lock(&v->pause_lock);
  100.26      if ( v->pause_count++ == 0 )
  100.27          set_bit(_VCPUF_paused, &v->vcpu_flags);
  100.28      spin_unlock(&v->pause_lock);
  100.29 +}
  100.30  
  100.31 +void vcpu_pause(struct vcpu *v)
  100.32 +{
  100.33 +    ASSERT(v != current);
  100.34 +    vcpu_pause_setup(v);
  100.35      vcpu_sleep_sync(v);
  100.36  }
  100.37  
  100.38 +void vcpu_pause_nosync(struct vcpu *v)
  100.39 +{
  100.40 +    vcpu_pause_setup(v);
  100.41 +    vcpu_sleep_nosync(v);
  100.42 +}
  100.43 +
  100.44  void vcpu_unpause(struct vcpu *v)
  100.45  {
  100.46      int wake;
   101.1 --- a/xen/common/elf.c	Thu Dec 14 08:54:54 2006 -0700
   101.2 +++ b/xen/common/elf.c	Thu Dec 14 08:57:36 2006 -0700
   101.3 @@ -216,16 +216,6 @@ int parseelfimage(struct domain_setup_in
   101.4          return -EINVAL;
   101.5      }
   101.6  
   101.7 -    /* Find the section-header strings table. */
   101.8 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
   101.9 -    {
  101.10 -        printk("ELF image has no section-header strings table (shstrtab).\n");
  101.11 -        return -EINVAL;
  101.12 -    }
  101.13 -    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
  101.14 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
  101.15 -    shstrtab = image + shdr->sh_offset;
  101.16 -
  101.17      dsi->__elfnote_section = NULL;
  101.18      dsi->__xen_guest_string = NULL;
  101.19  
  101.20 @@ -244,6 +234,16 @@ int parseelfimage(struct domain_setup_in
  101.21      /* Fall back to looking for the special '__xen_guest' section. */
  101.22      if ( dsi->__elfnote_section == NULL )
  101.23      {
  101.24 +        /* Find the section-header strings table. */
  101.25 +        if ( ehdr->e_shstrndx == SHN_UNDEF )
  101.26 +        {
  101.27 +            printk("ELF image has no section-header strings table.\n");
  101.28 +            return -EINVAL;
  101.29 +        }
  101.30 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
  101.31 +                            (ehdr->e_shstrndx*ehdr->e_shentsize));
  101.32 +        shstrtab = image + shdr->sh_offset;
  101.33 +
  101.34          for ( h = 0; h < ehdr->e_shnum; h++ )
  101.35          {
  101.36              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
  101.37 @@ -286,6 +286,8 @@ int parseelfimage(struct domain_setup_in
  101.38      }
  101.39  
  101.40      /*
  101.41 +     * A "bimodal" ELF note indicates the kernel will adjust to the
  101.42 +     * current paging mode, including handling extended cr3 syntax.
  101.43       * If we have ELF notes then PAE=yes implies that we must support
  101.44       * the extended cr3 syntax. Otherwise we need to find the
  101.45       * [extended-cr3] syntax in the __xen_guest string.
  101.46 @@ -294,9 +296,10 @@ int parseelfimage(struct domain_setup_in
  101.47      if ( dsi->__elfnote_section )
  101.48      {
  101.49          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
  101.50 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  101.51 +        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
  101.52 +            dsi->pae_kernel = PAEKERN_bimodal;
  101.53 +        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  101.54              dsi->pae_kernel = PAEKERN_extended_cr3;
  101.55 -
  101.56      }
  101.57      else
  101.58      {
   102.1 --- a/xen/common/gdbstub.c	Thu Dec 14 08:54:54 2006 -0700
   102.2 +++ b/xen/common/gdbstub.c	Thu Dec 14 08:57:36 2006 -0700
   102.3 @@ -42,6 +42,7 @@
   102.4  #include <xen/init.h>
   102.5  #include <xen/smp.h>
   102.6  #include <xen/console.h>
   102.7 +#include <xen/errno.h>
   102.8  
   102.9  /* Printk isn't particularly safe just after we've trapped to the
  102.10     debugger. so avoid it. */
   103.1 --- a/xen/common/kexec.c	Thu Dec 14 08:54:54 2006 -0700
   103.2 +++ b/xen/common/kexec.c	Thu Dec 14 08:57:36 2006 -0700
   103.3 @@ -140,13 +140,21 @@ void machine_crash_kexec(void)
   103.4  
   103.5  static void do_crashdump_trigger(unsigned char key)
   103.6  {
   103.7 -	printk("triggering crashdump\n");
   103.8 -	machine_crash_kexec();
   103.9 +    int pos = (test_bit(KEXEC_FLAG_CRASH_POS, &kexec_flags) != 0);
  103.10 +    if ( test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) )
  103.11 +    {
  103.12 +        printk("'%c' pressed -> triggering crashdump\n", key);
  103.13 +        machine_crash_kexec();
  103.14 +    }
  103.15 +    else
  103.16 +    {
  103.17 +        printk("'%c' pressed -> no crash kernel loaded -- not triggering crashdump\n", key);
  103.18 +    }
  103.19  }
  103.20  
  103.21  static __init int register_crashdump_trigger(void)
  103.22  {
  103.23 -	register_keyhandler('c', do_crashdump_trigger, "trigger a crashdump");
  103.24 +	register_keyhandler('C', do_crashdump_trigger, "trigger a crashdump");
  103.25  	return 0;
  103.26  }
  103.27  __initcall(register_crashdump_trigger);
   104.1 --- a/xen/common/sched_credit.c	Thu Dec 14 08:54:54 2006 -0700
   104.2 +++ b/xen/common/sched_credit.c	Thu Dec 14 08:57:36 2006 -0700
   104.3 @@ -56,7 +56,12 @@
   104.4  #define CSCHED_PRI_TS_UNDER     -1      /* time-share w/ credits */
   104.5  #define CSCHED_PRI_TS_OVER      -2      /* time-share w/o credits */
   104.6  #define CSCHED_PRI_IDLE         -64     /* idle */
   104.7 -#define CSCHED_PRI_TS_PARKED    -65     /* time-share w/ capped credits */
   104.8 +
   104.9 +
  104.10 +/*
  104.11 + * Flags
  104.12 + */
  104.13 +#define CSCHED_FLAG_VCPU_PARKED 0x0001  /* VCPU over capped credits */
  104.14  
  104.15  
  104.16  /*
  104.17 @@ -100,26 +105,21 @@
  104.18      _MACRO(vcpu_wake_onrunq)                \
  104.19      _MACRO(vcpu_wake_runnable)              \
  104.20      _MACRO(vcpu_wake_not_runnable)          \
  104.21 +    _MACRO(vcpu_park)                       \
  104.22 +    _MACRO(vcpu_unpark)                     \
  104.23      _MACRO(tickle_local_idler)              \
  104.24      _MACRO(tickle_local_over)               \
  104.25      _MACRO(tickle_local_under)              \
  104.26      _MACRO(tickle_local_other)              \
  104.27      _MACRO(tickle_idlers_none)              \
  104.28      _MACRO(tickle_idlers_some)              \
  104.29 -    _MACRO(vcpu_migrate)                    \
  104.30      _MACRO(load_balance_idle)               \
  104.31      _MACRO(load_balance_over)               \
  104.32      _MACRO(load_balance_other)              \
  104.33      _MACRO(steal_trylock_failed)            \
  104.34 -    _MACRO(steal_peer_down)                 \
  104.35      _MACRO(steal_peer_idle)                 \
  104.36 -    _MACRO(steal_peer_running)              \
  104.37 -    _MACRO(steal_peer_pinned)               \
  104.38 -    _MACRO(steal_peer_migrating)            \
  104.39 -    _MACRO(steal_peer_best_idler)           \
  104.40 -    _MACRO(steal_loner_candidate)           \
  104.41 -    _MACRO(steal_loner_signal)              \
  104.42 -    _MACRO(cpu_pick)                        \
  104.43 +    _MACRO(migrate_queued)                  \
  104.44 +    _MACRO(migrate_running)                 \
  104.45      _MACRO(dom_init)                        \
  104.46      _MACRO(dom_destroy)                     \
  104.47      _MACRO(vcpu_init)                       \
  104.48 @@ -146,7 +146,7 @@
  104.49      struct                                      \
  104.50      {                                           \
  104.51          CSCHED_STATS_EXPAND(CSCHED_STAT_DEFINE) \
  104.52 -    } stats
  104.53 +    } stats;
  104.54  
  104.55  #define CSCHED_STATS_PRINTK()                   \
  104.56      do                                          \
  104.57 @@ -155,14 +155,27 @@
  104.58          CSCHED_STATS_EXPAND(CSCHED_STAT_PRINTK) \
  104.59      } while ( 0 )
  104.60  
  104.61 -#define CSCHED_STAT_CRANK(_X)   (CSCHED_STAT(_X)++)
  104.62 +#define CSCHED_STAT_CRANK(_X)               (CSCHED_STAT(_X)++)
  104.63 +
  104.64 +#define CSCHED_VCPU_STATS_RESET(_V)                     \
  104.65 +    do                                                  \
  104.66 +    {                                                   \
  104.67 +        memset(&(_V)->stats, 0, sizeof((_V)->stats));   \
  104.68 +    } while ( 0 )
  104.69 +
  104.70 +#define CSCHED_VCPU_STAT_CRANK(_V, _X)      (((_V)->stats._X)++)
  104.71 +
  104.72 +#define CSCHED_VCPU_STAT_SET(_V, _X, _Y)    (((_V)->stats._X) = (_Y))
  104.73  
  104.74  #else /* CSCHED_STATS */
  104.75  
  104.76 -#define CSCHED_STATS_RESET()    do {} while ( 0 )
  104.77 -#define CSCHED_STATS_DEFINE()   do {} while ( 0 )
  104.78 -#define CSCHED_STATS_PRINTK()   do {} while ( 0 )
  104.79 -#define CSCHED_STAT_CRANK(_X)   do {} while ( 0 )
  104.80 +#define CSCHED_STATS_RESET()                do {} while ( 0 )
  104.81 +#define CSCHED_STATS_DEFINE()
  104.82 +#define CSCHED_STATS_PRINTK()               do {} while ( 0 )
  104.83 +#define CSCHED_STAT_CRANK(_X)               do {} while ( 0 )
  104.84 +#define CSCHED_VCPU_STATS_RESET(_V)         do {} while ( 0 )
  104.85 +#define CSCHED_VCPU_STAT_CRANK(_V, _X)      do {} while ( 0 )
  104.86 +#define CSCHED_VCPU_STAT_SET(_V, _X, _Y)    do {} while ( 0 )
  104.87  
  104.88  #endif /* CSCHED_STATS */
  104.89  
  104.90 @@ -184,14 +197,18 @@ struct csched_vcpu {
  104.91      struct csched_dom *sdom;
  104.92      struct vcpu *vcpu;
  104.93      atomic_t credit;
  104.94 +    uint16_t flags;
  104.95      int16_t pri;
  104.96 +#ifdef CSCHED_STATS
  104.97      struct {
  104.98          int credit_last;
  104.99          uint32_t credit_incr;
 104.100          uint32_t state_active;
 104.101          uint32_t state_idle;
 104.102 -        uint32_t migrate;
 104.103 +        uint32_t migrate_q;
 104.104 +        uint32_t migrate_r;
 104.105      } stats;
 104.106 +#endif
 104.107  };
 104.108  
 104.109  /*
 104.110 @@ -219,7 +236,7 @@ struct csched_private {
 104.111      uint32_t credit;
 104.112      int credit_balance;
 104.113      uint32_t runq_sort;
 104.114 -    CSCHED_STATS_DEFINE();
 104.115 +    CSCHED_STATS_DEFINE()
 104.116  };
 104.117  
 104.118  
 104.119 @@ -231,6 +248,15 @@ static struct csched_private csched_priv
 104.120  
 104.121  
 104.122  static inline int
 104.123 +__cycle_cpu(int cpu, const cpumask_t *mask)
 104.124 +{
 104.125 +    int nxt = next_cpu(cpu, *mask);
 104.126 +    if (nxt == NR_CPUS)
 104.127 +        nxt = first_cpu(*mask);
 104.128 +    return nxt;
 104.129 +}
 104.130 +
 104.131 +static inline int
 104.132  __vcpu_on_runq(struct csched_vcpu *svc)
 104.133  {
 104.134      return !list_empty(&svc->runq_elem);
 104.135 @@ -375,118 +401,138 @@ static inline void
 104.136  #define CSCHED_VCPU_CHECK(_vc)
 104.137  #endif
 104.138  
 104.139 -/*
 104.140 - * Indicates which of two given idlers is most efficient to run
 104.141 - * an additional VCPU.
 104.142 - *
 104.143 - * Returns:
 104.144 - *  0:           They are the same.
 104.145 - *  negative:    One is less efficient than Two.
 104.146 - *  positive:    One is more efficient than Two.
 104.147 - */
 104.148 -static int
 104.149 -csched_idler_compare(int one, int two)
 104.150 -{
 104.151 -    cpumask_t idlers;
 104.152 -    cpumask_t one_idlers;
 104.153 -    cpumask_t two_idlers;
 104.154 -
 104.155 -    idlers = csched_priv.idlers;
 104.156 -    cpu_clear(one, idlers);
 104.157 -    cpu_clear(two, idlers);
 104.158 -
 104.159 -    if ( cpu_isset(one, cpu_core_map[two]) )
 104.160 -    {
 104.161 -        cpus_and(one_idlers, idlers, cpu_sibling_map[one]);
 104.162 -        cpus_and(two_idlers, idlers, cpu_sibling_map[two]);
 104.163 -    }
 104.164 -    else
 104.165 -    {
 104.166 -        cpus_and(one_idlers, idlers, cpu_core_map[one]);
 104.167 -        cpus_and(two_idlers, idlers, cpu_core_map[two]);
 104.168 -    }
 104.169 -
 104.170 -    return cpus_weight(one_idlers) - cpus_weight(two_idlers);
 104.171 -}
 104.172 -
 104.173  static inline int
 104.174 -__csched_queued_vcpu_is_stealable(int local_cpu, struct vcpu *vc)
 104.175 +__csched_vcpu_is_migrateable(struct vcpu *vc, int dest_cpu)
 104.176  {
 104.177      /*
 104.178       * Don't pick up work that's in the peer's scheduling tail. Also only pick
 104.179       * up work that's allowed to run on our CPU.
 104.180       */
 104.181 -    if ( unlikely(test_bit(_VCPUF_running, &vc->vcpu_flags)) )
 104.182 -    {
 104.183 -        CSCHED_STAT_CRANK(steal_peer_running);
 104.184 -        return 0;
 104.185 -    }
 104.186 -
 104.187 -    if ( unlikely(!cpu_isset(local_cpu, vc->cpu_affinity)) )
 104.188 -    {
 104.189 -        CSCHED_STAT_CRANK(steal_peer_pinned);
 104.190 -        return 0;
 104.191 -    }
 104.192 -
 104.193 -    return 1;
 104.194 +    return !test_bit(_VCPUF_running, &vc->vcpu_flags) &&
 104.195 +           cpu_isset(dest_cpu, vc->cpu_affinity);
 104.196  }
 104.197  
 104.198 -static inline int
 104.199 -__csched_running_vcpu_is_stealable(int local_cpu, struct vcpu *vc)
 104.200 +static int
 104.201 +csched_cpu_pick(struct vcpu *vc)
 104.202  {
 104.203 -    BUG_ON( is_idle_vcpu(vc) );
 104.204 +    cpumask_t cpus;
 104.205 +    cpumask_t idlers;
 104.206 +    int cpu;
 104.207 +
 104.208 +    /*
 104.209 +     * Pick from online CPUs in VCPU's affinity mask, giving a
 104.210 +     * preference to its current processor if it's in there.
 104.211 +     */
 104.212 +    cpus_and(cpus, cpu_online_map, vc->cpu_affinity);
 104.213 +    cpu = cpu_isset(vc->processor, cpus)
 104.214 +            ? vc->processor
 104.215 +            : __cycle_cpu(vc->processor, &cpus);
 104.216 +    ASSERT( !cpus_empty(cpus) && cpu_isset(cpu, cpus) );
 104.217  
 104.218 -    if ( unlikely(!cpu_isset(local_cpu, vc->cpu_affinity)) )
 104.219 +    /*
 104.220 +     * Try to find an idle processor within the above constraints.
 104.221 +     *
 104.222 +     * In multi-core and multi-threaded CPUs, not all idle execution
 104.223 +     * vehicles are equal!
 104.224 +     *
 104.225 +     * We give preference to the idle execution vehicle with the most
 104.226 +     * idling neighbours in its grouping. This distributes work across
 104.227 +     * distinct cores first and guarantees we don't do something stupid
 104.228 +     * like run two VCPUs on co-hyperthreads while there are idle cores
 104.229 +     * or sockets.
 104.230 +     */
 104.231 +    idlers = csched_priv.idlers;
 104.232 +    cpu_set(cpu, idlers);
 104.233 +    cpus_and(cpus, cpus, idlers);
 104.234 +    cpu_clear(cpu, cpus);
 104.235 +
 104.236 +    while ( !cpus_empty(cpus) )
 104.237      {
 104.238 -        CSCHED_STAT_CRANK(steal_peer_pinned);
 104.239 -        return 0;
 104.240 +        cpumask_t cpu_idlers;
 104.241 +        cpumask_t nxt_idlers;
 104.242 +        int nxt;
 104.243 +
 104.244 +        nxt = __cycle_cpu(cpu, &cpus);
 104.245 +
 104.246 +        if ( cpu_isset(cpu, cpu_core_map[nxt]) )
 104.247 +        {
 104.248 +            ASSERT( cpu_isset(nxt, cpu_core_map[cpu]) );
 104.249 +            cpus_and(cpu_idlers, idlers, cpu_sibling_map[cpu]);
 104.250 +            cpus_and(nxt_idlers, idlers, cpu_sibling_map[nxt]);
 104.251 +        }
 104.252 +        else
 104.253 +        {
 104.254 +            ASSERT( !cpu_isset(nxt, cpu_core_map[cpu]) );
 104.255 +            cpus_and(cpu_idlers, idlers, cpu_core_map[cpu]);
 104.256 +            cpus_and(nxt_idlers, idlers, cpu_core_map[nxt]);
 104.257 +        }
 104.258 +
 104.259 +        if ( cpus_weight(cpu_idlers) < cpus_weight(nxt_idlers) )
 104.260 +        {
 104.261 +            cpu = nxt;
 104.262 +            cpu_clear(cpu, cpus);
 104.263 +        }
 104.264 +        else
 104.265 +        {
 104.266 +            cpus_andnot(cpus, cpus, nxt_idlers);
 104.267 +        }
 104.268      }
 104.269  
 104.270 -    if ( test_bit(_VCPUF_migrating, &vc->vcpu_flags) )
 104.271 -    {
 104.272 -        CSCHED_STAT_CRANK(steal_peer_migrating);
 104.273 -        return 0;
 104.274 -    }
 104.275 -
 104.276 -    if ( csched_idler_compare(local_cpu, vc->processor) <= 0 )
 104.277 -    {
 104.278 -        CSCHED_STAT_CRANK(steal_peer_best_idler);
 104.279 -        return 0;
 104.280 -    }
 104.281 -
 104.282 -    return 1;
 104.283 +    return cpu;
 104.284  }
 104.285  
 104.286 -static void
 104.287 -csched_vcpu_acct(struct csched_vcpu *svc, int credit_dec)
 104.288 +static inline void
 104.289 +__csched_vcpu_acct_start(struct csched_vcpu *svc)
 104.290  {
 104.291      struct csched_dom * const sdom = svc->sdom;
 104.292      unsigned long flags;
 104.293  
 104.294 -    /* Update credits */
 104.295 -    atomic_sub(credit_dec, &svc->credit);
 104.296 +    spin_lock_irqsave(&csched_priv.lock, flags);
 104.297  
 104.298 -    /* Put this VCPU and domain back on the active list if it was idling */
 104.299      if ( list_empty(&svc->active_vcpu_elem) )
 104.300      {
 104.301 -        spin_lock_irqsave(&csched_priv.lock, flags);
 104.302 +        CSCHED_VCPU_STAT_CRANK(svc, state_active);
 104.303 +        CSCHED_STAT_CRANK(acct_vcpu_active);
 104.304  
 104.305 -        if ( list_empty(&svc->active_vcpu_elem) )
 104.306 +        sdom->active_vcpu_count++;
 104.307 +        list_add(&svc->active_vcpu_elem, &sdom->active_vcpu);
 104.308 +        if ( list_empty(&sdom->active_sdom_elem) )
 104.309          {
 104.310 -            CSCHED_STAT_CRANK(acct_vcpu_active);
 104.311 -            svc->stats.state_active++;
 104.312 +            list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom);
 104.313 +            csched_priv.weight += sdom->weight;
 104.314 +        }
 104.315 +    }
 104.316 +
 104.317 +    spin_unlock_irqrestore(&csched_priv.lock, flags);
 104.318 +}
 104.319 +
 104.320 +static inline void
 104.321 +__csched_vcpu_acct_stop_locked(struct csched_vcpu *svc)
 104.322 +{
 104.323 +    struct csched_dom * const sdom = svc->sdom;
 104.324  
 104.325 -            sdom->active_vcpu_count++;
 104.326 -            list_add(&svc->active_vcpu_elem, &sdom->active_vcpu);
 104.327 -            if ( list_empty(&sdom->active_sdom_elem) )
 104.328 -            {
 104.329 -                list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom);
 104.330 -                csched_priv.weight += sdom->weight;
 104.331 -            }
 104.332 -        }
 104.333 +    BUG_ON( list_empty(&svc->active_vcpu_elem) );
 104.334 +
 104.335 +    CSCHED_VCPU_STAT_CRANK(svc, state_idle);
 104.336 +    CSCHED_STAT_CRANK(acct_vcpu_idle);
 104.337  
 104.338 -        spin_unlock_irqrestore(&csched_priv.lock, flags);
 104.339 +    sdom->active_vcpu_count--;
 104.340 +    list_del_init(&svc->active_vcpu_elem);
 104.341 +    if ( list_empty(&sdom->active_vcpu) )
 104.342 +    {
 104.343 +        BUG_ON( csched_priv.weight < sdom->weight );
 104.344 +        list_del_init(&sdom->active_sdom_elem);
 104.345 +        csched_priv.weight -= sdom->weight;
 104.346      }
 104.347 +}
 104.348 +
 104.349 +static void
 104.350 +csched_vcpu_acct(unsigned int cpu)
 104.351 +{
 104.352 +    struct csched_vcpu * const svc = CSCHED_VCPU(current);
 104.353 +
 104.354 +    ASSERT( current->processor == cpu );
 104.355 +    ASSERT( svc->sdom != NULL );
 104.356  
 104.357      /*
 104.358       * If this VCPU's priority was boosted when it last awoke, reset it.
 104.359 @@ -495,25 +541,30 @@ csched_vcpu_acct(struct csched_vcpu *svc
 104.360       */
 104.361      if ( svc->pri == CSCHED_PRI_TS_BOOST )
 104.362          svc->pri = CSCHED_PRI_TS_UNDER;
 104.363 -}
 104.364  
 104.365 -static inline void
 104.366 -__csched_vcpu_acct_idle_locked(struct csched_vcpu *svc)
 104.367 -{
 104.368 -    struct csched_dom * const sdom = svc->sdom;
 104.369 -
 104.370 -    BUG_ON( list_empty(&svc->active_vcpu_elem) );
 104.371 +    /*
 104.372 +     * Update credits
 104.373 +     */
 104.374 +    atomic_sub(CSCHED_CREDITS_PER_TICK, &svc->credit);
 104.375  
 104.376 -    CSCHED_STAT_CRANK(acct_vcpu_idle);
 104.377 -    svc->stats.state_idle++;
 104.378 -
 104.379 -    sdom->active_vcpu_count--;
 104.380 -    list_del_init(&svc->active_vcpu_elem);
 104.381 -    if ( list_empty(&sdom->active_vcpu) )
 104.382 +    /*
 104.383 +     * Put this VCPU and domain back on the active list if it was
 104.384 +     * idling.
 104.385 +     *
 104.386 +     * If it's been active a while, check if we'd be better off
 104.387 +     * migrating it to run elsewhere (see multi-core and multi-thread
 104.388 +     * support in csched_cpu_pick()).
 104.389 +     */
 104.390 +    if ( list_empty(&svc->active_vcpu_elem) )
 104.391      {
 104.392 -        BUG_ON( csched_priv.weight < sdom->weight );
 104.393 -        list_del_init(&sdom->active_sdom_elem);
 104.394 -        csched_priv.weight -= sdom->weight;
 104.395 +        __csched_vcpu_acct_start(svc);
 104.396 +    }
 104.397 +    else if ( csched_cpu_pick(current) != cpu )
 104.398 +    {
 104.399 +        CSCHED_VCPU_STAT_CRANK(svc, migrate_r);
 104.400 +        CSCHED_STAT_CRANK(migrate_running);
 104.401 +        set_bit(_VCPUF_migrating, &current->vcpu_flags);
 104.402 +        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
 104.403      }
 104.404  }
 104.405  
 104.406 @@ -536,16 +587,11 @@ csched_vcpu_init(struct vcpu *vc)
 104.407      svc->sdom = sdom;
 104.408      svc->vcpu = vc;
 104.409      atomic_set(&svc->credit, 0);
 104.410 +    svc->flags = 0U;
 104.411      svc->pri = is_idle_domain(dom) ? CSCHED_PRI_IDLE : CSCHED_PRI_TS_UNDER;
 104.412 -    memset(&svc->stats, 0, sizeof(svc->stats));
 104.413 +    CSCHED_VCPU_STATS_RESET(svc);
 104.414      vc->sched_priv = svc;
 104.415  
 104.416 -    CSCHED_VCPU_CHECK(vc);
 104.417 -
 104.418 -    /* Attach fair-share VCPUs to the accounting list */
 104.419 -    if ( likely(sdom != NULL) )
 104.420 -        csched_vcpu_acct(svc, 0);
 104.421 -
 104.422      /* Allocate per-PCPU info */
 104.423      if ( unlikely(!CSCHED_PCPU(vc->processor)) )
 104.424      {
 104.425 @@ -554,7 +600,6 @@ csched_vcpu_init(struct vcpu *vc)
 104.426      }
 104.427  
 104.428      CSCHED_VCPU_CHECK(vc);
 104.429 -
 104.430      return 0;
 104.431  }
 104.432  
 104.433 @@ -573,7 +618,7 @@ csched_vcpu_destroy(struct vcpu *vc)
 104.434      spin_lock_irqsave(&csched_priv.lock, flags);
 104.435  
 104.436      if ( !list_empty(&svc->active_vcpu_elem) )
 104.437 -        __csched_vcpu_acct_idle_locked(svc);
 104.438 +        __csched_vcpu_acct_stop_locked(svc);
 104.439  
 104.440      spin_unlock_irqrestore(&csched_priv.lock, flags);
 104.441  
 104.442 @@ -634,9 +679,16 @@ csched_vcpu_wake(struct vcpu *vc)
 104.443       * This allows wake-to-run latency sensitive VCPUs to preempt
 104.444       * more CPU resource intensive VCPUs without impacting overall 
 104.445       * system fairness.
 104.446 +     *
 104.447 +     * The one exception is for VCPUs of capped domains unpausing
 104.448 +     * after earning credits they had overspent. We don't boost
 104.449 +     * those.
 104.450       */
 104.451 -    if ( svc->pri == CSCHED_PRI_TS_UNDER )
 104.452 +    if ( svc->pri == CSCHED_PRI_TS_UNDER &&
 104.453 +         !(svc->flags & CSCHED_FLAG_VCPU_PARKED) )
 104.454 +    {
 104.455          svc->pri = CSCHED_PRI_TS_BOOST;
 104.456 +    }
 104.457  
 104.458      /* Put the VCPU on the runq and tickle CPUs */
 104.459      __runq_insert(cpu, svc);
 104.460 @@ -710,71 +762,8 @@ csched_dom_init(struct domain *dom)
 104.461  static void
 104.462  csched_dom_destroy(struct domain *dom)
 104.463  {
 104.464 -    struct csched_dom * const sdom = CSCHED_DOM(dom);
 104.465 -
 104.466      CSCHED_STAT_CRANK(dom_destroy);
 104.467 -
 104.468 -    xfree(sdom);
 104.469 -}
 104.470 -
 104.471 -static int
 104.472 -csched_cpu_pick(struct vcpu *vc)
 104.473 -{
 104.474 -    cpumask_t cpus;
 104.475 -    int cpu, nxt;
 104.476 -
 104.477 -    CSCHED_STAT_CRANK(cpu_pick);
 104.478 -
 104.479 -    /*
 104.480 -     * Pick from online CPUs in VCPU's affinity mask, giving a
 104.481 -     * preference to its current processor if it's in there.
 104.482 -     */
 104.483 -    cpus_and(cpus, cpu_online_map, vc->cpu_affinity);
 104.484 -    ASSERT( !cpus_empty(cpus) );
 104.485 -    cpu = cpu_isset(vc->processor, cpus) ? vc->processor : first_cpu(cpus);
 104.486 -
 104.487 -    /*
 104.488 -     * Try to find an idle processor within the above constraints.
 104.489 -     */
 104.490 -    cpus_and(cpus, cpus, csched_priv.idlers);
 104.491 -    if ( !cpus_empty(cpus) )
 104.492 -    {
 104.493 -        cpu = cpu_isset(cpu, cpus) ? cpu : first_cpu(cpus);
 104.494 -        cpu_clear(cpu, cpus);
 104.495 -
 104.496 -        /*
 104.497 -         * In multi-core and multi-threaded CPUs, not all idle execution
 104.498 -         * vehicles are equal!
 104.499 -         *
 104.500 -         * We give preference to the idle execution vehicle with the most
 104.501 -         * idling neighbours in its grouping. This distributes work across
 104.502 -         * distinct cores first and guarantees we don't do something stupid
 104.503 -         * like run two VCPUs on co-hyperthreads while there are idle cores
 104.504 -         * or sockets.
 104.505 -         */
 104.506 -        while ( !cpus_empty(cpus) )
 104.507 -        {
 104.508 -            nxt = first_cpu(cpus);
 104.509 -
 104.510 -            if ( csched_idler_compare(cpu, nxt) < 0 )
 104.511 -            {
 104.512 -                cpu = nxt;
 104.513 -                cpu_clear(nxt, cpus);
 104.514 -            }
 104.515 -            else if ( cpu_isset(cpu, cpu_core_map[nxt]) )
 104.516 -            {
 104.517 -                cpus_andnot(cpus, cpus, cpu_sibling_map[nxt]);
 104.518 -            }
 104.519 -            else
 104.520 -            {
 104.521 -                cpus_andnot(cpus, cpus, cpu_core_map[nxt]);
 104.522 -            }
 104.523 -
 104.524 -            ASSERT( !cpu_isset(nxt, cpus) );
 104.525 -        }
 104.526 -    }
 104.527 -
 104.528 -    return cpu;
 104.529 +    xfree(CSCHED_DOM(dom));
 104.530  }
 104.531  
 104.532  /*
 104.533 @@ -963,11 +952,19 @@ csched_acct(void)
 104.534               */
 104.535              if ( credit < 0 )
 104.536              {
 104.537 -                if ( sdom->cap != 0U && credit < -credit_cap )
 104.538 -                    svc->pri = CSCHED_PRI_TS_PARKED;
 104.539 -                else
 104.540 -                    svc->pri = CSCHED_PRI_TS_OVER;
 104.541 +                svc->pri = CSCHED_PRI_TS_OVER;
 104.542  
 104.543 +                /* Park running VCPUs of capped-out domains */
 104.544 +                if ( sdom->cap != 0U &&
 104.545 +                     credit < -credit_cap &&
 104.546 +                     !(svc->flags & CSCHED_FLAG_VCPU_PARKED) )
 104.547 +                {
 104.548 +                    CSCHED_STAT_CRANK(vcpu_park);
 104.549 +                    vcpu_pause_nosync(svc->vcpu);
 104.550 +                    svc->flags |= CSCHED_FLAG_VCPU_PARKED;
 104.551 +                }
 104.552 +
 104.553 +                /* Lower bound on credits */
 104.554                  if ( credit < -CSCHED_CREDITS_PER_TSLICE )
 104.555                  {
 104.556                      CSCHED_STAT_CRANK(acct_min_credit);
 104.557 @@ -979,16 +976,30 @@ csched_acct(void)
 104.558              {
 104.559                  svc->pri = CSCHED_PRI_TS_UNDER;
 104.560  
 104.561 +                /* Unpark any capped domains whose credits go positive */
 104.562 +                if ( svc->flags & CSCHED_FLAG_VCPU_PARKED)
 104.563 +                {
 104.564 +                    /*
 104.565 +                     * It's important to unset the flag AFTER the unpause()
 104.566 +                     * call to make sure the VCPU's priority is not boosted
 104.567 +                     * if it is woken up here.
 104.568 +                     */
 104.569 +                    CSCHED_STAT_CRANK(vcpu_unpark);
 104.570 +                    vcpu_unpause(svc->vcpu);
 104.571 +                    svc->flags &= ~CSCHED_FLAG_VCPU_PARKED;
 104.572 +                }
 104.573 +
 104.574 +                /* Upper bound on credits means VCPU stops earning */
 104.575                  if ( credit > CSCHED_CREDITS_PER_TSLICE )
 104.576                  {
 104.577 -                    __csched_vcpu_acct_idle_locked(svc);
 104.578 +                    __csched_vcpu_acct_stop_locked(svc);
 104.579                      credit = 0;
 104.580                      atomic_set(&svc->credit, credit);
 104.581                  }
 104.582              }
 104.583  
 104.584 -            svc->stats.credit_last = credit;
 104.585 -            svc->stats.credit_incr = credit_fair;
 104.586 +            CSCHED_VCPU_STAT_SET(svc, credit_last, credit);
 104.587 +            CSCHED_VCPU_STAT_SET(svc, credit_incr, credit_fair);
 104.588              credit_balance += credit;
 104.589          }
 104.590      }
 104.591 @@ -1004,21 +1015,14 @@ csched_acct(void)
 104.592  static void
 104.593  csched_tick(unsigned int cpu)
 104.594  {
 104.595 -    struct csched_vcpu * const svc = CSCHED_VCPU(current);
 104.596 -    struct csched_dom * const sdom = svc->sdom;
 104.597 -
 104.598      /*
 104.599       * Accounting for running VCPU
 104.600 -     *
 104.601 -     * Note: Some VCPUs, such as the idle tasks, are not credit scheduled.
 104.602       */
 104.603 -    if ( likely(sdom != NULL) )
 104.604 -    {
 104.605 -        csched_vcpu_acct(svc, CSCHED_CREDITS_PER_TICK);
 104.606 -    }
 104.607 +    if ( !is_idle_vcpu(current) )
 104.608 +        csched_vcpu_acct(cpu);
 104.609  
 104.610      /*
 104.611 -     * Accounting duty
 104.612 +     * Host-wide accounting duty
 104.613       *
 104.614       * Note: Currently, this is always done by the master boot CPU. Eventually,
 104.615       * we could distribute or at the very least cycle the duty.
 104.616 @@ -1040,40 +1044,48 @@ csched_tick(unsigned int cpu)
 104.617  }
 104.618  
 104.619  static struct csched_vcpu *
 104.620 -csched_runq_steal(struct csched_pcpu *spc, int cpu, int pri)
 104.621 +csched_runq_steal(int peer_cpu, int cpu, int pri)
 104.622  {
 104.623 +    const struct csched_pcpu * const peer_pcpu = CSCHED_PCPU(peer_cpu);
 104.624 +    const struct vcpu * const peer_vcpu = per_cpu(schedule_data, peer_cpu).curr;
 104.625 +    struct csched_vcpu *speer;
 104.626      struct list_head *iter;
 104.627 -    struct csched_vcpu *speer;
 104.628      struct vcpu *vc;
 104.629  
 104.630 -    list_for_each( iter, &spc->runq )
 104.631 +    /*
 104.632 +     * Don't steal from an idle CPU's runq because it's about to
 104.633 +     * pick up work from it itself.
 104.634 +     */
 104.635 +    if ( peer_pcpu != NULL && !is_idle_vcpu(peer_vcpu) )
 104.636      {
 104.637 -        speer = __runq_elem(iter);
 104.638 -
 104.639 -        /*
 104.640 -         * If next available VCPU here is not of higher priority than ours,
 104.641 -         * this PCPU is useless to us.
 104.642 -         */
 104.643 -        if ( speer->pri <= CSCHED_PRI_IDLE || speer->pri <= pri )
 104.644 +        list_for_each( iter, &peer_pcpu->runq )
 104.645          {
 104.646 -            CSCHED_STAT_CRANK(steal_peer_idle);
 104.647 -            break;
 104.648 -        }
 104.649 +            speer = __runq_elem(iter);
 104.650  
 104.651 -        /* Is this VCPU is runnable on our PCPU? */
 104.652 -        vc = speer->vcpu;
 104.653 -        BUG_ON( is_idle_vcpu(vc) );
 104.654 +            /*
 104.655 +             * If next available VCPU here is not of strictly higher
 104.656 +             * priority than ours, this PCPU is useless to us.
 104.657 +             */
 104.658 +            if ( speer->pri <= pri )
 104.659 +                break;
 104.660  
 104.661 -        if ( __csched_queued_vcpu_is_stealable(cpu, vc) )
 104.662 -        {
 104.663 -            /* We got a candidate. Grab it! */
 104.664 -            __runq_remove(speer);
 104.665 -            vc->processor = cpu;
 104.666 +            /* Is this VCPU is runnable on our PCPU? */
 104.667 +            vc = speer->vcpu;
 104.668 +            BUG_ON( is_idle_vcpu(vc) );
 104.669  
 104.670 -            return speer;
 104.671 +            if (__csched_vcpu_is_migrateable(vc, cpu))
 104.672 +            {
 104.673 +                /* We got a candidate. Grab it! */
 104.674 +                CSCHED_VCPU_STAT_CRANK(speer, migrate_q);
 104.675 +                CSCHED_STAT_CRANK(migrate_queued);
 104.676 +                __runq_remove(speer);
 104.677 +                vc->processor = cpu;
 104.678 +                return speer;
 104.679 +            }
 104.680          }
 104.681      }
 104.682  
 104.683 +    CSCHED_STAT_CRANK(steal_peer_idle);
 104.684      return NULL;
 104.685  }
 104.686  
 104.687 @@ -1081,12 +1093,11 @@ static struct csched_vcpu *
 104.688  csched_load_balance(int cpu, struct csched_vcpu *snext)
 104.689  {
 104.690      struct csched_vcpu *speer;
 104.691 -    struct csched_pcpu *spc;
 104.692 -    struct vcpu *peer_vcpu;
 104.693      cpumask_t workers;
 104.694 -    cpumask_t loners;
 104.695      int peer_cpu;
 104.696  
 104.697 +    BUG_ON( cpu != snext->vcpu->processor );
 104.698 +
 104.699      if ( snext->pri == CSCHED_PRI_IDLE )
 104.700          CSCHED_STAT_CRANK(load_balance_idle);
 104.701      else if ( snext->pri == CSCHED_PRI_TS_OVER )
 104.702 @@ -1095,22 +1106,16 @@ csched_load_balance(int cpu, struct csch
 104.703          CSCHED_STAT_CRANK(load_balance_other);
 104.704  
 104.705      /*
 104.706 -     * Peek at non-idling CPUs in the system
 104.707 +     * Peek at non-idling CPUs in the system, starting with our
 104.708 +     * immediate neighbour.
 104.709       */
 104.710 -    cpus_clear(loners);
 104.711      cpus_andnot(workers, cpu_online_map, csched_priv.idlers);
 104.712      cpu_clear(cpu, workers);
 104.713 -
 104.714      peer_cpu = cpu;
 104.715 -    BUG_ON( peer_cpu != snext->vcpu->processor );
 104.716  
 104.717      while ( !cpus_empty(workers) )
 104.718      {
 104.719 -        /* For each CPU of interest, starting with our neighbour... */
 104.720 -        peer_cpu = next_cpu(peer_cpu, workers);
 104.721 -        if ( peer_cpu == NR_CPUS )
 104.722 -            peer_cpu = first_cpu(workers);
 104.723 -
 104.724 +        peer_cpu = __cycle_cpu(peer_cpu, &workers);
 104.725          cpu_clear(peer_cpu, workers);
 104.726  
 104.727          /*
 104.728 @@ -1126,83 +1131,13 @@ csched_load_balance(int cpu, struct csch
 104.729              continue;
 104.730          }
 104.731  
 104.732 -        peer_vcpu = per_cpu(schedule_data, peer_cpu).curr;
 104.733 -        spc = CSCHED_PCPU(peer_cpu);
 104.734 -
 104.735 -        if ( unlikely(spc == NULL) )
 104.736 -        {
 104.737 -            CSCHED_STAT_CRANK(steal_peer_down);
 104.738 -        }
 104.739 -        else if ( unlikely(is_idle_vcpu(peer_vcpu)) )
 104.740 -        {
 104.741 -            /*
 104.742 -             * Don't steal from an idle CPU's runq because it's about to
 104.743 -             * pick up work from it itself.
 104.744 -             */
 104.745 -            CSCHED_STAT_CRANK(steal_peer_idle);
 104.746 -        }
 104.747 -        else if ( is_idle_vcpu(__runq_elem(spc->runq.next)->vcpu) )
 104.748 -        {
 104.749 -            if ( snext->pri == CSCHED_PRI_IDLE &&
 104.750 -                 __csched_running_vcpu_is_stealable(cpu, peer_vcpu) )
 104.751 -            {
 104.752 -                CSCHED_STAT_CRANK(steal_loner_candidate);
 104.753 -                cpu_set(peer_cpu, loners);
 104.754 -            }
 104.755 -        }
 104.756 -        else
 104.757 -        {
 104.758 -            /* Try to steal work from a remote CPU's runq. */
 104.759 -            speer = csched_runq_steal(spc, cpu, snext->pri);
 104.760 -            if ( speer != NULL )
 104.761 -            {
 104.762 -                spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock);
 104.763 -                CSCHED_STAT_CRANK(vcpu_migrate);
 104.764 -                speer->stats.migrate++;
 104.765 -                return speer;
 104.766 -            }
 104.767 -        }
 104.768 -
 104.769 +        /*
 104.770 +         * Any work over there to steal?
 104.771 +         */
 104.772 +        speer = csched_runq_steal(peer_cpu, cpu, snext->pri);
 104.773          spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock);
 104.774 -    }
 104.775 -
 104.776 -    /*
 104.777 -     * If we failed to find any remotely queued VCPUs to move here,
 104.778 -     * see if it would be more efficient to move any of the running
 104.779 -     * remote VCPUs over here.
 104.780 -     */
 104.781 -    while ( !cpus_empty(loners) )
 104.782 -    {
 104.783 -        /* For each CPU of interest, starting with our neighbour... */
 104.784 -        peer_cpu = next_cpu(peer_cpu, loners);
 104.785 -        if ( peer_cpu == NR_CPUS )
 104.786 -            peer_cpu = first_cpu(loners);
 104.787 -
 104.788 -        cpu_clear(peer_cpu, loners);
 104.789 -
 104.790 -        if ( !spin_trylock(&per_cpu(schedule_data, peer_cpu).schedule_lock) )
 104.791 -        {
 104.792 -            CSCHED_STAT_CRANK(steal_trylock_failed);
 104.793 -            continue;
 104.794 -        }
 104.795 -
 104.796 -        peer_vcpu = per_cpu(schedule_data, peer_cpu).curr;
 104.797 -        spc = CSCHED_PCPU(peer_cpu);
 104.798 -
 104.799 -        /* Signal the first candidate only. */
 104.800 -        if ( !is_idle_vcpu(peer_vcpu) &&
 104.801 -             is_idle_vcpu(__runq_elem(spc->runq.next)->vcpu) &&
 104.802 -             __csched_running_vcpu_is_stealable(cpu, peer_vcpu) )
 104.803 -        {
 104.804 -            set_bit(_VCPUF_migrating, &peer_vcpu->vcpu_flags);
 104.805 -            spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock);
 104.806 -
 104.807 -            CSCHED_STAT_CRANK(steal_loner_signal);
 104.808 -            cpu_raise_softirq(peer_cpu, SCHEDULE_SOFTIRQ);
 104.809 -            break;
 104.810 -        }
 104.811 -
 104.812 -        spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock);
 104.813 +        if ( speer != NULL )
 104.814 +            return speer;
 104.815      }
 104.816  
 104.817      /* Failed to find more important work elsewhere... */
 104.818 @@ -1270,7 +1205,6 @@ csched_schedule(s_time_t now)
 104.819      ret.task = snext->vcpu;
 104.820  
 104.821      CSCHED_VCPU_CHECK(ret.task);
 104.822 -
 104.823      return ret;
 104.824  }
 104.825  
 104.826 @@ -1279,22 +1213,25 @@ csched_dump_vcpu(struct csched_vcpu *svc
 104.827  {
 104.828      struct csched_dom * const sdom = svc->sdom;
 104.829  
 104.830 -    printk("[%i.%i] pri=%i cpu=%i",
 104.831 +    printk("[%i.%i] pri=%i flags=%x cpu=%i",
 104.832              svc->vcpu->domain->domain_id,
 104.833              svc->vcpu->vcpu_id,
 104.834              svc->pri,
 104.835 +            svc->flags,
 104.836              svc->vcpu->processor);
 104.837  
 104.838      if ( sdom )
 104.839      {
 104.840 -        printk(" credit=%i (%d+%u) {a/i=%u/%u m=%u w=%u}",
 104.841 -            atomic_read(&svc->credit),
 104.842 -            svc->stats.credit_last,
 104.843 -            svc->stats.credit_incr,
 104.844 -            svc->stats.state_active,
 104.845 -            svc->stats.state_idle,
 104.846 -            svc->stats.migrate,
 104.847 -            sdom->weight);
 104.848 +        printk(" credit=%i [w=%u]", atomic_read(&svc->credit), sdom->weight);
 104.849 +#ifdef CSCHED_STATS
 104.850 +        printk(" (%d+%u) {a/i=%u/%u m=%u+%u}",
 104.851 +                svc->stats.credit_last,
 104.852 +                svc->stats.credit_incr,
 104.853 +                svc->stats.state_active,
 104.854 +                svc->stats.state_idle,
 104.855 +                svc->stats.migrate_q,
 104.856 +                svc->stats.migrate_r);
 104.857 +#endif
 104.858      }
 104.859  
 104.860      printk("\n");
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/xen/common/xencomm.c	Thu Dec 14 08:57:36 2006 -0700
   105.3 @@ -0,0 +1,316 @@
   105.4 +/*
   105.5 + * This program is free software; you can redistribute it and/or modify
   105.6 + * it under the terms of the GNU General Public License as published by
   105.7 + * the Free Software Foundation; either version 2 of the License, or
   105.8 + * (at your option) any later version.
   105.9 + *
  105.10 + * This program is distributed in the hope that it will be useful,
  105.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  105.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  105.13 + * GNU General Public License for more details.
  105.14 + *
  105.15 + * You should have received a copy of the GNU General Public License
  105.16 + * along with this program; if not, write to the Free Software
  105.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  105.18 + *
  105.19 + * Copyright (C) IBM Corp. 2006
  105.20 + *
  105.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  105.22 + *          Tristan Gingold <tristan.gingold@bull.net>
  105.23 + */
  105.24 +
  105.25 +#include <xen/config.h>
  105.26 +#include <xen/mm.h>
  105.27 +#include <xen/sched.h>
  105.28 +#include <xen/xencomm.h>
  105.29 +#include <public/xen.h>
  105.30 +#include <public/xencomm.h>
  105.31 +
  105.32 +
  105.33 +#undef DEBUG
  105.34 +#ifdef DEBUG
  105.35 +static int xencomm_debug = 1; /* extremely verbose */
  105.36 +#else
  105.37 +#define xencomm_debug 0
  105.38 +#endif
  105.39 +
  105.40 +static unsigned long
  105.41 +xencomm_inline_from_guest(void *to, const void *from, unsigned int n,
  105.42 +        unsigned int skip)
  105.43 +{
  105.44 +    unsigned long src_paddr = xencomm_inline_addr(from);
  105.45 +
  105.46 +    src_paddr += skip;
  105.47 +
  105.48 +    while (n > 0) {
  105.49 +        unsigned int chunksz;
  105.50 +        unsigned long src_maddr;
  105.51 +        unsigned int bytes;
  105.52 +
  105.53 +        chunksz = PAGE_SIZE - (src_paddr % PAGE_SIZE);
  105.54 +
  105.55 +        bytes = min(chunksz, n);
  105.56 +
  105.57 +        src_maddr = paddr_to_maddr(src_paddr);
  105.58 +        if (xencomm_debug)
  105.59 +            printk("%lx[%d] -> %lx\n", src_maddr, bytes, (unsigned long)to);
  105.60 +        memcpy(to, (void *)src_maddr, bytes);
  105.61 +        src_paddr += bytes;
  105.62 +        to += bytes;
  105.63 +        n -= bytes;
  105.64 +    }
  105.65 +
  105.66 +    /* Always successful. */
  105.67 +    return 0;
  105.68 +}
  105.69 +
  105.70 +/**
  105.71 + * xencomm_copy_from_guest: Copy a block of data from domain space.
  105.72 + * @to:   Machine address.
  105.73 + * @from: Physical address to a xencomm buffer descriptor.
  105.74 + * @n:    Number of bytes to copy.
  105.75 + * @skip: Number of bytes from the start to skip.
  105.76 + *
  105.77 + * Copy data from domain to hypervisor.
  105.78 + *
  105.79 + * Returns number of bytes that could not be copied.
  105.80 + * On success, this will be zero.
  105.81 + */
  105.82 +unsigned long
  105.83 +xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
  105.84 +        unsigned int skip)
  105.85 +{
  105.86 +    struct xencomm_desc *desc;
  105.87 +    unsigned int from_pos = 0;
  105.88 +    unsigned int to_pos = 0;
  105.89 +    unsigned int i = 0;
  105.90 +
  105.91 +    if (xencomm_is_inline(from))
  105.92 +        return xencomm_inline_from_guest(to, from, n, skip);
  105.93 +
  105.94 +    /* first we need to access the descriptor */
  105.95 +    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
  105.96 +    if (desc == NULL)
  105.97 +        return n;
  105.98 +
  105.99 +    if (desc->magic != XENCOMM_MAGIC) {
 105.100 +        printk("%s: error: %p magic was 0x%x\n",
 105.101 +               __func__, desc, desc->magic);
 105.102 +        return n;
 105.103 +    }
 105.104 +
 105.105 +    /* iterate through the descriptor, copying up to a page at a time */
 105.106 +    while ((to_pos < n) && (i < desc->nr_addrs)) {
 105.107 +        unsigned long src_paddr = desc->address[i];
 105.108 +        unsigned int pgoffset;
 105.109 +        unsigned int chunksz;
 105.110 +        unsigned int chunk_skip;
 105.111 +
 105.112 +        if (src_paddr == XENCOMM_INVALID) {
 105.113 +            i++;
 105.114 +            continue;
 105.115 +        }
 105.116 +
 105.117 +        pgoffset = src_paddr % PAGE_SIZE;
 105.118 +        chunksz = PAGE_SIZE - pgoffset;
 105.119 +
 105.120 +        chunk_skip = min(chunksz, skip);
 105.121 +        from_pos += chunk_skip;
 105.122 +        chunksz -= chunk_skip;
 105.123 +        skip -= chunk_skip;
 105.124 +
 105.125 +        if (skip == 0) {
 105.126 +            unsigned long src_maddr;
 105.127 +            unsigned long dest = (unsigned long)to + to_pos;
 105.128 +            unsigned int bytes = min(chunksz, n - to_pos);
 105.129 +
 105.130 +            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
 105.131 +            if (src_maddr == 0)
 105.132 +                return n - to_pos;
 105.133 +
 105.134 +            if (xencomm_debug)
 105.135 +                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
 105.136 +            memcpy((void *)dest, (void *)src_maddr, bytes);
 105.137 +            from_pos += bytes;
 105.138 +            to_pos += bytes;
 105.139 +        }
 105.140 +
 105.141 +        i++;
 105.142 +    }
 105.143 +
 105.144 +    return n - to_pos;
 105.145 +}
 105.146 +
 105.147 +static unsigned long
 105.148 +xencomm_inline_to_guest(void *to, const void *from, unsigned int n,
 105.149 +        unsigned int skip)
 105.150 +{
 105.151 +    unsigned long dest_paddr = xencomm_inline_addr(to);
 105.152 +
 105.153 +    dest_paddr += skip;
 105.154 +
 105.155 +    while (n > 0) {
 105.156 +        unsigned int chunksz;
 105.157 +        unsigned long dest_maddr;
 105.158 +        unsigned int bytes;
 105.159 +
 105.160 +        chunksz = PAGE_SIZE - (dest_paddr % PAGE_SIZE);
 105.161 +
 105.162 +        bytes = min(chunksz, n);
 105.163 +
 105.164 +        dest_maddr = paddr_to_maddr(dest_paddr);
 105.165 +        if (xencomm_debug)
 105.166 +            printk("%lx[%d] -> %lx\n", (unsigned long)from, bytes, dest_maddr);
 105.167 +        memcpy((void *)dest_maddr, (void *)from, bytes);
 105.168 +        dest_paddr += bytes;
 105.169 +        from += bytes;
 105.170 +        n -= bytes;
 105.171 +    }
 105.172 +
 105.173 +    /* Always successful.  */
 105.174 +    return 0;
 105.175 +}
 105.176 +
 105.177 +/**
 105.178 + * xencomm_copy_to_guest: Copy a block of data to domain space.
 105.179 + * @to:     Physical address to xencomm buffer descriptor.
 105.180 + * @from:   Machine address.
 105.181 + * @n:      Number of bytes to copy.
 105.182 + * @skip: Number of bytes from the start to skip.
 105.183 + *
 105.184 + * Copy data from hypervisor to domain.
 105.185 + *
 105.186 + * Returns number of bytes that could not be copied.
 105.187 + * On success, this will be zero.
 105.188 + */
 105.189 +unsigned long
 105.190 +xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
 105.191 +        unsigned int skip)
 105.192 +{
 105.193 +    struct xencomm_desc *desc;
 105.194 +    unsigned int from_pos = 0;
 105.195 +    unsigned int to_pos = 0;
 105.196 +    unsigned int i = 0;
 105.197 +
 105.198 +    if (xencomm_is_inline(to))
 105.199 +        return xencomm_inline_to_guest(to, from, n, skip);
 105.200 +
 105.201 +    /* first we need to access the descriptor */
 105.202 +    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
 105.203 +    if (desc == NULL)
 105.204 +        return n;
 105.205 +
 105.206 +    if (desc->magic != XENCOMM_MAGIC) {
 105.207 +        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
 105.208 +        return n;
 105.209 +    }
 105.210 +
 105.211 +    /* iterate through the descriptor, copying up to a page at a time */
 105.212 +    while ((from_pos < n) && (i < desc->nr_addrs)) {
 105.213 +        unsigned long dest_paddr = desc->address[i];
 105.214 +        unsigned int pgoffset;
 105.215 +        unsigned int chunksz;
 105.216 +        unsigned int chunk_skip;
 105.217 +
 105.218 +        if (dest_paddr == XENCOMM_INVALID) {
 105.219 +            i++;
 105.220 +            continue;
 105.221 +        }
 105.222 +
 105.223 +        pgoffset = dest_paddr % PAGE_SIZE;
 105.224 +        chunksz = PAGE_SIZE - pgoffset;
 105.225 +
 105.226 +        chunk_skip = min(chunksz, skip);
 105.227 +        to_pos += chunk_skip;
 105.228 +        chunksz -= chunk_skip;
 105.229 +        skip -= chunk_skip;
 105.230 +
 105.231 +        if (skip == 0) {
 105.232 +            unsigned long dest_maddr;
 105.233 +            unsigned long source = (unsigned long)from + from_pos;
 105.234 +            unsigned int bytes = min(chunksz, n - from_pos);
 105.235 +
 105.236 +            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
 105.237 +            if (dest_maddr == 0)
 105.238 +                return -1;
 105.239 +
 105.240 +            if (xencomm_debug)
 105.241 +                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
 105.242 +            memcpy((void *)dest_maddr, (void *)source, bytes);
 105.243 +            from_pos += bytes;
 105.244 +            to_pos += bytes;
 105.245 +        }
 105.246 +
 105.247 +        i++;
 105.248 +    }
 105.249 +
 105.250 +    return n - from_pos;
 105.251 +}
 105.252 +
 105.253 +static int xencomm_inline_add_offset(void **handle, unsigned int bytes)
 105.254 +{
 105.255 +    *handle += bytes;
 105.256 +    return 0;
 105.257 +}
 105.258 +
 105.259 +/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
 105.260 + * exhausted pages to XENCOMM_INVALID. */
 105.261 +int xencomm_add_offset(void **handle, unsigned int bytes)
 105.262 +{
 105.263 +    struct xencomm_desc *desc;
 105.264 +    int i = 0;
 105.265 +
 105.266 +    if (xencomm_is_inline(*handle))
 105.267 +        return xencomm_inline_add_offset(handle, bytes);
 105.268 +
 105.269 +    /* first we need to access the descriptor */
 105.270 +    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)*handle);
 105.271 +    if (desc == NULL)
 105.272 +        return -1;
 105.273 +
 105.274 +    if (desc->magic != XENCOMM_MAGIC) {
 105.275 +        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
 105.276 +        return -1;
 105.277 +    }
 105.278 +
 105.279 +    /* iterate through the descriptor incrementing addresses */
 105.280 +    while ((bytes > 0) && (i < desc->nr_addrs)) {
 105.281 +        unsigned long dest_paddr = desc->address[i];
 105.282 +        unsigned int pgoffset;
 105.283 +        unsigned int chunksz;
 105.284 +        unsigned int chunk_skip;
 105.285 +
 105.286 +        pgoffset = dest_paddr % PAGE_SIZE;
 105.287 +        chunksz = PAGE_SIZE - pgoffset;
 105.288 +
 105.289 +        chunk_skip = min(chunksz, bytes);
 105.290 +        if (chunk_skip == chunksz) {
 105.291 +            /* exhausted this page */
 105.292 +            desc->address[i] = XENCOMM_INVALID;
 105.293 +        } else {
 105.294 +            desc->address[i] += chunk_skip;
 105.295 +        }
 105.296 +        bytes -= chunk_skip;
 105.297 +    }
 105.298 +    return 0;
 105.299 +}
 105.300 +
 105.301 +int xencomm_handle_is_null(void *handle)
 105.302 +{
 105.303 +    struct xencomm_desc *desc;
 105.304 +    int i;
 105.305 +
 105.306 +    if (xencomm_is_inline(handle))
 105.307 +        return xencomm_inline_addr(handle) == 0;
 105.308 +
 105.309 +    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
 105.310 +    if (desc == NULL)
 105.311 +        return 1;
 105.312 +
 105.313 +    for (i = 0; i < desc->nr_addrs; i++)
 105.314 +        if (desc->address[i] != XENCOMM_INVALID)
 105.315 +            return 0;
 105.316 +
 105.317 +    return 1;
 105.318 +}
 105.319 +
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/xen/include/asm-powerpc/acpi.h	Thu Dec 14 08:57:36 2006 -0700
   106.3 @@ -0,0 +1,2 @@
   106.4 +#define MAX_LOCAL_APIC 256
   106.5 +
   107.1 --- a/xen/include/asm-powerpc/cache.h	Thu Dec 14 08:54:54 2006 -0700
   107.2 +++ b/xen/include/asm-powerpc/cache.h	Thu Dec 14 08:57:36 2006 -0700
   107.3 @@ -70,4 +70,5 @@ struct cpu_caches {
   107.4      u32 ilines_per_page;
   107.5  };
   107.6  extern struct cpu_caches cpu_caches;
   107.7 +extern void cpu_flush_icache(void);
   107.8  #endif
   108.1 --- a/xen/include/asm-powerpc/config.h	Thu Dec 14 08:54:54 2006 -0700
   108.2 +++ b/xen/include/asm-powerpc/config.h	Thu Dec 14 08:57:36 2006 -0700
   108.3 @@ -21,7 +21,7 @@
   108.4  #ifndef __PPC_CONFIG_H__
   108.5  #define __PPC_CONFIG_H__
   108.6  
   108.7 -#define CONFIG_MAMBO 1
   108.8 +#define CONFIG_SYSTEMSIM 1
   108.9  #define HYPERVISOR_VIRT_START 0x0 /* XXX temp hack for common/kernel.c */
  108.10  
  108.11  
  108.12 @@ -50,6 +50,8 @@ extern char __bss_start[];
  108.13  #define CONFIG_GDB 1
  108.14  #define CONFIG_SMP 1
  108.15  #define CONFIG_PCI 1
  108.16 +#define CONFIG_NUMA 1
  108.17 +#define CONFIG_CMDLINE_SIZE 512
  108.18  #define NR_CPUS 16
  108.19  
  108.20  #ifndef ELFSIZE
   109.1 --- a/xen/include/asm-powerpc/debugger.h	Thu Dec 14 08:54:54 2006 -0700
   109.2 +++ b/xen/include/asm-powerpc/debugger.h	Thu Dec 14 08:57:36 2006 -0700
   109.3 @@ -13,14 +13,69 @@
   109.4   * along with this program; if not, write to the Free Software
   109.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   109.6   *
   109.7 - * Copyright (C) IBM Corp. 2005
   109.8 + * Copyright (C) IBM Corp. 2005, 2006
   109.9   *
  109.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  109.11 + *          Jimi Xenidis <jimix@watson.ibm.com>
  109.12   */
  109.13  
  109.14  #ifndef _ASM_DEBUGGER_H_
  109.15  #define _ASM_DEBUGGER_H_
  109.16  
  109.17 +#include <public/xen.h>
  109.18 +
  109.19 +extern void show_backtrace_regs(struct cpu_user_regs *);
  109.20 +extern void show_backtrace(ulong sp, ulong lr, ulong pc);
  109.21 +
  109.22 +static inline void show_execution_state(struct cpu_user_regs *regs)
  109.23 +{
  109.24 +    show_registers(regs);
  109.25 +}
  109.26 +
  109.27 +extern void dump_execution_state(void);
  109.28 +
  109.29 +static inline void dump_all_execution_state(void)
  109.30 +{
  109.31 +    ulong sp;
  109.32 +    ulong lr;
  109.33 +
  109.34 +    dump_execution_state();
  109.35 +    sp = (ulong)__builtin_frame_address(0);
  109.36 +    lr = (ulong)__builtin_return_address(0);
  109.37 +
  109.38 +    show_backtrace(sp, lr, lr);
  109.39 +}
  109.40 +
  109.41 +static inline void __force_crash(void)
  109.42 +{
  109.43 +    dump_all_execution_state();
  109.44 +    __builtin_trap();
  109.45 +}
  109.46 +
  109.47 +static inline void debugger_trap_immediate(void)
  109.48 +{
  109.49 +    dump_all_execution_state();
  109.50 +#ifdef CRASH_DEBUG
  109.51 +    __builtin_trap();
  109.52 +#endif
  109.53 +}
  109.54 +
  109.55 +static inline void unimplemented(void)
  109.56 +{
  109.57 +#ifdef VERBOSE
  109.58 +    dump_all_execution_state();
  109.59 +#endif
  109.60 +}
  109.61 +
  109.62 +extern void __warn(char *file, int line);
  109.63 +#define WARN() __warn(__FILE__, __LINE__)
  109.64 +#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
  109.65 +
  109.66 +extern void __attn(void);
  109.67 +#define ATTN() __attn();
  109.68 +
  109.69 +#define FORCE_CRASH() __force_crash()
  109.70 +
  109.71  #ifdef CRASH_DEBUG
  109.72  
  109.73  #include <xen/gdbstub.h>
  109.74 @@ -32,8 +87,6 @@ static inline int debugger_trap_fatal(
  109.75      return vector;
  109.76  }
  109.77  
  109.78 -#define debugger_trap_immediate() __asm__ __volatile__ ("trap");
  109.79 -
  109.80  #else /* CRASH_DEBUG */
  109.81  
  109.82  static inline int debugger_trap_fatal(
  109.83 @@ -43,17 +96,6 @@ static inline int debugger_trap_fatal(
  109.84      return vector;
  109.85  }
  109.86  
  109.87 -static inline void debugger_trap_immediate(void)
  109.88 -{
  109.89 -    ulong sp;
  109.90 -    ulong lr;
  109.91 -
  109.92 -    sp = (ulong)__builtin_frame_address(0);
  109.93 -    lr = (ulong)__builtin_return_address(0);
  109.94 -
  109.95 -    show_backtrace(sp, lr, lr);
  109.96 -}
  109.97 -
  109.98  #endif /* CRASH_DEBUG */
  109.99  
 109.100  #endif
   110.1 --- a/xen/include/asm-powerpc/delay.h	Thu Dec 14 08:54:54 2006 -0700
   110.2 +++ b/xen/include/asm-powerpc/delay.h	Thu Dec 14 08:57:36 2006 -0700
   110.3 @@ -13,16 +13,28 @@
   110.4   * along with this program; if not, write to the Free Software
   110.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   110.6   *
   110.7 - * Copyright (C) IBM Corp. 2005
   110.8 + * Copyright (C) IBM Corp. 2005, 2006
   110.9   *
  110.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  110.11 + *          Jimi Xenidis <jimix@watson.ibm.com>
  110.12   */
  110.13  
  110.14  #ifndef _ASM_DELAY_H_
  110.15  #define _ASM_DELAY_H_
  110.16  
  110.17 +#include <asm/time.h>
  110.18 +
  110.19  extern unsigned long ticks_per_usec; 
  110.20  #define __udelay udelay
  110.21 -extern void udelay(unsigned long usecs);
  110.22 +static inline void udelay(unsigned long usecs)
  110.23 +{
  110.24 +    unsigned long ticks = usecs * ticks_per_usec;
  110.25 +    unsigned long s;
  110.26 +    unsigned long e;
  110.27  
  110.28 +    s = get_timebase();
  110.29 +    do {
  110.30 +        e = get_timebase();
  110.31 +    } while ((e-s) < ticks);
  110.32 +}
  110.33  #endif
   111.1 --- a/xen/include/asm-powerpc/domain.h	Thu Dec 14 08:54:54 2006 -0700
   111.2 +++ b/xen/include/asm-powerpc/domain.h	Thu Dec 14 08:57:36 2006 -0700
   111.3 @@ -41,6 +41,9 @@ struct arch_domain {
   111.4      /* list of extents beyond RMA */
   111.5      struct list_head extent_list;
   111.6  
   111.7 +    uint foreign_mfn_count;
   111.8 +    uint *foreign_mfns;
   111.9 +
  111.10      /* I/O-port access bitmap mask. */
  111.11      u8 *iobmp_mask;       /* Address of IO bitmap mask, or NULL.      */
  111.12  
  111.13 @@ -86,7 +89,7 @@ struct arch_vcpu {
  111.14      struct slb_entry slb_entries[NUM_SLB_ENTRIES];
  111.15  
  111.16      /* I/O-port access bitmap. */
  111.17 -    u8 *iobmp;        /* Guest kernel virtual address of the bitmap. */
  111.18 +    XEN_GUEST_HANDLE(uint8_t) iobmp; /* Guest kernel virtual address of the bitmap. */
  111.19      int iobmp_limit;  /* Number of ports represented in the bitmap.  */
  111.20      int iopl;         /* Current IOPL for this VCPU. */
  111.21  
   112.1 --- a/xen/include/asm-powerpc/flushtlb.h	Thu Dec 14 08:54:54 2006 -0700
   112.2 +++ b/xen/include/asm-powerpc/flushtlb.h	Thu Dec 14 08:57:36 2006 -0700
   112.3 @@ -24,7 +24,6 @@
   112.4  #include <xen/config.h>
   112.5  #include <xen/percpu.h>
   112.6  #include <xen/types.h>
   112.7 -#include <asm/misc.h>
   112.8  
   112.9  /* The current time as shown by the virtual TLB clock. */
  112.10  extern u32 tlbflush_clock;
   113.1 --- a/xen/include/asm-powerpc/grant_table.h	Thu Dec 14 08:54:54 2006 -0700
   113.2 +++ b/xen/include/asm-powerpc/grant_table.h	Thu Dec 14 08:57:36 2006 -0700
   113.3 @@ -29,6 +29,10 @@
   113.4   * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and
   113.5   * must hold a reference to the page.
   113.6   */
   113.7 +extern long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn);
   113.8 +extern long pte_remove(ulong flags, ulong ptex, ulong avpn,
   113.9 +                       ulong *hi, ulong *lo);
  113.10 +
  113.11  int create_grant_host_mapping(
  113.12      unsigned long addr, unsigned long frame, unsigned int flags);
  113.13  int destroy_grant_host_mapping(
  113.14 @@ -41,8 +45,7 @@ int destroy_grant_host_mapping(
  113.15              (d), XENSHARE_writable);                                     \
  113.16      } while ( 0 )
  113.17  
  113.18 -#define gnttab_shared_mfn(d, t, i)                      \
  113.19 -    ((virt_to_maddr((t)->shared) >> PAGE_SHIFT) + (i))
  113.20 +#define gnttab_shared_mfn(d, t, i) (((ulong)((t)->shared) >> PAGE_SHIFT) + (i))
  113.21  
  113.22  #define gnttab_shared_gmfn(d, t, i)                     \
  113.23      (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i)))
  113.24 @@ -61,4 +64,9 @@ static inline void gnttab_clear_flag(uns
  113.25      clear_bit(lnr, laddr);
  113.26  }
  113.27  
  113.28 +static inline uint cpu_foreign_map_order(void)
  113.29 +{
  113.30 +    /* 16 GiB */
  113.31 +    return 34 - PAGE_SHIFT;
  113.32 +}
  113.33  #endif  /* __ASM_PPC_GRANT_TABLE_H__ */
   114.1 --- a/xen/include/asm-powerpc/guest_access.h	Thu Dec 14 08:54:54 2006 -0700
   114.2 +++ b/xen/include/asm-powerpc/guest_access.h	Thu Dec 14 08:57:36 2006 -0700
   114.3 @@ -21,82 +21,6 @@
   114.4  #ifndef __PPC_GUEST_ACCESS_H__
   114.5  #define __PPC_GUEST_ACCESS_H__
   114.6  
   114.7 -extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
   114.8 -        unsigned int len, unsigned int skip); 
   114.9 -extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
  114.10 -        unsigned int len, unsigned int skip); 
  114.11 -extern int xencomm_add_offset(void *handle, unsigned int bytes);
  114.12 -extern int xencomm_handle_is_null(void *ptr);
  114.13 -
  114.14 -
  114.15 -/* Is the guest handle a NULL reference? */
  114.16 -#define guest_handle_is_null(hnd) \
  114.17 -    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
  114.18 -
  114.19 -/* Offset the given guest handle into the array it refers to. */
  114.20 -#define guest_handle_add_offset(hnd, nr) ({         \
  114.21 -    const typeof((hnd).p) _ptr = (hnd).p;           \
  114.22 -    xencomm_add_offset(_ptr, nr * sizeof(*_ptr));   \
  114.23 -})
  114.24 -
  114.25 -/* Cast a guest handle to the specified type of handle. */
  114.26 -#define guest_handle_cast(hnd, type) ({         \
  114.27 -    type *_x = (hnd).p;                         \
  114.28 -    XEN_GUEST_HANDLE(type) _y; \
  114.29 -    set_xen_guest_handle(_y, _x); \
  114.30 -    _y; \
  114.31 -})
  114.32 -
  114.33 -/* Since we run in real mode, we can safely access all addresses. That also
  114.34 - * means our __routines are identical to our "normal" routines. */
  114.35 -#define guest_handle_okay(hnd, nr) 1
  114.36 -
  114.37 -/*
  114.38 - * Copy an array of objects to guest context via a guest handle.
  114.39 - * Optionally specify an offset into the guest array.
  114.40 - */
  114.41 -#define copy_to_guest_offset(hnd, idx, ptr, nr) \
  114.42 -    __copy_to_guest_offset(hnd, idx, ptr, nr)
  114.43 -
  114.44 -/* Copy sub-field of a structure to guest context via a guest handle. */
  114.45 -#define copy_field_to_guest(hnd, ptr, field) \
  114.46 -    __copy_field_to_guest(hnd, ptr, field)
  114.47 -
  114.48 -/*
  114.49 - * Copy an array of objects from guest context via a guest handle.
  114.50 - * Optionally specify an offset into the guest array.
  114.51 - */
  114.52 -#define copy_from_guest_offset(ptr, hnd, idx, nr) \
  114.53 -    __copy_from_guest_offset(ptr, hnd, idx, nr)
  114.54 -
  114.55 -/* Copy sub-field of a structure from guest context via a guest handle. */
  114.56 -#define copy_field_from_guest(ptr, hnd, field) \
  114.57 -    __copy_field_from_guest(ptr, hnd, field)
  114.58 -
  114.59 -#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                \
  114.60 -    const typeof(ptr) _x = (hnd).p;                                 \
  114.61 -    const typeof(ptr) _y = (ptr);                                   \
  114.62 -    xencomm_copy_to_guest(_x, _y, sizeof(*_x)*(nr), sizeof(*_x)*(idx)); \
  114.63 -})
  114.64 -
  114.65 -#define __copy_field_to_guest(hnd, ptr, field) ({                   \
  114.66 -    const int _off = offsetof(typeof(*ptr), field);                  \
  114.67 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
  114.68 -    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
  114.69 -    xencomm_copy_to_guest(_x, _y, sizeof(*_x), sizeof(*_x)*(_off)); \
  114.70 -})
  114.71 -
  114.72 -#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({              \
  114.73 -    const typeof(ptr) _x = (hnd).p;                                 \
  114.74 -    const typeof(ptr) _y = (ptr);                                   \
  114.75 -    xencomm_copy_from_guest(_y, _x, sizeof(*_x)*(nr), sizeof(*_x)*(idx));  \
  114.76 -})
  114.77 -
  114.78 -#define __copy_field_from_guest(ptr, hnd, field) ({                 \
  114.79 -    const int _off = offsetof(typeof(*ptr), field);                 \
  114.80 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
  114.81 -    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
  114.82 -    xencomm_copy_to_guest(_y, _x, sizeof(*_x), sizeof(*_x)*(_off)); \
  114.83 -})
  114.84 +#include <xen/xencomm.h>
  114.85  
  114.86  #endif /* __PPC_GUEST_ACCESS_H__ */
   115.1 --- a/xen/include/asm-powerpc/mach-default/irq_vectors.h	Thu Dec 14 08:54:54 2006 -0700
   115.2 +++ b/xen/include/asm-powerpc/mach-default/irq_vectors.h	Thu Dec 14 08:57:36 2006 -0700
   115.3 @@ -37,26 +37,10 @@
   115.4  #define FAST_TRAP -1 /* 0x80 */
   115.5  #define FIRST_SYSTEM_VECTOR	-1
   115.6  
   115.7 -#if 0
   115.8 -
   115.9 -/*
  115.10 - * Vectors 0-16 in some cases are used for ISA interrupts.
  115.11 - */
  115.12 +#define CALL_FUNCTION_VECTOR	0x0
  115.13 +#define EVENT_CHECK_VECTOR	0x1
  115.14  
  115.15 -/*
  115.16 - * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
  115.17 - *
  115.18 - *  some of the following vectors are 'rare', they are merged
  115.19 - *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
  115.20 - *  TLB, reschedule and local APIC vectors are performance-critical.
  115.21 - *
  115.22 - *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
  115.23 - */
  115.24 -#define SPURIOUS_APIC_VECTOR	0xff
  115.25 -#define ERROR_APIC_VECTOR	0xfe
  115.26 -#define INVALIDATE_TLB_VECTOR	0xfd
  115.27 -#define EVENT_CHECK_VECTOR	0xfc
  115.28 -#define CALL_FUNCTION_VECTOR	0xfb
  115.29 +#if 0
  115.30  
  115.31  #define THERMAL_APIC_VECTOR	0xf0
  115.32  /*
   116.1 --- a/xen/include/asm-powerpc/misc.h	Thu Dec 14 08:54:54 2006 -0700
   116.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.3 @@ -1,33 +0,0 @@
   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. 2005
  116.20 - *
  116.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  116.22 - */
  116.23 -
  116.24 -#ifndef _ASM_MISC_H_
  116.25 -#define _ASM_MISC_H_
  116.26 -
  116.27 -static inline void unimplemented(void)
  116.28 -{
  116.29 -}
  116.30 -
  116.31 -static inline void trap(void)
  116.32 -{
  116.33 -    asm volatile("trap");
  116.34 -}
  116.35 -
  116.36 -#endif
   117.1 --- a/xen/include/asm-powerpc/mm.h	Thu Dec 14 08:54:54 2006 -0700
   117.2 +++ b/xen/include/asm-powerpc/mm.h	Thu Dec 14 08:57:36 2006 -0700
   117.3 @@ -13,9 +13,10 @@
   117.4   * along with this program; if not, write to the Free Software
   117.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   117.6   *
   117.7 - * Copyright (C) IBM Corp. 2005
   117.8 + * Copyright (C) IBM Corp. 2005, 2006
   117.9   *
  117.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  117.11 + *          Jimi Xenidis <jimix@watson.ibm.com>
  117.12   */
  117.13  
  117.14  #ifndef _ASM_MM_H_
  117.15 @@ -25,10 +26,10 @@
  117.16  #include <xen/list.h>
  117.17  #include <xen/types.h>
  117.18  #include <xen/mm.h>
  117.19 -#include <asm/misc.h>
  117.20  #include <asm/system.h>
  117.21  #include <asm/flushtlb.h>
  117.22 -#include <asm/uaccess.h>
  117.23 +#include <asm/page.h>
  117.24 +#include <asm/debugger.h>
  117.25  
  117.26  #define memguard_guard_range(_p,_l)    ((void)0)
  117.27  #define memguard_unguard_range(_p,_l)    ((void)0)
  117.28 @@ -86,39 +87,38 @@ struct page_extents {
  117.29      /* page extent */
  117.30      struct page_info *pg;
  117.31      uint order;
  117.32 -    ulong pfn;
  117.33  };
  117.34  
  117.35   /* The following page types are MUTUALLY EXCLUSIVE. */
  117.36 -#define PGT_none            (0<<29) /* no special uses of this page */
  117.37 -#define PGT_RMA             (1<<29) /* This page is an RMA page? */
  117.38 -#define PGT_writable_page   (7<<29) /* has writable mappings of this page? */
  117.39 -#define PGT_type_mask       (7<<29) /* Bits 29-31. */
  117.40 +#define PGT_none            (0UL<<29) /* no special uses of this page */
  117.41 +#define PGT_RMA             (1UL<<29) /* This page is an RMA page? */
  117.42 +#define PGT_writable_page   (7UL<<29) /* has writable mappings of this page? */
  117.43 +#define PGT_type_mask       (7UL<<29) /* Bits 29-31. */
  117.44  
  117.45   /* Owning guest has pinned this page to its current type? */
  117.46  #define _PGT_pinned         28
  117.47 -#define PGT_pinned          (1U<<_PGT_pinned)
  117.48 +#define PGT_pinned          (1UL<<_PGT_pinned)
  117.49   /* Has this page been validated for use as its current type? */
  117.50  #define _PGT_validated      27
  117.51 -#define PGT_validated       (1U<<_PGT_validated)
  117.52 +#define PGT_validated       (1UL<<_PGT_validated)
  117.53  
  117.54   /* 16-bit count of uses of this frame as its current type. */
  117.55 -#define PGT_count_mask      ((1U<<16)-1)
  117.56 +#define PGT_count_mask      ((1UL<<16)-1)
  117.57  
  117.58   /* Cleared when the owning guest 'frees' this page. */
  117.59  #define _PGC_allocated      31
  117.60 -#define PGC_allocated       (1U<<_PGC_allocated)
  117.61 +#define PGC_allocated       (1UL<<_PGC_allocated)
  117.62   /* Set on a *guest* page to mark it out-of-sync with its shadow */
  117.63  #define _PGC_out_of_sync     30
  117.64 -#define PGC_out_of_sync     (1U<<_PGC_out_of_sync)
  117.65 +#define PGC_out_of_sync     (1UL<<_PGC_out_of_sync)
  117.66   /* Set when is using a page as a page table */
  117.67  #define _PGC_page_table      29
  117.68 -#define PGC_page_table      (1U<<_PGC_page_table)
  117.69 +#define PGC_page_table      (1UL<<_PGC_page_table)
  117.70  /* Set when using page for RMA */
  117.71  #define _PGC_page_RMA      28
  117.72 -#define PGC_page_RMA      (1U<<_PGC_page_RMA)
  117.73 +#define PGC_page_RMA      (1UL<<_PGC_page_RMA)
  117.74   /* 29-bit count of references to this frame. */
  117.75 -#define PGC_count_mask      ((1U<<28)-1)
  117.76 +#define PGC_count_mask      ((1UL<<28)-1)
  117.77  
  117.78  #define IS_XEN_HEAP_FRAME(_pfn) (page_to_maddr(_pfn) < xenheap_phys_end)
  117.79  
  117.80 @@ -133,6 +133,13 @@ static inline u32 pickle_domptr(struct d
  117.81  #define page_get_owner(_p)    (unpickle_domptr((_p)->u.inuse._domain))
  117.82  #define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d))
  117.83  
  117.84 +#define XENSHARE_writable 0
  117.85 +#define XENSHARE_readonly 1
  117.86 +extern void share_xen_page_with_guest(
  117.87 +    struct page_info *page, struct domain *d, int readonly);
  117.88 +extern void share_xen_page_with_privileged_guests(
  117.89 +    struct page_info *page, int readonly);
  117.90 +
  117.91  extern struct page_info *frame_table;
  117.92  extern unsigned long max_page;
  117.93  extern unsigned long total_pages;
  117.94 @@ -218,16 +225,18 @@ typedef struct {
  117.95  } vm_assist_info_t;
  117.96  extern vm_assist_info_t vm_assist_info[];
  117.97  
  117.98 -#define share_xen_page_with_guest(p, d, r) do { } while (0)
  117.99 -#define share_xen_page_with_privileged_guests(p, r) do { } while (0)
 117.100  
 117.101  /* hope that accesses to this will fail spectacularly */
 117.102 -#define machine_to_phys_mapping ((u32 *)-1UL)
 117.103 +#undef machine_to_phys_mapping
 117.104 +#define INVALID_M2P_ENTRY        (~0UL)
 117.105  
 117.106 -extern int update_grant_va_mapping(unsigned long va,
 117.107 -                                   unsigned long val,
 117.108 -                                   struct domain *,
 117.109 -                                   struct vcpu *);
 117.110 +/* do nothing, its all calculated */
 117.111 +#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
 117.112 +#define get_gpfn_from_mfn(mfn) (mfn)
 117.113 +
 117.114 +extern unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn);
 117.115 +
 117.116 +extern unsigned long paddr_to_maddr(unsigned long paddr);
 117.117  
 117.118  #define INVALID_MFN (~0UL)
 117.119  #define PFN_TYPE_NONE 0
 117.120 @@ -235,29 +244,48 @@ extern int update_grant_va_mapping(unsig
 117.121  #define PFN_TYPE_LOGICAL 2
 117.122  #define PFN_TYPE_IO 3
 117.123  #define PFN_TYPE_FOREIGN 4
 117.124 +#define PFN_TYPE_GNTTAB 5
 117.125  
 117.126  extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
 117.127 +static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
 117.128 +{
 117.129 +    int mtype;
 117.130 +    ulong mfn;
 117.131 +    
 117.132 +    mfn = pfn2mfn(d, gmfn, &mtype);
 117.133 +    if (mfn != INVALID_MFN) {
 117.134 +        switch (mtype) {
 117.135 +        case PFN_TYPE_RMA:
 117.136 +        case PFN_TYPE_LOGICAL:
 117.137 +            break;
 117.138 +        default:
 117.139 +            WARN();
 117.140 +            mfn = INVALID_MFN;
 117.141 +            break;
 117.142 +        }
 117.143 +    }
 117.144 +    return mfn;
 117.145 +}
 117.146 +
 117.147 +extern int update_grant_va_mapping(unsigned long va,
 117.148 +                                   unsigned long val,
 117.149 +                                   struct domain *,
 117.150 +                                   struct vcpu *);
 117.151  
 117.152  /* Arch-specific portion of memory_op hypercall. */
 117.153  long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
 117.154  
 117.155 -/* XXX implement me? */
 117.156 -#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
 117.157 -/* XXX only used for debug print right now... */
 117.158 -#define get_gpfn_from_mfn(mfn) (mfn)
 117.159 -
 117.160 -static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
 117.161 -{
 117.162 -	return pfn2mfn(d, gmfn, NULL);
 117.163 -}
 117.164 -
 117.165 -#define mfn_to_gmfn(_d, mfn) (mfn)
 117.166 -
 117.167  extern int allocate_rma(struct domain *d, unsigned int order_pages);
 117.168  extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages);
 117.169  extern void free_extents(struct domain *d);
 117.170  
 117.171 +extern int arch_domain_add_extent(struct domain *d, struct page_info *page,
 117.172 +        int order);
 117.173 +
 117.174  extern int steal_page(struct domain *d, struct page_info *page,
 117.175                          unsigned int memflags);
 117.176  
 117.177 +/* XXX these just exist until we can stop #including x86 code */
 117.178 +#define access_ok(addr,size) 1
 117.179 +#define array_access_ok(addr,count,size) 1
 117.180  #endif
   118.1 --- a/xen/include/asm-powerpc/msr.h	Thu Dec 14 08:54:54 2006 -0700
   118.2 +++ b/xen/include/asm-powerpc/msr.h	Thu Dec 14 08:57:36 2006 -0700
   118.3 @@ -51,9 +51,9 @@
   118.4  #define MSR_RI      ULL(0x0000000000000002)
   118.5  #define MSR_LE      ULL(0x0000000000000001)
   118.6  
   118.7 -/* MSR bits set on the Mambo simulator */
   118.8 +/* MSR bits set on the systemsim simulator */
   118.9  #define MSR_SIM     ULL(0x0000000020000000)
  118.10 -#define MSR_MAMBO   ULL(0x0000000010000000)
  118.11 +#define MSR_SYSTEMSIM ULL(0x0000000010000000)
  118.12  
  118.13  /* On a trap, srr1's copy of msr defines some bits as follows: */
  118.14  #define MSR_TRAP_FE     ULL(0x0000000000100000) /* Floating Point Exception */
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/xen/include/asm-powerpc/numa.h	Thu Dec 14 08:57:36 2006 -0700
   119.3 @@ -0,0 +1,2 @@
   119.4 +#include "../asm-x86/numa.h"
   119.5 +extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
   120.1 --- a/xen/include/asm-powerpc/page.h	Thu Dec 14 08:54:54 2006 -0700
   120.2 +++ b/xen/include/asm-powerpc/page.h	Thu Dec 14 08:57:36 2006 -0700
   120.3 @@ -13,9 +13,10 @@
   120.4   * along with this program; if not, write to the Free Software
   120.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   120.6   *
   120.7 - * Copyright (C) IBM Corp. 2005
   120.8 + * Copyright (C) IBM Corp. 2005, 2006
   120.9   *
  120.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  120.11 + *          Jimi Xenidis <jimix@watson.ibm.com>
  120.12   */
  120.13  
  120.14  #ifndef _ASM_PAGE_H
  120.15 @@ -28,7 +29,6 @@
  120.16  #ifndef __ASSEMBLY__
  120.17  
  120.18  #include <xen/config.h>
  120.19 -#include <asm/misc.h>
  120.20  #include <asm/cache.h>
  120.21  
  120.22  #define PFN_DOWN(x)   ((x) >> PAGE_SHIFT)
  120.23 @@ -129,5 +129,6 @@ static inline int get_order_from_pages(u
  120.24  #define _PAGE_PAT      0x080UL
  120.25  #define _PAGE_PSE      0x080UL
  120.26  #define _PAGE_GLOBAL   0x100UL
  120.27 +
  120.28  #endif  /* ! __ASSEMBLY__ */
  120.29  #endif
   121.1 --- a/xen/include/asm-powerpc/powerpc64/string.h	Thu Dec 14 08:54:54 2006 -0700
   121.2 +++ b/xen/include/asm-powerpc/powerpc64/string.h	Thu Dec 14 08:57:36 2006 -0700
   121.3 @@ -37,4 +37,7 @@ extern void * memmove(void *,const void 
   121.4  extern int memcmp(const void *,const void *,__kernel_size_t);
   121.5  extern void * memchr(const void *,int,__kernel_size_t);
   121.6  
   121.7 +extern void *systemsim_memset(void *, int, ulong);
   121.8 +extern void *systemsim_memcpy(void *, const void *, ulong);
   121.9 +
  121.10  #endif
   122.1 --- a/xen/include/asm-powerpc/processor.h	Thu Dec 14 08:54:54 2006 -0700
   122.2 +++ b/xen/include/asm-powerpc/processor.h	Thu Dec 14 08:57:36 2006 -0700
   122.3 @@ -31,6 +31,85 @@
   122.4  /* most assembler do not know this instruction */
   122.5  #define HRFID .long 0x4c000224
   122.6  
   122.7 +/* Processor Version Register (PVR) field extraction */
   122.8 +
   122.9 +#define PVR_VER(pvr)	(((pvr) >>  16) & 0xFFFF)	/* Version field */
  122.10 +#define PVR_REV(pvr)	(((pvr) >>   0) & 0xFFFF)	/* Revison field */
  122.11 +
  122.12 +#define __is_processor(pv)	(PVR_VER(mfspr(SPRN_PVR)) == (pv))
  122.13 +
  122.14 +/*
  122.15 + * IBM has further subdivided the standard PowerPC 16-bit version and
  122.16 + * revision subfields of the PVR for the PowerPC 403s into the following:
  122.17 + */
  122.18 +
  122.19 +#define PVR_FAM(pvr)	(((pvr) >> 20) & 0xFFF)	/* Family field */
  122.20 +#define PVR_MEM(pvr)	(((pvr) >> 16) & 0xF)	/* Member field */
  122.21 +#define PVR_CORE(pvr)	(((pvr) >> 12) & 0xF)	/* Core field */
  122.22 +#define PVR_CFG(pvr)	(((pvr) >>  8) & 0xF)	/* Configuration field */
  122.23 +#define PVR_MAJ(pvr)	(((pvr) >>  4) & 0xF)	/* Major revision field */
  122.24 +#define PVR_MIN(pvr)	(((pvr) >>  0) & 0xF)	/* Minor revision field */
  122.25 +
  122.26 +/* Processor Version Numbers */
  122.27 +
  122.28 +#define PVR_403GA	0x00200000
  122.29 +#define PVR_403GB	0x00200100
  122.30 +#define PVR_403GC	0x00200200
  122.31 +#define PVR_403GCX	0x00201400
  122.32 +#define PVR_405GP	0x40110000
  122.33 +#define PVR_STB03XXX	0x40310000
  122.34 +#define PVR_NP405H	0x41410000
  122.35 +#define PVR_NP405L	0x41610000
  122.36 +#define PVR_601		0x00010000
  122.37 +#define PVR_602		0x00050000
  122.38 +#define PVR_603		0x00030000
  122.39 +#define PVR_603e	0x00060000
  122.40 +#define PVR_603ev	0x00070000
  122.41 +#define PVR_603r	0x00071000
  122.42 +#define PVR_604		0x00040000
  122.43 +#define PVR_604e	0x00090000
  122.44 +#define PVR_604r	0x000A0000
  122.45 +#define PVR_620		0x00140000
  122.46 +#define PVR_740		0x00080000
  122.47 +#define PVR_750		PVR_740
  122.48 +#define PVR_740P	0x10080000
  122.49 +#define PVR_750P	PVR_740P
  122.50 +#define PVR_7400	0x000C0000
  122.51 +#define PVR_7410	0x800C0000
  122.52 +#define PVR_7450	0x80000000
  122.53 +#define PVR_8540	0x80200000
  122.54 +#define PVR_8560	0x80200000
  122.55 +/*
  122.56 + * For the 8xx processors, all of them report the same PVR family for
  122.57 + * the PowerPC core. The various versions of these processors must be
  122.58 + * differentiated by the version number in the Communication Processor
  122.59 + * Module (CPM).
  122.60 + */
  122.61 +#define PVR_821		0x00500000
  122.62 +#define PVR_823		PVR_821
  122.63 +#define PVR_850		PVR_821
  122.64 +#define PVR_860		PVR_821
  122.65 +#define PVR_8240	0x00810100
  122.66 +#define PVR_8245	0x80811014
  122.67 +#define PVR_8260	PVR_8240
  122.68 +
  122.69 +/* 64-bit processors */
  122.70 +/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
  122.71 +#define PV_NORTHSTAR	0x0033
  122.72 +#define PV_PULSAR	0x0034
  122.73 +#define PV_POWER4	0x0035
  122.74 +#define PV_ICESTAR	0x0036
  122.75 +#define PV_SSTAR	0x0037
  122.76 +#define PV_POWER4p	0x0038
  122.77 +#define PV_970		0x0039
  122.78 +#define PV_POWER5	0x003A
  122.79 +#define PV_POWER5p	0x003B
  122.80 +#define PV_970FX	0x003C
  122.81 +#define PV_630		0x0040
  122.82 +#define PV_630p	0x0041
  122.83 +#define PV_970MP	0x0044
  122.84 +#define PV_BE		0x0070
  122.85 +
  122.86  #ifndef __ASSEMBLY__ 
  122.87  #include <xen/types.h>
  122.88  
  122.89 @@ -38,13 +117,10 @@ struct domain;
  122.90  struct vcpu;
  122.91  struct cpu_user_regs;
  122.92  extern int cpu_machinecheck(struct cpu_user_regs *);
  122.93 -extern void cpu_scom_init(void);
  122.94  extern void show_registers(struct cpu_user_regs *);
  122.95 -extern void show_execution_state(struct cpu_user_regs *);
  122.96 -extern void show_backtrace(ulong sp, ulong lr, ulong pc);
  122.97  extern unsigned int cpu_extent_order(void);
  122.98  extern unsigned int cpu_default_rma_order_pages(void);
  122.99 -extern int cpu_rma_valid(unsigned int log);
 122.100 +extern int cpu_rma_valid(unsigned int order);
 122.101  extern uint cpu_large_page_orders(uint *sizes, uint max);
 122.102  extern void cpu_initialize(int cpuid);
 122.103  extern void cpu_init_vcpu(struct vcpu *);
 122.104 @@ -54,13 +130,6 @@ extern void load_cpu_sprs(struct vcpu *)
 122.105  extern void flush_segments(void);
 122.106  extern void dump_segments(int valid);
 122.107  
 122.108 -/* XXX this could also land us in GDB */
 122.109 -#define dump_execution_state() BUG()
 122.110 -
 122.111 -extern void __warn(char *file, int line);
 122.112 -#define WARN() __warn(__FILE__, __LINE__)
 122.113 -#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
 122.114 -
 122.115  #define ARCH_HAS_PREFETCH
 122.116  static inline void prefetch(const void *x) {;}
 122.117  
 122.118 @@ -83,7 +152,8 @@ static inline ulong mfmsr(void) {
 122.119  static inline void nop(void) {
 122.120      __asm__ __volatile__ ("nop");
 122.121  }
 122.122 -#define cpu_relax() nop()
 122.123 +/* will need to address thread priorities when we go SMT */
 122.124 +#define cpu_relax() barrier()
 122.125  
 122.126  static inline unsigned int mfpir(void)
 122.127  {
 122.128 @@ -207,13 +277,13 @@ static inline unsigned mfdsisr(void)
 122.129      return val;
 122.130  }
 122.131  
 122.132 -#ifdef CONFIG_MAMBO
 122.133 -static inline int on_mambo(void)
 122.134 +#ifdef CONFIG_SYSTEMSIM
 122.135 +static inline int on_systemsim(void)
 122.136  {
 122.137 -    return !!(mfmsr() & MSR_MAMBO);
 122.138 +    return !!(mfmsr() & MSR_SYSTEMSIM);
 122.139  }
 122.140 -#else /* CONFIG_MAMBO */
 122.141 -static inline int on_mambo(void) { return 0; }
 122.142 +#else /* CONFIG_SYSTEMSIM */
 122.143 +static inline int on_systemsim(void) { return 0; }
 122.144  #endif
 122.145  
 122.146  #endif /* __ASSEMBLY__ */
   123.1 --- a/xen/include/asm-powerpc/smp.h	Thu Dec 14 08:54:54 2006 -0700
   123.2 +++ b/xen/include/asm-powerpc/smp.h	Thu Dec 14 08:57:36 2006 -0700
   123.3 @@ -25,6 +25,12 @@
   123.4  #include <xen/cpumask.h>
   123.5  #include <xen/init.h>
   123.6  #include <asm/current.h>
   123.7 +
   123.8 +/* crap to make x86 "common code" happy */
   123.9 +#define BAD_APICID 0xFFu
  123.10 +extern u8 x86_cpu_to_apicid[];
  123.11 +
  123.12 +
  123.13  extern int smp_num_siblings;
  123.14  
  123.15  /* revisit when we support SMP */
  123.16 @@ -35,4 +41,20 @@ extern cpumask_t cpu_sibling_map[];
  123.17  extern cpumask_t cpu_core_map[];
  123.18  extern void __devinit smp_generic_take_timebase(void);
  123.19  extern void __devinit smp_generic_give_timebase(void);
  123.20 +
  123.21 +#define SA_INTERRUPT	0x20000000u
  123.22 +typedef int irqreturn_t;
  123.23 +extern int request_irq(unsigned int irq,
  123.24 +    irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
  123.25 +    unsigned long irqflags, const char * devname, void *dev_id);
  123.26 +void smp_message_recv(int msg, struct cpu_user_regs *regs);
  123.27 +void smp_call_function_interrupt(struct cpu_user_regs *regs);
  123.28 +void smp_event_check_interrupt(void);
  123.29 +void send_IPI_mask(cpumask_t mask, int vector);
  123.30 +
  123.31 +#undef DEBUG_IPI
  123.32 +#ifdef DEBUG_IPI
  123.33 +void ipi_torture_test(void);
  123.34  #endif
  123.35 +
  123.36 +#endif
   124.1 --- a/xen/include/asm-powerpc/spinlock.h	Thu Dec 14 08:54:54 2006 -0700
   124.2 +++ b/xen/include/asm-powerpc/spinlock.h	Thu Dec 14 08:57:36 2006 -0700
   124.3 @@ -70,18 +70,15 @@ cas_u32(volatile u32 *ptr, u32 oval, u32
   124.4      return tmp;
   124.5  }
   124.6  
   124.7 -typedef union {
   124.8 +typedef struct {
   124.9      volatile u32 lock;
  124.10 -    struct {
  124.11 -        s8 recurse_cpu;
  124.12 -        u8 recurse_cnt;
  124.13 -        s16 lock;
  124.14 -    } fields;
  124.15 +    s16 recurse_cpu;
  124.16 +    u16 recurse_cnt;
  124.17  } spinlock_t;
  124.18  
  124.19  #define __UNLOCKED (0U)
  124.20  #define __LOCKED (~__UNLOCKED)
  124.21 -#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { __UNLOCKED }
  124.22 +#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { __UNLOCKED, -1, 0 }
  124.23  static inline void spin_lock_init(spinlock_t *lock)
  124.24  {
  124.25      *lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
  124.26 @@ -181,17 +178,17 @@ static inline void _raw_read_unlock(rwlo
  124.27  static inline void _raw_spin_unlock_recursive(spinlock_t *lock)
  124.28  {
  124.29      int cpu = smp_processor_id();
  124.30 -    if (likely(lock->fields.recurse_cpu != cpu)) {
  124.31 +    if (likely(lock->recurse_cpu != cpu)) {
  124.32          spin_lock(lock);
  124.33 -        lock->fields.recurse_cpu = cpu;
  124.34 +        lock->recurse_cpu = cpu;
  124.35      }
  124.36 -    lock->fields.recurse_cnt++;
  124.37 +    lock->recurse_cnt++;
  124.38  }
  124.39  
  124.40  static inline void _raw_spin_unlock_recursive(spinlock_t *lock)
  124.41  {
  124.42 -    if (likely(--lock->fields.recurse_cnt == 0)) {
  124.43 -        lock->fields.recurse_cpu = -1;
  124.44 +    if (likely(--lock->recurse_cnt == 0)) {
  124.45 +        lock->recurse_cpu = -1;
  124.46          spin_unlock(lock);
  124.47      }
  124.48  }
  124.49 @@ -200,19 +197,19 @@ static inline void _raw_spin_unlock_recu
  124.50  #define _raw_spin_lock_recursive(_lock)            \
  124.51      do {                                           \
  124.52          int cpu = smp_processor_id();              \
  124.53 -        if ( likely((_lock)->fields.recurse_cpu != cpu) ) \
  124.54 +        if ( likely((_lock)->recurse_cpu != cpu) ) \
  124.55          {                                          \
  124.56              spin_lock(_lock);                      \
  124.57 -            (_lock)->fields.recurse_cpu = cpu;            \
  124.58 +            (_lock)->recurse_cpu = cpu;            \
  124.59          }                                          \
  124.60 -        (_lock)->fields.recurse_cnt++;                    \
  124.61 +        (_lock)->recurse_cnt++;                    \
  124.62      } while ( 0 )
  124.63  
  124.64  #define _raw_spin_unlock_recursive(_lock)          \
  124.65      do {                                           \
  124.66 -        if ( likely(--(_lock)->fields.recurse_cnt == 0) ) \
  124.67 +        if ( likely(--(_lock)->recurse_cnt == 0) ) \
  124.68          {                                          \
  124.69 -            (_lock)->fields.recurse_cpu = -1;             \
  124.70 +            (_lock)->recurse_cpu = -1;             \
  124.71              spin_unlock(_lock);                    \
  124.72          }                                          \
  124.73      } while ( 0 )
   125.1 --- a/xen/include/asm-powerpc/uaccess.h	Thu Dec 14 08:54:54 2006 -0700
   125.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.3 @@ -1,38 +0,0 @@
   125.4 -/*
   125.5 - * This program is free software; you can redistribute it and/or modify
   125.6 - * it under the terms of the GNU General Public License as published by
   125.7 - * the Free Software Foundation; either version 2 of the License, or
   125.8 - * (at your option) any later version.
   125.9 - *
  125.10 - * This program is distributed in the hope that it will be useful,
  125.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  125.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  125.13 - * GNU General Public License for more details.
  125.14 - *
  125.15 - * You should have received a copy of the GNU General Public License
  125.16 - * along with this program; if not, write to the Free Software
  125.17 - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  125.18 - *
  125.19 - * Copyright (C) IBM Corp. 2006
  125.20 - *
  125.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  125.22 - */
  125.23 -
  125.24 -#ifndef __PPC_UACCESS_H__
  125.25 -#define __PPC_UACCESS_H__
  125.26 -
  125.27 -#include <xen/errno.h>
  125.28 -#include <asm/page.h>
  125.29 -#include <asm/guest_access.h>
  125.30 -
  125.31 -/* since we run in real mode, we can safely access all addresses.
  125.32 - * XXX well, except IO. should we check for that here? */
  125.33 -#define access_ok(addr,size) 1
  125.34 -#define array_access_ok(addr,count,size) 1
  125.35 -
  125.36 -#define __copy_to_user copy_to_user
  125.37 -#define __copy_from_user copy_from_user
  125.38 -#define copy_to_user(to,from,len) xencomm_copy_to_guest(to,from,len,0)
  125.39 -#define copy_from_user(to,from,len) xencomm_copy_from_guest(to,from,len,0)
  125.40 -
  125.41 -#endif /* __PPC_UACCESS_H__ */
   126.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.2 +++ b/xen/include/asm-powerpc/xenoprof.h	Thu Dec 14 08:57:36 2006 -0700
   126.3 @@ -0,0 +1,26 @@
   126.4 +/*
   126.5 + * This program is free software; you can redistribute it and/or modify
   126.6 + * it under the terms of the GNU General Public License as published by
   126.7 + * the Free Software Foundation; either version 2 of the License, or
   126.8 + * (at your option) any later version.
   126.9 + *
  126.10 + * This program is distributed in the hope that it will be useful,
  126.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  126.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  126.13 + * GNU General Public License for more details.
  126.14 + *
  126.15 + * You should have received a copy of the GNU General Public License
  126.16 + * along with this program; if not, write to the Free Software
  126.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  126.18 + *
  126.19 + * Copyright (C) IBM Corp. 2006
  126.20 + *
  126.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  126.22 + */
  126.23 +
  126.24 +#ifndef __ASM_PPC_XENOPROF_H__
  126.25 +#define __ASM_PPC_XENOPROF_H__
  126.26 +
  126.27 +/* unimplemented */
  126.28 +
  126.29 +#endif
   127.1 --- a/xen/include/asm-x86/numa.h	Thu Dec 14 08:54:54 2006 -0700
   127.2 +++ b/xen/include/asm-x86/numa.h	Thu Dec 14 08:57:36 2006 -0700
   127.3 @@ -37,7 +37,7 @@ extern void __init init_cpu_to_node(void
   127.4  
   127.5  static inline void clear_node_cpumask(int cpu)
   127.6  {
   127.7 -	clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
   127.8 +	cpu_clear(cpu, node_to_cpumask[cpu_to_node(cpu)]);
   127.9  }
  127.10  
  127.11  /* Simple perfect hash to map physical addresses to node numbers */
   128.1 --- a/xen/include/asm-x86/page.h	Thu Dec 14 08:54:54 2006 -0700
   128.2 +++ b/xen/include/asm-x86/page.h	Thu Dec 14 08:57:36 2006 -0700
   128.3 @@ -26,25 +26,37 @@
   128.4  #endif
   128.5  
   128.6  /* Read a pte atomically from memory. */
   128.7 -#define l1e_read_atomic(l1ep) l1e_from_intpte(pte_read_atomic(l1ep))
   128.8 -#define l2e_read_atomic(l2ep) l2e_from_intpte(pte_read_atomic(l2ep))
   128.9 -#define l3e_read_atomic(l3ep) l3e_from_intpte(pte_read_atomic(l3ep))
  128.10 -#define l4e_read_atomic(l4ep) l4e_from_intpte(pte_read_atomic(l4ep))
  128.11 +#define l1e_read_atomic(l1ep) \
  128.12 +    l1e_from_intpte(pte_read_atomic(&l1e_get_intpte(*(l1ep))))
  128.13 +#define l2e_read_atomic(l2ep) \
  128.14 +    l2e_from_intpte(pte_read_atomic(&l2e_get_intpte(*(l2ep))))
  128.15 +#define l3e_read_atomic(l3ep) \
  128.16 +    l3e_from_intpte(pte_read_atomic(&l3e_get_intpte(*(l3ep))))
  128.17 +#define l4e_read_atomic(l4ep) \
  128.18 +    l4e_from_intpte(pte_read_atomic(&l4e_get_intpte(*(l4ep))))
  128.19  
  128.20  /* Write a pte atomically to memory. */
  128.21 -#define l1e_write_atomic(l1ep, l1e) pte_write_atomic(l1ep, l1e_get_intpte(l1e))
  128.22 -#define l2e_write_atomic(l2ep, l2e) pte_write_atomic(l2ep, l2e_get_intpte(l2e))
  128.23 -#define l3e_write_atomic(l3ep, l3e) pte_write_atomic(l3ep, l3e_get_intpte(l3e))
  128.24 -#define l4e_write_atomic(l4ep, l4e) pte_write_atomic(l4ep, l4e_get_intpte(l4e))
  128.25 +#define l1e_write_atomic(l1ep, l1e) \
  128.26 +    pte_write_atomic(&l1e_get_intpte(*(l1ep)), l1e_get_intpte(l1e))
  128.27 +#define l2e_write_atomic(l2ep, l2e) \
  128.28 +    pte_write_atomic(&l2e_get_intpte(*(l2ep)), l2e_get_intpte(l2e))
  128.29 +#define l3e_write_atomic(l3ep, l3e) \
  128.30 +    pte_write_atomic(&l3e_get_intpte(*(l3ep)), l3e_get_intpte(l3e))
  128.31 +#define l4e_write_atomic(l4ep, l4e) \
  128.32 +    pte_write_atomic(&l4e_get_intpte(*(l4ep)), l4e_get_intpte(l4e))
  128.33  
  128.34  /*
  128.35   * Write a pte safely but non-atomically to memory.
  128.36   * The PTE may become temporarily not-present during the update.
  128.37   */
  128.38 -#define l1e_write(l1ep, l1e) pte_write(l1ep, l1e_get_intpte(l1e))
  128.39 -#define l2e_write(l2ep, l2e) pte_write(l2ep, l2e_get_intpte(l2e))
  128.40 -#define l3e_write(l3ep, l3e) pte_write(l3ep, l3e_get_intpte(l3e))
  128.41 -#define l4e_write(l4ep, l4e) pte_write(l4ep, l4e_get_intpte(l4e))
  128.42 +#define l1e_write(l1ep, l1e) \
  128.43 +    pte_write(&l1e_get_intpte(*(l1ep)), l1e_get_intpte(l1e))
  128.44 +#define l2e_write(l2ep, l2e) \
  128.45 +    pte_write(&l2e_get_intpte(*(l2ep)), l2e_get_intpte(l2e))
  128.46 +#define l3e_write(l3ep, l3e) \
  128.47 +    pte_write(&l3e_get_intpte(*(l3ep)), l3e_get_intpte(l3e))
  128.48 +#define l4e_write(l4ep, l4e) \
  128.49 +    pte_write(&l4e_get_intpte(*(l4ep)), l4e_get_intpte(l4e))
  128.50  
  128.51  /* Get direct integer representation of a pte's contents (intpte_t). */
  128.52  #define l1e_get_intpte(x)          ((x).l1)
   129.1 --- a/xen/include/asm-x86/shadow.h	Thu Dec 14 08:54:54 2006 -0700
   129.2 +++ b/xen/include/asm-x86/shadow.h	Thu Dec 14 08:57:36 2006 -0700
   129.3 @@ -540,6 +540,9 @@ extern int shadow_remove_write_access(st
   129.4   * Returns non-zero if we need to flush TLBs. */
   129.5  extern int shadow_remove_all_mappings(struct vcpu *v, mfn_t target_mfn);
   129.6  
   129.7 +/* Remove all mappings from the shadows. */
   129.8 +extern void shadow_blow_tables(struct domain *d);
   129.9 +
  129.10  void
  129.11  shadow_remove_all_shadows_and_parents(struct vcpu *v, mfn_t gmfn);
  129.12  /* This is a HVM page that we thing is no longer a pagetable.
   130.1 --- a/xen/include/asm-x86/x86_32/page-2level.h	Thu Dec 14 08:54:54 2006 -0700
   130.2 +++ b/xen/include/asm-x86/x86_32/page-2level.h	Thu Dec 14 08:57:36 2006 -0700
   130.3 @@ -28,9 +28,9 @@ typedef l2_pgentry_t root_pgentry_t;
   130.4  
   130.5  #endif /* !__ASSEMBLY__ */
   130.6  
   130.7 -#define pte_read_atomic(ptep)       (*(intpte_t *)(ptep))
   130.8 -#define pte_write_atomic(ptep, pte) ((*(intpte_t *)(ptep)) = (pte))
   130.9 -#define pte_write(ptep, pte)        ((*(intpte_t *)(ptep)) = (pte))
  130.10 +#define pte_read_atomic(ptep)       (*(ptep))
  130.11 +#define pte_write_atomic(ptep, pte) (*(ptep) = (pte))
  130.12 +#define pte_write(ptep, pte)        (*(ptep) = (pte))
  130.13  
  130.14  /* root table */
  130.15  #define root_get_pfn              l2e_get_pfn
   131.1 --- a/xen/include/asm-x86/x86_32/page-3level.h	Thu Dec 14 08:54:54 2006 -0700
   131.2 +++ b/xen/include/asm-x86/x86_32/page-3level.h	Thu Dec 14 08:57:36 2006 -0700
   131.3 @@ -38,22 +38,23 @@ typedef l3_pgentry_t root_pgentry_t;
   131.4  
   131.5  #endif /* !__ASSEMBLY__ */
   131.6  
   131.7 -#define pte_read_atomic(ptep) ({                                            \
   131.8 -    intpte_t __pte = *(intpte_t *)(ptep), __npte;                           \
   131.9 -    while ( (__npte = cmpxchg((intpte_t *)(ptep), __pte, __pte)) != __pte ) \
  131.10 -        __pte = __npte;                                                     \
  131.11 +#define pte_read_atomic(ptep) ({                              \
  131.12 +    intpte_t __pte = *(ptep), __npte;                         \
  131.13 +    while ( (__npte = cmpxchg(ptep, __pte, __pte)) != __pte ) \
  131.14 +        __pte = __npte;                                       \
  131.15      __pte; })
  131.16 -#define pte_write_atomic(ptep, pte) do {                                    \
  131.17 -    intpte_t __pte = *(intpte_t *)(ptep), __npte;                           \
  131.18 -    while ( (__npte = cmpxchg((intpte_t *)(ptep), __pte, (pte))) != __pte ) \
  131.19 -        __pte = __npte;                                                     \
  131.20 +#define pte_write_atomic(ptep, pte) do {                      \
  131.21 +    intpte_t __pte = *(ptep), __npte;                         \
  131.22 +    while ( (__npte = cmpxchg(ptep, __pte, (pte))) != __pte ) \
  131.23 +        __pte = __npte;                                       \
  131.24  } while ( 0 )
  131.25 -#define pte_write(ptep, pte) do {               \
  131.26 -    *((u32 *)(ptep)+0) = 0;                     \
  131.27 -    wmb();                                      \
  131.28 -    *((u32 *)(ptep)+1) = (pte) >> 32;           \
  131.29 -    wmb();                                      \
  131.30 -    *((u32 *)(ptep)+0) = (pte) >>  0;           \
  131.31 +#define pte_write(ptep, pte) do {                             \
  131.32 +    u32 *__ptep_words = (u32 *)(ptep);                        \
  131.33 +    __ptep_words[0] = 0;                                      \
  131.34 +    wmb();                                                    \
  131.35 +    __ptep_words[1] = (pte) >> 32;                            \
  131.36 +    wmb();                                                    \
  131.37 +    __ptep_words[0] = (pte) >>  0;                            \
  131.38  } while ( 0 )
  131.39  
  131.40  /* root table */
   132.1 --- a/xen/include/asm-x86/x86_64/page.h	Thu Dec 14 08:54:54 2006 -0700
   132.2 +++ b/xen/include/asm-x86/x86_64/page.h	Thu Dec 14 08:57:36 2006 -0700
   132.3 @@ -43,9 +43,9 @@ typedef l4_pgentry_t root_pgentry_t;
   132.4  
   132.5  #endif /* !__ASSEMBLY__ */
   132.6  
   132.7 -#define pte_read_atomic(ptep)       (*(intpte_t *)(ptep))
   132.8 -#define pte_write_atomic(ptep, pte) ((*(intpte_t *)(ptep)) = (pte))
   132.9 -#define pte_write(ptep, pte)        ((*(intpte_t *)(ptep)) = (pte))
  132.10 +#define pte_read_atomic(ptep)       (*(ptep))
  132.11 +#define pte_write_atomic(ptep, pte) (*(ptep) = (pte))
  132.12 +#define pte_write(ptep, pte)        (*(ptep) = (pte))
  132.13  
  132.14  /* Given a virtual address, get an entry offset into a linear page table. */
  132.15  #define l1_linear_offset(_a) (((_a) & VADDR_MASK) >> L1_PAGETABLE_SHIFT)
   133.1 --- a/xen/include/public/arch-powerpc.h	Thu Dec 14 08:54:54 2006 -0700
   133.2 +++ b/xen/include/public/arch-powerpc.h	Thu Dec 14 08:57:36 2006 -0700
   133.3 @@ -73,6 +73,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
   133.4  
   133.5  #ifndef __ASSEMBLY__
   133.6  
   133.7 +#define XENCOMM_INLINE_FLAG (1UL << 63)
   133.8 +
   133.9  typedef uint64_t xen_ulong_t;
  133.10  
  133.11  /* User-accessible registers: need to be saved/restored for every nested Xen
   134.1 --- a/xen/include/public/domctl.h	Thu Dec 14 08:54:54 2006 -0700
   134.2 +++ b/xen/include/public/domctl.h	Thu Dec 14 08:57:36 2006 -0700
   134.3 @@ -385,6 +385,13 @@ struct xen_domctl_settimeoffset {
   134.4  typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
   134.5  DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
   134.6  
   134.7 +#define XEN_DOMCTL_real_mode_area     26
   134.8 +struct xen_domctl_real_mode_area {
   134.9 +    uint32_t log; /* log2 of Real Mode Area size */
  134.10 +};
  134.11 +typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t;
  134.12 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t);
  134.13 +
  134.14  struct xen_domctl {
  134.15      uint32_t cmd;
  134.16      uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
  134.17 @@ -410,6 +417,7 @@ struct xen_domctl {
  134.18          struct xen_domctl_hypercall_init    hypercall_init;
  134.19          struct xen_domctl_arch_setup        arch_setup;
  134.20          struct xen_domctl_settimeoffset     settimeoffset;
  134.21 +        struct xen_domctl_real_mode_area    real_mode_area;
  134.22          uint8_t                             pad[128];
  134.23      } u;
  134.24  };
   135.1 --- a/xen/include/public/io/fbif.h	Thu Dec 14 08:54:54 2006 -0700
   135.2 +++ b/xen/include/public/io/fbif.h	Thu Dec 14 08:57:36 2006 -0700
   135.3 @@ -1,19 +1,31 @@
   135.4  /*
   135.5   * fbif.h -- Xen virtual frame buffer device
   135.6   *
   135.7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   135.8 + * of this software and associated documentation files (the "Software"), to
   135.9 + * deal in the Software without restriction, including without limitation the
  135.10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  135.11 + * sell copies of the Software, and to permit persons to whom the Software is
  135.12 + * furnished to do so, subject to the following conditions:
  135.13 + *
  135.14 + * The above copyright notice and this permission notice shall be included in
  135.15 + * all copies or substantial portions of the Software.
  135.16 + *
  135.17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  135.18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  135.19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  135.20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  135.21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  135.22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  135.23 + * DEALINGS IN THE SOFTWARE.
  135.24 + *
  135.25   * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
  135.26   * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
  135.27 - *
  135.28 - *  This file is subject to the terms and conditions of the GNU General Public
  135.29 - *  License. See the file COPYING in the main directory of this archive for
  135.30 - *  more details.
  135.31   */
  135.32  
  135.33  #ifndef __XEN_PUBLIC_IO_FBIF_H__
  135.34  #define __XEN_PUBLIC_IO_FBIF_H__
  135.35  
  135.36 -#include <asm/types.h>
  135.37 -
  135.38  /* Out events (frontend -> backend) */
  135.39  
  135.40  /*
  135.41 @@ -31,20 +43,20 @@
  135.42