ia64/xen-unstable

changeset 11065:9fc1979e9b00

Merge with xen-ia64-unstable.
author kfraser@localhost.localdomain
date Wed Aug 09 18:15:27 2006 +0100 (2006-08-09)
parents fc6c3d866477 b60ea69932b1
children bd11c4855c5d
files tools/libxc/xc_ppc_linux_build.c xen/include/asm-ia64/linux-null/linux/kallsyms.h xen/include/asm-ia64/linux-null/linux/workqueue.h
line diff
     1.1 --- a/.hgignore	Wed Aug 09 10:32:23 2006 -0600
     1.2 +++ b/.hgignore	Wed Aug 09 18:15:27 2006 +0100
     1.3 @@ -197,7 +197,7 @@
     1.4  ^xen/xen$
     1.5  ^xen/xen-syms$
     1.6  ^xen/xen\..*$
     1.7 -^xen/arch/ppc/dom0\.bin$
     1.8 -^xen/arch/ppc/asm-offsets\.s$
     1.9 -^xen/arch/ppc/firmware
    1.10 -^xen/arch/ppc/firmware_image
    1.11 +^xen/arch/powerpc/dom0\.bin$
    1.12 +^xen/arch/powerpc/asm-offsets\.s$
    1.13 +^xen/arch/powerpc/firmware
    1.14 +^xen/arch/powerpc/firmware_image
     2.1 --- a/tools/libxc/Makefile	Wed Aug 09 10:32:23 2006 -0600
     2.2 +++ b/tools/libxc/Makefile	Wed Aug 09 18:15:27 2006 +0100
     2.3 @@ -29,7 +29,6 @@ GUEST_SRCS-y :=
     2.4  GUEST_SRCS-y += xc_load_bin.c
     2.5  GUEST_SRCS-y += xc_load_elf.c
     2.6  GUEST_SRCS-y += xg_private.c
     2.7 -GUEST_SRCS-$(CONFIG_POWERPC) += xc_ppc_linux_build.c
     2.8  GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
     2.9  GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
    2.10  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
    2.11 @@ -140,3 +139,4 @@ libxenguest.so.$(MAJOR).$(MINOR): $(GUES
    2.12  	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) -shared -o $@ $^ -lz -lxenctrl
    2.13  
    2.14  -include $(DEPS)
    2.15 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/libxc/powerpc64/Makefile	Wed Aug 09 18:15:27 2006 +0100
     3.3 @@ -0,0 +1,1 @@
     3.4 +GUEST_SRCS-y += powerpc64/xc_linux_build.c
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c	Wed Aug 09 18:15:27 2006 +0100
     4.3 @@ -0,0 +1,408 @@
     4.4 +/*
     4.5 + * This program is free software; you can redistribute it and/or modify
     4.6 + * it under the terms of the GNU General Public License as published by
     4.7 + * the Free Software Foundation; either version 2 of the License, or
     4.8 + * (at your option) any later version.
     4.9 + *
    4.10 + * This program is distributed in the hope that it will be useful,
    4.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.13 + * GNU General Public License for more details.
    4.14 + *
    4.15 + * You should have received a copy of the GNU General Public License
    4.16 + * along with this program; if not, write to the Free Software
    4.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    4.18 + *
    4.19 + * Copyright (C) IBM Corporation 2006
    4.20 + *
    4.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    4.22 + */
    4.23 +
    4.24 +#include <stdio.h>
    4.25 +#include <stdint.h>
    4.26 +#include <stdlib.h>
    4.27 +#include <string.h>
    4.28 +#include <unistd.h>
    4.29 +#include <fcntl.h>
    4.30 +#include <sys/types.h>
    4.31 +#include <inttypes.h>
    4.32 +
    4.33 +#include <xen/dom0_ops.h>
    4.34 +#include <xen/memory.h>
    4.35 +#include <xc_private.h>
    4.36 +#include <xg_private.h>
    4.37 +#include <xenctrl.h>
    4.38 +
    4.39 +/* XXX 64M hack */
    4.40 +#define MEMSIZE (64UL << 20)
    4.41 +#define INITRD_ADDR (24UL << 20)
    4.42 +
    4.43 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
    4.44 +
    4.45 +#define max(x,y) ({ \
    4.46 +        const typeof(x) _x = (x);       \
    4.47 +        const typeof(y) _y = (y);       \
    4.48 +        (void) (&_x == &_y);            \
    4.49 +        _x > _y ? _x : _y; })
    4.50 +
    4.51 +static void *load_file(const char *path, unsigned long *filesize)
    4.52 +{
    4.53 +    void *img;
    4.54 +    ssize_t size;
    4.55 +    int fd;
    4.56 +
    4.57 +    DPRINTF("load_file(%s)\n", path);
    4.58 +
    4.59 +    fd = open(path, O_RDONLY);
    4.60 +    if (fd < 0) {
    4.61 +        perror(path);
    4.62 +        return NULL;
    4.63 +    }
    4.64 +
    4.65 +    size = lseek(fd, 0, SEEK_END);
    4.66 +    if (size < 0) {
    4.67 +        perror(path);
    4.68 +        close(fd);
    4.69 +        return NULL;
    4.70 +    }
    4.71 +    lseek(fd, 0, SEEK_SET);
    4.72 +
    4.73 +    img = malloc(size);
    4.74 +    if (img == NULL) {
    4.75 +        perror(path);
    4.76 +        close(fd);
    4.77 +        return NULL;
    4.78 +    }
    4.79 +
    4.80 +    size = read(fd, img, size);
    4.81 +    if (size <= 0) {
    4.82 +        perror(path);
    4.83 +        close(fd);
    4.84 +        free(img);
    4.85 +        return NULL;
    4.86 +    }
    4.87 +
    4.88 +    if (filesize)
    4.89 +        *filesize = size;
    4.90 +    close(fd);
    4.91 +    return img;
    4.92 +}
    4.93 +
    4.94 +static int init_boot_vcpu(
    4.95 +    int xc_handle,
    4.96 +    int domid,
    4.97 +    struct domain_setup_info *dsi,
    4.98 +    unsigned long dtb,
    4.99 +    unsigned long kaddr)
   4.100 +{
   4.101 +    vcpu_guest_context_t ctxt;
   4.102 +    int rc;
   4.103 +
   4.104 +    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   4.105 +    ctxt.user_regs.pc = dsi->v_kernentry;
   4.106 +    ctxt.user_regs.msr = 0;
   4.107 +    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   4.108 +    ctxt.user_regs.gprs[3] = dtb;
   4.109 +    ctxt.user_regs.gprs[4] = kaddr;
   4.110 +    ctxt.user_regs.gprs[5] = 0;
   4.111 +    /* There is a buggy kernel that does not zero the "local_paca", so
   4.112 +     * we must make sure this register is 0 */
   4.113 +    ctxt.user_regs.gprs[13] = 0;
   4.114 +
   4.115 +    DPRINTF("xc_vcpu_setvcpucontext:\n"
   4.116 +                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
   4.117 +                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   4.118 +                 " %016"PRIx64"\n",
   4.119 +                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   4.120 +                 ctxt.user_regs.gprs[1],
   4.121 +                 ctxt.user_regs.gprs[2],
   4.122 +                 ctxt.user_regs.gprs[3],
   4.123 +                 ctxt.user_regs.gprs[4],
   4.124 +                 ctxt.user_regs.gprs[5]);
   4.125 +    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   4.126 +    if (rc < 0)
   4.127 +        perror("setdomaininfo");
   4.128 +
   4.129 +    return rc;
   4.130 +}
   4.131 +
   4.132 +static int install_image(
   4.133 +        int xc_handle,
   4.134 +        int domid,
   4.135 +        xen_pfn_t *page_array,
   4.136 +        void *image,
   4.137 +        unsigned long paddr,
   4.138 +        unsigned long size)
   4.139 +{
   4.140 +    uint8_t *img = image;
   4.141 +    int i;
   4.142 +    int rc = 0;
   4.143 +
   4.144 +    if (paddr & ~PAGE_MASK) {
   4.145 +        printf("*** unaligned address\n");
   4.146 +        return -1;
   4.147 +    }
   4.148 +
   4.149 +    for (i = 0; i < size; i += PAGE_SIZE) {
   4.150 +        void *page = img + i;
   4.151 +        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   4.152 +        xen_pfn_t mfn = page_array[pfn];
   4.153 +
   4.154 +        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   4.155 +        if (rc < 0) {
   4.156 +            perror("xc_copy_to_domain_page");
   4.157 +            break;
   4.158 +        }
   4.159 +    }
   4.160 +    return rc;
   4.161 +}
   4.162 +
   4.163 +/* XXX be more flexible about placement in memory */
   4.164 +static int load_dtb(
   4.165 +    int xc_handle,
   4.166 +    int domid,
   4.167 +    const char *dtb_path,
   4.168 +    unsigned long dtb_addr,
   4.169 +    struct domain_setup_info *dsi,
   4.170 +    xen_pfn_t *page_array)
   4.171 +{
   4.172 +    uint8_t *img;
   4.173 +    unsigned long dtb_size;
   4.174 +    int rc = 0;
   4.175 +
   4.176 +    img = load_file(dtb_path, &dtb_size);
   4.177 +    if (img == NULL) {
   4.178 +        rc = -1;
   4.179 +        goto out;
   4.180 +    }
   4.181 +
   4.182 +    DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size);
   4.183 +    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
   4.184 +
   4.185 +out:
   4.186 +    free(img);
   4.187 +    return rc;
   4.188 +}
   4.189 +
   4.190 +unsigned long spin_list[] = {
   4.191 +#if 0
   4.192 +    0x100,
   4.193 +    0x200,
   4.194 +    0x300,
   4.195 +    0x380,
   4.196 +    0x400,
   4.197 +    0x480,
   4.198 +    0x500,
   4.199 +    0x700,
   4.200 +    0x900,
   4.201 +    0xc00,
   4.202 +#endif
   4.203 +    0
   4.204 +};
   4.205 +
   4.206 +/* XXX yes, this is a hack */
   4.207 +static void hack_kernel_img(char *img)
   4.208 +{
   4.209 +    const off_t file_offset = 0x10000;
   4.210 +    unsigned long *addr = spin_list;
   4.211 +
   4.212 +    while (*addr) {
   4.213 +        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
   4.214 +        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
   4.215 +        *instruction = 0x48000000;
   4.216 +        addr++;
   4.217 +    }
   4.218 +}
   4.219 +
   4.220 +static int load_kernel(
   4.221 +    int xc_handle,
   4.222 +    int domid,
   4.223 +    const char *kernel_path,
   4.224 +    struct domain_setup_info *dsi,
   4.225 +    xen_pfn_t *page_array)
   4.226 +{
   4.227 +    struct load_funcs load_funcs;
   4.228 +    char *kernel_img;
   4.229 +    unsigned long kernel_size;
   4.230 +    int rc;
   4.231 +
   4.232 +    /* load the kernel ELF file */
   4.233 +    kernel_img = load_file(kernel_path, &kernel_size);
   4.234 +    if (kernel_img == NULL) {
   4.235 +        rc = -1;
   4.236 +        goto out;
   4.237 +    }
   4.238 +
   4.239 +    hack_kernel_img(kernel_img);
   4.240 +
   4.241 +    DPRINTF("probe_elf\n");
   4.242 +    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
   4.243 +    if (rc < 0) {
   4.244 +        rc = -1;
   4.245 +        printf("%s is not an ELF file\n", kernel_path);
   4.246 +        goto out;
   4.247 +    }
   4.248 +
   4.249 +    DPRINTF("parseimage\n");
   4.250 +    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
   4.251 +    if (rc < 0) {
   4.252 +        rc = -1;
   4.253 +        goto out;
   4.254 +    }
   4.255 +
   4.256 +    DPRINTF("loadimage\n");
   4.257 +    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
   4.258 +            page_array, dsi);
   4.259 +
   4.260 +    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
   4.261 +    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
   4.262 +    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
   4.263 +    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
   4.264 +    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
   4.265 +
   4.266 +out:
   4.267 +    free(kernel_img);
   4.268 +    return rc;
   4.269 +}
   4.270 +
   4.271 +static int load_initrd(
   4.272 +    int xc_handle,
   4.273 +    int domid,
   4.274 +    xen_pfn_t *page_array,
   4.275 +    const char *initrd_path,
   4.276 +    unsigned long *base,
   4.277 +    unsigned long *len)
   4.278 +{
   4.279 +    uint8_t *initrd_img;
   4.280 +    int rc = -1;
   4.281 +
   4.282 +    /* load the initrd file */
   4.283 +    initrd_img = load_file(initrd_path, len);
   4.284 +    if (initrd_img == NULL)
   4.285 +        return -1;
   4.286 +
   4.287 +    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
   4.288 +    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
   4.289 +                *len))
   4.290 +        goto out;
   4.291 +
   4.292 +    *base = INITRD_ADDR;
   4.293 +    rc = 0;
   4.294 +
   4.295 +out:
   4.296 +    free(initrd_img);
   4.297 +    return rc;
   4.298 +}
   4.299 +
   4.300 +static unsigned long create_start_info(start_info_t *si,
   4.301 +        unsigned int console_evtchn, unsigned int store_evtchn)
   4.302 +{
   4.303 +    unsigned long eomem;
   4.304 +    unsigned long si_addr;
   4.305 +
   4.306 +    memset(si, 0, sizeof(*si));
   4.307 +    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
   4.308 +
   4.309 +    eomem = MEMSIZE;
   4.310 +    si->nr_pages = eomem >> PAGE_SHIFT;
   4.311 +    si->shared_info = eomem - (PAGE_SIZE * 1);
   4.312 +    si->store_mfn = si->nr_pages - 2;
   4.313 +    si->store_evtchn = store_evtchn;
   4.314 +    si->console_mfn = si->nr_pages - 3;
   4.315 +    si->console_evtchn = console_evtchn;
   4.316 +    si_addr = eomem - (PAGE_SIZE * 4);
   4.317 +
   4.318 +    return si_addr;
   4.319 +}
   4.320 +
   4.321 +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
   4.322 +{
   4.323 +    int nr_pages;
   4.324 +    int rc;
   4.325 +
   4.326 +    DPRINTF("xc_get_tot_pages\n");
   4.327 +    nr_pages = xc_get_tot_pages(xc_handle, domid);
   4.328 +    DPRINTF("  0x%x\n", nr_pages);
   4.329 +
   4.330 +    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   4.331 +    if (*page_array == NULL) {
   4.332 +        perror("malloc");
   4.333 +        return -1;
   4.334 +    }
   4.335 +
   4.336 +    DPRINTF("xc_get_pfn_list\n");
   4.337 +    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
   4.338 +    if (rc != nr_pages) {
   4.339 +        perror("Could not get the page frame list");
   4.340 +        return -1;
   4.341 +    }
   4.342 +
   4.343 +    return 0;
   4.344 +}
   4.345 +
   4.346 +
   4.347 +
   4.348 +int xc_linux_build(int xc_handle,
   4.349 +                   uint32_t domid,
   4.350 +                   const char *image_name,
   4.351 +                   const char *initrd_name,
   4.352 +                   const char *cmdline,
   4.353 +                   const char *features,
   4.354 +                   unsigned long flags,
   4.355 +                   unsigned int store_evtchn,
   4.356 +                   unsigned long *store_mfn,
   4.357 +                   unsigned int console_evtchn,
   4.358 +                   unsigned long *console_mfn)
   4.359 +{
   4.360 +    struct domain_setup_info dsi;
   4.361 +    xen_pfn_t *page_array = NULL;
   4.362 +    unsigned long kern_addr;
   4.363 +    unsigned long dtb_addr;
   4.364 +    unsigned long si_addr;
   4.365 +    unsigned long initrd_base = 0;
   4.366 +    unsigned long initrd_len = 0;
   4.367 +    start_info_t si;
   4.368 +    int rc = 0;
   4.369 +
   4.370 +    if (get_page_array(xc_handle, domid, &page_array)) {
   4.371 +        rc = -1;
   4.372 +        goto out;
   4.373 +    }
   4.374 +
   4.375 +    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
   4.376 +        rc = -1;
   4.377 +        goto out;
   4.378 +    }
   4.379 +    kern_addr = 0;
   4.380 +
   4.381 +    if (initrd_name && initrd_name[0] != '\0' &&
   4.382 +        load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
   4.383 +                &initrd_len)) {
   4.384 +        rc = -1;
   4.385 +        goto out;
   4.386 +    }
   4.387 +    /* XXX install initrd addr/len into device tree */
   4.388 +
   4.389 +    dtb_addr = (16 << 20);
   4.390 +    if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) {
   4.391 +        dtb_addr = 0;
   4.392 +    }
   4.393 +
   4.394 +    si_addr = create_start_info(&si, console_evtchn, store_evtchn);
   4.395 +    *console_mfn = page_array[si.console_mfn];
   4.396 +    *store_mfn = page_array[si.store_mfn];
   4.397 +    
   4.398 +    if (install_image(xc_handle, domid, page_array, &si, si_addr,
   4.399 +                sizeof(start_info_t))) {
   4.400 +        rc = -1;
   4.401 +        goto out;
   4.402 +    }
   4.403 +
   4.404 +    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
   4.405 +        rc = -1;
   4.406 +        goto out;
   4.407 +    }
   4.408 +
   4.409 +out:
   4.410 +    return rc;
   4.411 +}
     5.1 --- a/tools/libxc/xc_ppc_linux_build.c	Wed Aug 09 10:32:23 2006 -0600
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,414 +0,0 @@
     5.4 -/*
     5.5 - * This program is free software; you can redistribute it and/or modify
     5.6 - * it under the terms of the GNU General Public License as published by
     5.7 - * the Free Software Foundation; either version 2 of the License, or
     5.8 - * (at your option) any later version.
     5.9 - *
    5.10 - * This program is distributed in the hope that it will be useful,
    5.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.13 - * GNU General Public License for more details.
    5.14 - *
    5.15 - * You should have received a copy of the GNU General Public License
    5.16 - * along with this program; if not, write to the Free Software
    5.17 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    5.18 - *
    5.19 - * Copyright (C) IBM Corporation 2006
    5.20 - *
    5.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    5.22 - */
    5.23 -
    5.24 -#include <stdio.h>
    5.25 -#include <stdint.h>
    5.26 -#include <stdlib.h>
    5.27 -#include <string.h>
    5.28 -#include <unistd.h>
    5.29 -#include <fcntl.h>
    5.30 -#include <sys/types.h>
    5.31 -#include <inttypes.h>
    5.32 -
    5.33 -#include <xen/dom0_ops.h>
    5.34 -#include <xen/memory.h>
    5.35 -#include <xc_private.h>
    5.36 -#include <xg_private.h>
    5.37 -#include <xenctrl.h>
    5.38 -
    5.39 -/* XXX 64M hack */
    5.40 -#define MEMSIZE (64UL << 20)
    5.41 -#define INITRD_ADDR (24UL << 20)
    5.42 -
    5.43 -int verbose;
    5.44 -#define VERBOSE(stuff, ...) \
    5.45 -    if (verbose) \
    5.46 -        stuff __VA_ARGS__;
    5.47 -
    5.48 -#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
    5.49 -
    5.50 -#define max(x,y) ({ \
    5.51 -        const typeof(x) _x = (x);       \
    5.52 -        const typeof(y) _y = (y);       \
    5.53 -        (void) (&_x == &_y);            \
    5.54 -        _x > _y ? _x : _y; })
    5.55 -
    5.56 -static void *load_file(const char *path, unsigned long *filesize)
    5.57 -{
    5.58 -    void *img;
    5.59 -    ssize_t size;
    5.60 -    int fd;
    5.61 -
    5.62 -    VERBOSE(printf("load_file(%s)\n", path));
    5.63 -
    5.64 -    fd = open(path, O_RDONLY);
    5.65 -    if (fd < 0) {
    5.66 -        perror(path);
    5.67 -        return NULL;
    5.68 -    }
    5.69 -
    5.70 -    size = lseek(fd, 0, SEEK_END);
    5.71 -    if (size < 0) {
    5.72 -        perror(path);
    5.73 -        close(fd);
    5.74 -        return NULL;
    5.75 -    }
    5.76 -    lseek(fd, 0, SEEK_SET);
    5.77 -
    5.78 -    img = malloc(size);
    5.79 -    if (img == NULL) {
    5.80 -        perror(path);
    5.81 -        close(fd);
    5.82 -        return NULL;
    5.83 -    }
    5.84 -
    5.85 -    size = read(fd, img, size);
    5.86 -    if (size <= 0) {
    5.87 -        perror(path);
    5.88 -        close(fd);
    5.89 -        free(img);
    5.90 -        return NULL;
    5.91 -    }
    5.92 -
    5.93 -    if (filesize)
    5.94 -        *filesize = size;
    5.95 -    close(fd);
    5.96 -    return img;
    5.97 -}
    5.98 -
    5.99 -static int init_boot_vcpu(
   5.100 -    int xc_handle,
   5.101 -    int domid,
   5.102 -    struct domain_setup_info *dsi,
   5.103 -    unsigned long dtb,
   5.104 -    unsigned long kaddr)
   5.105 -{
   5.106 -    vcpu_guest_context_t ctxt;
   5.107 -    int rc;
   5.108 -
   5.109 -    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   5.110 -    ctxt.user_regs.pc = dsi->v_kernentry;
   5.111 -    ctxt.user_regs.msr = 0;
   5.112 -    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   5.113 -    ctxt.user_regs.gprs[3] = dtb;
   5.114 -    ctxt.user_regs.gprs[4] = kaddr;
   5.115 -    ctxt.user_regs.gprs[5] = 0;
   5.116 -    /* There is a buggy kernel that does not zero the "local_paca", so
   5.117 -     * we must make sure this register is 0 */
   5.118 -    ctxt.user_regs.gprs[13] = 0;
   5.119 -
   5.120 -    VERBOSE(printf("xc_vcpu_setvcpucontext:\n"
   5.121 -                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
   5.122 -                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   5.123 -                 " %016"PRIx64"\n",
   5.124 -                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   5.125 -                 ctxt.user_regs.gprs[1],
   5.126 -                 ctxt.user_regs.gprs[2],
   5.127 -                 ctxt.user_regs.gprs[3],
   5.128 -                 ctxt.user_regs.gprs[4],
   5.129 -                 ctxt.user_regs.gprs[5]));
   5.130 -    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   5.131 -    if (rc < 0)
   5.132 -        perror("setdomaininfo");
   5.133 -
   5.134 -    return rc;
   5.135 -}
   5.136 -
   5.137 -static int install_image(
   5.138 -        int xc_handle,
   5.139 -        int domid,
   5.140 -        xen_pfn_t *page_array,
   5.141 -        void *image,
   5.142 -        unsigned long paddr,
   5.143 -        unsigned long size)
   5.144 -{
   5.145 -    uint8_t *img = image;
   5.146 -    int i;
   5.147 -    int rc = 0;
   5.148 -
   5.149 -    if (paddr & ~PAGE_MASK) {
   5.150 -        printf("*** unaligned address\n");
   5.151 -        return -1;
   5.152 -    }
   5.153 -
   5.154 -    for (i = 0; i < size; i += PAGE_SIZE) {
   5.155 -        void *page = img + i;
   5.156 -        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   5.157 -        xen_pfn_t mfn = page_array[pfn];
   5.158 -
   5.159 -        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   5.160 -        if (rc < 0) {
   5.161 -            perror("xc_copy_to_domain_page");
   5.162 -            break;
   5.163 -        }
   5.164 -    }
   5.165 -    return rc;
   5.166 -}
   5.167 -
   5.168 -/* XXX be more flexible about placement in memory */
   5.169 -static int load_dtb(
   5.170 -    int xc_handle,
   5.171 -    int domid,
   5.172 -    const char *dtb_path,
   5.173 -    unsigned long dtb_addr,
   5.174 -    struct domain_setup_info *dsi,
   5.175 -    xen_pfn_t *page_array)
   5.176 -{
   5.177 -    uint8_t *img;
   5.178 -    unsigned long dtb_size;
   5.179 -    int rc = 0;
   5.180 -
   5.181 -    img = load_file(dtb_path, &dtb_size);
   5.182 -    if (img == NULL) {
   5.183 -        rc = -1;
   5.184 -        goto out;
   5.185 -    }
   5.186 -
   5.187 -    VERBOSE(printf("copying device tree to 0x%lx[0x%lx]\n",
   5.188 -            dtb_addr, dtb_size));
   5.189 -    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
   5.190 -
   5.191 -out:
   5.192 -    free(img);
   5.193 -    return rc;
   5.194 -}
   5.195 -
   5.196 -unsigned long spin_list[] = {
   5.197 -#if 0
   5.198 -    0x100,
   5.199 -    0x200,
   5.200 -    0x300,
   5.201 -    0x380,
   5.202 -    0x400,
   5.203 -    0x480,
   5.204 -    0x500,
   5.205 -    0x700,
   5.206 -    0x900,
   5.207 -    0xc00,
   5.208 -#endif
   5.209 -    0
   5.210 -};
   5.211 -
   5.212 -/* XXX yes, this is a hack */
   5.213 -static void hack_kernel_img(char *img)
   5.214 -{
   5.215 -    const off_t file_offset = 0x10000;
   5.216 -    unsigned long *addr = spin_list;
   5.217 -
   5.218 -    while (*addr) {
   5.219 -        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
   5.220 -        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
   5.221 -        *instruction = 0x48000000;
   5.222 -        addr++;
   5.223 -    }
   5.224 -}
   5.225 -
   5.226 -static int load_kernel(
   5.227 -    int xc_handle,
   5.228 -    int domid,
   5.229 -    const char *kernel_path,
   5.230 -    struct domain_setup_info *dsi,
   5.231 -    xen_pfn_t *page_array)
   5.232 -{
   5.233 -    struct load_funcs load_funcs;
   5.234 -    char *kernel_img;
   5.235 -    unsigned long kernel_size;
   5.236 -    int rc;
   5.237 -
   5.238 -    /* load the kernel ELF file */
   5.239 -    kernel_img = load_file(kernel_path, &kernel_size);
   5.240 -    if (kernel_img == NULL) {
   5.241 -        rc = -1;
   5.242 -        goto out;
   5.243 -    }
   5.244 -
   5.245 -    hack_kernel_img(kernel_img);
   5.246 -
   5.247 -    VERBOSE(printf("probe_elf\n"));
   5.248 -    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
   5.249 -    if (rc < 0) {
   5.250 -        rc = -1;
   5.251 -        printf("%s is not an ELF file\n", kernel_path);
   5.252 -        goto out;
   5.253 -    }
   5.254 -
   5.255 -    VERBOSE(printf("parseimage\n"));
   5.256 -    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
   5.257 -    if (rc < 0) {
   5.258 -        rc = -1;
   5.259 -        goto out;
   5.260 -    }
   5.261 -
   5.262 -    VERBOSE(printf("loadimage\n"));
   5.263 -    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
   5.264 -            page_array, dsi);
   5.265 -
   5.266 -    VERBOSE(printf("  v_start     %016"PRIx64"\n", dsi->v_start));
   5.267 -    VERBOSE(printf("  v_end       %016"PRIx64"\n", dsi->v_end));
   5.268 -    VERBOSE(printf("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart));
   5.269 -    VERBOSE(printf("  v_kernend   %016"PRIx64"\n", dsi->v_kernend));
   5.270 -    VERBOSE(printf("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry));
   5.271 -
   5.272 -out:
   5.273 -    free(kernel_img);
   5.274 -    return rc;
   5.275 -}
   5.276 -
   5.277 -static int load_initrd(
   5.278 -    int xc_handle,
   5.279 -    int domid,
   5.280 -    xen_pfn_t *page_array,
   5.281 -    const char *initrd_path,
   5.282 -    unsigned long *base,
   5.283 -    unsigned long *len)
   5.284 -{
   5.285 -    uint8_t *initrd_img;
   5.286 -    int rc = -1;
   5.287 -
   5.288 -    /* load the initrd file */
   5.289 -    initrd_img = load_file(initrd_path, len);
   5.290 -    if (initrd_img == NULL)
   5.291 -        return -1;
   5.292 -
   5.293 -    VERBOSE(printf("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len));
   5.294 -    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
   5.295 -                *len))
   5.296 -        goto out;
   5.297 -
   5.298 -    *base = INITRD_ADDR;
   5.299 -    rc = 0;
   5.300 -
   5.301 -out:
   5.302 -    free(initrd_img);
   5.303 -    return rc;
   5.304 -}
   5.305 -
   5.306 -static unsigned long create_start_info(start_info_t *si,
   5.307 -        unsigned int console_evtchn, unsigned int store_evtchn)
   5.308 -{
   5.309 -    unsigned long eomem;
   5.310 -    unsigned long si_addr;
   5.311 -
   5.312 -    memset(si, 0, sizeof(*si));
   5.313 -    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
   5.314 -
   5.315 -    eomem = MEMSIZE;
   5.316 -    si->nr_pages = eomem >> PAGE_SHIFT;
   5.317 -    si->shared_info = eomem - (PAGE_SIZE * 1);
   5.318 -    si->store_mfn = si->nr_pages - 2;
   5.319 -    si->store_evtchn = store_evtchn;
   5.320 -    si->console_mfn = si->nr_pages - 3;
   5.321 -    si->console_evtchn = console_evtchn;
   5.322 -    si_addr = eomem - (PAGE_SIZE * 4);
   5.323 -
   5.324 -    return si_addr;
   5.325 -}
   5.326 -
   5.327 -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
   5.328 -{
   5.329 -    int nr_pages;
   5.330 -    int rc;
   5.331 -
   5.332 -    VERBOSE(printf("xc_get_tot_pages\n"));
   5.333 -    nr_pages = xc_get_tot_pages(xc_handle, domid);
   5.334 -    VERBOSE(printf("  0x%x\n", nr_pages));
   5.335 -
   5.336 -    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   5.337 -    if (*page_array == NULL) {
   5.338 -        perror("malloc");
   5.339 -        return -1;
   5.340 -    }
   5.341 -
   5.342 -    VERBOSE(printf("xc_get_pfn_list\n"));
   5.343 -    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
   5.344 -    if (rc != nr_pages) {
   5.345 -        perror("Could not get the page frame list");
   5.346 -        return -1;
   5.347 -    }
   5.348 -
   5.349 -    return 0;
   5.350 -}
   5.351 -
   5.352 -
   5.353 -
   5.354 -int xc_linux_build(int xc_handle,
   5.355 -                   uint32_t domid,
   5.356 -                   const char *image_name,
   5.357 -                   const char *initrd_name,
   5.358 -                   const char *cmdline,
   5.359 -                   const char *features,
   5.360 -                   unsigned long flags,
   5.361 -                   unsigned int store_evtchn,
   5.362 -                   unsigned long *store_mfn,
   5.363 -                   unsigned int console_evtchn,
   5.364 -                   unsigned long *console_mfn)
   5.365 -{
   5.366 -    struct domain_setup_info dsi;
   5.367 -    xen_pfn_t *page_array = NULL;
   5.368 -    unsigned long kern_addr;
   5.369 -    unsigned long dtb_addr;
   5.370 -    unsigned long si_addr;
   5.371 -    unsigned long initrd_base = 0;
   5.372 -    unsigned long initrd_len = 0;
   5.373 -    start_info_t si;
   5.374 -    int rc = 0;
   5.375 -
   5.376 -    if (get_page_array(xc_handle, domid, &page_array)) {
   5.377 -        rc = -1;
   5.378 -        goto out;
   5.379 -    }
   5.380 -
   5.381 -    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
   5.382 -        rc = -1;
   5.383 -        goto out;
   5.384 -    }
   5.385 -    kern_addr = 0;
   5.386 -
   5.387 -    if (initrd_name && initrd_name[0] != '\0' &&
   5.388 -        load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
   5.389 -                &initrd_len)) {
   5.390 -        rc = -1;
   5.391 -        goto out;
   5.392 -    }
   5.393 -    /* XXX install initrd addr/len into device tree */
   5.394 -
   5.395 -    dtb_addr = (16 << 20);
   5.396 -    if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) {
   5.397 -        dtb_addr = 0;
   5.398 -    }
   5.399 -
   5.400 -    si_addr = create_start_info(&si, store_evtchn, console_evtchn);
   5.401 -    *console_mfn = page_array[si.console_mfn];
   5.402 -    *store_mfn = page_array[si.store_mfn];
   5.403 -    
   5.404 -    if (install_image(xc_handle, domid, page_array, &si, si_addr,
   5.405 -                sizeof(start_info_t))) {
   5.406 -        rc = -1;
   5.407 -        goto out;
   5.408 -    }
   5.409 -
   5.410 -    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
   5.411 -        rc = -1;
   5.412 -        goto out;
   5.413 -    }
   5.414 -
   5.415 -out:
   5.416 -    return rc;
   5.417 -}
     6.1 --- a/xen/arch/powerpc/Makefile	Wed Aug 09 10:32:23 2006 -0600
     6.2 +++ b/xen/arch/powerpc/Makefile	Wed Aug 09 18:15:27 2006 +0100
     6.3 @@ -83,6 +83,9 @@ physdev.o: ../x86/physdev.c
     6.4  
     6.5  HDRS += $(wildcard *.h)
     6.6  
     6.7 +CMDLINE = "xen"
     6.8 +boot_of.o: CFLAGS += -DCMDLINE="\"$(CMDLINE)\""
     6.9 +
    6.10  start.o: boot/start.S
    6.11  	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
    6.12  
     7.1 --- a/xen/arch/powerpc/boot_of.c	Wed Aug 09 10:32:23 2006 -0600
     7.2 +++ b/xen/arch/powerpc/boot_of.c	Wed Aug 09 18:15:27 2006 +0100
     7.3 @@ -37,6 +37,10 @@ static int of_out;
     7.4  static ofdn_t boot_cpu;
     7.5  static char bootargs[256];
     7.6  
     7.7 +#define COMMAND_LINE_SIZE 512
     7.8 +static char builtin_cmdline[COMMAND_LINE_SIZE]
     7.9 +    __attribute__((section("__builtin_cmdline"))) = CMDLINE;
    7.10 +
    7.11  extern struct ns16550_defaults ns16550;
    7.12  
    7.13  #undef OF_DEBUG
    7.14 @@ -449,8 +453,8 @@ static void boot_of_bootargs(multiboot_i
    7.15      int rc;
    7.16  
    7.17      rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
    7.18 -    if (rc == OF_FAILURE) {
    7.19 -        strcpy(bootargs, "xen");
    7.20 +    if (rc == OF_FAILURE || bootargs[0] == '\0') {
    7.21 +        strlcpy(bootargs, builtin_cmdline, sizeof(bootargs));
    7.22      }
    7.23  
    7.24      mbi->flags |= MBI_CMDLINE;
     8.1 --- a/xen/arch/powerpc/dom0_ops.c	Wed Aug 09 10:32:23 2006 -0600
     8.2 +++ b/xen/arch/powerpc/dom0_ops.c	Wed Aug 09 18:15:27 2006 +0100
     8.3 @@ -40,23 +40,40 @@ long arch_do_dom0_op(struct dom0_op *op,
     8.4      long ret = 0;
     8.5  
     8.6      switch (op->cmd) {
     8.7 -    case DOM0_GETMEMLIST: {
     8.8 -        /* XXX 64M hackage */
     8.9 -        const int memsize = (64UL<<20);
    8.10 -        int domain_pfns = memsize>>12;
    8.11 -        int max_pfns = op->u.getmemlist.max_pfns;
    8.12 -        int domid = op->u.getmemlist.domain;
    8.13 +    case DOM0_GETMEMLIST:
    8.14 +    {
    8.15          int i;
    8.16 +        struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
    8.17 +        unsigned long max_pfns = op->u.getmemlist.max_pfns;
    8.18 +        xen_pfn_t mfn;
    8.19 +        struct list_head *list_ent;
    8.20 +
    8.21 +        ret = -EINVAL;
    8.22 +        if ( d != NULL )
    8.23 +        {
    8.24 +            ret = 0;
    8.25  
    8.26 -        for (i = 0; (i < max_pfns) && (i < domain_pfns); i++) {
    8.27 -            xen_pfn_t mfn = (((domid + 1) * memsize) >> 12) + i;
    8.28 -            if (copy_to_guest_offset(op->u.getmemlist.buffer, i, &mfn, 1)) {
    8.29 -                ret = -EFAULT;
    8.30 -                break;
    8.31 +            spin_lock(&d->page_alloc_lock);
    8.32 +            list_ent = d->page_list.next;
    8.33 +            for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
    8.34 +            {
    8.35 +                mfn = page_to_mfn(list_entry(
    8.36 +                    list_ent, struct page_info, list));
    8.37 +                if ( copy_to_guest_offset(op->u.getmemlist.buffer,
    8.38 +                                          i, &mfn, 1) )
    8.39 +                {
    8.40 +                    ret = -EFAULT;
    8.41 +                    break;
    8.42 +                }
    8.43 +                list_ent = mfn_to_page(mfn)->list.next;
    8.44              }
    8.45 +            spin_unlock(&d->page_alloc_lock);
    8.46 +
    8.47 +            op->u.getmemlist.num_pfns = i;
    8.48 +            copy_to_guest(u_dom0_op, op, 1);
    8.49 +            
    8.50 +            put_domain(d);
    8.51          }
    8.52 -        op->u.getmemlist.num_pfns = i;
    8.53 -        copy_to_guest(u_dom0_op, op, 1);
    8.54      }
    8.55      break;
    8.56  
     9.1 --- a/xen/arch/powerpc/domain.c	Wed Aug 09 10:32:23 2006 -0600
     9.2 +++ b/xen/arch/powerpc/domain.c	Wed Aug 09 18:15:27 2006 +0100
     9.3 @@ -73,6 +73,10 @@ unsigned long hypercall_create_continuat
     9.4  
     9.5  int arch_domain_create(struct domain *d)
     9.6  {
     9.7 +    struct page_info *rma;
     9.8 +    unsigned long rma_base;
     9.9 +    unsigned long rma_size;
    9.10 +    unsigned int rma_order;
    9.11  
    9.12      if (d->domain_id == IDLE_DOMAIN_ID) {
    9.13          d->shared_info = (void *)alloc_xenheap_page();
    9.14 @@ -81,17 +85,28 @@ int arch_domain_create(struct domain *d)
    9.15          return 0;
    9.16      }
    9.17  
    9.18 -    /* XXX the hackage... hardcode 64M domains */
    9.19 -    d->arch.rma_base = (64<<20) * (d->domain_id + 1);
    9.20 -    d->arch.rma_size = (64<<20);
    9.21 +    rma_order = cpu_rma_order();
    9.22 +    rma_size = 1UL << rma_order << PAGE_SHIFT;
    9.23  
    9.24 -    printk("clearing RMO: 0x%lx[0x%lx]\n", d->arch.rma_base, d->arch.rma_size);
    9.25 -    memset((void*)d->arch.rma_base, 0, d->arch.rma_size);
    9.26 +    /* allocate the real mode area */
    9.27 +    d->max_pages = 1UL << rma_order;
    9.28 +    rma = alloc_domheap_pages(d, rma_order, 0);
    9.29 +    if (NULL == rma)
    9.30 +        return 1;
    9.31 +    rma_base = page_to_maddr(rma);
    9.32 +
    9.33 +    BUG_ON(rma_base & (rma_size-1)); /* check alignment */
    9.34 +
    9.35 +    d->arch.rma_base = rma_base;
    9.36 +    d->arch.rma_size = rma_size;
    9.37 +
    9.38 +    printk("clearing RMO: 0x%lx[0x%lx]\n", rma_base, rma_size);
    9.39 +    memset((void *)rma_base, 0, rma_size);
    9.40  
    9.41      htab_alloc(d, LOG_DEFAULT_HTAB_BYTES);
    9.42  
    9.43      d->shared_info = (shared_info_t *)
    9.44 -        (rma_addr(&d->arch, RMA_SHARED_INFO) + d->arch.rma_base);
    9.45 +        (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base);
    9.46  
    9.47      d->arch.large_page_sizes = 1;
    9.48      d->arch.large_page_shift[0] = 24; /* 16 M for 970s */
    10.1 --- a/xen/arch/powerpc/of_handler/devtree.c	Wed Aug 09 10:32:23 2006 -0600
    10.2 +++ b/xen/arch/powerpc/of_handler/devtree.c	Wed Aug 09 18:15:27 2006 +0100
    10.3 @@ -203,12 +203,14 @@ ofh_finddevice(u32 nargs, u32 nrets, s32
    10.4              /* good enuff */
    10.5              if (devspec[0] == '\0') {
    10.6                  if (*ap == -1) {
    10.7 +                    *ph = -1;
    10.8                      return OF_FAILURE;
    10.9                  }
   10.10                  *ph = *ap;
   10.11              } else {
   10.12                  *ph = ofd_node_find(mem, devspec);
   10.13                  if (*ph <= 0) {
   10.14 +                    *ph = -1;
   10.15                      return OF_FAILURE;
   10.16                  }
   10.17              }
    11.1 --- a/xen/arch/powerpc/powerpc64/ppc970.c	Wed Aug 09 10:32:23 2006 -0600
    11.2 +++ b/xen/arch/powerpc/powerpc64/ppc970.c	Wed Aug 09 18:15:27 2006 +0100
    11.3 @@ -31,6 +31,12 @@
    11.4  
    11.5  #undef SERIALIZE
    11.6  
    11.7 +unsigned int cpu_rma_order(void)
    11.8 +{
    11.9 +    /* XXX what about non-HV mode? */
   11.10 +    return 14; /* 1<<14<<PAGE_SIZE = 64M */
   11.11 +}
   11.12 +
   11.13  void cpu_initialize(void)
   11.14  {
   11.15      ulong stack;
   11.16 @@ -102,7 +108,6 @@ void cpu_initialize(void)
   11.17      mthid5(hid5.word);
   11.18  
   11.19      __asm__ __volatile__("isync; slbia; isync" : : : "memory");
   11.20 -    
   11.21  }
   11.22  
   11.23  void cpu_init_vcpu(struct vcpu *v)
    12.1 --- a/xen/arch/powerpc/usercopy.c	Wed Aug 09 10:32:23 2006 -0600
    12.2 +++ b/xen/arch/powerpc/usercopy.c	Wed Aug 09 18:15:27 2006 +0100
    12.3 @@ -238,5 +238,5 @@ int xencomm_handle_is_null(void *ptr)
    12.4  
    12.5      desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
    12.6  
    12.7 -    return (desc->address[0] == XENCOMM_INVALID);
    12.8 +    return (desc->nr_addrs == 0);
    12.9  }
    15.1 --- a/xen/include/asm-powerpc/processor.h	Wed Aug 09 10:32:23 2006 -0600
    15.2 +++ b/xen/include/asm-powerpc/processor.h	Wed Aug 09 18:15:27 2006 +0100
    15.3 @@ -39,6 +39,7 @@ struct vcpu;
    15.4  struct cpu_user_regs;
    15.5  extern void show_registers(struct cpu_user_regs *);
    15.6  extern void show_execution_state(struct cpu_user_regs *);
    15.7 +extern unsigned int cpu_rma_order(void);
    15.8  extern void cpu_initialize(void);
    15.9  extern void cpu_init_vcpu(struct vcpu *);
   15.10  extern void save_cpu_sprs(struct vcpu *);