ia64/xen-unstable

changeset 13938:7bf078335342

[XEND][POWERPC] Move flat device tree construction from python to libxc for xc_linux_build().

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Sun Jan 21 08:14:27 2007 -0500 (2007-01-21)
parents cc1eb0689bcf
children 09b3fd488726
files tools/libxc/powerpc64/Makefile tools/libxc/powerpc64/mk_flatdevtree.c tools/libxc/powerpc64/mk_flatdevtree.h tools/libxc/powerpc64/xc_linux_build.c tools/libxc/xenguest.h tools/python/xen/xend/image.py
line diff
     1.1 --- a/tools/libxc/powerpc64/Makefile	Sun Jan 21 07:49:50 2007 -0500
     1.2 +++ b/tools/libxc/powerpc64/Makefile	Sun Jan 21 08:14:27 2007 -0500
     1.3 @@ -1,4 +1,5 @@
     1.4  GUEST_SRCS-y += powerpc64/flatdevtree.c
     1.5 +GUEST_SRCS-y += powerpc64/mk_flatdevtree.c
     1.6  GUEST_SRCS-y += powerpc64/xc_linux_build.c
     1.7  GUEST_SRCS-y += powerpc64/xc_prose_build.c
     1.8  GUEST_SRCS-y += powerpc64/utils.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/libxc/powerpc64/mk_flatdevtree.c	Sun Jan 21 08:14:27 2007 -0500
     2.3 @@ -0,0 +1,605 @@
     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 IBM Corporation 2007
    2.20 + *
    2.21 + * Authors: Ryan Harper <ryanh@us.ibm.com>
    2.22 + */
    2.23 +
    2.24 +#include <stdio.h>
    2.25 +#include <stdlib.h>
    2.26 +#include <string.h>
    2.27 +#include <fcntl.h>
    2.28 +#include <dirent.h>
    2.29 +#include <unistd.h>
    2.30 +#include <libgen.h>    
    2.31 +#include <inttypes.h>
    2.32 +#include <math.h>
    2.33 +#include <errno.h>
    2.34 +#include <sys/types.h>
    2.35 +#include <sys/dir.h>
    2.36 +#include <sys/stat.h>
    2.37 +#include <sys/param.h>
    2.38 +
    2.39 +#include <xc_private.h> /* for PERROR() */
    2.40 +
    2.41 +#include "mk_flatdevtree.h"
    2.42 +
    2.43 +static uint32_t current_phandle = 0;
    2.44 +
    2.45 +static uint32_t get_phandle(void)
    2.46 +{
    2.47 +   return current_phandle++;
    2.48 +}
    2.49 +
    2.50 +static int readfile(const char *fullpath, void *data, int len)
    2.51 +{
    2.52 +    struct stat st;
    2.53 +    int saved_errno;
    2.54 +    int rc = -1;
    2.55 +    int fd;
    2.56 +   
    2.57 +    if ((fd = open(fullpath, O_RDONLY)) == -1) {
    2.58 +        PERROR("%s: failed to open file %s", __func__, fullpath);
    2.59 +        return -1;
    2.60 +    }
    2.61 +
    2.62 +    if ((rc = fstat(fd, &st)) == -1) {
    2.63 +        PERROR("%s: failed to stat fd %d", __func__, fd);
    2.64 +        goto error;
    2.65 +    }
    2.66 +
    2.67 +    if (S_ISREG(st.st_mode))
    2.68 +        rc = read(fd, data, len); 
    2.69 +
    2.70 +    close(fd);
    2.71 +    return rc;
    2.72 +
    2.73 +error:
    2.74 +    saved_errno = errno;
    2.75 +    close(fd);
    2.76 +    errno = saved_errno;
    2.77 +    return -1;
    2.78 +}
    2.79 +
    2.80 +/* 
    2.81 + * @property - string to check against the filter list
    2.82 + * @filter   - NULL terminated list of strings 
    2.83 + *
    2.84 + * compare @property string to each string in @filter
    2.85 + *
    2.86 + * return 1 if @property matches any filter, otherwise 0
    2.87 + *
    2.88 + */
    2.89 +static int match(const char *property, const char **filter)
    2.90 +{
    2.91 +    int i;
    2.92 +    
    2.93 +    for (i=0; filter[i] != NULL; i++) {
    2.94 +        /* compare the filter to property */
    2.95 +        if (strncmp(property, filter[i], strlen(filter[i])) == 0)
    2.96 +            return 1;
    2.97 +    }
    2.98 +
    2.99 +    return 0;
   2.100 +}
   2.101 +
   2.102 +/*
   2.103 + * copy the node at @dirpath filtering out any properties that match in @propfilter
   2.104 + */
   2.105 +static int copynode(struct ft_cxt *cxt, const char *dirpath, const char **propfilter)
   2.106 +{   
   2.107 +    struct dirent *tree;
   2.108 +    struct stat st;
   2.109 +    DIR *dir;
   2.110 +    char fullpath[MAX_PATH];
   2.111 +    char *bname = NULL;
   2.112 +    char *basec = NULL;
   2.113 +    int saved_errno;
   2.114 +
   2.115 +    if ((dir = opendir(dirpath)) == NULL) {
   2.116 +        PERROR("%s: failed to open dir %s", __func__, dirpath);
   2.117 +        return -1;
   2.118 +    }
   2.119 +
   2.120 +    while (1) {
   2.121 +        if ((tree = readdir(dir)) == NULL)
   2.122 +            break;  /* reached end of directory entries */
   2.123 +
   2.124 +        /* ignore . and .. */
   2.125 +        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
   2.126 +            continue;
   2.127 +
   2.128 +        /* build full path name of the file, for stat() */
   2.129 +        if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath,
   2.130 +                     tree->d_name) >= sizeof(fullpath)) {
   2.131 +            PERROR("%s: failed to build full path", __func__);
   2.132 +            goto error;
   2.133 +        }
   2.134 +
   2.135 +        /* stat the entry */
   2.136 +        if (stat(fullpath, &st) < 0) {
   2.137 +            PERROR("%s: failed to stat file %s", __func__, fullpath);
   2.138 +            goto error;
   2.139 +        }
   2.140 +
   2.141 +        if (S_ISDIR(st.st_mode)) {
   2.142 +            /* start a new node for a dir */
   2.143 +            ft_begin_node(cxt, tree->d_name);
   2.144 +
   2.145 +            /* copy everything in this dir */
   2.146 +            if (copynode(cxt, fullpath, propfilter) < 0) {
   2.147 +                PERROR("%s: failed to copy node @ %s", __func__, fullpath);
   2.148 +                goto error;
   2.149 +            }
   2.150 +
   2.151 +            /* end the node */
   2.152 +            ft_end_node(cxt);
   2.153 +        }
   2.154 +        /* add files in dir as properties */
   2.155 +        else if (S_ISREG(st.st_mode)) {
   2.156 +
   2.157 +            if ((basec = strdup(fullpath)) == NULL) {
   2.158 +                PERROR("%s: failed to dupe string", __func__);
   2.159 +                goto error;
   2.160 +            }
   2.161 +
   2.162 +            if ((bname = basename(basec)) == NULL) {
   2.163 +                PERROR("%s: basename() failed", __func__);
   2.164 +                goto error;
   2.165 +            }
   2.166 +
   2.167 +            /* only add files that don't match the property filter string */
   2.168 +            if (!match(bname, propfilter)) {
   2.169 +                char data[BUFSIZE];
   2.170 +                int len;
   2.171 +
   2.172 +                /* snarf the data and push into the property */
   2.173 +                if ((len = readfile(fullpath, data, sizeof(data))) < 0) {
   2.174 +                    PERROR("%s: failed to read data from file %s", __func__,
   2.175 +                                                                   fullpath);
   2.176 +                    goto error;
   2.177 +                }
   2.178 +                ft_prop(cxt, tree->d_name, data, len);
   2.179 +
   2.180 +            }
   2.181 +
   2.182 +            /* strdup mallocs memory */
   2.183 +            if (basec != NULL ) {
   2.184 +                free(basec);
   2.185 +                basec = NULL;
   2.186 +            }
   2.187 +
   2.188 +        }
   2.189 +    }
   2.190 +
   2.191 +    closedir(dir);
   2.192 +    return 0;
   2.193 +
   2.194 +error:
   2.195 +    saved_errno = errno;
   2.196 +
   2.197 +    /* strdup mallocs memory */
   2.198 +    if (basec != NULL ) {
   2.199 +        free(basec);
   2.200 +        basec = NULL;
   2.201 +    }
   2.202 +
   2.203 +    closedir(dir);
   2.204 +
   2.205 +    errno = saved_errno;
   2.206 +    return -1;
   2.207 +}
   2.208 +
   2.209 +static int find_cpu0(char *cpupath, int len)
   2.210 +{   
   2.211 +    const char path[] = "/proc/device-tree/cpus";
   2.212 +    const char device[] = "device_type";
   2.213 +    const char dev_cpu[] = "cpu";
   2.214 +    const char reg[] = "reg";
   2.215 +    char data[sizeof(dev_cpu)];
   2.216 +    char prop[MAX_PATH];
   2.217 +    char node[MAX_PATH];
   2.218 +    struct dirent *tree;
   2.219 +    struct stat st;
   2.220 +    DIR* dir;
   2.221 +    int saved_errno;
   2.222 +    int found = 0;
   2.223 +
   2.224 +    if ((dir = opendir(path)) == NULL) {
   2.225 +        PERROR("%s: failed to open directory %s", __func__, path);
   2.226 +        return -1;
   2.227 +    }    
   2.228 +
   2.229 +    while (!found) {
   2.230 +
   2.231 +        if ((tree = readdir(dir)) == NULL)
   2.232 +            break;  /* reached end of directory entries */
   2.233 +
   2.234 +        /* ignore ., .. */
   2.235 +        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
   2.236 +            continue;
   2.237 +
   2.238 +        /* build full path name of the file, for stat() */
   2.239 +        if (snprintf(node, sizeof(node), "%s/%s", path,
   2.240 +                     tree->d_name) >= sizeof(node)) {
   2.241 +            PERROR("%s: failed to concat strings", __func__);
   2.242 +            goto error;
   2.243 +        }
   2.244 +
   2.245 +        /* stat the entry */
   2.246 +        if (stat(node, &st) < 0) {
   2.247 +            PERROR("%s: failed to stat file %s", __func__, node);
   2.248 +            /* something funny happen in /proc/device-tree, but march onward */
   2.249 +            continue;
   2.250 +        }
   2.251 +
   2.252 +        /* for each dir, check the device_type property until we find 'cpu'*/
   2.253 +        if (S_ISDIR(st.st_mode)) {
   2.254 +
   2.255 +            /* construct path to device_type */
   2.256 +            if (snprintf(prop, sizeof(prop), "%s/%s", node,
   2.257 +                         device) >= sizeof(prop)) {
   2.258 +                PERROR("%s: failed to concat strings", __func__);
   2.259 +                goto error;
   2.260 +            }
   2.261 +
   2.262 +            /* read device_type into buffer */
   2.263 +            if ((readfile(prop, data, sizeof(data))) < 0) {
   2.264 +                PERROR("%s: failed to read data from file %s", __func__, prop);
   2.265 +                goto error;
   2.266 +            }
   2.267 +
   2.268 +            /* if the device_type is 'cpu',  and reg is 0 
   2.269 +             * return the path where we found it */
   2.270 +            if (strcmp(data, "cpu") == 0) {
   2.271 +
   2.272 +                /* construct path to reg */
   2.273 +                if (snprintf(prop, sizeof(prop), "%s/%s", node,
   2.274 +                             reg) >= sizeof(prop)) {
   2.275 +                    PERROR("%s: failed to concat strings", __func__);
   2.276 +                    goto error;
   2.277 +                }
   2.278 +
   2.279 +                /* using data buffer since reg and device_type values have same size */
   2.280 +                if ((readfile(prop, data, sizeof(data))) < 0) {
   2.281 +                    PERROR("%s: failed to read data from file %s", __func__, prop);
   2.282 +                    goto error;
   2.283 +                }
   2.284 +
   2.285 +                /* now check property "reg" for value 0 */
   2.286 +                if ((u32)*data == 0) {
   2.287 +                    if (snprintf(cpupath, len, "%s", node) >= len) {
   2.288 +                        PERROR("%s: failed to copy cpupath", __func__);
   2.289 +                        goto error;
   2.290 +                    }
   2.291 +                    found = 1;
   2.292 +                }
   2.293 +            }
   2.294 +        }
   2.295 +    }
   2.296 +
   2.297 +    closedir(dir);
   2.298 +    return found;
   2.299 +
   2.300 +error:
   2.301 +    saved_errno = errno;
   2.302 +    closedir(dir);
   2.303 +    errno = saved_errno;
   2.304 +    return -1;
   2.305 +}
   2.306 +
   2.307 +void free_devtree(struct ft_cxt *root)
   2.308 +{
   2.309 +    if ((root != NULL) && root->bph != NULL) {
   2.310 +        free(root->bph);
   2.311 +        root->bph = NULL;
   2.312 +    }
   2.313 +}
   2.314 +
   2.315 +int make_devtree(struct ft_cxt *root,
   2.316 +                 uint32_t domid, 
   2.317 +                 uint32_t mem_mb,
   2.318 +                 unsigned long rma_bytes,
   2.319 +                 unsigned long shadow_mb,
   2.320 +                 unsigned long initrd_base,
   2.321 +                 unsigned long initrd_len,
   2.322 +                 const char *bootargs)
   2.323 +{
   2.324 +    struct boot_param_header *bph = NULL;
   2.325 +    uint64_t val[2];
   2.326 +    uint32_t val32[2];
   2.327 +    unsigned long remaining;
   2.328 +    unsigned long rma_reserve = 4 * PAGE_SIZE;
   2.329 +    unsigned long initrd_end = initrd_base + initrd_len;
   2.330 +    int64_t shadow_mb_log;
   2.331 +    uint64_t pft_size;
   2.332 +    char cpupath[MAX_PATH];
   2.333 +    const char *propfilter[] = { "ibm", "linux,", NULL };
   2.334 +    char *cpupath_copy = NULL;
   2.335 +    char *cpuname = NULL;
   2.336 +    int saved_errno;
   2.337 +    int dtb_fd = -1;
   2.338 +    uint32_t cpu0_phandle = get_phandle();
   2.339 +    uint32_t xen_phandle = get_phandle();
   2.340 +    uint32_t rma_phandle = get_phandle();
   2.341 +
   2.342 +    /* initialize bph to prevent double free on error path */
   2.343 +    root->bph = NULL;
   2.344 +
   2.345 +    /* carve out space for bph */
   2.346 +    if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) {
   2.347 +        PERROR("%s: Failed to malloc bph buffer size", __func__);
   2.348 +        goto error;
   2.349 +    }
   2.350 +
   2.351 +    /* NB: struct ft_cxt root defined at top of file */
   2.352 +    /* root = Tree() */
   2.353 +    ft_begin(root, bph, BPH_SIZE);
   2.354 +
   2.355 +    /* you MUST set reservations BEFORE _starting_the_tree_ */
   2.356 +
   2.357 +    /* reserve some pages at the end of RMA */
   2.358 +    val[0] = cpu_to_be64((u64) (rma_bytes - rma_reserve));
   2.359 +    val[1] = cpu_to_be64((u64) rma_reserve);
   2.360 +    ft_add_rsvmap(root, val[0], val[1]);
   2.361 +
   2.362 +    /* reserve space for initrd if needed */
   2.363 +    if ( initrd_len > 0 )  {
   2.364 +        val[0] = cpu_to_be64((u64) initrd_base);
   2.365 +        val[1] = cpu_to_be64((u64) initrd_len);
   2.366 +        ft_add_rsvmap(root, val[0], val[1]);
   2.367 +    }
   2.368 +
   2.369 +    /* NB: ft_add_rsvmap() already terminates with a NULL reservation for us */
   2.370 +
   2.371 +    /* done with reservations, _starting_the_tree_ */
   2.372 +    ft_begin_tree(root);
   2.373 +
   2.374 +    /* make root node */
   2.375 +    ft_begin_node(root, "");
   2.376 +
   2.377 +    /* root.addprop('device_type', 'chrp-but-not-really\0') */
   2.378 +    ft_prop_str(root, "device_type", "chrp-but-not-really");
   2.379 +
   2.380 +    /* root.addprop('#size-cells', 2) */
   2.381 +    ft_prop_int(root, "#size-cells", 2);
   2.382 +
   2.383 +    /* root.addprop('#address-cells', 2) */
   2.384 +    ft_prop_int(root, "#address-cells", 2);
   2.385 +
   2.386 +    /* root.addprop('model', 'Momentum,Maple-D\0') */
   2.387 +    ft_prop_str(root, "model", "Momentum,Maple-D");
   2.388 +
   2.389 +    /* root.addprop('compatible', 'Momentum,Maple\0') */
   2.390 +    ft_prop_str(root, "compatible", "Momentum,Maple");
   2.391 +
   2.392 +    /* start chosen node */
   2.393 +    ft_begin_node(root, "chosen");
   2.394 +
   2.395 +    /* chosen.addprop('cpu', cpu0.get_phandle()) */
   2.396 +    ft_prop_int(root, "cpu", cpu0_phandle);
   2.397 +
   2.398 +    /* chosen.addprop('rma', rma.get_phandle()) */
   2.399 +    ft_prop_int(root, "memory", rma_phandle);
   2.400 +
   2.401 +    /* chosen.addprop('linux,stdout-path', '/xen/console\0') */
   2.402 +    ft_prop_str(root, "linux,stdout-path", "/xen/console");
   2.403 +
   2.404 +    /* chosen.addprop('interrupt-controller, xen.get_phandle()) */
   2.405 +    ft_prop_int(root, "interrupt-controller", xen_phandle);
   2.406 +
   2.407 +    /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */
   2.408 +    if ( bootargs != NULL )
   2.409 +        ft_prop_str(root, "bootargs", bootargs);
   2.410 +
   2.411 +    /* mark where the initrd is, if present */
   2.412 +    if ( initrd_len > 0 ) {
   2.413 +        val[0] = cpu_to_be64((u64) initrd_base);
   2.414 +        val[1] = cpu_to_be64((u64) initrd_end);
   2.415 +        ft_prop(root, "linux,initrd-start", &(val[0]), sizeof(val[0]));
   2.416 +        ft_prop(root, "linux,initrd-end", &(val[1]), sizeof(val[1]));
   2.417 +    }
   2.418 +
   2.419 +    /* end chosen node */
   2.420 +    ft_end_node(root);
   2.421 +
   2.422 +    /* xen = root.addnode('xen') */
   2.423 +    ft_begin_node(root, "xen");
   2.424 +
   2.425 +    /* start-info is the first page in the RMA reserved area */
   2.426 +    val[0] = cpu_to_be64((u64) (rma_bytes - rma_reserve));
   2.427 +    val[1] = cpu_to_be64((u64) PAGE_SIZE);
   2.428 +    ft_prop(root, "start-info", val, sizeof(val));
   2.429 +
   2.430 +    /*  xen.addprop('version', 'Xen-3.0-unstable\0') */
   2.431 +    ft_prop_str(root, "version", "Xen-3.0-unstable");
   2.432 +
   2.433 +    /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */
   2.434 +    val[0] = cpu_to_be64((u64) domid);
   2.435 +    val[1] = cpu_to_be64((u64) 0);
   2.436 +    ft_prop(root, "reg", val, sizeof(val));
   2.437 +
   2.438 +    /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */
   2.439 +    /* libxc doesn't know the domain name, that is purely a xend thing */
   2.440 +    /* ft_prop_str(root, "domain-name", domain_name); */
   2.441 +
   2.442 +    /* add xen/linux,phandle for chosen/interrupt-controller */
   2.443 +    ft_prop_int(root, "linux,phandle", xen_phandle);
   2.444 +
   2.445 +    /* xencons = xen.addnode('console') */
   2.446 +    ft_begin_node(root, "console");
   2.447 +
   2.448 +    /* xencons.addprop('interrupts', 1, 0) */
   2.449 +    val32[0] = cpu_to_be32((u32) 1);
   2.450 +    val32[1] = cpu_to_be32((u32) 0);
   2.451 +    ft_prop(root, "interrupts", val32, sizeof(val32));
   2.452 +
   2.453 +    /* end of console */
   2.454 +    ft_end_node(root);
   2.455 +
   2.456 +    /* end of xen node */
   2.457 +    ft_end_node(root);
   2.458 +
   2.459 +    /* rma = root.addnode('memory@0') */
   2.460 +    ft_begin_node(root, "memory@0");
   2.461 +
   2.462 +    /* rma.addprop('reg', long(0), long(rma_bytes)) */
   2.463 +    val[0] = cpu_to_be64((u64) 0);
   2.464 +    val[1] = cpu_to_be64((u64) rma_bytes);
   2.465 +    ft_prop(root, "reg", val, sizeof(val));
   2.466 +
   2.467 +    /* rma.addprop('device_type', 'memory\0') */
   2.468 +    ft_prop_str(root, "device_type", "memory");
   2.469 +
   2.470 +    /* add linux,phandle for chosen/rma node */
   2.471 +    ft_prop_int(root, "linux,phandle", rma_phandle);
   2.472 +
   2.473 +    /* end of memory@0 */
   2.474 +    ft_end_node(root);
   2.475 +
   2.476 +    /* calculate remaining bytes from total - rma size */
   2.477 +    remaining = (mem_mb * 1024 * 1024) - rma_bytes;
   2.478 +
   2.479 +    /* memory@<rma_bytes> is all remaining memory after RMA */
   2.480 +    if (remaining > 0)
   2.481 +    {
   2.482 +        char mem[MAX_PATH];
   2.483 +        
   2.484 +        if (snprintf(mem, sizeof(mem), "memory@%lx",
   2.485 +                     rma_bytes) >= sizeof(mem)) {
   2.486 +            PERROR("%s: failed to build memory string", __func__);
   2.487 +            goto error;
   2.488 +        }
   2.489 +
   2.490 +        /* memory@<rma_bytes> is all remaining memory after RMA */
   2.491 +        ft_begin_node(root, mem);
   2.492 +
   2.493 +        /* mem.addprop('reg', long(rma_bytes), long(remaining)) */
   2.494 +        val[0] = cpu_to_be64((u64) rma_bytes);
   2.495 +        val[1] = cpu_to_be64((u64) remaining);
   2.496 +        ft_prop(root, "reg", val, sizeof(val));
   2.497 +
   2.498 +        /* mem.addprop('device_type', 'memory\0') */
   2.499 +        ft_prop_str(root, "device_type", "memory");
   2.500 +
   2.501 +        /* end memory@<rma_bytes> node */
   2.502 +        ft_end_node(root);
   2.503 +    }
   2.504 +
   2.505 +    /* add CPU nodes */
   2.506 +    /* cpus = root.addnode('cpus') */
   2.507 +    ft_begin_node(root, "cpus");
   2.508 +
   2.509 +    /* cpus.addprop('smp-enabled') */
   2.510 +    ft_prop(root, "smp-enabled", NULL, 0);
   2.511 +
   2.512 +    /* cpus.addprop('#size-cells', 0) */
   2.513 +    ft_prop_int(root, "#size-cells", 0);
   2.514 +
   2.515 +    /* cpus.addprop('#address-cells', 1) */
   2.516 +    ft_prop_int(root, "#address-cells", 1);
   2.517 +
   2.518 +    /*
   2.519 +     * Copy all properties the system firmware gave us from a 
   2.520 +     * CPU node in the device tree.
   2.521 +     */
   2.522 +    if (find_cpu0(cpupath, sizeof(cpupath)) <= 0) {
   2.523 +        PERROR("%s: failed find cpu0 node in host devtree", __func__);
   2.524 +        goto error;
   2.525 +    }
   2.526 +
   2.527 +    /* get the basename from path to cpu device */
   2.528 +    if ((cpupath_copy = strdup(cpupath)) == NULL) {
   2.529 +        PERROR("%s: failed to dupe string", __func__);
   2.530 +        goto error;
   2.531 +    }
   2.532 +    if ((cpuname = basename(cpupath_copy)) == NULL) {
   2.533 +        PERROR("%s: basename() failed", __func__);
   2.534 +        goto error;
   2.535 +    }
   2.536 +     
   2.537 +    /* start node for the cpu */
   2.538 +    ft_begin_node(root, cpuname);
   2.539 +
   2.540 +    /* strdup() mallocs memory */
   2.541 +    if ( cpupath_copy != NULL ) {
   2.542 +        free(cpupath_copy);
   2.543 +        cpupath_copy = NULL;
   2.544 +    }
   2.545 +
   2.546 +    /* copy over most properties from host tree for cpu */
   2.547 +    if (copynode(root, cpupath, propfilter) < 0) {
   2.548 +        PERROR("%s: failed to copy node", __func__);
   2.549 +            goto error;
   2.550 +    }
   2.551 +
   2.552 +    /* calculate the pft-size */
   2.553 +    shadow_mb_log = (int)log2((double)shadow_mb);
   2.554 +    pft_size = shadow_mb_log + 20;
   2.555 +
   2.556 +    val32[0] = cpu_to_be32((u32) 0);
   2.557 +    val32[1] = cpu_to_be32((u32) pft_size);
   2.558 +    ft_prop(root, "ibm,pft-size", val32, sizeof(val32));
   2.559 +
   2.560 +    /* make phandle for cpu0 */
   2.561 +    ft_prop_int(root, "linux,phandle", cpu0_phandle);
   2.562 +
   2.563 +    /* end <cpuname> node */
   2.564 +    ft_end_node(root);
   2.565 +
   2.566 +    /* end cpus node */
   2.567 +    ft_end_node(root);
   2.568 +
   2.569 +    /* end root node */
   2.570 +    ft_end_node(root);
   2.571 +
   2.572 +    /* end of the tree */
   2.573 +    if (ft_end_tree(root) != 0) {
   2.574 +        PERROR("%s: failed to end tree", __func__);
   2.575 +        goto error;
   2.576 +    }
   2.577 +
   2.578 +    /* write a copy of the tree to a file */
   2.579 +    if ((dtb_fd = open(DTB_FILE , O_RDWR)) == -1) {
   2.580 +        PERROR("%s: failed to open file %s", __func__, DTB_FILE);
   2.581 +        goto error;
   2.582 +    }
   2.583 +
   2.584 +    if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) {
   2.585 +        PERROR("%s: failed to write blob to file", __func__);
   2.586 +        goto error; 
   2.587 +    }
   2.588 +
   2.589 +    return 0;
   2.590 + 
   2.591 +error:
   2.592 +    saved_errno = errno;
   2.593 +
   2.594 +    /* strdup() mallocs memory */
   2.595 +    if ( cpupath_copy != NULL ) {
   2.596 +        free(cpupath_copy);
   2.597 +        cpupath_copy = NULL;
   2.598 +    }
   2.599 +
   2.600 +    /* free bph buffer */
   2.601 +    free_devtree(root);
   2.602 +
   2.603 +    if (dtb_fd)
   2.604 +        close(dtb_fd);
   2.605 +
   2.606 +    errno = saved_errno;
   2.607 +    return -1;
   2.608 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/libxc/powerpc64/mk_flatdevtree.h	Sun Jan 21 08:14:27 2007 -0500
     3.3 @@ -0,0 +1,42 @@
     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 IBM Corporation 2007
    3.20 + *
    3.21 + * Authors: Ryan Harper <ryanh@us.ibm.com>
    3.22 + */
    3.23 +
    3.24 +#ifndef MK_FLATDEVTREE_H
    3.25 +#define MK_FLATDEVTREE_H
    3.26 +
    3.27 +#include "flatdevtree_env.h"
    3.28 +#include "flatdevtree.h"
    3.29 +
    3.30 +extern void free_devtree(struct ft_cxt *root);
    3.31 +extern int make_devtree(struct ft_cxt *root,
    3.32 +                        uint32_t domid, 
    3.33 +                        uint32_t mem_mb,
    3.34 +                        unsigned long rma_bytes,
    3.35 +                        unsigned long shadow_mb,
    3.36 +                        unsigned long initrd_base,
    3.37 +                        unsigned long initrd_len,
    3.38 +                        const char *bootargs);
    3.39 +
    3.40 +#define MAX_PATH 200
    3.41 +#define BUFSIZE 1024
    3.42 +#define BPH_SIZE 16*1024
    3.43 +#define DTB_FILE "/tmp/domU.dtb"
    3.44 +
    3.45 +#endif /* MK_FLATDEVTREE_H */
     4.1 --- a/tools/libxc/powerpc64/xc_linux_build.c	Sun Jan 21 07:49:50 2007 -0500
     4.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c	Sun Jan 21 08:14:27 2007 -0500
     4.3 @@ -13,9 +13,10 @@
     4.4   * along with this program; if not, write to the Free Software
     4.5   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     4.6   *
     4.7 - * Copyright (C) IBM Corporation 2006
     4.8 + * Copyright IBM Corporation 2006, 2007
     4.9   *
    4.10   * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    4.11 + *          Ryan Harper <ryanh@us.ibm.com>
    4.12   */
    4.13  
    4.14  #include <stdio.h>
    4.15 @@ -36,6 +37,7 @@
    4.16  #include "flatdevtree_env.h"
    4.17  #include "flatdevtree.h"
    4.18  #include "utils.h"
    4.19 +#include "mk_flatdevtree.h"
    4.20  
    4.21  #define INITRD_ADDR (24UL << 20)
    4.22  #define DEVTREE_ADDR (16UL << 20)
    4.23 @@ -78,85 +80,6 @@ static int init_boot_vcpu(
    4.24      return rc;
    4.25  }
    4.26  
    4.27 -static int load_devtree(
    4.28 -    int xc_handle,
    4.29 -    int domid,
    4.30 -    xen_pfn_t *page_array,
    4.31 -    void *devtree,
    4.32 -    unsigned long devtree_addr,
    4.33 -    uint64_t initrd_base,
    4.34 -    unsigned long initrd_len,
    4.35 -    start_info_t *start_info __attribute__((unused)),
    4.36 -    unsigned long start_info_addr)
    4.37 -{
    4.38 -    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
    4.39 -    struct boot_param_header *header;
    4.40 -    void *chosen;
    4.41 -    void *xen;
    4.42 -    uint64_t initrd_end = initrd_base + initrd_len;
    4.43 -    unsigned int devtree_size;
    4.44 -    int rc = 0;
    4.45 -
    4.46 -    DPRINTF("adding initrd props\n");
    4.47 -
    4.48 -    chosen = ft_find_node(devtree, "/chosen");
    4.49 -    if (chosen == NULL) {
    4.50 -        DPRINTF("couldn't find /chosen\n");
    4.51 -        return -1;
    4.52 -    }
    4.53 -
    4.54 -    xen = ft_find_node(devtree, "/xen");
    4.55 -    if (xen == NULL) {
    4.56 -        DPRINTF("couldn't find /xen\n");
    4.57 -        return -1;
    4.58 -    }
    4.59 -
    4.60 -    /* initrd-start */
    4.61 -    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
    4.62 -            &initrd_base, sizeof(initrd_base));
    4.63 -    if (rc < 0) {
    4.64 -        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
    4.65 -        return rc;
    4.66 -    }
    4.67 -
    4.68 -    /* initrd-end */
    4.69 -    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
    4.70 -            &initrd_end, sizeof(initrd_end));
    4.71 -    if (rc < 0) {
    4.72 -        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
    4.73 -        return rc;
    4.74 -    }
    4.75 -
    4.76 -    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
    4.77 -    if (rc < 0) {
    4.78 -        DPRINTF("couldn't set initrd reservation\n");
    4.79 -        return ~0UL;
    4.80 -    }
    4.81 -
    4.82 -    /* start-info (XXX being removed soon) */
    4.83 -    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
    4.84 -    if (rc < 0) {
    4.85 -        DPRINTF("couldn't set /xen/start-info\n");
    4.86 -        return rc;
    4.87 -    }
    4.88 -
    4.89 -    header = devtree;
    4.90 -    devtree_size = header->totalsize;
    4.91 -    {
    4.92 -        static const char dtb[] = "/tmp/xc_domU.dtb";
    4.93 -        int dfd = creat(dtb, 0666);
    4.94 -        if (dfd != -1) {
    4.95 -            write(dfd, devtree, devtree_size);
    4.96 -            close(dfd);
    4.97 -        } else
    4.98 -            DPRINTF("could not open(\"%s\")\n", dtb);
    4.99 -    }
   4.100 -
   4.101 -    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
   4.102 -    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
   4.103 -                       devtree_size);
   4.104 -}
   4.105 -
   4.106  static int load_initrd(
   4.107      int xc_handle,
   4.108      int domid,
   4.109 @@ -187,13 +110,14 @@ out:
   4.110  }
   4.111  
   4.112  static unsigned long create_start_info(
   4.113 -    void *devtree, start_info_t *start_info,
   4.114 -        unsigned int console_evtchn, unsigned int store_evtchn,
   4.115 -    unsigned long nr_pages, unsigned long rma_pages)
   4.116 +        start_info_t *start_info,
   4.117 +        unsigned int console_evtchn,
   4.118 +        unsigned int store_evtchn,
   4.119 +        unsigned long nr_pages,
   4.120 +        unsigned long rma_pages)
   4.121  {
   4.122      unsigned long start_info_addr;
   4.123      uint64_t rma_top;
   4.124 -    int rc;
   4.125  
   4.126      memset(start_info, 0, sizeof(*start_info));
   4.127      snprintf(start_info->magic, sizeof(start_info->magic),
   4.128 @@ -210,13 +134,6 @@ static unsigned long create_start_info(
   4.129      start_info->console.domU.evtchn = console_evtchn;
   4.130      start_info_addr = rma_top - 4*PAGE_SIZE;
   4.131  
   4.132 -    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
   4.133 -    if (rc < 0) {
   4.134 -        DPRINTF("couldn't set start_info reservation\n");
   4.135 -        return ~0UL;
   4.136 -    }
   4.137 -
   4.138 -
   4.139      return start_info_addr;
   4.140  }
   4.141  
   4.142 @@ -238,8 +155,7 @@ int xc_linux_build(int xc_handle,
   4.143                     unsigned int store_evtchn,
   4.144                     unsigned long *store_mfn,
   4.145                     unsigned int console_evtchn,
   4.146 -                   unsigned long *console_mfn,
   4.147 -                   void *devtree)
   4.148 +                   unsigned long *console_mfn)
   4.149  {
   4.150      start_info_t start_info;
   4.151      struct domain_setup_info dsi;
   4.152 @@ -251,14 +167,18 @@ int xc_linux_build(int xc_handle,
   4.153      unsigned long initrd_len = 0;
   4.154      unsigned long start_info_addr;
   4.155      unsigned long rma_pages;
   4.156 +    unsigned long shadow_mb;
   4.157 +    int rma_log = 26;  /* 64MB RMA */
   4.158      int rc = 0;
   4.159 +    int op;
   4.160 +    struct ft_cxt devtree;
   4.161  
   4.162      DPRINTF("%s\n", __func__);
   4.163  
   4.164      nr_pages = mem_mb << (20 - PAGE_SHIFT);
   4.165      DPRINTF("nr_pages 0x%lx\n", nr_pages);
   4.166  
   4.167 -    rma_pages = get_rma_pages(devtree);
   4.168 +    rma_pages = (1 << rma_log) >> PAGE_SHIFT;
   4.169      if (rma_pages == 0) {
   4.170          rc = -1;
   4.171          goto out;
   4.172 @@ -285,8 +205,25 @@ int xc_linux_build(int xc_handle,
   4.173          }
   4.174      }
   4.175  
   4.176 +    /* fetch the current shadow_memory value for this domain */
   4.177 +    op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
   4.178 +    if (xc_shadow_control(xc_handle, domid, op, NULL, 0, 
   4.179 +                          &shadow_mb, 0, NULL) < 0 ) {
   4.180 +        rc = -1;
   4.181 +        goto out;
   4.182 +    }
   4.183 +
   4.184 +    /* build the devtree here */
   4.185 +    DPRINTF("constructing devtree\n");
   4.186 +    if (make_devtree(&devtree, domid, mem_mb, (rma_pages*PAGE_SIZE), shadow_mb,
   4.187 +                     initrd_base, initrd_len, cmdline) < 0) {
   4.188 +        DPRINTF("failed to create flattened device tree\n");
   4.189 +        rc = -1;
   4.190 +        goto out;
   4.191 +    }
   4.192 +    
   4.193      /* start_info stuff: about to be removed  */
   4.194 -    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
   4.195 +    start_info_addr = create_start_info(&start_info, console_evtchn,
   4.196                                          store_evtchn, nr_pages, rma_pages);
   4.197      *console_mfn = page_array[start_info.console.domU.mfn];
   4.198      *store_mfn = page_array[start_info.store_mfn];
   4.199 @@ -296,16 +233,15 @@ int xc_linux_build(int xc_handle,
   4.200          goto out;
   4.201      }
   4.202  
   4.203 -    if (devtree) {
   4.204 -        DPRINTF("loading flattened device tree\n");
   4.205 -        devtree_addr = DEVTREE_ADDR;
   4.206 -        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
   4.207 -                         initrd_base, initrd_len, &start_info,
   4.208 -                         start_info_addr)) {
   4.209 -            DPRINTF("couldn't load flattened device tree.\n");
   4.210 -            rc = -1;
   4.211 -            goto out;
   4.212 -        }
   4.213 +    devtree_addr = DEVTREE_ADDR;
   4.214 +    DPRINTF("loading flattened device tree to 0x%lx[0x%x]\n",
   4.215 +            devtree_addr, devtree.bph->totalsize);
   4.216 +
   4.217 +    if (install_image(xc_handle, domid, page_array, (void *)devtree.bph,
   4.218 +                      devtree_addr, devtree.bph->totalsize)) {
   4.219 +        DPRINTF("couldn't load flattened device tree.\n");
   4.220 +        rc = -1;
   4.221 +        goto out;
   4.222      }
   4.223  
   4.224      if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
   4.225 @@ -314,6 +250,7 @@ int xc_linux_build(int xc_handle,
   4.226      }
   4.227  
   4.228  out:
   4.229 +    free_devtree(&devtree);
   4.230      free_page_array(page_array);
   4.231      return rc;
   4.232  }
     5.1 --- a/tools/libxc/xenguest.h	Sun Jan 21 07:49:50 2007 -0500
     5.2 +++ b/tools/libxc/xenguest.h	Sun Jan 21 08:14:27 2007 -0500
     5.3 @@ -134,7 +134,6 @@ int xc_prose_build(int xc_handle,
     5.4                     unsigned int store_evtchn,
     5.5                     unsigned long *store_mfn,
     5.6                     unsigned int console_evtchn,
     5.7 -                   unsigned long *console_mfn,
     5.8 -                   void *arch_args);
     5.9 +                   unsigned long *console_mfn);
    5.10  
    5.11  #endif /* XENGUEST_H */
     6.1 --- a/tools/python/xen/xend/image.py	Sun Jan 21 07:49:50 2007 -0500
     6.2 +++ b/tools/python/xen/xend/image.py	Sun Jan 21 08:14:27 2007 -0500
     6.3 @@ -239,8 +239,6 @@ class PPC_LinuxImageHandler(LinuxImageHa
     6.4          log.debug("vcpus          = %d", self.vm.getVCpuCount())
     6.5          log.debug("features       = %s", self.vm.getFeatures())
     6.6  
     6.7 -        devtree = FlatDeviceTree.build(self)
     6.8 -
     6.9          return xc.linux_build(domid          = self.vm.getDomid(),
    6.10                                memsize        = mem_mb,
    6.11                                image          = self.kernel,
    6.12 @@ -248,8 +246,7 @@ class PPC_LinuxImageHandler(LinuxImageHa
    6.13                                console_evtchn = console_evtchn,
    6.14                                cmdline        = self.cmdline,
    6.15                                ramdisk        = self.ramdisk,
    6.16 -                              features       = self.vm.getFeatures(),
    6.17 -                              arch_args      = devtree.to_bin())
    6.18 +                              features       = self.vm.getFeatures())
    6.19  
    6.20      def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
    6.21          """@param shadow_mem_kb The configured shadow memory, in KiB.