direct-io.hg

changeset 12948:f2aaf35c7759

[TOOLS][POWERPC] Add Prose Domain Builder
The following patch addes a Prose domain builder. For the moment it
is a clone of the linux ppc64 builder but will diverge quickly.
Signed-off-by: Jonathan Appavoo <jappavoo@us.ibm.com>
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Wed Oct 18 06:43:33 2006 -0400 (2006-10-18)
parents 877361bfe3ae
children 5c3b6b623c57
files tools/libxc/powerpc64/Makefile tools/libxc/powerpc64/xc_prose_build.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py
line diff
     1.1 --- a/tools/libxc/powerpc64/Makefile	Wed Oct 18 06:24:57 2006 -0400
     1.2 +++ b/tools/libxc/powerpc64/Makefile	Wed Oct 18 06:43:33 2006 -0400
     1.3 @@ -1,4 +1,4 @@
     1.4  GUEST_SRCS-y += powerpc64/xc_linux_build.c
     1.5  GUEST_SRCS-y += powerpc64/flatdevtree.c
     1.6 -
     1.7 +GUEST_SRCS-y += powerpc64/xc_prose_build.c
     1.8  CTRL_SRCS-y += powerpc64/xc_memory.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/libxc/powerpc64/xc_prose_build.c	Wed Oct 18 06:43:33 2006 -0400
     2.3 @@ -0,0 +1,478 @@
     2.4 +/*
     2.5 + * This program is free software; you can redistribute it and/or modify
     2.6 + * it under the terms of the GNU General Public License as published by
     2.7 + * the Free Software Foundation; either version 2 of the License, or
     2.8 + * (at your option) any later version.
     2.9 + *
    2.10 + * This program is distributed in the hope that it will be useful,
    2.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.13 + * GNU General Public License for more details.
    2.14 + *
    2.15 + * You should have received a copy of the GNU General Public License
    2.16 + * along with this program; if not, write to the Free Software
    2.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    2.18 + *
    2.19 + * Copyright (C) IBM Corporation 2006
    2.20 + *
    2.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    2.22 + */
    2.23 +
    2.24 +#include <stdio.h>
    2.25 +#include <stdint.h>
    2.26 +#include <stdlib.h>
    2.27 +#include <string.h>
    2.28 +#include <unistd.h>
    2.29 +#include <fcntl.h>
    2.30 +#include <sys/types.h>
    2.31 +#include <inttypes.h>
    2.32 +
    2.33 +#include <xen/xen.h>
    2.34 +#include <xen/memory.h>
    2.35 +#include <xc_private.h>
    2.36 +#include <xg_private.h>
    2.37 +#include <xenctrl.h>
    2.38 +
    2.39 +#include "flatdevtree_env.h"
    2.40 +#include "flatdevtree.h"
    2.41 +
    2.42 +#define INITRD_ADDR (24UL << 20)
    2.43 +#define DEVTREE_ADDR (16UL << 20)
    2.44 +
    2.45 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
    2.46 +
    2.47 +#define max(x,y) ({ \
    2.48 +        const typeof(x) _x = (x);       \
    2.49 +        const typeof(y) _y = (y);       \
    2.50 +        (void) (&_x == &_y);            \
    2.51 +        _x > _y ? _x : _y; })
    2.52 +
    2.53 +static void *load_file(const char *path, unsigned long *filesize)
    2.54 +{
    2.55 +    void *img;
    2.56 +    ssize_t size;
    2.57 +    int fd;
    2.58 +
    2.59 +    DPRINTF("load_file(%s)\n", path);
    2.60 +
    2.61 +    fd = open(path, O_RDONLY);
    2.62 +    if (fd < 0) {
    2.63 +        perror(path);
    2.64 +        return NULL;
    2.65 +    }
    2.66 +
    2.67 +    size = lseek(fd, 0, SEEK_END);
    2.68 +    if (size < 0) {
    2.69 +        perror(path);
    2.70 +        close(fd);
    2.71 +        return NULL;
    2.72 +    }
    2.73 +    lseek(fd, 0, SEEK_SET);
    2.74 +
    2.75 +    img = malloc(size);
    2.76 +    if (img == NULL) {
    2.77 +        perror(path);
    2.78 +        close(fd);
    2.79 +        return NULL;
    2.80 +    }
    2.81 +
    2.82 +    size = read(fd, img, size);
    2.83 +    if (size <= 0) {
    2.84 +        perror(path);
    2.85 +        close(fd);
    2.86 +        free(img);
    2.87 +        return NULL;
    2.88 +    }
    2.89 +
    2.90 +    if (filesize)
    2.91 +        *filesize = size;
    2.92 +    close(fd);
    2.93 +    return img;
    2.94 +}
    2.95 +
    2.96 +static int init_boot_vcpu(
    2.97 +    int xc_handle,
    2.98 +    int domid,
    2.99 +    struct domain_setup_info *dsi,
   2.100 +    unsigned long devtree_addr,
   2.101 +    unsigned long kern_addr)
   2.102 +{
   2.103 +    vcpu_guest_context_t ctxt;
   2.104 +    int rc;
   2.105 +
   2.106 +    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   2.107 +    ctxt.user_regs.pc = dsi->v_kernentry;
   2.108 +    ctxt.user_regs.msr = 0;
   2.109 +    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   2.110 +    ctxt.user_regs.gprs[3] = devtree_addr;
   2.111 +    ctxt.user_regs.gprs[4] = kern_addr;
   2.112 +    ctxt.user_regs.gprs[5] = 0; /* reserved for specifying OF handler */
   2.113 +    /* There is a buggy kernel that does not zero the "local_paca", so
   2.114 +     * we must make sure this register is 0 */
   2.115 +    ctxt.user_regs.gprs[13] = 0;
   2.116 +
   2.117 +    DPRINTF("xc_vcpu_setvcpucontext:\n"
   2.118 +                 "  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
   2.119 +                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   2.120 +                 " %016"PRIx64"\n",
   2.121 +                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   2.122 +                 ctxt.user_regs.gprs[1],
   2.123 +                 ctxt.user_regs.gprs[2],
   2.124 +                 ctxt.user_regs.gprs[3],
   2.125 +                 ctxt.user_regs.gprs[4],
   2.126 +                 ctxt.user_regs.gprs[5]);
   2.127 +    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   2.128 +    if (rc < 0)
   2.129 +        perror("setdomaininfo");
   2.130 +
   2.131 +    return rc;
   2.132 +}
   2.133 +
   2.134 +static int install_image(
   2.135 +        int xc_handle,
   2.136 +        int domid,
   2.137 +        xen_pfn_t *page_array,
   2.138 +        void *image,
   2.139 +        unsigned long paddr,
   2.140 +        unsigned long size)
   2.141 +{
   2.142 +    uint8_t *img = image;
   2.143 +    int i;
   2.144 +    int rc = 0;
   2.145 +
   2.146 +    if (paddr & ~PAGE_MASK) {
   2.147 +        printf("*** unaligned address\n");
   2.148 +        return -1;
   2.149 +    }
   2.150 +
   2.151 +    for (i = 0; i < size; i += PAGE_SIZE) {
   2.152 +        void *page = img + i;
   2.153 +        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   2.154 +        xen_pfn_t mfn = page_array[pfn];
   2.155 +
   2.156 +        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   2.157 +        if (rc < 0) {
   2.158 +            perror("xc_copy_to_domain_page");
   2.159 +            break;
   2.160 +        }
   2.161 +    }
   2.162 +    return rc;
   2.163 +}
   2.164 +
   2.165 +static int load_devtree(
   2.166 +    int xc_handle,
   2.167 +    int domid,
   2.168 +    xen_pfn_t *page_array,
   2.169 +    void *devtree,
   2.170 +    unsigned long devtree_addr,
   2.171 +    uint64_t initrd_base,
   2.172 +    unsigned long initrd_len,
   2.173 +    start_info_t *si,
   2.174 +    unsigned long si_addr)
   2.175 +{
   2.176 +    uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
   2.177 +    struct boot_param_header *header;
   2.178 +    void *chosen;
   2.179 +    void *xen;
   2.180 +    uint64_t initrd_end = initrd_base + initrd_len;
   2.181 +    unsigned int devtree_size;
   2.182 +    int rc = 0;
   2.183 +
   2.184 +    DPRINTF("adding initrd props\n");
   2.185 +
   2.186 +    chosen = ft_find_node(devtree, "/chosen");
   2.187 +    if (chosen == NULL) {
   2.188 +        DPRINTF("couldn't find /chosen\n");
   2.189 +        return -1;
   2.190 +    }
   2.191 +
   2.192 +    xen = ft_find_node(devtree, "/xen");
   2.193 +    if (xen == NULL) {
   2.194 +        DPRINTF("couldn't find /xen\n");
   2.195 +        return -1;
   2.196 +    }
   2.197 +
   2.198 +    /* initrd-start */
   2.199 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
   2.200 +            &initrd_base, sizeof(initrd_base));
   2.201 +    if (rc < 0) {
   2.202 +        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
   2.203 +        return rc;
   2.204 +    }
   2.205 +
   2.206 +    /* initrd-end */
   2.207 +    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
   2.208 +            &initrd_end, sizeof(initrd_end));
   2.209 +    if (rc < 0) {
   2.210 +        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
   2.211 +        return rc;
   2.212 +    }
   2.213 +
   2.214 +    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
   2.215 +    if (rc < 0) {
   2.216 +        DPRINTF("couldn't set initrd reservation\n");
   2.217 +        return ~0UL;
   2.218 +    }
   2.219 +
   2.220 +    /* start-info (XXX being removed soon) */
   2.221 +    rc = ft_set_prop(&devtree, xen, "start-info",
   2.222 +            start_info, sizeof(start_info));
   2.223 +    if (rc < 0) {
   2.224 +        DPRINTF("couldn't set /xen/start-info\n");
   2.225 +        return rc;
   2.226 +    }
   2.227 +
   2.228 +    header = devtree;
   2.229 +    devtree_size = header->totalsize;
   2.230 +    {
   2.231 +        static const char dtb[] = "/tmp/xc_domU.dtb";
   2.232 +        int dfd = creat(dtb, 0666);
   2.233 +        if (dfd != -1) {
   2.234 +            write(dfd, devtree, devtree_size);
   2.235 +            close(dfd);
   2.236 +        } else
   2.237 +            DPRINTF("could not open(\"%s\")\n", dtb);
   2.238 +    }
   2.239 +
   2.240 +    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
   2.241 +    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
   2.242 +                       devtree_size);
   2.243 +}
   2.244 +
   2.245 +static int load_kernel(
   2.246 +    int xc_handle,
   2.247 +    int domid,
   2.248 +    const char *kernel_path,
   2.249 +    struct domain_setup_info *dsi,
   2.250 +    xen_pfn_t *page_array)
   2.251 +{
   2.252 +    struct load_funcs load_funcs;
   2.253 +    char *kernel_img;
   2.254 +    unsigned long kernel_size;
   2.255 +    int rc;
   2.256 +
   2.257 +    /* load the kernel ELF file */
   2.258 +    kernel_img = load_file(kernel_path, &kernel_size);
   2.259 +    if (kernel_img == NULL) {
   2.260 +        rc = -1;
   2.261 +        goto out;
   2.262 +    }
   2.263 +
   2.264 +    DPRINTF("probe_elf\n");
   2.265 +    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
   2.266 +    if (rc < 0) {
   2.267 +        rc = -1;
   2.268 +        printf("%s is not an ELF file\n", kernel_path);
   2.269 +        goto out;
   2.270 +    }
   2.271 +
   2.272 +    DPRINTF("parseimage\n");
   2.273 +    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
   2.274 +    if (rc < 0) {
   2.275 +        rc = -1;
   2.276 +        goto out;
   2.277 +    }
   2.278 +
   2.279 +    DPRINTF("loadimage\n");
   2.280 +    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
   2.281 +            page_array, dsi);
   2.282 +
   2.283 +    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
   2.284 +    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
   2.285 +    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
   2.286 +    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
   2.287 +    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
   2.288 +
   2.289 +out:
   2.290 +    free(kernel_img);
   2.291 +    return rc;
   2.292 +}
   2.293 +
   2.294 +static int load_initrd(
   2.295 +    int xc_handle,
   2.296 +    int domid,
   2.297 +    xen_pfn_t *page_array,
   2.298 +    const char *initrd_path,
   2.299 +    unsigned long *base,
   2.300 +    unsigned long *len)
   2.301 +{
   2.302 +    uint8_t *initrd_img;
   2.303 +    int rc = -1;
   2.304 +
   2.305 +    /* load the initrd file */
   2.306 +    initrd_img = load_file(initrd_path, len);
   2.307 +    if (initrd_img == NULL)
   2.308 +        return -1;
   2.309 +
   2.310 +    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
   2.311 +    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
   2.312 +                *len))
   2.313 +        goto out;
   2.314 +
   2.315 +    *base = INITRD_ADDR;
   2.316 +    rc = 0;
   2.317 +
   2.318 +out:
   2.319 +    free(initrd_img);
   2.320 +    return rc;
   2.321 +}
   2.322 +
   2.323 +static unsigned long create_start_info(void *devtree, start_info_t *si,
   2.324 +        unsigned int console_evtchn, unsigned int store_evtchn,
   2.325 +        unsigned long nr_pages, const char *cmdline)
   2.326 +{
   2.327 +    void *rma;
   2.328 +    unsigned long si_addr;
   2.329 +    uint64_t rma_reg[2];
   2.330 +    uint64_t rma_top;
   2.331 +    int rc;
   2.332 +
   2.333 +    memset(si, 0, sizeof(*si));
   2.334 +    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
   2.335 +
   2.336 +    rma = ft_find_node(devtree, "/memory@0");
   2.337 +    if (rma == NULL) {
   2.338 +        DPRINTF("couldn't find /memory@0\n");
   2.339 +        return ~0UL;
   2.340 +    }
   2.341 +    rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
   2.342 +    if (rc < 0) {
   2.343 +        DPRINTF("couldn't get /memory@0/reg\n");
   2.344 +        return ~0UL;
   2.345 +    }
   2.346 +    rma_top = rma_reg[0] + rma_reg[1];
   2.347 +    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
   2.348 +
   2.349 +    si->nr_pages = nr_pages;
   2.350 +    si->shared_info = rma_top - PAGE_SIZE;
   2.351 +    si->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
   2.352 +    si->store_evtchn = store_evtchn;
   2.353 +    si->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
   2.354 +    si->console.domU.evtchn = console_evtchn;
   2.355 +    strncpy((char *)si->cmd_line, cmdline, MAX_GUEST_CMDLINE);
   2.356 +    /* just in case we truncated cmdline with strncpy add 0 at the end */
   2.357 +    si->cmd_line[MAX_GUEST_CMDLINE]=0;
   2.358 +    si_addr = rma_top - 4*PAGE_SIZE;
   2.359 +
   2.360 +    rc = ft_set_rsvmap(devtree, 0, si_addr, 4*PAGE_SIZE);
   2.361 +    if (rc < 0) {
   2.362 +        DPRINTF("couldn't set start_info reservation\n");
   2.363 +        return ~0UL;
   2.364 +    }
   2.365 +
   2.366 +
   2.367 +    return si_addr;
   2.368 +}
   2.369 +
   2.370 +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
   2.371 +                          unsigned long *nr_pages)
   2.372 +{
   2.373 +    int rc;
   2.374 +
   2.375 +    DPRINTF("xc_get_tot_pages\n");
   2.376 +    *nr_pages = xc_get_tot_pages(xc_handle, domid);
   2.377 +    DPRINTF("  0x%lx\n", *nr_pages);
   2.378 +
   2.379 +    *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
   2.380 +    if (*page_array == NULL) {
   2.381 +        perror("malloc");
   2.382 +        return -1;
   2.383 +    }
   2.384 +
   2.385 +    DPRINTF("xc_get_pfn_list\n");
   2.386 +    rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
   2.387 +    if (rc != *nr_pages) {
   2.388 +        perror("Could not get the page frame list");
   2.389 +        return -1;
   2.390 +    }
   2.391 +
   2.392 +    return 0;
   2.393 +}
   2.394 +
   2.395 +static void free_page_array(xen_pfn_t *page_array)
   2.396 +{
   2.397 +    free(page_array);
   2.398 +}
   2.399 +
   2.400 +
   2.401 +
   2.402 +int xc_prose_build(int xc_handle,
   2.403 +                   uint32_t domid,
   2.404 +                   const char *image_name,
   2.405 +                   const char *initrd_name,
   2.406 +                   const char *cmdline,
   2.407 +                   const char *features,
   2.408 +                   unsigned long flags,
   2.409 +                   unsigned int store_evtchn,
   2.410 +                   unsigned long *store_mfn,
   2.411 +                   unsigned int console_evtchn,
   2.412 +                   unsigned long *console_mfn,
   2.413 +                   void *devtree)
   2.414 +{
   2.415 +    start_info_t si;
   2.416 +    struct domain_setup_info dsi;
   2.417 +    xen_pfn_t *page_array = NULL;
   2.418 +    unsigned long nr_pages;
   2.419 +    unsigned long devtree_addr = 0;
   2.420 +    unsigned long kern_addr;
   2.421 +    unsigned long initrd_base = 0;
   2.422 +    unsigned long initrd_len = 0;
   2.423 +    unsigned long si_addr;
   2.424 +    int rc = 0;
   2.425 +
   2.426 +    DPRINTF("%s\n", __func__);
   2.427 +
   2.428 +    DPRINTF("cmdline=%s\n", cmdline);
   2.429 +
   2.430 +    if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
   2.431 +        rc = -1;
   2.432 +        goto out;
   2.433 +    }
   2.434 +
   2.435 +    DPRINTF("loading image '%s'\n", image_name);
   2.436 +    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
   2.437 +        rc = -1;
   2.438 +        goto out;
   2.439 +    }
   2.440 +    kern_addr = 0;
   2.441 +
   2.442 +    if (initrd_name && initrd_name[0] != '\0') {
   2.443 +        DPRINTF("loading initrd '%s'\n", initrd_name);
   2.444 +        if (load_initrd(xc_handle, domid, page_array, initrd_name,
   2.445 +                &initrd_base, &initrd_len)) {
   2.446 +            rc = -1;
   2.447 +            goto out;
   2.448 +        }
   2.449 +    }
   2.450 +
   2.451 +    /* start_info stuff: about to be removed  */
   2.452 +    si_addr = create_start_info(devtree, &si, console_evtchn, store_evtchn,
   2.453 +                                nr_pages,cmdline);
   2.454 +    *console_mfn = page_array[si.console.domU.mfn];
   2.455 +    *store_mfn = page_array[si.store_mfn];
   2.456 +    if (install_image(xc_handle, domid, page_array, &si, si_addr,
   2.457 +                sizeof(start_info_t))) {
   2.458 +        rc = -1;
   2.459 +        goto out;
   2.460 +    }
   2.461 +
   2.462 +    if (devtree) {
   2.463 +        DPRINTF("loading flattened device tree\n");
   2.464 +        devtree_addr = DEVTREE_ADDR;
   2.465 +        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
   2.466 +                     initrd_base, initrd_len, &si, si_addr)) {
   2.467 +            DPRINTF("couldn't load flattened device tree.\n");
   2.468 +            rc = -1;
   2.469 +            goto out;
   2.470 +        }
   2.471 +    }
   2.472 +
   2.473 +    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
   2.474 +        rc = -1;
   2.475 +        goto out;
   2.476 +    }
   2.477 +
   2.478 +out:
   2.479 +    free_page_array(page_array);
   2.480 +    return rc;
   2.481 +}
     3.1 --- a/tools/libxc/xenguest.h	Wed Oct 18 06:24:57 2006 -0400
     3.2 +++ b/tools/libxc/xenguest.h	Wed Oct 18 06:43:33 2006 -0400
     3.3 @@ -122,4 +122,17 @@ int xc_set_hvm_param(
     3.4  int xc_get_hvm_param(
     3.5      int handle, domid_t dom, int param, unsigned long *value);
     3.6  
     3.7 +int xc_prose_build(int xc_handle,
     3.8 +                   uint32_t domid,
     3.9 +                   const char *image_name,
    3.10 +                   const char *ramdisk_name,
    3.11 +                   const char *cmdline,
    3.12 +                   const char *features,
    3.13 +                   unsigned long flags,
    3.14 +                   unsigned int store_evtchn,
    3.15 +                   unsigned long *store_mfn,
    3.16 +                   unsigned int console_evtchn,
    3.17 +                   unsigned long *console_mfn,
    3.18 +                   void *arch_args);
    3.19 +
    3.20  #endif /* XENGUEST_H */
     4.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 18 06:24:57 2006 -0400
     4.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 18 06:43:33 2006 -0400
     4.3 @@ -369,6 +369,47 @@ static PyObject *pyxc_linux_build(XcObje
     4.4                           "console_mfn", console_mfn);
     4.5  }
     4.6  
     4.7 +static PyObject *pyxc_prose_build(XcObject *self,
     4.8 +                                  PyObject *args,
     4.9 +                                  PyObject *kwds)
    4.10 +{
    4.11 +    uint32_t dom;
    4.12 +    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
    4.13 +    int flags = 0;
    4.14 +    int store_evtchn, console_evtchn;
    4.15 +    unsigned long store_mfn = 0;
    4.16 +    unsigned long console_mfn = 0;
    4.17 +    void *arch_args = NULL;
    4.18 +    int unused;
    4.19 +
    4.20 +    static char *kwd_list[] = { "dom", "store_evtchn",
    4.21 +                                "console_evtchn", "image",
    4.22 +                                /* optional */
    4.23 +                                "ramdisk", "cmdline", "flags",
    4.24 +                                "features", "arch_args", NULL };
    4.25 +
    4.26 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
    4.27 +                                      &dom, &store_evtchn,
    4.28 +                                      &console_evtchn, &image,
    4.29 +                                      /* optional */
    4.30 +                                      &ramdisk, &cmdline, &flags,
    4.31 +                                      &features, &arch_args, &unused) )
    4.32 +        return NULL;
    4.33 +
    4.34 +    if ( xc_prose_build(self->xc_handle, dom, image,
    4.35 +                        ramdisk, cmdline, features, flags,
    4.36 +                        store_evtchn, &store_mfn,
    4.37 +                        console_evtchn, &console_mfn,
    4.38 +                        arch_args) != 0 ) {
    4.39 +        if (!errno)
    4.40 +             errno = EINVAL;
    4.41 +        return PyErr_SetFromErrno(xc_error);
    4.42 +    }
    4.43 +    return Py_BuildValue("{s:i,s:i}", 
    4.44 +                         "store_mfn", store_mfn,
    4.45 +                         "console_mfn", console_mfn);
    4.46 +}
    4.47 +
    4.48  static PyObject *pyxc_hvm_build(XcObject *self,
    4.49                                  PyObject *args,
    4.50                                  PyObject *kwds)
    4.51 @@ -1003,6 +1044,18 @@ static PyMethodDef pyxc_methods[] = {
    4.52        " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
    4.53        "Returns: [int] 0 on success; -1 on error.\n" },
    4.54  
    4.55 +    { "prose_build", 
    4.56 +      (PyCFunction)pyxc_prose_build, 
    4.57 +      METH_VARARGS | METH_KEYWORDS, "\n"
    4.58 +      "Build a new Linux guest OS.\n"
    4.59 +      " dom     [int]:      Identifier of domain to build into.\n"
    4.60 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
    4.61 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
    4.62 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
    4.63 +      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
    4.64 +      "Returns: [int] 0 on success; -1 on error.\n" },
    4.65 +
    4.66 +
    4.67      { "hvm_build", 
    4.68        (PyCFunction)pyxc_hvm_build, 
    4.69        METH_VARARGS | METH_KEYWORDS, "\n"
     5.1 --- a/tools/python/xen/xend/image.py	Wed Oct 18 06:24:57 2006 -0400
     5.2 +++ b/tools/python/xen/xend/image.py	Wed Oct 18 06:43:33 2006 -0400
     5.3 @@ -246,6 +246,47 @@ class PPC_LinuxImageHandler(LinuxImageHa
     5.4                                features       = self.vm.getFeatures(),
     5.5                                arch_args      = devtree.to_bin())
     5.6  
     5.7 +class PPC_ProseImageHandler(LinuxImageHandler):
     5.8 +
     5.9 +    ostype = "prose"
    5.10 +
    5.11 +    def configure(self, imageConfig, deviceConfig):
    5.12 +        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
    5.13 +        self.imageConfig = imageConfig
    5.14 +
    5.15 +    def buildDomain(self):
    5.16 +        store_evtchn = self.vm.getStorePort()
    5.17 +        console_evtchn = self.vm.getConsolePort()
    5.18 +
    5.19 +        log.debug("dom            = %d", self.vm.getDomid())
    5.20 +        log.debug("image          = %s", self.kernel)
    5.21 +        log.debug("store_evtchn   = %d", store_evtchn)
    5.22 +        log.debug("console_evtchn = %d", console_evtchn)
    5.23 +        log.debug("cmdline        = %s", self.cmdline)
    5.24 +        log.debug("ramdisk        = %s", self.ramdisk)
    5.25 +        log.debug("vcpus          = %d", self.vm.getVCpuCount())
    5.26 +        log.debug("features       = %s", self.vm.getFeatures())
    5.27 +
    5.28 +        devtree = FlatDeviceTree.build(self)
    5.29 +
    5.30 +        return xc.prose_build(dom            = self.vm.getDomid(),
    5.31 +                              image          = self.kernel,
    5.32 +                              store_evtchn   = store_evtchn,
    5.33 +                              console_evtchn = console_evtchn,
    5.34 +                              cmdline        = self.cmdline,
    5.35 +                              ramdisk        = self.ramdisk,
    5.36 +                              features       = self.vm.getFeatures(),
    5.37 +                              arch_args      = devtree.to_bin())
    5.38 +
    5.39 +    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
    5.40 +        """@param shadow_mem_kb The configured shadow memory, in KiB.
    5.41 +        @param maxmem_kb The configured maxmem, in KiB.
    5.42 +        @return The corresponding required amount of shadow memory, also in
    5.43 +        KiB.
    5.44 +        PowerPC currently uses "shadow memory" to refer to the hash table."""
    5.45 +        return max(maxmem_kb / 64, shadow_mem_kb)
    5.46 +
    5.47 +
    5.48  class HVMImageHandler(ImageHandler):
    5.49  
    5.50      def __init__(self, vm, imageConfig, deviceConfig):
    5.51 @@ -512,6 +553,7 @@ class X86_HVM_ImageHandler(HVMImageHandl
    5.52  _handlers = {
    5.53      "powerpc": {
    5.54          "linux": PPC_LinuxImageHandler,
    5.55 +        "prose": PPC_ProseImageHandler,
    5.56      },
    5.57      "ia64": {
    5.58          "linux": LinuxImageHandler,