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
|