[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [XenPPC] [PATCH 3 of 4] [PATCH] Move flat device tree construction from python to libxc for xc_linux_build()




Ok there are a few things here.

On Jan 11, 2007, at 1:42 PM, Ryan Harper wrote:

7 files changed, 617 insertions(+), 17 deletions(-)
tools/libxc/powerpc64/Makefile         |    1
tools/libxc/powerpc64/mk_flatdevtree.c | 520 ++++++++++++++++++++++ ++++++++++
tools/libxc/powerpc64/mk_flatdevtree.h |   48 ++
tools/libxc/powerpc64/xc_linux_build.c |   44 ++
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 <ryanh@xxxxxxxxxx>
# Date 1168544367 21600
# Node ID e4fda6c5e7a907b5e4726c4f4d5f117c0f4d6f50
# Parent  0279229b68453a4a1b3613ac02c8b8ca9a965875
[PATCH] Move flat device tree construction from python to libxc for xc_linux_build().

Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>

diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Thu Jan 11 13:39:27 2007 -0600
+++ b/tools/libxc/powerpc64/Makefile    Thu Jan 11 13:39:27 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 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ xc_linux_build.c --- a/tools/libxc/powerpc64/xc_linux_build.c Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/libxc/powerpc64/xc_linux_build.c Thu Jan 11 13:39:27 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
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Ryan Harper <ryanh@xxxxxxxxxx>
  */

 #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)
@@ -238,8 +240,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,12 +252,48 @@ 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 rc = 0;
+    int op;
+    uint32_t nr_vcpus;
+    xc_dominfo_t info;
+    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);
+
+    /* XXX: fetch the number of vcpus configured for this domain
+       checking that xc_domain_getinfo returns info for exactly 1
+       dom */

Hmm, you are doing this, what is the "XXX" for?

+    if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
+ DPRINTF("xc_domain_getinfo() failed, can't determine max_vcpu_id\n");
+        rc = -1;
+        goto out;
+    }
+
+    /* NB: max_vcpu_id is zero-based */
+    nr_vcpus = info.max_vcpu_id + 1;

Not sure what you are actually doing here, we boot all domains UP and hotplug the rest, so the devtree will never have more than one CPU node.


+
+    /* XXX: fetch the current shadow_memory value for this domain */
Again, why the "XXX"? are you Vin Diesel or Ice Cube?!

+    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, nr_vcpus, shadow_mb, cmdline) < 0) {

I'd expect make_devtree() to only take one argument and use separate ft_* calls to fill in the rest of these params.

+        DPRINTF("failed to create flattened device tree\n");
+        rc = -1;
+        goto out;
+    }
+
+    /* point devtree at bph blob */
+    devtree = root.bph;

     rma_pages = get_rma_pages(devtree);
     if (rma_pages == 0) {
@@ -314,6 +351,7 @@ int xc_linux_build(int xc_handle,
     }

 out:
+    free_devtree(root.bph);
     free_page_array(page_array);
     return rc;
 }
diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Thu Jan 11 13:39:27 2007 -0600
+++ b/tools/libxc/xenguest.h    Thu Jan 11 13:39:27 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 0279229b6845 -r e4fda6c5e7a9 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Jan 11 13:39:27 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Jan 11 13:39:27 2007 -0600
@@ -338,28 +338,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 ) {
         if (!errno)
              errno = EINVAL;
         return PyErr_SetFromErrno(xc_error);
diff -r 0279229b6845 -r e4fda6c5e7a9 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Jan 11 13:39:27 2007 -0600
+++ b/tools/python/xen/xend/image.py    Thu Jan 11 13:39:27 2007 -0600
@@ -234,8 +234,6 @@ class PPC_LinuxImageHandler(LinuxImageHa

this patch should make the PPC_LinuxImageHandler class should just go away.

         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,
@@ -243,8 +241,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 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ mk_flatdevtree.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.c Thu Jan 11 13:39:27 2007 -0600

Would I be correct in thinking that this file is trying to bind flatdevtree support routines to libc? if so, maybe this should be libc_flatdevtree.c or flatdevtree_libc.c?

@@ -0,0 +1,520 @@
+/*
+ * 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 <ryanh@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <inttypes.h>
+#include <math.h>
+#include <regex.h>
+
+#include <xc_private.h> /* for DPRINTF */
+
+#include "mk_flatdevtree.h"
+
+static int _readfile(const char *fullpath, void *data, int len)
this function static the _ prefix is not necessary (and technically the system's namespace), if you want a prefix then make it more meaningful.

+{
+    struct stat st;
+    size_t rv;
+    FILE *f;

Why fopen(3) rather than open(2) since you are reading 1 byte at a time?

+    int bytes = 0;
+    int rc = -1;
+
+    if ((f = fopen(fullpath, "r")) == NULL) {
+        DPRINTF("failed to open %s", fullpath);
+        goto out;
+    }
+

OMG, PLEASE no goto's return something meaningful also. I could _maybe_ see the "goto close", but the "goto out" is insulting.

+    if (stat(fullpath, &st) < 0) {
+        DPRINTF("failed to stat %s", fullpath);
+        goto close;
+    }
Perhaps you should stat first so you can bail out early if !S_ISREG() below. or even better how about instead of stat() use fstat(fileno(f), &st), since you have the file open anyway.

+
+    if (st.st_size > len) {
+ DPRINTF("file to be read(%s) exceeds buffer len (%d)\n", fullpath, len);
+        goto close;
+    }
+    rv = (int)st.st_size;

hmm, do you really need the cast?
hmm2, you do not use rv for anything.

+    if (S_ISREG(st.st_mode)) {
just to be clear, you are not allowing symlinks, this is fine, I'm just checking.

+        while(1) {
+            /* bail if buffer is full */
+            if (bytes >= len)
+                break;
+
+            /* read a byte at a time */
+            rv = fread((void *)data+bytes, 1, 1, f);
+
+            /* break when fread doesn't return any data */
+            if ( rv == 0 )
+                break;
+
+            rc = ++bytes;
+        }
hmm, why is this not just rc = read(fd, data, MIN(len, st.st_size));

+    }
+
+close:
+    fclose(f);
+out:
+    return rc;
+}
+
+static int _copynode(struct ft_cxt *cxt, const char *dirpath, const char *propfilter)
This is a scary bad function, not sure what it does, but looks awfully complex.
A lot of other comment apply here.

+{
+    struct dirent *tree;
+    struct stat st;
+    DIR *dir;
+    char fullpath[MAX_PATH];
+    char *bname = NULL;
+    char *basec = NULL;
+    regex_t compre;
+    int rc = -1;
+
+    if (regcomp(&compre, propfilter, REG_EXTENDED) != 0) {
+        DPRINTF("failed to compile regexp %s\n", propfilter);
+        goto out;
+    }
+
+    if ((dir = opendir(dirpath)) == NULL) {
+        DPRINTF("failed to open dir %s", dirpath);
+        goto out;
+    }
+
+    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, MAX_PATH, "%s/%s", dirpath, tree- >d_name) <= 0) {
Fix these everywhere
s/MAX_PATH/sizeof(fullpath)/

+ DPRINTF("failed to concat %s to %s", fullpath, tree- >d_name);
+            goto out;
+        }
+
+        /* stat the entry */
+        if (stat(fullpath, &st) < 0) {
+            DPRINTF("failed to stat %s\n", fullpath);
+            goto out;
+        }
+
+        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) {
+ DPRINTF("failed to copy node %s, with filter %s \n", fullpath,
+                        propfilter);
+                goto out;
+            }
+
+            /* 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) {
+                DPRINTF("failed to strdup() %s\n", fullpath);
+                goto out;
+            }
+
+            if ((bname = basename(basec)) == NULL) {
+                DPRINTF("failed to basename() %s\n", basec);
+                goto out;
+            }
+
+ /* only add files that don't match the property filter string */
+            if (regexec(&compre, bname, 0, NULL, 0) != 0) {
+                char data[BUFSIZE];
+                int len;
+
+                /* snarf the data and push into the property */
+                if ((len = _readfile(fullpath, data, BUFSIZE)) < 0) {
+ DPRINTF("failed to read data from file %s\n", fullpath);
+                    goto out;
+                }
+                ft_prop(cxt, tree->d_name, data, len);
+            }
+        }
+    }
+
+    rc = 0;
+
+out:
+    /* strdup mallocs memory */
+    if (basec != NULL )
+        free(basec);
+
+ /* FIXME: do I need to free compre before doing another regcomp? */
+    regfree(&compre);
+    return rc;
+}
+
+static int _find_first_cpu(const char *dirpath, char *cpupath)
+{
+    char path[MAX_PATH];
+    struct dirent *tree;
+    struct stat st;
+    DIR* dir;
+    int found = 0;
+    int rc = -1;
+
+ if (snprintf(path, MAX_PATH, "%s/%s", HOST_PROC_DEVTREE, "cpus") <= 0) {
+        DPRINTF("failed to build cpu path\n");
+        goto out;
+    }
+
+    if ((dir = opendir(path)) == NULL) {
+        DPRINTF("failed to open dir %s", path);
+        goto out;
+    }
+
+    while (!found) {
+        char node[MAX_PATH];
+
+        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, MAX_PATH, "%s/%s", path, tree->d_name) <= 0) {
+            DPRINTF("failed to concat %s to %s", path, tree->d_name);
+            goto out;
+        }
+
+        /* stat the entry */
+        if (stat(node, &st) < 0) {
+            DPRINTF("failed to stat %s\n", node);
+            goto out;
Should you not continue here? It just means someone removed the file on you.

+        }
+
+        /* for each dir, check the device_type until we find a cpu*/
+        if (S_ISDIR(st.st_mode)) {
+            char cpu[MAX_PATH];
+            char data[BUFSIZE];
+            int len;
+
+ if (snprintf(cpu, MAX_PATH, "%s/%s", node, "device_type") <= 0) { + DPRINTF("failed to concat %s to %s", node,"device_type");
+                goto out;
+            }
+
+            if ((len = _readfile(cpu, data, BUFSIZE)) < 0) {
s/BUFSIZE/sizeof(data)/

+                DPRINTF("failed to read data from file %s\n", cpu);
+                goto out;
+            }
+
+            if (data && ((strncmp(data, "cpu", 3) == 0))) {
How could (data == NULL)?
you should be comparing the whole word "cpu" not just looking for strings that start with cpu.
In fact you could
  const char dev_cpu[] = "cpu";
  char data[sizeof(dev_cpu)];
and save some stack space.

If you are looking for _any_ CPU node then you are ok, if you are looking for the first then you must look for the CPU node that has a "reg" property of 0.

+                if (snprintf(cpupath, MAX_PATH, "%s", node) <= 0) {
+                    DPRINTF("failed to copy cpupath\n");
+                    goto out;
+                }
+                found = 1;
+            }
+        }
+    }
+    rc = 0;
+out:
+    return rc;
+}
+
+void free_devtree(struct boot_param_header *bph)
+{
+    if (bph != NULL) {
+        free(bph);
+        bph = NULL;
+    }
+}
+
+int make_devtree(
+    struct ft_cxt *root,
+    uint32_t domid, uint32_t mem_mb,
+    uint32_t vcpus,
+    unsigned long shadow_mb,
+    const char *bootargs)
+{
+    struct boot_param_header *bph;
+    uint64_t val[2];
+    uint32_t val32[2];
+    uint64_t totalmem;
+    uint64_t rma_bytes;
+    uint64_t remaining;
+    uint64_t pft_size;
+    int64_t shadow_mb_log;
+    int i;
+    int cpu0;
+    int rma_log;
+    int rc = -1;
+    char cpu0path[MAX_PATH];
+    FILE *dtb_fh = NULL;
+
+    /* carve out space for bph */
+ if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) {
+        DPRINTF("Failed to malloc bph buffer size %d\n", BPH_SIZE);
+        goto fail;
+    }
+
+    /* NB: struct ft_cxt root defined at top of file */
+    /* root = Tree() */
+    ft_begin(root, bph, BPH_SIZE);
+
+ /* XXX:NB: you MUST set reservations BEFORE _starting_the_tree_ */
+
+    /* root.reserve(0x1000000, 0x1000) */
+    val[0] = cpu_to_be64((u64) 0x1000000);
+    val[1] = cpu_to_be64((u64) 0x1000);
+    ft_add_rsvmap(root, val[0], val[1]);
+
+    /* root.reserve(0x3ffc000, 0x4000 */
+    val[0] = cpu_to_be64((u64) 0x3ffc000);
+    val[1] = cpu_to_be64((u64) 0x4000);
+    ft_add_rsvmap(root, val[0], val[1]);
+
+    /* done with reservations, _starting_the_tree_ */
+    ft_begin_tree(root);
+
+    /* FIXME: not sure if we need to 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", PHANDLE_CPU0);
+
+    /* chosen.addprop('rma', rma.get_phandle()) */
+    ft_prop_int(root, "memory", PHANDLE_RMA);
+
+    /* 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", PHANDLE_XEN);
+
+    /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */
+    if ( bootargs != NULL )
+        ft_prop_str(root, "bootargs", bootargs);
+
+    /* xc_linux_load.c will overwrite these 64-bit properties later
+    *
+    * chosen.addprop('linux,initrd-start', long(0))
+    * chosen.addprop('linux,initrd-end', long(0)))
+    */
+    val[0] = cpu_to_be64((u64) 0);
+    ft_prop(root, "linux,initrd-start", val, sizeof(val[0]));
+    ft_prop(root, "linux,initrd-end", val, sizeof(val[0]));
+
+    /* end chosen node */
+    ft_end_node(root);
+
+    /* xen = root.addnode('xen') */
+    ft_begin_node(root, "xen");
+
+    /* xen.addprop('start-info', long(0x3ffc000), long(0x1000)) */
+    val[0] = cpu_to_be64((u64) 0x3ffc000);
+    val[1] = cpu_to_be64((u64) 0x1000);
+    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') */
+ /* XXX: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", PHANDLE_XEN);
+
+    /* 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);
+
+    /* add memory nodes */
+    totalmem = mem_mb * 1024 * 1024;
+    rma_log = 26; /* XXX: usually a parameter */
+    rma_bytes = 1 << rma_log;
+    remaining = totalmem - rma_bytes;
+
+    /* rma = root.addnode('memory@0') */
+    ft_begin_node(root, "memory@0");
+
+    /* 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", PHANDLE_RMA);
+
+    /* end of memory@0 */
+    ft_end_node(root);
+
+    /* memory@1 is all the rest */
+    if (remaining > 0)
+    {
+        /* mem = root.addnode('memory@1') */
+        ft_begin_node(root, "memory@1");
+
+        /* mem.addprop('reg', long(rma_bytes), long(remaining)) */
+        /* FIXME: should long(rma_bytes) be 0 ? */
+        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@1 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, except for 'linux,' + * properties, from the first CPU node in the device tree. Do this once for
+    * every vcpu. Hopefully all cpus are identical...
+    */
+    cpu0 = -1;
+    if (_find_first_cpu(HOST_PROC_DEVTREE, cpu0path) < 0) {
+        DPRINTF("failed find first cpu in host devtree\n");
+        goto fail;
+    }
+
+    for (i=0; i < vcpus; i++) {
+        char cpuname[32];
+
+        if (snprintf(cpuname, 32, "%s%u", CPU_PREFIX, i) <= 0) {
+            DPRINTF("failed to concat %s to %u", CPU_PREFIX, i);
+            goto fail;
+        }
+
+        ft_begin_node(root, cpuname);
+        if (_copynode(root, cpu0path, NOLINUXPROPS) < 0) {
+            DPRINTF("failed to copynode @ path %s\n", cpu0path);
+            goto fail;
+        }
+
+        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));
+
+        if (cpu0 == -1) {
+            cpu0 = i;
+            /* make phandle for cpu0 */
+            ft_prop_int(root, "linux,phandle", PHANDLE_CPU0);
+        }
+        /* xen CPUx 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) {
+        DPRINTF("failed to end tree\n");
+        goto fail;
+    }
+
+    /* write a copy of the tree to a file */
+    if ((dtb_fh = fopen(DTB_FILE , "w")) == NULL) {
+        DPRINTF("failed to open %s", DTB_FILE);
+        goto fail;
+    }
+
+    if (fwrite((const void *)bph, 1, bph->totalsize, dtb_fh) <= 0) {
+        DPRINTF("failed to write blob to file\n");
+        goto fail;
+    }
+
+    rc = 0;
+    goto out;
+
+fail:
+    free_devtree(bph);
+out:
+    if (dtb_fh != NULL)
+        fclose(dtb_fh);
+    return rc;
+}
diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ mk_flatdevtree.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.h Thu Jan 11 13:39:27 2007 -0600
@@ -0,0 +1,48 @@
+/*
+ * 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 <ryanh@xxxxxxxxxx>
+ */
+
+#ifndef MK_FLATDEVTREE_H
+#define MK_FLATDEVTREE_H
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+
+extern void free_devtree(struct boot_param_header *bph);
+extern int make_devtree(struct ft_cxt *root,
+                        uint32_t domid,
+                        uint32_t mem_mb,
+                        uint32_t vcpus,
+                        unsigned long shadow_mb,
+                        const char *bootargs);
+
+#define MAX_PATH 200
+#define BUFSIZE 1024
+#define BPH_SIZE 16*1024
+
+#define PHANDLE_CPU0  1
+#define PHANDLE_RMA   2
+#define PHANDLE_XEN   3
+
+#define HOST_PROC_DEVTREE "/proc/device-tree"
+#define CPU_PREFIX "PowerPC,970@"
+#define NOLINUXPROPS "(^ibm)|(^linux,)"
+#define DTB_FILE "/tmp/domUoftree.out"
+
+#endif /* MK_FLATDEVTREE_H */

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


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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.