ia64/xen-unstable

changeset 11061:b2fc8357b8ff

[LIBXC] move xc_ppc_linux_build.c into a powerpc64 directory
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Hollis Blanchard <hollisb@us.ibm.com>
date Tue Aug 08 15:11:25 2006 -0500 (2006-08-08)
parents 00a41d1daf89
children d161ee2ade7e
files tools/libxc/powerpc64/Makefile tools/libxc/powerpc64/xc_linux_build.c tools/libxc/xc_ppc_linux_build.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/libxc/powerpc64/Makefile	Tue Aug 08 15:11:25 2006 -0500
     1.3 @@ -0,0 +1,1 @@
     1.4 +CTRL_SRCS-y += powerpc64/xc_linux_build.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c	Tue Aug 08 15:11:25 2006 -0500
     2.3 @@ -0,0 +1,408 @@
     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/dom0_ops.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 +/* XXX 64M hack */
    2.40 +#define MEMSIZE (64UL << 20)
    2.41 +#define INITRD_ADDR (24UL << 20)
    2.42 +
    2.43 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
    2.44 +
    2.45 +#define max(x,y) ({ \
    2.46 +        const typeof(x) _x = (x);       \
    2.47 +        const typeof(y) _y = (y);       \
    2.48 +        (void) (&_x == &_y);            \
    2.49 +        _x > _y ? _x : _y; })
    2.50 +
    2.51 +static void *load_file(const char *path, unsigned long *filesize)
    2.52 +{
    2.53 +    void *img;
    2.54 +    ssize_t size;
    2.55 +    int fd;
    2.56 +
    2.57 +    DPRINTF("load_file(%s)\n", path);
    2.58 +
    2.59 +    fd = open(path, O_RDONLY);
    2.60 +    if (fd < 0) {
    2.61 +        perror(path);
    2.62 +        return NULL;
    2.63 +    }
    2.64 +
    2.65 +    size = lseek(fd, 0, SEEK_END);
    2.66 +    if (size < 0) {
    2.67 +        perror(path);
    2.68 +        close(fd);
    2.69 +        return NULL;
    2.70 +    }
    2.71 +    lseek(fd, 0, SEEK_SET);
    2.72 +
    2.73 +    img = malloc(size);
    2.74 +    if (img == NULL) {
    2.75 +        perror(path);
    2.76 +        close(fd);
    2.77 +        return NULL;
    2.78 +    }
    2.79 +
    2.80 +    size = read(fd, img, size);
    2.81 +    if (size <= 0) {
    2.82 +        perror(path);
    2.83 +        close(fd);
    2.84 +        free(img);
    2.85 +        return NULL;
    2.86 +    }
    2.87 +
    2.88 +    if (filesize)
    2.89 +        *filesize = size;
    2.90 +    close(fd);
    2.91 +    return img;
    2.92 +}
    2.93 +
    2.94 +static int init_boot_vcpu(
    2.95 +    int xc_handle,
    2.96 +    int domid,
    2.97 +    struct domain_setup_info *dsi,
    2.98 +    unsigned long dtb,
    2.99 +    unsigned long kaddr)
   2.100 +{
   2.101 +    vcpu_guest_context_t ctxt;
   2.102 +    int rc;
   2.103 +
   2.104 +    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   2.105 +    ctxt.user_regs.pc = dsi->v_kernentry;
   2.106 +    ctxt.user_regs.msr = 0;
   2.107 +    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   2.108 +    ctxt.user_regs.gprs[3] = dtb;
   2.109 +    ctxt.user_regs.gprs[4] = kaddr;
   2.110 +    ctxt.user_regs.gprs[5] = 0;
   2.111 +    /* There is a buggy kernel that does not zero the "local_paca", so
   2.112 +     * we must make sure this register is 0 */
   2.113 +    ctxt.user_regs.gprs[13] = 0;
   2.114 +
   2.115 +    DPRINTF("xc_vcpu_setvcpucontext:\n"
   2.116 +                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
   2.117 +                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   2.118 +                 " %016"PRIx64"\n",
   2.119 +                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   2.120 +                 ctxt.user_regs.gprs[1],
   2.121 +                 ctxt.user_regs.gprs[2],
   2.122 +                 ctxt.user_regs.gprs[3],
   2.123 +                 ctxt.user_regs.gprs[4],
   2.124 +                 ctxt.user_regs.gprs[5]);
   2.125 +    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   2.126 +    if (rc < 0)
   2.127 +        perror("setdomaininfo");
   2.128 +
   2.129 +    return rc;
   2.130 +}
   2.131 +
   2.132 +static int install_image(
   2.133 +        int xc_handle,
   2.134 +        int domid,
   2.135 +        xen_pfn_t *page_array,
   2.136 +        void *image,
   2.137 +        unsigned long paddr,
   2.138 +        unsigned long size)
   2.139 +{
   2.140 +    uint8_t *img = image;
   2.141 +    int i;
   2.142 +    int rc = 0;
   2.143 +
   2.144 +    if (paddr & ~PAGE_MASK) {
   2.145 +        printf("*** unaligned address\n");
   2.146 +        return -1;
   2.147 +    }
   2.148 +
   2.149 +    for (i = 0; i < size; i += PAGE_SIZE) {
   2.150 +        void *page = img + i;
   2.151 +        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   2.152 +        xen_pfn_t mfn = page_array[pfn];
   2.153 +
   2.154 +        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   2.155 +        if (rc < 0) {
   2.156 +            perror("xc_copy_to_domain_page");
   2.157 +            break;
   2.158 +        }
   2.159 +    }
   2.160 +    return rc;
   2.161 +}
   2.162 +
   2.163 +/* XXX be more flexible about placement in memory */
   2.164 +static int load_dtb(
   2.165 +    int xc_handle,
   2.166 +    int domid,
   2.167 +    const char *dtb_path,
   2.168 +    unsigned long dtb_addr,
   2.169 +    struct domain_setup_info *dsi,
   2.170 +    xen_pfn_t *page_array)
   2.171 +{
   2.172 +    uint8_t *img;
   2.173 +    unsigned long dtb_size;
   2.174 +    int rc = 0;
   2.175 +
   2.176 +    img = load_file(dtb_path, &dtb_size);
   2.177 +    if (img == NULL) {
   2.178 +        rc = -1;
   2.179 +        goto out;
   2.180 +    }
   2.181 +
   2.182 +    DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size);
   2.183 +    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
   2.184 +
   2.185 +out:
   2.186 +    free(img);
   2.187 +    return rc;
   2.188 +}
   2.189 +
   2.190 +unsigned long spin_list[] = {
   2.191 +#if 0
   2.192 +    0x100,
   2.193 +    0x200,
   2.194 +    0x300,
   2.195 +    0x380,
   2.196 +    0x400,
   2.197 +    0x480,
   2.198 +    0x500,
   2.199 +    0x700,
   2.200 +    0x900,
   2.201 +    0xc00,
   2.202 +#endif
   2.203 +    0
   2.204 +};
   2.205 +
   2.206 +/* XXX yes, this is a hack */
   2.207 +static void hack_kernel_img(char *img)
   2.208 +{
   2.209 +    const off_t file_offset = 0x10000;
   2.210 +    unsigned long *addr = spin_list;
   2.211 +
   2.212 +    while (*addr) {
   2.213 +        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
   2.214 +        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
   2.215 +        *instruction = 0x48000000;
   2.216 +        addr++;
   2.217 +    }
   2.218 +}
   2.219 +
   2.220 +static int load_kernel(
   2.221 +    int xc_handle,
   2.222 +    int domid,
   2.223 +    const char *kernel_path,
   2.224 +    struct domain_setup_info *dsi,
   2.225 +    xen_pfn_t *page_array)
   2.226 +{
   2.227 +    struct load_funcs load_funcs;
   2.228 +    char *kernel_img;
   2.229 +    unsigned long kernel_size;
   2.230 +    int rc;
   2.231 +
   2.232 +    /* load the kernel ELF file */
   2.233 +    kernel_img = load_file(kernel_path, &kernel_size);
   2.234 +    if (kernel_img == NULL) {
   2.235 +        rc = -1;
   2.236 +        goto out;
   2.237 +    }
   2.238 +
   2.239 +    hack_kernel_img(kernel_img);
   2.240 +
   2.241 +    DPRINTF("probe_elf\n");
   2.242 +    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
   2.243 +    if (rc < 0) {
   2.244 +        rc = -1;
   2.245 +        printf("%s is not an ELF file\n", kernel_path);
   2.246 +        goto out;
   2.247 +    }
   2.248 +
   2.249 +    DPRINTF("parseimage\n");
   2.250 +    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
   2.251 +    if (rc < 0) {
   2.252 +        rc = -1;
   2.253 +        goto out;
   2.254 +    }
   2.255 +
   2.256 +    DPRINTF("loadimage\n");
   2.257 +    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
   2.258 +            page_array, dsi);
   2.259 +
   2.260 +    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
   2.261 +    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
   2.262 +    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
   2.263 +    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
   2.264 +    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
   2.265 +
   2.266 +out:
   2.267 +    free(kernel_img);
   2.268 +    return rc;
   2.269 +}
   2.270 +
   2.271 +static int load_initrd(
   2.272 +    int xc_handle,
   2.273 +    int domid,
   2.274 +    xen_pfn_t *page_array,
   2.275 +    const char *initrd_path,
   2.276 +    unsigned long *base,
   2.277 +    unsigned long *len)
   2.278 +{
   2.279 +    uint8_t *initrd_img;
   2.280 +    int rc = -1;
   2.281 +
   2.282 +    /* load the initrd file */
   2.283 +    initrd_img = load_file(initrd_path, len);
   2.284 +    if (initrd_img == NULL)
   2.285 +        return -1;
   2.286 +
   2.287 +    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
   2.288 +    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
   2.289 +                *len))
   2.290 +        goto out;
   2.291 +
   2.292 +    *base = INITRD_ADDR;
   2.293 +    rc = 0;
   2.294 +
   2.295 +out:
   2.296 +    free(initrd_img);
   2.297 +    return rc;
   2.298 +}
   2.299 +
   2.300 +static unsigned long create_start_info(start_info_t *si,
   2.301 +        unsigned int console_evtchn, unsigned int store_evtchn)
   2.302 +{
   2.303 +    unsigned long eomem;
   2.304 +    unsigned long si_addr;
   2.305 +
   2.306 +    memset(si, 0, sizeof(*si));
   2.307 +    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
   2.308 +
   2.309 +    eomem = MEMSIZE;
   2.310 +    si->nr_pages = eomem >> PAGE_SHIFT;
   2.311 +    si->shared_info = eomem - (PAGE_SIZE * 1);
   2.312 +    si->store_mfn = si->nr_pages - 2;
   2.313 +    si->store_evtchn = store_evtchn;
   2.314 +    si->console_mfn = si->nr_pages - 3;
   2.315 +    si->console_evtchn = console_evtchn;
   2.316 +    si_addr = eomem - (PAGE_SIZE * 4);
   2.317 +
   2.318 +    return si_addr;
   2.319 +}
   2.320 +
   2.321 +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
   2.322 +{
   2.323 +    int nr_pages;
   2.324 +    int rc;
   2.325 +
   2.326 +    DPRINTF("xc_get_tot_pages\n");
   2.327 +    nr_pages = xc_get_tot_pages(xc_handle, domid);
   2.328 +    DPRINTF("  0x%x\n", nr_pages);
   2.329 +
   2.330 +    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   2.331 +    if (*page_array == NULL) {
   2.332 +        perror("malloc");
   2.333 +        return -1;
   2.334 +    }
   2.335 +
   2.336 +    DPRINTF("xc_get_pfn_list\n");
   2.337 +    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
   2.338 +    if (rc != nr_pages) {
   2.339 +        perror("Could not get the page frame list");
   2.340 +        return -1;
   2.341 +    }
   2.342 +
   2.343 +    return 0;
   2.344 +}
   2.345 +
   2.346 +
   2.347 +
   2.348 +int xc_linux_build(int xc_handle,
   2.349 +                   uint32_t domid,
   2.350 +                   const char *image_name,
   2.351 +                   const char *initrd_name,
   2.352 +                   const char *cmdline,
   2.353 +                   const char *features,
   2.354 +                   unsigned long flags,
   2.355 +                   unsigned int store_evtchn,
   2.356 +                   unsigned long *store_mfn,
   2.357 +                   unsigned int console_evtchn,
   2.358 +                   unsigned long *console_mfn)
   2.359 +{
   2.360 +    struct domain_setup_info dsi;
   2.361 +    xen_pfn_t *page_array = NULL;
   2.362 +    unsigned long kern_addr;
   2.363 +    unsigned long dtb_addr;
   2.364 +    unsigned long si_addr;
   2.365 +    unsigned long initrd_base = 0;
   2.366 +    unsigned long initrd_len = 0;
   2.367 +    start_info_t si;
   2.368 +    int rc = 0;
   2.369 +
   2.370 +    if (get_page_array(xc_handle, domid, &page_array)) {
   2.371 +        rc = -1;
   2.372 +        goto out;
   2.373 +    }
   2.374 +
   2.375 +    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
   2.376 +        rc = -1;
   2.377 +        goto out;
   2.378 +    }
   2.379 +    kern_addr = 0;
   2.380 +
   2.381 +    if (initrd_name && initrd_name[0] != '\0' &&
   2.382 +        load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
   2.383 +                &initrd_len)) {
   2.384 +        rc = -1;
   2.385 +        goto out;
   2.386 +    }
   2.387 +    /* XXX install initrd addr/len into device tree */
   2.388 +
   2.389 +    dtb_addr = (16 << 20);
   2.390 +    if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) {
   2.391 +        dtb_addr = 0;
   2.392 +    }
   2.393 +
   2.394 +    si_addr = create_start_info(&si, console_evtchn, store_evtchn);
   2.395 +    *console_mfn = page_array[si.console_mfn];
   2.396 +    *store_mfn = page_array[si.store_mfn];
   2.397 +    
   2.398 +    if (install_image(xc_handle, domid, page_array, &si, si_addr,
   2.399 +                sizeof(start_info_t))) {
   2.400 +        rc = -1;
   2.401 +        goto out;
   2.402 +    }
   2.403 +
   2.404 +    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
   2.405 +        rc = -1;
   2.406 +        goto out;
   2.407 +    }
   2.408 +
   2.409 +out:
   2.410 +    return rc;
   2.411 +}
     3.1 --- a/tools/libxc/xc_ppc_linux_build.c	Mon Aug 07 17:16:18 2006 -0500
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,408 +0,0 @@
     3.4 -/*
     3.5 - * This program is free software; you can redistribute it and/or modify
     3.6 - * it under the terms of the GNU General Public License as published by
     3.7 - * the Free Software Foundation; either version 2 of the License, or
     3.8 - * (at your option) any later version.
     3.9 - *
    3.10 - * This program is distributed in the hope that it will be useful,
    3.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.13 - * GNU General Public License for more details.
    3.14 - *
    3.15 - * You should have received a copy of the GNU General Public License
    3.16 - * along with this program; if not, write to the Free Software
    3.17 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    3.18 - *
    3.19 - * Copyright (C) IBM Corporation 2006
    3.20 - *
    3.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    3.22 - */
    3.23 -
    3.24 -#include <stdio.h>
    3.25 -#include <stdint.h>
    3.26 -#include <stdlib.h>
    3.27 -#include <string.h>
    3.28 -#include <unistd.h>
    3.29 -#include <fcntl.h>
    3.30 -#include <sys/types.h>
    3.31 -#include <inttypes.h>
    3.32 -
    3.33 -#include <xen/dom0_ops.h>
    3.34 -#include <xen/memory.h>
    3.35 -#include <xc_private.h>
    3.36 -#include <xg_private.h>
    3.37 -#include <xenctrl.h>
    3.38 -
    3.39 -/* XXX 64M hack */
    3.40 -#define MEMSIZE (64UL << 20)
    3.41 -#define INITRD_ADDR (24UL << 20)
    3.42 -
    3.43 -#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
    3.44 -
    3.45 -#define max(x,y) ({ \
    3.46 -        const typeof(x) _x = (x);       \
    3.47 -        const typeof(y) _y = (y);       \
    3.48 -        (void) (&_x == &_y);            \
    3.49 -        _x > _y ? _x : _y; })
    3.50 -
    3.51 -static void *load_file(const char *path, unsigned long *filesize)
    3.52 -{
    3.53 -    void *img;
    3.54 -    ssize_t size;
    3.55 -    int fd;
    3.56 -
    3.57 -    DPRINTF("load_file(%s)\n", path);
    3.58 -
    3.59 -    fd = open(path, O_RDONLY);
    3.60 -    if (fd < 0) {
    3.61 -        perror(path);
    3.62 -        return NULL;
    3.63 -    }
    3.64 -
    3.65 -    size = lseek(fd, 0, SEEK_END);
    3.66 -    if (size < 0) {
    3.67 -        perror(path);
    3.68 -        close(fd);
    3.69 -        return NULL;
    3.70 -    }
    3.71 -    lseek(fd, 0, SEEK_SET);
    3.72 -
    3.73 -    img = malloc(size);
    3.74 -    if (img == NULL) {
    3.75 -        perror(path);
    3.76 -        close(fd);
    3.77 -        return NULL;
    3.78 -    }
    3.79 -
    3.80 -    size = read(fd, img, size);
    3.81 -    if (size <= 0) {
    3.82 -        perror(path);
    3.83 -        close(fd);
    3.84 -        free(img);
    3.85 -        return NULL;
    3.86 -    }
    3.87 -
    3.88 -    if (filesize)
    3.89 -        *filesize = size;
    3.90 -    close(fd);
    3.91 -    return img;
    3.92 -}
    3.93 -
    3.94 -static int init_boot_vcpu(
    3.95 -    int xc_handle,
    3.96 -    int domid,
    3.97 -    struct domain_setup_info *dsi,
    3.98 -    unsigned long dtb,
    3.99 -    unsigned long kaddr)
   3.100 -{
   3.101 -    vcpu_guest_context_t ctxt;
   3.102 -    int rc;
   3.103 -
   3.104 -    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
   3.105 -    ctxt.user_regs.pc = dsi->v_kernentry;
   3.106 -    ctxt.user_regs.msr = 0;
   3.107 -    ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
   3.108 -    ctxt.user_regs.gprs[3] = dtb;
   3.109 -    ctxt.user_regs.gprs[4] = kaddr;
   3.110 -    ctxt.user_regs.gprs[5] = 0;
   3.111 -    /* There is a buggy kernel that does not zero the "local_paca", so
   3.112 -     * we must make sure this register is 0 */
   3.113 -    ctxt.user_regs.gprs[13] = 0;
   3.114 -
   3.115 -    DPRINTF("xc_vcpu_setvcpucontext:\n"
   3.116 -                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
   3.117 -                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
   3.118 -                 " %016"PRIx64"\n",
   3.119 -                 ctxt.user_regs.pc, ctxt.user_regs.msr,
   3.120 -                 ctxt.user_regs.gprs[1],
   3.121 -                 ctxt.user_regs.gprs[2],
   3.122 -                 ctxt.user_regs.gprs[3],
   3.123 -                 ctxt.user_regs.gprs[4],
   3.124 -                 ctxt.user_regs.gprs[5]);
   3.125 -    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
   3.126 -    if (rc < 0)
   3.127 -        perror("setdomaininfo");
   3.128 -
   3.129 -    return rc;
   3.130 -}
   3.131 -
   3.132 -static int install_image(
   3.133 -        int xc_handle,
   3.134 -        int domid,
   3.135 -        xen_pfn_t *page_array,
   3.136 -        void *image,
   3.137 -        unsigned long paddr,
   3.138 -        unsigned long size)
   3.139 -{
   3.140 -    uint8_t *img = image;
   3.141 -    int i;
   3.142 -    int rc = 0;
   3.143 -
   3.144 -    if (paddr & ~PAGE_MASK) {
   3.145 -        printf("*** unaligned address\n");
   3.146 -        return -1;
   3.147 -    }
   3.148 -
   3.149 -    for (i = 0; i < size; i += PAGE_SIZE) {
   3.150 -        void *page = img + i;
   3.151 -        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
   3.152 -        xen_pfn_t mfn = page_array[pfn];
   3.153 -
   3.154 -        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
   3.155 -        if (rc < 0) {
   3.156 -            perror("xc_copy_to_domain_page");
   3.157 -            break;
   3.158 -        }
   3.159 -    }
   3.160 -    return rc;
   3.161 -}
   3.162 -
   3.163 -/* XXX be more flexible about placement in memory */
   3.164 -static int load_dtb(
   3.165 -    int xc_handle,
   3.166 -    int domid,
   3.167 -    const char *dtb_path,
   3.168 -    unsigned long dtb_addr,
   3.169 -    struct domain_setup_info *dsi,
   3.170 -    xen_pfn_t *page_array)
   3.171 -{
   3.172 -    uint8_t *img;
   3.173 -    unsigned long dtb_size;
   3.174 -    int rc = 0;
   3.175 -
   3.176 -    img = load_file(dtb_path, &dtb_size);
   3.177 -    if (img == NULL) {
   3.178 -        rc = -1;
   3.179 -        goto out;
   3.180 -    }
   3.181 -
   3.182 -    DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size);
   3.183 -    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
   3.184 -
   3.185 -out:
   3.186 -    free(img);
   3.187 -    return rc;
   3.188 -}
   3.189 -
   3.190 -unsigned long spin_list[] = {
   3.191 -#if 0
   3.192 -    0x100,
   3.193 -    0x200,
   3.194 -    0x300,
   3.195 -    0x380,
   3.196 -    0x400,
   3.197 -    0x480,
   3.198 -    0x500,
   3.199 -    0x700,
   3.200 -    0x900,
   3.201 -    0xc00,
   3.202 -#endif
   3.203 -    0
   3.204 -};
   3.205 -
   3.206 -/* XXX yes, this is a hack */
   3.207 -static void hack_kernel_img(char *img)
   3.208 -{
   3.209 -    const off_t file_offset = 0x10000;
   3.210 -    unsigned long *addr = spin_list;
   3.211 -
   3.212 -    while (*addr) {
   3.213 -        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
   3.214 -        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
   3.215 -        *instruction = 0x48000000;
   3.216 -        addr++;
   3.217 -    }
   3.218 -}
   3.219 -
   3.220 -static int load_kernel(
   3.221 -    int xc_handle,
   3.222 -    int domid,
   3.223 -    const char *kernel_path,
   3.224 -    struct domain_setup_info *dsi,
   3.225 -    xen_pfn_t *page_array)
   3.226 -{
   3.227 -    struct load_funcs load_funcs;
   3.228 -    char *kernel_img;
   3.229 -    unsigned long kernel_size;
   3.230 -    int rc;
   3.231 -
   3.232 -    /* load the kernel ELF file */
   3.233 -    kernel_img = load_file(kernel_path, &kernel_size);
   3.234 -    if (kernel_img == NULL) {
   3.235 -        rc = -1;
   3.236 -        goto out;
   3.237 -    }
   3.238 -
   3.239 -    hack_kernel_img(kernel_img);
   3.240 -
   3.241 -    DPRINTF("probe_elf\n");
   3.242 -    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
   3.243 -    if (rc < 0) {
   3.244 -        rc = -1;
   3.245 -        printf("%s is not an ELF file\n", kernel_path);
   3.246 -        goto out;
   3.247 -    }
   3.248 -
   3.249 -    DPRINTF("parseimage\n");
   3.250 -    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
   3.251 -    if (rc < 0) {
   3.252 -        rc = -1;
   3.253 -        goto out;
   3.254 -    }
   3.255 -
   3.256 -    DPRINTF("loadimage\n");
   3.257 -    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
   3.258 -            page_array, dsi);
   3.259 -
   3.260 -    DPRINTF("  v_start     %016"PRIx64"\n", dsi->v_start);
   3.261 -    DPRINTF("  v_end       %016"PRIx64"\n", dsi->v_end);
   3.262 -    DPRINTF("  v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
   3.263 -    DPRINTF("  v_kernend   %016"PRIx64"\n", dsi->v_kernend);
   3.264 -    DPRINTF("  v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
   3.265 -
   3.266 -out:
   3.267 -    free(kernel_img);
   3.268 -    return rc;
   3.269 -}
   3.270 -
   3.271 -static int load_initrd(
   3.272 -    int xc_handle,
   3.273 -    int domid,
   3.274 -    xen_pfn_t *page_array,
   3.275 -    const char *initrd_path,
   3.276 -    unsigned long *base,
   3.277 -    unsigned long *len)
   3.278 -{
   3.279 -    uint8_t *initrd_img;
   3.280 -    int rc = -1;
   3.281 -
   3.282 -    /* load the initrd file */
   3.283 -    initrd_img = load_file(initrd_path, len);
   3.284 -    if (initrd_img == NULL)
   3.285 -        return -1;
   3.286 -
   3.287 -    DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
   3.288 -    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
   3.289 -                *len))
   3.290 -        goto out;
   3.291 -
   3.292 -    *base = INITRD_ADDR;
   3.293 -    rc = 0;
   3.294 -
   3.295 -out:
   3.296 -    free(initrd_img);
   3.297 -    return rc;
   3.298 -}
   3.299 -
   3.300 -static unsigned long create_start_info(start_info_t *si,
   3.301 -        unsigned int console_evtchn, unsigned int store_evtchn)
   3.302 -{
   3.303 -    unsigned long eomem;
   3.304 -    unsigned long si_addr;
   3.305 -
   3.306 -    memset(si, 0, sizeof(*si));
   3.307 -    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
   3.308 -
   3.309 -    eomem = MEMSIZE;
   3.310 -    si->nr_pages = eomem >> PAGE_SHIFT;
   3.311 -    si->shared_info = eomem - (PAGE_SIZE * 1);
   3.312 -    si->store_mfn = si->nr_pages - 2;
   3.313 -    si->store_evtchn = store_evtchn;
   3.314 -    si->console_mfn = si->nr_pages - 3;
   3.315 -    si->console_evtchn = console_evtchn;
   3.316 -    si_addr = eomem - (PAGE_SIZE * 4);
   3.317 -
   3.318 -    return si_addr;
   3.319 -}
   3.320 -
   3.321 -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
   3.322 -{
   3.323 -    int nr_pages;
   3.324 -    int rc;
   3.325 -
   3.326 -    DPRINTF("xc_get_tot_pages\n");
   3.327 -    nr_pages = xc_get_tot_pages(xc_handle, domid);
   3.328 -    DPRINTF("  0x%x\n", nr_pages);
   3.329 -
   3.330 -    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
   3.331 -    if (*page_array == NULL) {
   3.332 -        perror("malloc");
   3.333 -        return -1;
   3.334 -    }
   3.335 -
   3.336 -    DPRINTF("xc_get_pfn_list\n");
   3.337 -    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
   3.338 -    if (rc != nr_pages) {
   3.339 -        perror("Could not get the page frame list");
   3.340 -        return -1;
   3.341 -    }
   3.342 -
   3.343 -    return 0;
   3.344 -}
   3.345 -
   3.346 -
   3.347 -
   3.348 -int xc_linux_build(int xc_handle,
   3.349 -                   uint32_t domid,
   3.350 -                   const char *image_name,
   3.351 -                   const char *initrd_name,
   3.352 -                   const char *cmdline,
   3.353 -                   const char *features,
   3.354 -                   unsigned long flags,
   3.355 -                   unsigned int store_evtchn,
   3.356 -                   unsigned long *store_mfn,
   3.357 -                   unsigned int console_evtchn,
   3.358 -                   unsigned long *console_mfn)
   3.359 -{
   3.360 -    struct domain_setup_info dsi;
   3.361 -    xen_pfn_t *page_array = NULL;
   3.362 -    unsigned long kern_addr;
   3.363 -    unsigned long dtb_addr;
   3.364 -    unsigned long si_addr;
   3.365 -    unsigned long initrd_base = 0;
   3.366 -    unsigned long initrd_len = 0;
   3.367 -    start_info_t si;
   3.368 -    int rc = 0;
   3.369 -
   3.370 -    if (get_page_array(xc_handle, domid, &page_array)) {
   3.371 -        rc = -1;
   3.372 -        goto out;
   3.373 -    }
   3.374 -
   3.375 -    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
   3.376 -        rc = -1;
   3.377 -        goto out;
   3.378 -    }
   3.379 -    kern_addr = 0;
   3.380 -
   3.381 -    if (initrd_name && initrd_name[0] != '\0' &&
   3.382 -        load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
   3.383 -                &initrd_len)) {
   3.384 -        rc = -1;
   3.385 -        goto out;
   3.386 -    }
   3.387 -    /* XXX install initrd addr/len into device tree */
   3.388 -
   3.389 -    dtb_addr = (16 << 20);
   3.390 -    if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) {
   3.391 -        dtb_addr = 0;
   3.392 -    }
   3.393 -
   3.394 -    si_addr = create_start_info(&si, console_evtchn, store_evtchn);
   3.395 -    *console_mfn = page_array[si.console_mfn];
   3.396 -    *store_mfn = page_array[si.store_mfn];
   3.397 -    
   3.398 -    if (install_image(xc_handle, domid, page_array, &si, si_addr,
   3.399 -                sizeof(start_info_t))) {
   3.400 -        rc = -1;
   3.401 -        goto out;
   3.402 -    }
   3.403 -
   3.404 -    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
   3.405 -        rc = -1;
   3.406 -        goto out;
   3.407 -    }
   3.408 -
   3.409 -out:
   3.410 -    return rc;
   3.411 -}