WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

Re: [XenPPC] [PATCH 3 of 4] [PATCH] Move flat device tree construction f

To: Ryan Harper <ryanh@xxxxxxxxxx>
Subject: Re: [XenPPC] [PATCH 3 of 4] [PATCH] Move flat device tree construction from python to libxc for xc_linux_build()
From: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
Date: Thu, 11 Jan 2007 17:52:47 -0500
Cc: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Thu, 11 Jan 2007 14:52:38 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <e4fda6c5e7a907b5e472.1168544525@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
References: <e4fda6c5e7a907b5e472.1168544525@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx

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

<Prev in Thread] Current Thread [Next in Thread>