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
|