7 files changed, 699 insertions(+), 113 deletions(-)
tools/libxc/powerpc64/Makefile         |    1 
tools/libxc/powerpc64/mk_flatdevtree.c |  605 ++++++++++++++++++++++++++++++++
tools/libxc/powerpc64/mk_flatdevtree.h |   42 ++
tools/libxc/powerpc64/xc_linux_build.c |  143 ++-----
tools/libxc/xenguest.h                 |    4 
tools/python/xen/lowlevel/xc/xc.c      |   12 
tools/python/xen/xend/image.py         |    5 


# HG changeset patch
# User Ryan Harper <[EMAIL PROTECTED]>
# Date 1168988154 21600
# Node ID a01ef2a2051e8c1295f3b5caf27f4faf5f91a93f
# Parent  5568efb41da42a55318fa05d3ce0aa73e774e6d1
[PATCH] Move flat device tree construction from python to libxc for 
xc_linux_build().

Signed-off-by: Ryan Harper <[EMAIL PROTECTED]>

diff -r 5568efb41da4 -r a01ef2a2051e tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Mon Jan 15 13:27:20 2007 -0500
+++ b/tools/libxc/powerpc64/Makefile    Tue Jan 16 16:55:54 2007 -0600
@@ -1,4 +1,5 @@ GUEST_SRCS-y += powerpc64/flatdevtree.c
 GUEST_SRCS-y += powerpc64/flatdevtree.c
+GUEST_SRCS-y += powerpc64/mk_flatdevtree.c
 GUEST_SRCS-y += powerpc64/xc_linux_build.c
 GUEST_SRCS-y += powerpc64/xc_prose_build.c
 GUEST_SRCS-y += powerpc64/utils.c
diff -r 5568efb41da4 -r a01ef2a2051e tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c    Mon Jan 15 13:27:20 2007 -0500
+++ b/tools/libxc/powerpc64/xc_linux_build.c    Tue Jan 16 16:55:54 2007 -0600
@@ -13,9 +13,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  *
  * Authors: Hollis Blanchard <[EMAIL PROTECTED]>
+ *          Ryan Harper <[EMAIL PROTECTED]>
  */
 
 #include <stdio.h>
@@ -36,6 +37,7 @@
 #include "flatdevtree_env.h"
 #include "flatdevtree.h"
 #include "utils.h"
+#include "mk_flatdevtree.h"
 
 #define INITRD_ADDR (24UL << 20)
 #define DEVTREE_ADDR (16UL << 20)
@@ -78,85 +80,6 @@ static int init_boot_vcpu(
     return rc;
 }
 
-static int load_devtree(
-    int xc_handle,
-    int domid,
-    xen_pfn_t *page_array,
-    void *devtree,
-    unsigned long devtree_addr,
-    uint64_t initrd_base,
-    unsigned long initrd_len,
-    start_info_t *start_info __attribute__((unused)),
-    unsigned long start_info_addr)
-{
-    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
-    struct boot_param_header *header;
-    void *chosen;
-    void *xen;
-    uint64_t initrd_end = initrd_base + initrd_len;
-    unsigned int devtree_size;
-    int rc = 0;
-
-    DPRINTF("adding initrd props\n");
-
-    chosen = ft_find_node(devtree, "/chosen");
-    if (chosen == NULL) {
-        DPRINTF("couldn't find /chosen\n");
-        return -1;
-    }
-
-    xen = ft_find_node(devtree, "/xen");
-    if (xen == NULL) {
-        DPRINTF("couldn't find /xen\n");
-        return -1;
-    }
-
-    /* initrd-start */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
-            &initrd_base, sizeof(initrd_base));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
-        return rc;
-    }
-
-    /* initrd-end */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
-            &initrd_end, sizeof(initrd_end));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
-        return rc;
-    }
-
-    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
-    if (rc < 0) {
-        DPRINTF("couldn't set initrd reservation\n");
-        return ~0UL;
-    }
-
-    /* start-info (XXX being removed soon) */
-    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
-    if (rc < 0) {
-        DPRINTF("couldn't set /xen/start-info\n");
-        return rc;
-    }
-
-    header = devtree;
-    devtree_size = header->totalsize;
-    {
-        static const char dtb[] = "/tmp/xc_domU.dtb";
-        int dfd = creat(dtb, 0666);
-        if (dfd != -1) {
-            write(dfd, devtree, devtree_size);
-            close(dfd);
-        } else
-            DPRINTF("could not open(\"%s\")\n", dtb);
-    }
-
-    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
-    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
-                       devtree_size);
-}
-
 static int load_initrd(
     int xc_handle,
     int domid,
@@ -187,13 +110,14 @@ out:
 }
 
 static unsigned long create_start_info(
-    void *devtree, start_info_t *start_info,
-        unsigned int console_evtchn, unsigned int store_evtchn,
-    unsigned long nr_pages, unsigned long rma_pages)
+        start_info_t *start_info,
+        unsigned int console_evtchn,
+        unsigned int store_evtchn,
+        unsigned long nr_pages,
+        unsigned long rma_pages)
 {
     unsigned long start_info_addr;
     uint64_t rma_top;
-    int rc;
 
     memset(start_info, 0, sizeof(*start_info));
     snprintf(start_info->magic, sizeof(start_info->magic),
@@ -209,13 +133,6 @@ static unsigned long create_start_info(
     start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
     start_info->console.domU.evtchn = console_evtchn;
     start_info_addr = rma_top - 4*PAGE_SIZE;
-
-    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
-    if (rc < 0) {
-        DPRINTF("couldn't set start_info reservation\n");
-        return ~0UL;
-    }
-
 
     return start_info_addr;
 }
@@ -238,8 +155,7 @@ int xc_linux_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn,
-                   void *devtree)
+                   unsigned long *console_mfn)
 {
     start_info_t start_info;
     struct domain_setup_info dsi;
@@ -251,14 +167,19 @@ int xc_linux_build(int xc_handle,
     unsigned long initrd_len = 0;
     unsigned long start_info_addr;
     unsigned long rma_pages;
+    unsigned long shadow_mb;
+    int rma_log = 26;  /* 64MB RMA */
     int rc = 0;
+    int op;
+    struct ft_cxt root;
+    void *devtree;
 
     DPRINTF("%s\n", __func__);
 
     nr_pages = mem_mb << (20 - PAGE_SHIFT);
     DPRINTF("nr_pages 0x%lx\n", nr_pages);
 
-    rma_pages = get_rma_pages(devtree);
+    rma_pages = (1 << rma_log) >> PAGE_SHIFT;
     if (rma_pages == 0) {
         rc = -1;
         goto out;
@@ -285,8 +206,27 @@ int xc_linux_build(int xc_handle,
         }
     }
 
+    /* fetch the current shadow_memory value for this domain */
+    op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
+    if (xc_shadow_control(xc_handle, domid, op, NULL, 0, &shadow_mb, 0, NULL) 
< 0 ) {
+        rc = -1;
+        goto out;
+    }
+
+    /* build the devtree here */
+    DPRINTF("constructing devtree\n");
+    if (make_devtree(&root, domid, mem_mb, (rma_pages * PAGE_SIZE), shadow_mb, 
+                     initrd_base, initrd_len, cmdline) < 0) {
+        DPRINTF("failed to create flattened device tree\n");
+        rc = -1;
+        goto out;
+    }
+    
+    /* point devtree at bph blob */
+    devtree = root.bph;
+
     /* start_info stuff: about to be removed  */
-    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+    start_info_addr = create_start_info(&start_info, console_evtchn,
                                         store_evtchn, nr_pages, rma_pages);
     *console_mfn = page_array[start_info.console.domU.mfn];
     *store_mfn = page_array[start_info.store_mfn];
@@ -297,11 +237,15 @@ int xc_linux_build(int xc_handle,
     }
 
     if (devtree) {
-        DPRINTF("loading flattened device tree\n");
+        struct boot_param_header *header = root.bph;
+        unsigned int devtree_size = header->totalsize;
+
         devtree_addr = DEVTREE_ADDR;
-        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
-                         initrd_base, initrd_len, &start_info,
-                         start_info_addr)) {
+        DPRINTF("loading flattened device tree to 0x%lx[0x%x]\n",
+                devtree_addr, devtree_size);
+
+        if (install_image(xc_handle, domid, page_array, devtree, devtree_addr,
+                       devtree_size)) {
             DPRINTF("couldn't load flattened device tree.\n");
             rc = -1;
             goto out;
@@ -314,6 +258,7 @@ int xc_linux_build(int xc_handle,
     }
 
 out:
+    free_devtree(&root);
     free_page_array(page_array);
     return rc;
 }
diff -r 5568efb41da4 -r a01ef2a2051e tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Mon Jan 15 13:27:20 2007 -0500
+++ b/tools/libxc/xenguest.h    Tue Jan 16 16:55:54 2007 -0600
@@ -57,7 +57,6 @@ int xc_linux_restore(int xc_handle, int 
  * @parm store_mfn returned with the mfn of the store page
  * @parm console_evtchn the console event channel for this domain to use
  * @parm console_mfn returned with the mfn of the console page
- * @parm arch_args architecture-specific data
  * @return 0 on success, -1 on failure
  */
 int xc_linux_build(int xc_handle,
@@ -71,8 +70,7 @@ int xc_linux_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn,
-                   void *arch_args);
+                   unsigned long *console_mfn);
 
 /**
  * This function will create a domain for a paravirtualized Linux
diff -r 5568efb41da4 -r a01ef2a2051e tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Jan 15 13:27:20 2007 -0500
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Jan 16 16:55:54 2007 -0600
@@ -360,28 +360,26 @@ static PyObject *pyxc_linux_build(XcObje
     unsigned int mem_mb;
     unsigned long store_mfn = 0;
     unsigned long console_mfn = 0;
-    void *arch_args = NULL;
     int unused;
 
     static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
                                 "console_evtchn", "image",
                                 /* optional */
                                 "ramdisk", "cmdline", "flags",
-                                "features", "arch_args", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssiss#", kwd_list,
+                                "features", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,
                                       &dom, &store_evtchn, &mem_mb,
                                       &console_evtchn, &image,
                                       /* optional */
                                       &ramdisk, &cmdline, &flags,
-                                      &features, &arch_args, &unused) )
+                                      &features, &unused) )
         return NULL;
 
     if ( xc_linux_build(self->xc_handle, dom, mem_mb, image,
                         ramdisk, cmdline, features, flags,
                         store_evtchn, &store_mfn,
-                        console_evtchn, &console_mfn,
-                        arch_args) != 0 ) {
+                        console_evtchn, &console_mfn) != 0 ) {
         return pyxc_error_to_exception();
     }
     return Py_BuildValue("{s:i,s:i}", 
diff -r 5568efb41da4 -r a01ef2a2051e tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Mon Jan 15 13:27:20 2007 -0500
+++ b/tools/python/xen/xend/image.py    Tue Jan 16 16:55:54 2007 -0600
@@ -239,8 +239,6 @@ class PPC_LinuxImageHandler(LinuxImageHa
         log.debug("vcpus          = %d", self.vm.getVCpuCount())
         log.debug("features       = %s", self.vm.getFeatures())
 
-        devtree = FlatDeviceTree.build(self)
-
         return xc.linux_build(domid          = self.vm.getDomid(),
                               memsize        = mem_mb,
                               image          = self.kernel,
@@ -248,8 +246,7 @@ class PPC_LinuxImageHandler(LinuxImageHa
                               console_evtchn = console_evtchn,
                               cmdline        = self.cmdline,
                               ramdisk        = self.ramdisk,
-                              features       = self.vm.getFeatures(),
-                              arch_args      = devtree.to_bin())
+                              features       = self.vm.getFeatures())
 
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         """@param shadow_mem_kb The configured shadow memory, in KiB.
diff -r 5568efb41da4 -r a01ef2a2051e tools/libxc/powerpc64/mk_flatdevtree.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.c    Tue Jan 16 16:55:54 2007 -0600
@@ -0,0 +1,605 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Ryan Harper <[EMAIL PROTECTED]>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <libgen.h>    
+#include <inttypes.h>
+#include <math.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <xc_private.h> /* for PERROR() */
+
+#include "mk_flatdevtree.h"
+
+static uint32_t current_phandle = 0;
+
+static uint32_t get_phandle(void)
+{
+   return current_phandle++;
+}
+
+static int readfile(const char *fullpath, void *data, int len)
+{
+    struct stat st;
+    int saved_errno;
+    int rc = -1;
+    int fd;
+   
+    if ((fd = open(fullpath, O_RDONLY)) == -1) {
+        PERROR("%s: failed to open file %s", __func__, fullpath);
+        return -1;
+    }
+
+    if ((rc = fstat(fd, &st)) == -1) {
+        PERROR("%s: failed to stat fd %d", __func__, fd);
+        goto error;
+    }
+
+    if (S_ISREG(st.st_mode))
+        rc = read(fd, data, len); 
+
+    close(fd);
+    return rc;
+
+error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return -1;
+}
+
+/* 
+ * @property - string to check against the filter list
+ * @filter   - NULL terminated list of strings 
+ *
+ * compare @property string to each string in @filter
+ *
+ * return 1 if @property matches any filter, otherwise 0
+ *
+ */
+static int match(const char *property, const char **filter)
+{
+    int i;
+    
+    for (i=0; filter[i] != NULL; i++) {
+        /* compare the filter to property */
+        if (strncmp(property, filter[i], strlen(filter[i])) == 0)
+            return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * copy the node at @dirpath filtering out any properties that match in 
@propfilter
+ */
+static int copynode(struct ft_cxt *cxt, const char *dirpath, const char 
**propfilter)
+{   
+    struct dirent *tree;
+    struct stat st;
+    DIR *dir;
+    char fullpath[MAX_PATH];
+    char *bname = NULL;
+    char *basec = NULL;
+    int saved_errno;
+
+    if ((dir = opendir(dirpath)) == NULL) {
+        PERROR("%s: failed to open dir %s", __func__, dirpath);
+        return -1;
+    }
+
+    while (1) {
+        if ((tree = readdir(dir)) == NULL)
+            break;  /* reached end of directory entries */
+
+        /* ignore . and .. */
+        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
+            continue;
+
+        /* build full path name of the file, for stat() */
+        if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath,
+                     tree->d_name) >= sizeof(fullpath)) {
+            PERROR("%s: failed to build full path", __func__);
+            goto error;
+        }
+
+        /* stat the entry */
+        if (stat(fullpath, &st) < 0) {
+            PERROR("%s: failed to stat file %s", __func__, fullpath);
+            goto error;
+        }
+
+        if (S_ISDIR(st.st_mode)) {
+            /* start a new node for a dir */
+            ft_begin_node(cxt, tree->d_name);
+
+            /* copy everything in this dir */
+            if (copynode(cxt, fullpath, propfilter) < 0) {
+                PERROR("%s: failed to copy node @ %s", __func__, fullpath);
+                goto error;
+            }
+
+            /* end the node */
+            ft_end_node(cxt);
+        }
+        /* add files in dir as properties */
+        else if (S_ISREG(st.st_mode)) {
+
+            if ((basec = strdup(fullpath)) == NULL) {
+                PERROR("%s: failed to dupe string", __func__);
+                goto error;
+            }
+
+            if ((bname = basename(basec)) == NULL) {
+                PERROR("%s: basename() failed", __func__);
+                goto error;
+            }
+
+            /* only add files that don't match the property filter string */
+            if (!match(bname, propfilter)) {
+                char data[BUFSIZE];
+                int len;
+
+                /* snarf the data and push into the property */
+                if ((len = readfile(fullpath, data, sizeof(data))) < 0) {
+                    PERROR("%s: failed to read data from file %s", __func__,
+                                                                   fullpath);
+                    goto error;
+                }
+                ft_prop(cxt, tree->d_name, data, len);
+
+            }
+
+            /* strdup mallocs memory */
+            if (basec != NULL ) {
+                free(basec);
+                basec = NULL;
+            }
+
+        }
+    }
+
+    closedir(dir);
+    return 0;
+
+error:
+    saved_errno = errno;
+
+    /* strdup mallocs memory */
+    if (basec != NULL ) {
+        free(basec);
+        basec = NULL;
+    }
+
+    closedir(dir);
+
+    errno = saved_errno;
+    return -1;
+}
+
+static int find_cpu0(char *cpupath, int len)
+{   
+    const char path[] = "/proc/device-tree/cpus";
+    const char device[] = "device_type";
+    const char dev_cpu[] = "cpu";
+    const char reg[] = "reg";
+    char data[sizeof(dev_cpu)];
+    char prop[MAX_PATH];
+    char node[MAX_PATH];
+    struct dirent *tree;
+    struct stat st;
+    DIR* dir;
+    int saved_errno;
+    int found = 0;
+
+    if ((dir = opendir(path)) == NULL) {
+        PERROR("%s: failed to open directory %s", __func__, path);
+        return -1;
+    }    
+
+    while (!found) {
+
+        if ((tree = readdir(dir)) == NULL)
+            break;  /* reached end of directory entries */
+
+        /* ignore ., .. */
+        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
+            continue;
+
+        /* build full path name of the file, for stat() */
+        if (snprintf(node, sizeof(node), "%s/%s", path,
+                     tree->d_name) >= sizeof(node)) {
+            PERROR("%s: failed to concat strings", __func__);
+            goto error;
+        }
+
+        /* stat the entry */
+        if (stat(node, &st) < 0) {
+            PERROR("%s: failed to stat file %s", __func__, node);
+            /* something funny happen in /proc/device-tree, but march onward */
+            continue;
+        }
+
+        /* for each dir, check the device_type property until we find 'cpu'*/
+        if (S_ISDIR(st.st_mode)) {
+
+            /* construct path to device_type */
+            if (snprintf(prop, sizeof(prop), "%s/%s", node,
+                         device) >= sizeof(prop)) {
+                PERROR("%s: failed to concat strings", __func__);
+                goto error;
+            }
+
+            /* read device_type into buffer */
+            if ((readfile(prop, data, sizeof(data))) < 0) {
+                PERROR("%s: failed to read data from file %s", __func__, prop);
+                goto error;
+            }
+
+            /* if the device_type is 'cpu',  and reg is 0 
+             * return the path where we found it */
+            if (strcmp(data, "cpu") == 0) {
+
+                /* construct path to reg */
+                if (snprintf(prop, sizeof(prop), "%s/%s", node,
+                             reg) >= sizeof(prop)) {
+                    PERROR("%s: failed to concat strings", __func__);
+                    goto error;
+                }
+
+                /* using data buffer since reg and device_type values have 
same size */
+                if ((readfile(prop, data, sizeof(data))) < 0) {
+                    PERROR("%s: failed to read data from file %s", __func__, 
prop);
+                    goto error;
+                }
+
+                /* now check property "reg" for value 0 */
+                if ((u32)*data == 0) {
+                    if (snprintf(cpupath, len, "%s", node) >= len) {
+                        PERROR("%s: failed to copy cpupath", __func__);
+                        goto error;
+                    }
+                    found = 1;
+                }
+            }
+        }
+    }
+
+    closedir(dir);
+    return found;
+
+error:
+    saved_errno = errno;
+    closedir(dir);
+    errno = saved_errno;
+    return -1;
+}
+
+void free_devtree(struct ft_cxt *root)
+{
+    if ((root != NULL) && root->bph != NULL) {
+        free(root->bph);
+        root->bph = NULL;
+    }
+}
+
+int make_devtree(struct ft_cxt *root,
+                 uint32_t domid, 
+                 uint32_t mem_mb,
+                 unsigned long rma_bytes,
+                 unsigned long shadow_mb,
+                 unsigned long initrd_base,
+                 unsigned long initrd_len,
+                 const char *bootargs)
+{
+    struct boot_param_header *bph = NULL;
+    uint64_t val[2];
+    uint32_t val32[2];
+    unsigned long remaining;
+    unsigned long rma_reserve = 4 * PAGE_SIZE;
+    unsigned long initrd_end = initrd_base + initrd_len;
+    int64_t shadow_mb_log;
+    uint64_t pft_size;
+    char cpupath[MAX_PATH];
+    const char *propfilter[] = { "ibm", "linux,", NULL };
+    char *cpupath_copy = NULL;
+    char *cpuname = NULL;
+    int saved_errno;
+    int dtb_fd = -1;
+    uint32_t cpu0_phandle = get_phandle();
+    uint32_t xen_phandle = get_phandle();
+    uint32_t rma_phandle = get_phandle();
+
+    /* initialize bph to prevent double free on error path */
+    root->bph = NULL;
+
+    /* carve out space for bph */
+    if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) {
+        PERROR("%s: Failed to malloc bph buffer size", __func__);
+        goto error;
+    }
+
+    /* NB: struct ft_cxt root defined at top of file */
+    /* root = Tree() */
+    ft_begin(root, bph, BPH_SIZE);
+
+    /* you MUST set reservations BEFORE _starting_the_tree_ */
+
+    /* reserve some pages at the end of RMA */
+    val[0] = cpu_to_be64((u64) (rma_bytes - rma_reserve));
+    val[1] = cpu_to_be64((u64) rma_reserve);
+    ft_add_rsvmap(root, val[0], val[1]);
+
+    /* reserve space for initrd if needed */
+    if ( initrd_len > 0 )  {
+        val[0] = cpu_to_be64((u64) initrd_base);
+        val[1] = cpu_to_be64((u64) initrd_len);
+        ft_add_rsvmap(root, val[0], val[1]);
+    }
+
+    /* NB: ft_add_rsvmap() already terminates with a NULL reservation for us */
+
+    /* done with reservations, _starting_the_tree_ */
+    ft_begin_tree(root);
+
+    /* make root node */
+    ft_begin_node(root, "");
+
+    /* root.addprop('device_type', 'chrp-but-not-really\0') */
+    ft_prop_str(root, "device_type", "chrp-but-not-really");
+
+    /* root.addprop('#size-cells', 2) */
+    ft_prop_int(root, "#size-cells", 2);
+
+    /* root.addprop('#address-cells', 2) */
+    ft_prop_int(root, "#address-cells", 2);
+
+    /* root.addprop('model', 'Momentum,Maple-D\0') */
+    ft_prop_str(root, "model", "Momentum,Maple-D");
+
+    /* root.addprop('compatible', 'Momentum,Maple\0') */
+    ft_prop_str(root, "compatible", "Momentum,Maple");
+
+    /* start chosen node */
+    ft_begin_node(root, "chosen");
+
+    /* chosen.addprop('cpu', cpu0.get_phandle()) */
+    ft_prop_int(root, "cpu", cpu0_phandle);
+
+    /* chosen.addprop('rma', rma.get_phandle()) */
+    ft_prop_int(root, "memory", rma_phandle);
+
+    /* chosen.addprop('linux,stdout-path', '/xen/console\0') */
+    ft_prop_str(root, "linux,stdout-path", "/xen/console");
+
+    /* chosen.addprop('interrupt-controller, xen.get_phandle()) */
+    ft_prop_int(root, "interrupt-controller", xen_phandle);
+
+    /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */
+    if ( bootargs != NULL )
+        ft_prop_str(root, "bootargs", bootargs);
+
+    /* mark where the initrd is, if present */
+    if ( initrd_len > 0 ) {
+        val[0] = cpu_to_be64((u64) initrd_base);
+        val[1] = cpu_to_be64((u64) initrd_end);
+        ft_prop(root, "linux,initrd-start", &(val[0]), sizeof(val[0]));
+        ft_prop(root, "linux,initrd-end", &(val[1]), sizeof(val[1]));
+    }
+
+    /* end chosen node */
+    ft_end_node(root);
+
+    /* xen = root.addnode('xen') */
+    ft_begin_node(root, "xen");
+
+    /* start-info is the first page in the RMA reserved area */
+    val[0] = cpu_to_be64((u64) (rma_bytes - rma_reserve));
+    val[1] = cpu_to_be64((u64) PAGE_SIZE);
+    ft_prop(root, "start-info", val, sizeof(val));
+
+    /*  xen.addprop('version', 'Xen-3.0-unstable\0') */
+    ft_prop_str(root, "version", "Xen-3.0-unstable");
+
+    /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */
+    val[0] = cpu_to_be64((u64) domid);
+    val[1] = cpu_to_be64((u64) 0);
+    ft_prop(root, "reg", val, sizeof(val));
+
+    /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */
+    /* libxc doesn't know the domain name, that is purely a xend thing */
+    /* ft_prop_str(root, "domain-name", domain_name); */
+
+    /* add xen/linux,phandle for chosen/interrupt-controller */
+    ft_prop_int(root, "linux,phandle", xen_phandle);
+
+    /* xencons = xen.addnode('console') */
+    ft_begin_node(root, "console");
+
+    /* xencons.addprop('interrupts', 1, 0) */
+    val32[0] = cpu_to_be32((u32) 1);
+    val32[1] = cpu_to_be32((u32) 0);
+    ft_prop(root, "interrupts", val32, sizeof(val32));
+
+    /* end of console */
+    ft_end_node(root);
+
+    /* end of xen node */
+    ft_end_node(root);
+
+    /* rma = root.addnode('[EMAIL PROTECTED]') */
+    ft_begin_node(root, "[EMAIL PROTECTED]");
+
+    /* rma.addprop('reg', long(0), long(rma_bytes)) */
+    val[0] = cpu_to_be64((u64) 0);
+    val[1] = cpu_to_be64((u64) rma_bytes);
+    ft_prop(root, "reg", val, sizeof(val));
+
+    /* rma.addprop('device_type', 'memory\0') */
+    ft_prop_str(root, "device_type", "memory");
+
+    /* add linux,phandle for chosen/rma node */
+    ft_prop_int(root, "linux,phandle", rma_phandle);
+
+    /* end of [EMAIL PROTECTED] */
+    ft_end_node(root);
+
+    /* calculate remaining bytes from total - rma size */
+    remaining = (mem_mb * 1024 * 1024) - rma_bytes;
+
+    /* memory@<rma_bytes> is all remaining memory after RMA */
+    if (remaining > 0)
+    {
+        char mem[MAX_PATH];
+        
+        if (snprintf(mem, sizeof(mem), "[EMAIL PROTECTED]",
+                     rma_bytes) >= sizeof(mem)) {
+            PERROR("%s: failed to build memory string", __func__);
+            goto error;
+        }
+
+        /* memory@<rma_bytes> is all remaining memory after RMA */
+        ft_begin_node(root, mem);
+
+        /* mem.addprop('reg', long(rma_bytes), long(remaining)) */
+        val[0] = cpu_to_be64((u64) rma_bytes);
+        val[1] = cpu_to_be64((u64) remaining);
+        ft_prop(root, "reg", val, sizeof(val));
+
+        /* mem.addprop('device_type', 'memory\0') */
+        ft_prop_str(root, "device_type", "memory");
+
+        /* end memory@<rma_bytes> node */
+        ft_end_node(root);
+    }
+
+    /* add CPU nodes */
+    /* cpus = root.addnode('cpus') */
+    ft_begin_node(root, "cpus");
+
+    /* cpus.addprop('smp-enabled') */
+    ft_prop(root, "smp-enabled", NULL, 0);
+
+    /* cpus.addprop('#size-cells', 0) */
+    ft_prop_int(root, "#size-cells", 0);
+
+    /* cpus.addprop('#address-cells', 1) */
+    ft_prop_int(root, "#address-cells", 1);
+
+    /*
+     * Copy all properties the system firmware gave us from a 
+     * CPU node in the device tree.
+     */
+    if (find_cpu0(cpupath, sizeof(cpupath)) <= 0) {
+        PERROR("%s: failed find cpu0 node in host devtree", __func__);
+        goto error;
+    }
+
+    /* get the basename from path to cpu device */
+    if ((cpupath_copy = strdup(cpupath)) == NULL) {
+        PERROR("%s: failed to dupe string", __func__);
+        goto error;
+    }
+    if ((cpuname = basename(cpupath_copy)) == NULL) {
+        PERROR("%s: basename() failed", __func__);
+        goto error;
+    }
+     
+    /* start node for the cpu */
+    ft_begin_node(root, cpuname);
+
+    /* strdup() mallocs memory */
+    if ( cpupath_copy != NULL ) {
+        free(cpupath_copy);
+        cpupath_copy = NULL;
+    }
+
+    /* copy over most properties from host tree for cpu */
+    if (copynode(root, cpupath, propfilter) < 0) {
+        PERROR("%s: failed to copy node", __func__);
+            goto error;
+    }
+
+    /* calculate the pft-size */
+    shadow_mb_log = (int)log2((double)shadow_mb);
+    pft_size = shadow_mb_log + 20;
+
+    val32[0] = cpu_to_be32((u32) 0);
+    val32[1] = cpu_to_be32((u32) pft_size);
+    ft_prop(root, "ibm,pft-size", val32, sizeof(val32));
+
+    /* make phandle for cpu0 */
+    ft_prop_int(root, "linux,phandle", cpu0_phandle);
+
+    /* end <cpuname> node */
+    ft_end_node(root);
+
+    /* end cpus node */
+    ft_end_node(root);
+
+    /* end root node */
+    ft_end_node(root);
+
+    /* end of the tree */
+    if (ft_end_tree(root) != 0) {
+        PERROR("%s: failed to end tree", __func__);
+        goto error;
+    }
+
+    /* write a copy of the tree to a file */
+    if ((dtb_fd = open(DTB_FILE , O_RDWR)) == -1) {
+        PERROR("%s: failed to open file %s", __func__, DTB_FILE);
+        goto error;
+    }
+
+    if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) {
+        PERROR("%s: failed to write blob to file", __func__);
+        goto error; 
+    }
+
+    return 0;
+ 
+error:
+    saved_errno = errno;
+
+    /* strdup() mallocs memory */
+    if ( cpupath_copy != NULL ) {
+        free(cpupath_copy);
+        cpupath_copy = NULL;
+    }
+
+    /* free bph buffer */
+    free_devtree(root);
+
+    if (dtb_fd)
+        close(dtb_fd);
+
+    errno = saved_errno;
+    return -1;
+}
diff -r 5568efb41da4 -r a01ef2a2051e tools/libxc/powerpc64/mk_flatdevtree.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.h    Tue Jan 16 16:55:54 2007 -0600
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Ryan Harper <[EMAIL PROTECTED]>
+ */
+
+#ifndef MK_FLATDEVTREE_H
+#define MK_FLATDEVTREE_H
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+
+extern void free_devtree(struct ft_cxt *root);
+extern int make_devtree(struct ft_cxt *root,
+                        uint32_t domid, 
+                        uint32_t mem_mb,
+                        unsigned long rma_bytes,
+                        unsigned long shadow_mb,
+                        unsigned long initrd_base,
+                        unsigned long initrd_len,
+                        const char *bootargs);
+
+#define MAX_PATH 200
+#define BUFSIZE 1024
+#define BPH_SIZE 16*1024
+#define DTB_FILE "/tmp/domU.dtb"
+
+#endif /* MK_FLATDEVTREE_H */

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to