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-devel

Re: [Xen-devel] Proposal for init/kexec/hotplug format for Xen

To: Anthony Liguori <aliguori@xxxxxxxxxx>
Subject: Re: [Xen-devel] Proposal for init/kexec/hotplug format for Xen
From: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Date: Mon, 28 Feb 2005 23:06:53 +1100
Cc: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>, Jeremy Katz <katzj@xxxxxxxxxx>, Xen Mailing List <xen-devel@xxxxxxxxxxxxxxxxxxxxx>
Delivery-date: Mon, 28 Feb 2005 12:09:48 +0000
Envelope-to: xen+James.Bulpin@xxxxxxxxxxxx
In-reply-to: <4221E676.5000008@xxxxxxxxxx>
List-archive: <http://sourceforge.net/mailarchive/forum.php?forum=xen-devel>
List-help: <mailto:xen-devel-request@lists.sourceforge.net?subject=help>
List-id: List for Xen developers <xen-devel.lists.sourceforge.net>
List-post: <mailto:xen-devel@lists.sourceforge.net>
List-subscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=subscribe>
List-unsubscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=unsubscribe>
References: <1109451460.32219.11.camel@xxxxxxxxxxxxxxxxxxxxx> <68d3daa4e95f4ba6740c6c0ffd3f67b8@xxxxxxxxxxxx> <4221E676.5000008@xxxxxxxxxx>
Sender: xen-devel-admin@xxxxxxxxxxxxxxxxxxxxx
On Sun, 2005-02-27 at 09:25 -0600, Anthony Liguori wrote:
> Keir Fraser wrote:
> > I like the idea of bringing out device discovery, bringup, teardown, 
> > recovery all into its own driver or subsystem -- it seems the obvious 
> > way to go. But I think the 'device tree' should be in the 
> > to-be-designed persistent store, and we publish an interface to allow 
> > guests to peek/poke that store.
> 
> I think publishing domain-information in an OF-like tree would be great.

I'm not convinced of the persistent store idea, at least for this.  I
think it's simpler to have it dropped into memory at boot (just like the
initrd image), and then later messages are sent which update it (ie.
hotlplug) which have a similar form.

The former is implemented, but breaks when I actually test it (you can
see that code #ifdef'ed out, debugging now).  I added simple routines so
that you can build a device tree and pass it to the domain builder.

Included below for your reading pleasure,
Rusty.
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c 
xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c
--- xen-unstable/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c   
2005-02-26 01:20:55.000000000 +1100
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c   
2005-02-28 09:27:36.000000000 +1100
@@ -1142,6 +1142,11 @@ static unsigned long __init setup_memory
        }
 #endif
 
+       /* We're going to keep pointers into this */
+       if (xen_start_info.devtree_len)
+               reserve_bootmem(xen_start_info.devtree_start,
+                               xen_start_info.devtree_len);
+
        phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
 
        return max_low_pfn;
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c 
xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c
--- xen-unstable/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c      
1970-01-01 10:00:00.000000000 +1000
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c      
2005-02-28 10:08:44.000000000 +1100
@@ -0,0 +1,148 @@
+/******************************************************************************
+ * Simple device tree unbundling and query interface.
+ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ *
+ * 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
+ */
+#include <asm-xen/devtree.h>
+
+LIST_HEAD(devtree_root);
+spinlock_t devtree_lock;
+
+/* Skip separator, return next path element. */
+static inline const char *path_element(const char *path, unsigned int *len)
+{
+       path += strspn(path, "/");
+       *len = strcspn(path, "/");
+       return path;
+}
+
+struct xen_devtree *devtree_get(const char *path)
+{
+       struct xen_devtree *i;
+       struct list_head *list = &devtree_root;
+       unsigned int pathlen;
+
+       assert_spin_locked(&devtree_lock);
+
+       path = path_element(path, &pathlen);
+next_level:
+       list_for_each_entry(i, list, siblings) {
+               /* Doesn't match?  Keep looking through names. */
+               if (strlen(i->name) != pathlen
+                   || memcmp(path, i->name, pathlen) != 0)
+                       continue;
+
+               path = path_element(path, &pathlen);
+               /* Finished iteration?  This is the element they want. */
+               if (pathlen == 0)
+                       return i;
+
+               list = &i->children;
+               goto next_level;
+       }
+       return NULL;
+}
+
+/* This is recursive, but used for debugging simple trees, so an OK hack. */
+static void dump_tree(struct list_head *list, int indent)
+{
+       struct xen_devtree *i;
+
+       list_for_each_entry(i, list, siblings) {
+               unsigned int j;
+               for (j = 0; j < indent; j++)
+                       printk(" ");
+               printk("- %s (%u)\n", i->name, i->length);
+               dump_tree(&i->children, indent+2);
+       }
+}
+
+#define DEVTREE_VERSION 1
+
+/* Initial routine to populate tree from flattened structure. */
+static void __init devtree_init(void)
+{
+       struct xen_devtree_header *head;
+       const struct xen_devtree_node *nodes;
+       const char *names;
+       void *data;
+       struct xen_devtree **dev_array;
+       unsigned int i, length;
+
+       BUG_ON(!list_empty(&devtree_root));
+
+       head = (void *)xen_start_info.devtree_start;
+       length = xen_start_info.devtree_len;
+
+       /* No device tree at all currently for domain 0. */
+       if (length == 0)
+               return;
+
+       if (head->last_comp_version > DEVTREE_VERSION)
+               panic("Incompatible Xen device tree version %i (%i)\n",
+                     head->version, head->last_comp_version);
+
+       /* Simple sanity checks. */
+       if (head->root_offset >= length
+           || head->root_offset + head->num_nodes * sizeof(*nodes) >= length
+           || head->name_offset >= length
+           || head->data_offset >= length)
+               panic("Xen device tree v%i %u/%u/%u/%u overflows %lu\n",
+                     head->version, head->root_offset, head->num_nodes,
+                     head->name_offset, head->data_offset,
+                     length);
+
+       nodes = (void *)head + head->root_offset;
+       names = (void *)head + head->name_offset;
+       data = (void *)head + head->data_offset;
+
+       /* Set up temporary node number to node mapping. */
+       dev_array = kmalloc(sizeof(*dev_array) * head->num_nodes, GFP_KERNEL);
+
+       /* Element 0 is simple a root node marker; ignore it. */
+       for (i = 1; i < head->num_nodes; i++) {
+               BUG_ON(nodes[i].parent >= i);
+
+               dev_array[i] = kmalloc(sizeof(*dev_array[i]), GFP_KERNEL);
+               dev_array[i]->name = names + nodes[i].name;
+               dev_array[i]->length = nodes[i].len;
+               dev_array[i]->data = data + nodes[i].data;
+               INIT_LIST_HEAD(&dev_array[i]->children);
+               /* Locking here is simple paranoia. */
+               spin_lock_irq(&devtree_lock);
+               if (nodes[i].parent == 0)
+                       list_add(&dev_array[i]->siblings, &devtree_root);
+               else
+                       list_add(&dev_array[i]->siblings,
+                                &dev_array[nodes[i].parent]->children);
+               spin_unlock_irq(&devtree_lock);
+       }
+       kfree(dev_array);
+
+       dump_tree(&devtree_root, 0);
+}
+
+core_initcall(devtree_init);
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h 
xen-unstable-devtree/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h
--- xen-unstable/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h      
1970-01-01 10:00:00.000000000 +1000
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h      
2005-02-28 10:05:46.000000000 +1100
@@ -0,0 +1,27 @@
+#ifndef __ASM_DEVTREE_H__
+#define __ASM_DEVTREE_H__
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+struct xen_devtree
+{
+       /* Siblings list */
+       struct list_head siblings;
+
+       /* Children */
+       struct list_head children;
+
+       const char *name;
+       u32 length;
+       void *data;
+};
+
+/* Root of the tree, and the big lock to protect all allocations. */
+extern struct list_head devtree_root;
+extern spinlock_t devtree_lock;
+
+/* Must be holding devtree_lock.  Returns NULL if no such entry. */
+struct xen_devtree *devtree_get(const char *path);
+#endif /* __ASM_DEVTREE_H__ */
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/Makefile xen-unstable-devtree/tools/libxc/Makefile
--- xen-unstable/tools/libxc/Makefile   2005-02-26 01:20:58.000000000 +1100
+++ xen-unstable-devtree/tools/libxc/Makefile   2005-02-28 04:59:05.000000000 
+1100
@@ -29,6 +29,7 @@ SRCS     += xc_misc.c
 SRCS     += xc_physdev.c
 SRCS     += xc_private.c
 SRCS     += xc_rrobin.c
+SRCS     += xc_devtree.c
 SRCS     += xc_vmx_build.c
 
 CFLAGS   += -Wall
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc.h xen-unstable-devtree/tools/libxc/xc.h
--- xen-unstable/tools/libxc/xc.h       2005-02-07 15:12:20.000000000 +1100
+++ xen-unstable-devtree/tools/libxc/xc.h       2005-02-28 07:07:35.000000000 
+1100
@@ -169,6 +169,30 @@ int xc_shadow_control(int xc_handle,
 
 struct XcIOContext;
 
+/*\
+ * Functions to handle device trees, which are fed into the image in a
+ * flattened form to describe their environment.  Device trees are
+ * trees of keyword value pairs, eg /cpu/1/foo = 1.
+\*/
+struct devtree;
+
+struct devtree *xc_devtree_root_alloc(void);
+
+#define xc_devtree_add(r, d, n, var) \
+       xc_devtree_add_bytes(r, d, n, &(var), sizeof(var), __alignof__(var))
+
+#define xc_devtree_add_string(r, d, n, string) \
+       xc_devtree_add_bytes(r, d, n, (string), strlen(string)+1, 1)
+
+struct devtree *xc_devtree_add_bytes(struct devtree *root,
+                                    const char *dirname,
+                                    const char *name,
+                                    void *data,
+                                    u32 length,
+                                    u32 align);
+
+void xc_devtree_free(struct devtree *root);
+
 /**
  * This function will save a domain running Linux to an IO context.  This
  * IO context is currently a private interface making this function difficult
@@ -198,7 +222,8 @@ int xc_linux_build(int xc_handle,
                    const char *cmdline,
                    unsigned int control_evtchn,
                    unsigned long flags,
-                   unsigned int vcpus);
+                   unsigned int vcpus,
+                   struct devtree *devtree);
 
 int
 xc_plan9_build (int xc_handle,
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_devtree.c 
xen-unstable-devtree/tools/libxc/xc_devtree.c
--- xen-unstable/tools/libxc/xc_devtree.c       1970-01-01 10:00:00.000000000 
+1000
+++ xen-unstable-devtree/tools/libxc/xc_devtree.c       2005-02-28 
10:09:32.000000000 +1100
@@ -0,0 +1,222 @@
+/*
+ * Code to set up the device tree for a partition.
+ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ *
+ * 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
+ */
+#include "xc_private.h"
+
+#define DEVTREE_VERSION 1
+#define DEVTREE_COMPAT_VERSION 1
+
+struct devtree
+{
+       struct devtree *sibling;
+       struct devtree *children;
+
+       u32 datalen;
+       u32 align;
+       void *data;
+
+       char name[0];
+};
+
+/* Skip separator, return next path element. */
+static inline const char *path_element(const char *path, unsigned int *len)
+{
+       path += strspn(path, "/");
+       *len = strcspn(path, "/");
+       return path;
+}
+
+/* Find this name (of this length) under the root. */
+static struct devtree *find(struct devtree *root,
+                           const char *name, unsigned int len)
+{
+       struct devtree *i;
+       for (i = root->children; i; i = i->sibling)
+               if (strlen(i->name) == len && memcmp(name, i->name, len) == 0)
+                       return i;
+       return NULL;
+}
+
+static struct devtree *xc_dt_new(const char *name, unsigned int namelen,
+                                void *data, unsigned int datalen,
+                                unsigned int align)
+{
+       struct devtree *dt = malloc(sizeof(*dt) + namelen + 1 + datalen);
+
+       if (!dt)
+               return NULL;
+
+       dt->children = NULL;
+       dt->sibling = NULL;
+
+       memcpy(dt->name, name, namelen);
+       dt->name[namelen] = '\0';
+
+       dt->datalen = datalen;
+       dt->align = align;
+       dt->data = dt->name + namelen + 1;
+       memcpy(dt->data, data, datalen);
+       return dt;
+}
+
+struct devtree *xc_devtree_root_alloc(void)
+{
+       return xc_dt_new(NULL, 0, NULL, 0, 1);
+}
+
+/* Find directory, make it if neccessary.  */
+static struct devtree *find_dir(struct devtree *root, const char *dirname)
+{
+       unsigned int dirlen;
+       struct devtree *subdir;
+
+       dirname = path_element(dirname, &dirlen);
+       if (dirlen == 0)
+               return root;
+
+       subdir = find(root, dirname, dirlen);
+       if (!subdir) {
+               subdir = xc_dt_new(dirname, dirlen, NULL, 0, 0);
+               if (!subdir)
+                       return NULL;
+               subdir->sibling = root->children;
+               root->children = subdir;
+       }
+       return find_dir(subdir, dirname + dirlen);
+}
+
+struct devtree *xc_devtree_add_bytes(struct devtree *root,
+                                    const char *dirname,
+                                    const char *name,
+                                    void *data,
+                                    u32 length,
+                                    u32 align)
+{
+       struct devtree *dir, *dt;
+
+       dir = find_dir(root, dirname);
+       if (!dir)
+               return NULL;
+
+       dt = xc_dt_new(name, strlen(name), data, length, align);
+       if (!dt)
+               return NULL;
+
+       dt->sibling = dir->children;
+       dir->children = dt;
+       return root;
+}
+
+void xc_devtree_free(struct devtree *root)
+{
+       struct devtree *i;
+
+       for (i = root->children; i; i = i->sibling)
+               xc_devtree_free(i);
+       free(root);
+}
+
+/* Assume alignment is a power of 2. */
+static inline u32 align_up(u32 val, u32 alignment)
+{
+       return (val + alignment-1) & ~(alignment-1);
+}
+
+static u32 calculate_sizes(struct devtree *root, u32 *namelen, u32 *datalen,
+                          u32 *maxalign)
+{
+       u32 nodes = 1;
+       struct devtree *i;
+
+       *namelen += strlen(root->name) + 1;
+       *datalen = align_up(*datalen, root->align) + root->datalen;
+
+       if (root->align > *maxalign)
+               *maxalign = root->align;
+
+       for (i = root->children; i; i = i->sibling)
+               nodes += calculate_sizes(i, namelen, datalen, maxalign);
+       return nodes;
+}
+
+/* FIXME: In future if trees get big, search for duplicate names. */
+static void copy_nodes(struct devtree *root, u32 parent_index,
+                      struct xen_devtree_node *nodes, u32 *nodeindex,
+                      char *names, u32 *nameindex,
+                      void *data, u32 *dataindex)
+{
+       struct devtree *i;
+
+       /* Copy myself in. */
+       nodes[*nodeindex].parent = parent_index;
+       strcpy(names + *nameindex, root->name);
+       nodes[*nodeindex].name = *nameindex;
+       *nameindex += strlen(root->name) + 1;
+       *dataindex = align_up(*dataindex, root->align);
+       memcpy(data + *dataindex, root->data, root->datalen);
+       nodes[*nodeindex].data = *dataindex;
+       *dataindex += root->datalen;
+       nodes[*nodeindex].len = root->datalen;
+
+       parent_index = (*nodeindex);
+       (*nodeindex)++;
+
+       /* Copy children in. */
+       for (i = root->children; i; i = i->sibling)
+               copy_nodes(i, parent_index, nodes, nodeindex,
+                          names, nameindex, data, dataindex);
+}
+
+struct xen_devtree_header *xc_devtree_flatten(struct devtree *root, u32 *len)
+{
+       u32 nodes, namelen, datalen, maxalign;
+       u32 nodeindex, nameindex, dataindex;
+       struct xen_devtree_header *hdr;
+
+       namelen = datalen = 0;
+       maxalign = 1;
+
+       /* Walk once to calculate lengths (and hence offsets). */
+       nodes = calculate_sizes(root, &namelen, &datalen, &maxalign);
+
+       *len = sizeof(*hdr) + nodes * sizeof(struct xen_devtree_node);
+       *len += namelen;
+       *len = align_up(*len, maxalign);
+       *len += datalen;
+
+       hdr = malloc(*len);
+       if (!hdr)
+               return NULL;
+
+       hdr->version = DEVTREE_VERSION;
+       hdr->last_comp_version = DEVTREE_COMPAT_VERSION;
+       hdr->root_offset = sizeof(*hdr);
+       hdr->num_nodes = nodes;
+       hdr->name_offset = hdr->root_offset
+               + nodes * sizeof(struct xen_devtree_node);
+       hdr->data_offset = align_up(hdr->name_offset + namelen, maxalign);
+
+       nodeindex = nameindex = dataindex = 0;
+       /* Walk a second time actually copying. */
+       copy_nodes(root, 0,
+                  (void *)hdr + hdr->root_offset, &nodeindex,
+                  (void *)hdr + hdr->name_offset, &nameindex,
+                  (void *)hdr + hdr->data_offset, &dataindex);
+       return hdr;
+}
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_linux_build.c 
xen-unstable-devtree/tools/libxc/xc_linux_build.c
--- xen-unstable/tools/libxc/xc_linux_build.c   2005-02-26 01:20:58.000000000 
+1100
+++ xen-unstable-devtree/tools/libxc/xc_linux_build.c   2005-02-28 
06:25:05.000000000 +1100
@@ -52,7 +52,8 @@ static int setup_guest(int xc_handle,
                          unsigned long shared_info_frame,
                          unsigned int control_evtchn,
                          unsigned long flags,
-                         unsigned int vcpus)
+                         unsigned int vcpus,
+                         void *flat_tree, unsigned long flat_size)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -72,6 +73,8 @@ static int setup_guest(int xc_handle,
     struct domain_setup_info dsi;
     unsigned long vinitrd_start;
     unsigned long vinitrd_end;
+    unsigned long vdevtree_start;
+    unsigned long vdevtree_end;
     unsigned long vphysmap_start;
     unsigned long vphysmap_end;
     unsigned long vstartinfo_start;
@@ -110,7 +113,9 @@ static int setup_guest(int xc_handle,
      */
     vinitrd_start    = round_pgup(dsi.v_end);
     vinitrd_end      = vinitrd_start + initrd_len;
-    vphysmap_start   = round_pgup(vinitrd_end);
+    vdevtree_start   = round_pgup(vinitrd_end);
+    vdevtree_end     = vdevtree_start + flat_size;
+    vphysmap_start   = round_pgup(vdevtree_end);
     vphysmap_end     = vphysmap_start + (nr_pages * sizeof(unsigned long));
     vpt_start        = round_pgup(vphysmap_end);
     for ( nr_pt_pages = 2; ; nr_pt_pages++ )
@@ -131,6 +136,7 @@ static int setup_guest(int xc_handle,
     printf("VIRTUAL MEMORY ARRANGEMENT:\n"
            " Loaded kernel: %08lx->%08lx\n"
            " Init. ramdisk: %08lx->%08lx\n"
+           " Device tree:   %08lx->%08lx\n"
            " Phys-Mach map: %08lx->%08lx\n"
            " Page tables:   %08lx->%08lx\n"
            " Start info:    %08lx->%08lx\n"
@@ -138,6 +144,7 @@ static int setup_guest(int xc_handle,
            " TOTAL:         %08lx->%08lx\n",
            dsi.v_kernstart, dsi.v_kernend, 
            vinitrd_start, vinitrd_end,
+           vdevtree_start, vdevtree_end,
            vphysmap_start, vphysmap_end,
            vpt_start, vpt_end,
            vstartinfo_start, vstartinfo_end,
@@ -187,6 +194,15 @@ static int setup_guest(int xc_handle,
         }
     }
 
+    /* Load the flattened device tree. */
+    for ( i = (vdevtree_start - dsi.v_start); 
+         i < (vdevtree_end - dsi.v_start); i += PAGE_SIZE )
+    {
+       xc_copy_to_domain_page(xc_handle, dom,
+                              page_array[i>>PAGE_SHIFT],
+                              flat_tree + i);
+    }
+
     if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
@@ -323,7 +339,8 @@ int xc_linux_build(int xc_handle,
                    const char *cmdline,
                    unsigned int control_evtchn,
                    unsigned long flags,
-                   unsigned int vcpus)
+                   unsigned int vcpus,
+                   struct devtree *devtree)
 {
     dom0_op_t launch_op, op;
     int initrd_fd = -1;
@@ -333,7 +350,9 @@ int xc_linux_build(int xc_handle,
     unsigned long nr_pages;
     char         *image = NULL;
     unsigned long image_size, initrd_size=0;
+    u32 flat_size = 0;
     unsigned long vstartinfo_start, vkern_entry;
+    struct xen_devtree_header *flat_tree = NULL;
 
     if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
     {
@@ -383,13 +402,22 @@ int xc_linux_build(int xc_handle,
         ERROR("Domain is already constructed");
         goto error_out;
     }
+    if ( devtree )
+    {
+       flat_tree = xc_devtree_flatten(devtree, &flat_size);
+       if ( !flat_tree ) {
+           ERROR("Out of memory flattening device tree");
+           goto error_out;
+       }
+    }
 
     if ( setup_guest(xc_handle, domid, image, image_size, 
                        initrd_gfd, initrd_size, nr_pages, 
                        &vstartinfo_start, &vkern_entry,
                        ctxt, cmdline,
                        op.u.getdomaininfo.shared_info_frame,
-                       control_evtchn, flags, vcpus) < 0 )
+                       control_evtchn, flags, vcpus,
+                       flat_tree, flat_size) < 0 )
     {
         ERROR("Error constructing guest OS");
         goto error_out;
@@ -401,6 +429,8 @@ int xc_linux_build(int xc_handle,
         gzclose(initrd_gfd);
     if ( image != NULL )
         free(image);
+    if ( flat_tree )
+       free(flat_tree);
 
     ctxt->flags = 0;
 
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_private.h 
xen-unstable-devtree/tools/libxc/xc_private.h
--- xen-unstable/tools/libxc/xc_private.h       2005-02-07 15:12:19.000000000 
+1100
+++ xen-unstable-devtree/tools/libxc/xc_private.h       2005-02-28 
07:08:07.000000000 +1100
@@ -202,4 +202,9 @@ void xc_map_memcpy(unsigned long dst, ch
                    int xch, u32 dom, unsigned long *parray,
                    unsigned long vstart);
 
+/* Returns a flattened structure: free() as normal. */
+struct xen_devtree_header;
+struct devtree;
+struct xen_devtree_header *xc_devtree_flatten(struct devtree *root, u32 *len);
+
 #endif /* __XC_PRIVATE_H__ */
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/python/xen/lowlevel/xc/xc.c 
xen-unstable-devtree/tools/python/xen/lowlevel/xc/xc.c
--- xen-unstable/tools/python/xen/lowlevel/xc/xc.c      2005-02-26 
01:20:59.000000000 +1100
+++ xen-unstable-devtree/tools/python/xen/lowlevel/xc/xc.c      2005-02-28 
10:18:30.000000000 +1100
@@ -349,19 +349,34 @@ static PyObject *pyxc_linux_build(PyObje
     u32   dom;
     char *image, *ramdisk = NULL, *cmdline = "";
     int   control_evtchn, flags = 0, vcpus = 1;
+    struct devtree *root = NULL;
 
     static char *kwd_list[] = { "dom", "control_evtchn", 
                                 "image", "ramdisk", "cmdline", "flags", 
"vcpus",
                                 NULL };
 
+#if 0
+    root = xc_devtree_root_alloc();
+    root = xc_devtree_add_string(root, "/", "test", "teststring");
+    {
+           int x = 7;
+           root = xc_devtree_add(root, "/dir/subdir", "seven", x);
+    }
+#endif
+
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssii", kwd_list, 
                                       &dom, &control_evtchn, 
                                       &image, &ramdisk, &cmdline, &flags, 
&vcpus) )
         return NULL;
 
+
     if ( xc_linux_build(xc->xc_handle, dom, image,
-                        ramdisk, cmdline, control_evtchn, flags, vcpus) != 0 )
+                        ramdisk, cmdline, control_evtchn, flags, vcpus, root) 
!= 0 )
         return PyErr_SetFromErrno(xc_error);
+
+#if 0
+    xc_devtree_free(root);
+#endif
     
     Py_INCREF(zero);
     return zero;
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/xen/include/public/xen.h 
xen-unstable-devtree/xen/include/public/xen.h
--- xen-unstable/xen/include/public/xen.h       2005-02-26 01:21:04.000000000 
+1100
+++ xen-unstable-devtree/xen/include/public/xen.h       2005-02-28 
04:50:02.000000000 +1100
@@ -428,8 +428,30 @@ typedef struct {
     _MEMORY_PADDING(F);
     memory_t mod_len;         /* 56: Size (bytes) of pre-loaded module.    */
     _MEMORY_PADDING(G);
-    u8 cmd_line[MAX_CMDLINE]; /* 64 */
-} PACKED start_info_t; /* 320 bytes */
+    memory_t devtree_start;   /* 64: VIRTUAL address of device tree. */
+    _MEMORY_PADDING(H);
+    memory_t devtree_len;     /* 72: Size (bytes) of device tree. */
+    _MEMORY_PADDING(I);
+    u8 cmd_line[MAX_CMDLINE]; /* 80 */
+} PACKED start_info_t; /* 336 bytes */
+
+/* Nodes are arranged so parent always preceeds us. */
+struct xen_devtree_node
+{
+    u32 parent;               /* Index of parent (root has parent 0 = self) */
+    u32 name;                 /* Offset of name in name table. */
+    u32 data, len;            /* Offset of data in data table, and length */
+};
+
+struct xen_devtree_header
+{
+    u32 version;              /* Version of this structure. */
+    u32 last_comp_version;    /* You must be >= this to read it. */
+    u32 root_offset;          /* Offset to root of tree. */
+    u32 num_nodes;            /* Total number of nodes in tree. */
+    u32 name_offset;          /* Offset to (nul-terminated) names table. */
+    u32 data_offset;          /* Offset to data table. */
+};
 
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-devel

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