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: Mon, 15 Jan 2007 15:52:51 -0500
Cc: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Mon, 15 Jan 2007 12:52:30 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070115185132.GC24048@xxxxxxxxxx>
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> <6B483F52-F1A3-40E2-8525-4B917B884474@xxxxxxxxxxxxxx> <20070115185132.GC24048@xxxxxxxxxx>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx

On Jan 15, 2007, at 1:51 PM, Ryan Harper wrote:

* Jimi Xenidis <jimix@xxxxxxxxxxxxxx> [2007-01-11 16:53]:

Ok there are a few things here.

BTW: some of these issues existed in the original python, but they are yours now :)

Respun with fixes:

- preserve and return errno where approriate
- using open/close and read/write instead of f*
- dropped vcpu argument, only fill out one cpu in devtree
- dropped regexp requirment, use a null-terminated list of filters
- made sure to call closedir()
- fixed double-free of bph on error path
- fixed static function names
- renamed find_first_cpu to find_cpu, we don't care which cpu we find

I believe you _must_ use the the entry that has a reg property of 0.



--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
ryanh@xxxxxxxxxx

diffstat output:
b/tools/libxc/powerpc64/mk_flatdevtree.c | 567 +++++++++++++++++++ ++++++++++++
 b/tools/libxc/powerpc64/mk_flatdevtree.h |   44 ++
 tools/libxc/powerpc64/Makefile           |    1
 tools/libxc/powerpc64/xc_linux_build.c   |   30 +
 tools/libxc/xenguest.h                   |    4
 tools/python/xen/lowlevel/xc/xc.c        |   12
 tools/python/xen/xend/image.py           |    5
 7 files changed, 646 insertions(+), 17 deletions(-)

Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>
---
[PATCH] Move flat device tree construction from python to libxc for xc_linux_build().

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

diff -r 3edbfb956864 tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Fri Jan 12 15:16:42 2007 -0600
+++ b/tools/libxc/powerpc64/Makefile    Fri Jan 12 15:16:42 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 3edbfb956864 tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/libxc/powerpc64/xc_linux_build.c Fri Jan 12 16:00:33 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 <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,34 @@ 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;
+    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);
+
+    /* 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, shadow_mb, cmdline) < 0) {
+        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 +337,7 @@ int xc_linux_build(int xc_handle,
     }

 out:
+    free_devtree(&root);
     free_page_array(page_array);
     return rc;
 }
diff -r 3edbfb956864 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Fri Jan 12 15:16:42 2007 -0600
+++ b/tools/libxc/xenguest.h    Fri Jan 12 17:08:40 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 3edbfb956864 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Jan 12 15:16:42 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Jan 12 17:08:40 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 3edbfb956864 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Jan 12 15:16:42 2007 -0600
+++ b/tools/python/xen/xend/image.py    Fri Jan 12 17:08:40 2007 -0600
@@ -234,8 +234,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,
@@ -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 3edbfb956864 tools/libxc/powerpc64/mk_flatdevtree.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.c Sun Jan 14 13:28:16 2007 -0600
@@ -0,0 +1,567 @@
+/*
+ * 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 <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 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, MIN(len, st.st_size));
My brain fart, the MIN() is not necessary. you want to read no-more than your buffer allows, so just use len and forget about st.st_size. This assumes that you are not interested in the case where len yields a partial read, are you?

+
+    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;
+
+    if ((property == NULL) || (filter == NULL) || (*filter == NULL))
+        return -1;
This will get interpreted as a "match" bye its users, I would not even bother checking.
SEGVs are good! :)

+
+    for (i=0; filter[i] != NULL; i++) {
+ /* compare the filter to property, ignoring NULL terminator */
+        if (strncmp(property, filter[i], sizeof(filter[i])-1) == 0)

This function has no clue what the contents of "filter" is so you cannot use sizeof().
Assuming sizeof() worked, it is your intention to match the substring?

+            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)
+{

This is totally informational, but I think the blob/fnmatch routines may make this code way simpler.

+    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) <= 0) {
snprintf will almost never return -1, what you are really interested in is if the result does not fit in the buffer, so the test would be:
  >= sizeof(fullpath).
To "be complete" you should also check against "!=-1" which means that the strlen() of the result would be to bit for an int (hard to do that, but possible) :)

+            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_cpu(char *cpupath, int len)
+{
+    const char path[] = "/proc/device-tree/cpus";
+    const char device[] = "device_type";
+    const char dev_cpu[] = "cpu";
+    char data[sizeof(dev_cpu)];
+    char cpu[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) <= 0) {
+            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(cpu, sizeof(cpu), "%s/%s", node, device) <= 0) {
+                PERROR("%s: failed to concat strings", __func__);
+                goto error;
+            }
+
+            /* read device_type into buffer */
+            if ((readfile(cpu, data, sizeof(data))) < 0) {
+ PERROR("%s: failed to read data from file %s", __func__, cpu);
+                goto error;
+            }
+
+ /* if the device_type is 'cpu', return the path where we found it */
+            if (strcmp(data, "cpu") == 0) {
+                if (snprintf(cpupath, len, "%s", node) <= 0) {
+                    PERROR("%s: failed to copy cpupath", __func__);
+                    goto error;
+                }
+                found = 1;
+            }
+        }
+    }
+
+    closedir(dir);
+    return 0;
+
+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 shadow_mb,
+    const char *bootargs)
+{
+    struct boot_param_header *bph = NULL;
+    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;
+    char cpupath[MAX_PATH];
+    const char *propfilter[] = { "ibm", "linux,", NULL };
+    char *cpupath_copy = NULL;
+    char *cpuname = NULL;
+    int saved_errno;
+    int dtb_fd = -1;
+    int rma_log;
+
+    /* 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_ */
+
Any ideas what this reservation is for? is it for the flat-devtree itself?
+    /* 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]);
+

this value is keyed off of rma_bytes
+    /* 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);
+
+    /* 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);

Instead of defining a static set of phandles, can you have a function that hands out a counted value, sorta like:
  cpu0_phandle = new_handle();

that way we don;t have to associate a numerical value to each, especially new ones.


+
+    /* 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");

the 0x3ffc00 value is offset from rma_bytes
+
+    /* 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') */
+ /* 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; /* 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)
+    {

this really should be "memory@<rma_bytes>"

+        /* mem = root.addnode('memory@1') */
+        ft_begin_node(root, "memory@1");
+
+        /* 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@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 from a
+     * CPU node in the device tree.
+     */
+    if (find_cpu(cpupath, sizeof(cpupath)) < 0) {
+ PERROR("%s: failed find a cpu device 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", PHANDLE_CPU0);
+
+    /* 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 3edbfb956864 tools/libxc/powerpc64/mk_flatdevtree.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.h Fri Jan 12 16:01:06 2007 -0600
@@ -0,0 +1,44 @@
+/*
+ * 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 ft_cxt *root);
+extern int make_devtree(struct ft_cxt *root,
+                        uint32_t domid,
+                        uint32_t mem_mb,
+                        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 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

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