[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XenPPC] [PATCH 3 of 4] [PATCH] Move flat device tree construction from python to libxc for xc_linux_build()
Ok there are a few things here. On Jan 11, 2007, at 1:42 PM, Ryan Harper wrote: 7 files changed, 617 insertions(+), 17 deletions(-) tools/libxc/powerpc64/Makefile | 1tools/libxc/powerpc64/mk_flatdevtree.c | 520 ++++++++++++++++++++++ ++++++++++tools/libxc/powerpc64/mk_flatdevtree.h | 48 ++ tools/libxc/powerpc64/xc_linux_build.c | 44 ++ tools/libxc/xenguest.h | 4 tools/python/xen/lowlevel/xc/xc.c | 12 tools/python/xen/xend/image.py | 5 # HG changeset patch # User Ryan Harper <ryanh@xxxxxxxxxx> # Date 1168544367 21600 # Node ID e4fda6c5e7a907b5e4726c4f4d5f117c0f4d6f50 # Parent 0279229b68453a4a1b3613ac02c8b8ca9a965875[PATCH] Move flat device tree construction from python to libxc for xc_linux_build().Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx> diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/Makefile --- a/tools/libxc/powerpc64/Makefile Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/libxc/powerpc64/Makefile Thu Jan 11 13:39:27 2007 -0600 @@ -1,4 +1,5 @@ GUEST_SRCS-y += powerpc64/flatdevtree.c GUEST_SRCS-y += powerpc64/flatdevtree.c +GUEST_SRCS-y += powerpc64/mk_flatdevtree.c GUEST_SRCS-y += powerpc64/xc_linux_build.c GUEST_SRCS-y += powerpc64/xc_prose_build.c GUEST_SRCS-y += powerpc64/utils.cdiff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ xc_linux_build.c --- a/tools/libxc/powerpc64/xc_linux_build.c Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/libxc/powerpc64/xc_linux_build.c Thu Jan 11 13:39:27 2007 -0600@@ -13,9 +13,10 @@ * along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.* - * Copyright (C) IBM Corporation 2006 + * Copyright IBM Corporation 2006 * * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> + * Ryan Harper <ryanh@xxxxxxxxxx> */ #include <stdio.h> @@ -36,6 +37,7 @@ #include "flatdevtree_env.h" #include "flatdevtree.h" #include "utils.h" +#include "mk_flatdevtree.h" #define INITRD_ADDR (24UL << 20) #define DEVTREE_ADDR (16UL << 20) @@ -238,8 +240,7 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn, - void *devtree) + unsigned long *console_mfn) { start_info_t start_info; struct domain_setup_info dsi; @@ -251,12 +252,48 @@ int xc_linux_build(int xc_handle, unsigned long initrd_len = 0; unsigned long start_info_addr; unsigned long rma_pages; + unsigned long shadow_mb; int rc = 0; + int op; + uint32_t nr_vcpus; + xc_dominfo_t info; + struct ft_cxt root; + void *devtree; DPRINTF("%s\n", __func__); nr_pages = mem_mb << (20 - PAGE_SHIFT); DPRINTF("nr_pages 0x%lx\n", nr_pages); + + /* XXX: fetch the number of vcpus configured for this domain + checking that xc_domain_getinfo returns info for exactly 1 + dom */ Hmm, you are doing this, what is the "XXX" for? + if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {+ DPRINTF("xc_domain_getinfo() failed, can't determine max_vcpu_id\n");+ rc = -1; + goto out; + } + + /* NB: max_vcpu_id is zero-based */ + nr_vcpus = info.max_vcpu_id + 1; Not sure what you are actually doing here, we boot all domains UP and hotplug the rest, so the devtree will never have more than one CPU node. + + /* XXX: fetch the current shadow_memory value for this domain */ Again, why the "XXX"? are you Vin Diesel or Ice Cube?! + op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;+ if (xc_shadow_control(xc_handle, domid, op, NULL, 0, &shadow_mb, 0, NULL) < 0 ) {+ rc = -1; + goto out; + } + + /* build the devtree here */ + DPRINTF("constructing devtree\n");+ if (make_devtree(&root, domid, mem_mb, nr_vcpus, shadow_mb, cmdline) < 0) { I'd expect make_devtree() to only take one argument and use separate ft_* calls to fill in the rest of these params. + DPRINTF("failed to create flattened device tree\n"); + rc = -1; + goto out; + } + + /* point devtree at bph blob */ + devtree = root.bph; rma_pages = get_rma_pages(devtree); if (rma_pages == 0) { @@ -314,6 +351,7 @@ int xc_linux_build(int xc_handle, } out: + free_devtree(root.bph); free_page_array(page_array); return rc; } diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/libxc/xenguest.h Thu Jan 11 13:39:27 2007 -0600 @@ -57,7 +57,6 @@ int xc_linux_restore(int xc_handle, int * @parm store_mfn returned with the mfn of the store page* @parm console_evtchn the console event channel for this domain to use* @parm console_mfn returned with the mfn of the console page - * @parm arch_args architecture-specific data * @return 0 on success, -1 on failure */ int xc_linux_build(int xc_handle, @@ -71,8 +70,7 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn, - void *arch_args); + unsigned long *console_mfn); /** * This function will create a domain for a paravirtualized Linux diff -r 0279229b6845 -r e4fda6c5e7a9 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Jan 11 13:39:27 2007 -0600 @@ -338,28 +338,26 @@ static PyObject *pyxc_linux_build(XcObje unsigned int mem_mb; unsigned long store_mfn = 0; unsigned long console_mfn = 0; - void *arch_args = NULL; int unused; static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "console_evtchn", "image", /* optional */ "ramdisk", "cmdline", "flags", - "features", "arch_args", NULL }; -- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssiss#", kwd_list,+ "features", NULL }; ++ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,&dom, &store_evtchn, &mem_mb, &console_evtchn, &image, /* optional */ &ramdisk, &cmdline, &flags,- &features, &arch_args, &unused) )+ &features, &unused) ) return NULL; if ( xc_linux_build(self->xc_handle, dom, mem_mb, image, ramdisk, cmdline, features, flags, store_evtchn, &store_mfn, - console_evtchn, &console_mfn, - arch_args) != 0 ) { + console_evtchn, &console_mfn) != 0 ) { if (!errno) errno = EINVAL; return PyErr_SetFromErrno(xc_error); diff -r 0279229b6845 -r e4fda6c5e7a9 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Thu Jan 11 13:39:27 2007 -0600 +++ b/tools/python/xen/xend/image.py Thu Jan 11 13:39:27 2007 -0600 @@ -234,8 +234,6 @@ class PPC_LinuxImageHandler(LinuxImageHa this patch should make the PPC_LinuxImageHandler class should just go away. log.debug("vcpus = %d", self.vm.getVCpuCount()) log.debug("features = %s", self.vm.getFeatures()) - devtree = FlatDeviceTree.build(self) - return xc.linux_build(domid = self.vm.getDomid(), memsize = mem_mb, image = self.kernel, @@ -243,8 +241,7 @@ class PPC_LinuxImageHandler(LinuxImageHa console_evtchn = console_evtchn, cmdline = self.cmdline, ramdisk = self.ramdisk, - features = self.vm.getFeatures(), - arch_args = devtree.to_bin()) + features = self.vm.getFeatures()) def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): """@param shadow_mem_kb The configured shadow memory, in KiB.diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ mk_flatdevtree.c--- /dev/null Thu Jan 01 00:00:00 1970 +0000+++ b/tools/libxc/powerpc64/mk_flatdevtree.c Thu Jan 11 13:39:27 2007 -0600 Would I be correct in thinking that this file is trying to bind flatdevtree support routines to libc? if so, maybe this should be libc_flatdevtree.c or flatdevtree_libc.c? this function static the _ prefix is not necessary (and technically the system's namespace), if you want a prefix then make it more meaningful.@@ -0,0 +1,520 @@ +/*+ * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+ * + * Copyright IBM Corporation 2007 + * + * Authors: Ryan Harper <ryanh@xxxxxxxxxx> + */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <fcntl.h> +#include <dirent.h> +#include <unistd.h> +#include <libgen.h> +#include <inttypes.h> +#include <math.h> +#include <regex.h> + +#include <xc_private.h> /* for DPRINTF */ + +#include "mk_flatdevtree.h" + +static int _readfile(const char *fullpath, void *data, int len) +{ + struct stat st; + size_t rv; + FILE *f; Why fopen(3) rather than open(2) since you are reading 1 byte at a time? + int bytes = 0; + int rc = -1; + + if ((f = fopen(fullpath, "r")) == NULL) { + DPRINTF("failed to open %s", fullpath); + goto out; + } + OMG, PLEASE no goto's return something meaningful also. I could _maybe_ see the "goto close", but the "goto out" is insulting. Perhaps you should stat first so you can bail out early if !S_ISREG() below. or even better how about instead of stat() use fstat(fileno(f), &st), since you have the file open anyway.+ if (stat(fullpath, &st) < 0) { + DPRINTF("failed to stat %s", fullpath); + goto close; + } + + if (st.st_size > len) {+ DPRINTF("file to be read(%s) exceeds buffer len (%d)\n", fullpath, len);+ goto close; + } + rv = (int)st.st_size; hmm, do you really need the cast? hmm2, you do not use rv for anything. just to be clear, you are not allowing symlinks, this is fine, I'm just checking.+ if (S_ISREG(st.st_mode)) { + while(1) { + /* bail if buffer is full */ + if (bytes >= len) + break; + + /* read a byte at a time */ + rv = fread((void *)data+bytes, 1, 1, f); + + /* break when fread doesn't return any data */ + if ( rv == 0 ) + break; + + rc = ++bytes; + } hmm, why is this not just rc = read(fd, data, MIN(len, st.st_size)); This is a scary bad function, not sure what it does, but looks awfully complex.+ } + +close: + fclose(f); +out: + return rc; +} ++static int _copynode(struct ft_cxt *cxt, const char *dirpath, const char *propfilter) A lot of other comment apply here. +{ + struct dirent *tree; + struct stat st; + DIR *dir; + char fullpath[MAX_PATH]; + char *bname = NULL; + char *basec = NULL; + regex_t compre; + int rc = -1; + + if (regcomp(&compre, propfilter, REG_EXTENDED) != 0) { + DPRINTF("failed to compile regexp %s\n", propfilter); + goto out; + } + + if ((dir = opendir(dirpath)) == NULL) { + DPRINTF("failed to open dir %s", dirpath); + goto out; + } + + while (1) { + if ((tree = readdir(dir)) == NULL) + break; /* reached end of directory entries */ + + /* ignore . and .. */+ if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree- >d_name,"..") == 0)+ continue; + + /* build full path name of the file, for stat() */+ if (snprintf(fullpath, MAX_PATH, "%s/%s", dirpath, tree- >d_name) <= 0) { Fix these everywhere s/MAX_PATH/sizeof(fullpath)/ + DPRINTF("failed to concat %s to %s", fullpath, tree- >d_name);Should you not continue here? It just means someone removed the file on you.+ goto out; + } + + /* stat the entry */ + if (stat(fullpath, &st) < 0) { + DPRINTF("failed to stat %s\n", fullpath); + goto out; + } + + if (S_ISDIR(st.st_mode)) { + /* start a new node for a dir */ + ft_begin_node(cxt, tree->d_name); + + /* copy everything in this dir */ + if (_copynode(cxt, fullpath, propfilter) < 0) {+ DPRINTF("failed to copy node %s, with filter %s \n", fullpath,+ propfilter); + goto out; + } + + /* end the node */ + ft_end_node(cxt); + } + /* add files in dir as properties */ + else if (S_ISREG(st.st_mode)) { + + if ((basec = strdup(fullpath)) == NULL) { + DPRINTF("failed to strdup() %s\n", fullpath); + goto out; + } + + if ((bname = basename(basec)) == NULL) { + DPRINTF("failed to basename() %s\n", basec); + goto out; + } ++ /* only add files that don't match the property filter string */+ if (regexec(&compre, bname, 0, NULL, 0) != 0) { + char data[BUFSIZE]; + int len; + + /* snarf the data and push into the property */ + if ((len = _readfile(fullpath, data, BUFSIZE)) < 0) {+ DPRINTF("failed to read data from file %s\n", fullpath);+ goto out; + } + ft_prop(cxt, tree->d_name, data, len); + } + } + } + + rc = 0; + +out: + /* strdup mallocs memory */ + if (basec != NULL ) + free(basec); ++ /* FIXME: do I need to free compre before doing another regcomp? */+ regfree(&compre); + return rc; +} + +static int _find_first_cpu(const char *dirpath, char *cpupath) +{ + char path[MAX_PATH]; + struct dirent *tree; + struct stat st; + DIR* dir; + int found = 0; + int rc = -1; ++ if (snprintf(path, MAX_PATH, "%s/%s", HOST_PROC_DEVTREE, "cpus") <= 0) {+ DPRINTF("failed to build cpu path\n"); + goto out; + } + + if ((dir = opendir(path)) == NULL) { + DPRINTF("failed to open dir %s", path); + goto out; + } + + while (!found) { + char node[MAX_PATH]; + + if ((tree = readdir(dir)) == NULL) + break; /* reached end of directory entries */ + + /* ignore ., .. */+ if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree- >d_name,"..") == 0)+ continue; + + /* build full path name of the file, for stat() */+ if (snprintf(node, MAX_PATH, "%s/%s", path, tree->d_name) <= 0) {+ DPRINTF("failed to concat %s to %s", path, tree->d_name); + goto out; + } + + /* stat the entry */ + if (stat(node, &st) < 0) { + DPRINTF("failed to stat %s\n", node); + goto out; + } + + /* for each dir, check the device_type until we find a cpu*/ + if (S_ISDIR(st.st_mode)) { + char cpu[MAX_PATH]; + char data[BUFSIZE]; + int len; ++ if (snprintf(cpu, MAX_PATH, "%s/%s", node, "device_type") <= 0) { + DPRINTF("failed to concat %s to %s", node,"device_type");+ goto out; + } + + if ((len = _readfile(cpu, data, BUFSIZE)) < 0) { s/BUFSIZE/sizeof(data)/ + DPRINTF("failed to read data from file %s\n", cpu); + goto out; + } + + if (data && ((strncmp(data, "cpu", 3) == 0))) { How could (data == NULL)?you should be comparing the whole word "cpu" not just looking for strings that start with cpu. In fact you could const char dev_cpu[] = "cpu"; char data[sizeof(dev_cpu)]; and save some stack space.If you are looking for _any_ CPU node then you are ok, if you are looking for the first then you must look for the CPU node that has a "reg" property of 0. + if (snprintf(cpupath, MAX_PATH, "%s", node) <= 0) { + DPRINTF("failed to copy cpupath\n"); + goto out; + } + found = 1; + } + } + } + rc = 0; +out: + return rc; +} + +void free_devtree(struct boot_param_header *bph) +{ + if (bph != NULL) { + free(bph); + bph = NULL; + } +} + +int make_devtree( + struct ft_cxt *root, + uint32_t domid, uint32_t mem_mb, + uint32_t vcpus, + unsigned long shadow_mb, + const char *bootargs) +{ + struct boot_param_header *bph; + uint64_t val[2]; + uint32_t val32[2]; + uint64_t totalmem; + uint64_t rma_bytes; + uint64_t remaining; + uint64_t pft_size; + int64_t shadow_mb_log; + int i; + int cpu0; + int rma_log; + int rc = -1; + char cpu0path[MAX_PATH]; + FILE *dtb_fh = NULL; + + /* carve out space for bph */+ if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) {+ DPRINTF("Failed to malloc bph buffer size %d\n", BPH_SIZE); + goto fail; + } + + /* NB: struct ft_cxt root defined at top of file */ + /* root = Tree() */ + ft_begin(root, bph, BPH_SIZE); ++ /* XXX:NB: you MUST set reservations BEFORE _starting_the_tree_ */+ + /* root.reserve(0x1000000, 0x1000) */ + val[0] = cpu_to_be64((u64) 0x1000000); + val[1] = cpu_to_be64((u64) 0x1000); + ft_add_rsvmap(root, val[0], val[1]); + + /* root.reserve(0x3ffc000, 0x4000 */ + val[0] = cpu_to_be64((u64) 0x3ffc000); + val[1] = cpu_to_be64((u64) 0x4000); + ft_add_rsvmap(root, val[0], val[1]); + + /* done with reservations, _starting_the_tree_ */ + ft_begin_tree(root); + + /* FIXME: not sure if we need to make root node */ + ft_begin_node(root, ""); + + /* root.addprop('device_type', 'chrp-but-not-really\0') */ + ft_prop_str(root, "device_type", "chrp-but-not-really"); + + /* root.addprop('#size-cells', 2) */ + ft_prop_int(root, "#size-cells", 2); + + /* root.addprop('#address-cells', 2) */ + ft_prop_int(root, "#address-cells", 2); + + /* root.addprop('model', 'Momentum,Maple-D\0') */ + ft_prop_str(root, "model", "Momentum,Maple-D"); + + /* root.addprop('compatible', 'Momentum,Maple\0') */ + ft_prop_str(root, "compatible", "Momentum,Maple"); + + /* start chosen node */ + ft_begin_node(root, "chosen"); + + /* chosen.addprop('cpu', cpu0.get_phandle()) */ + ft_prop_int(root, "cpu", PHANDLE_CPU0); + + /* chosen.addprop('rma', rma.get_phandle()) */ + ft_prop_int(root, "memory", PHANDLE_RMA); + + /* chosen.addprop('linux,stdout-path', '/xen/console\0') */ + ft_prop_str(root, "linux,stdout-path", "/xen/console"); + + /* chosen.addprop('interrupt-controller, xen.get_phandle()) */ + ft_prop_int(root, "interrupt-controller", PHANDLE_XEN); + + /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */ + if ( bootargs != NULL ) + ft_prop_str(root, "bootargs", bootargs); + + /* xc_linux_load.c will overwrite these 64-bit properties later + * + * chosen.addprop('linux,initrd-start', long(0)) + * chosen.addprop('linux,initrd-end', long(0))) + */ + val[0] = cpu_to_be64((u64) 0); + ft_prop(root, "linux,initrd-start", val, sizeof(val[0])); + ft_prop(root, "linux,initrd-end", val, sizeof(val[0])); + + /* end chosen node */ + ft_end_node(root); + + /* xen = root.addnode('xen') */ + ft_begin_node(root, "xen"); + + /* xen.addprop('start-info', long(0x3ffc000), long(0x1000)) */ + val[0] = cpu_to_be64((u64) 0x3ffc000); + val[1] = cpu_to_be64((u64) 0x1000); + ft_prop(root, "start-info", val, sizeof(val)); + + /* xen.addprop('version', 'Xen-3.0-unstable\0') */ + ft_prop_str(root, "version", "Xen-3.0-unstable"); + + /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */ + val[0] = cpu_to_be64((u64) domid); + val[1] = cpu_to_be64((u64) 0); + ft_prop(root, "reg", val, sizeof(val)); + + /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */+ /* XXX:libxc doesn't know the domain name, that is purely a xend thing */+ /* ft_prop_str(root, "domain-name", domain_name); */ + + /* add xen/linux,phandle for chosen/interrupt-controller */ + ft_prop_int(root, "linux,phandle", PHANDLE_XEN); + + /* xencons = xen.addnode('console') */ + ft_begin_node(root, "console"); + + /* xencons.addprop('interrupts', 1, 0) */ + val32[0] = cpu_to_be32((u32) 1); + val32[1] = cpu_to_be32((u32) 0); + ft_prop(root, "interrupts", val32, sizeof(val32)); + + /* end of console */ + ft_end_node(root); + + /* end of xen node */ + ft_end_node(root); + + /* add memory nodes */ + totalmem = mem_mb * 1024 * 1024; + rma_log = 26; /* XXX: usually a parameter */ + rma_bytes = 1 << rma_log; + remaining = totalmem - rma_bytes; + + /* rma = root.addnode('memory@0') */ + ft_begin_node(root, "memory@0"); + + /* rma.addprop('reg', long(0), long(rma_bytes)) */ + val[0] = cpu_to_be64((u64) 0); + val[1] = cpu_to_be64((u64) rma_bytes); + ft_prop(root, "reg", val, sizeof(val)); + + /* rma.addprop('device_type', 'memory\0') */ + ft_prop_str(root, "device_type", "memory"); + + /* add linux,phandle for chosen/rma node */ + ft_prop_int(root, "linux,phandle", PHANDLE_RMA); + + /* end of memory@0 */ + ft_end_node(root); + + /* memory@1 is all the rest */ + if (remaining > 0) + { + /* mem = root.addnode('memory@1') */ + ft_begin_node(root, "memory@1"); + + /* mem.addprop('reg', long(rma_bytes), long(remaining)) */ + /* FIXME: should long(rma_bytes) be 0 ? */ + val[0] = cpu_to_be64((u64) rma_bytes); + val[1] = cpu_to_be64((u64) remaining); + ft_prop(root, "reg", val, sizeof(val)); + + /* mem.addprop('device_type', 'memory\0') */ + ft_prop_str(root, "device_type", "memory"); + + /* end memory@1 node */ + ft_end_node(root); + } + + /* add CPU nodes */ + /* cpus = root.addnode('cpus') */ + ft_begin_node(root, "cpus"); + + /* cpus.addprop('smp-enabled') */ + ft_prop(root, "smp-enabled", NULL, 0); + + /* cpus.addprop('#size-cells', 0) */ + ft_prop_int(root, "#size-cells", 0); + + /* cpus.addprop('#address-cells', 1) */ + ft_prop_int(root, "#address-cells", 1); + + /*+ * Copy all properties the system firmware gave us, except for 'linux,' + * properties, from the first CPU node in the device tree. Do this once for+ * every vcpu. Hopefully all cpus are identical... + */ + cpu0 = -1; + if (_find_first_cpu(HOST_PROC_DEVTREE, cpu0path) < 0) { + DPRINTF("failed find first cpu in host devtree\n"); + goto fail; + } + + for (i=0; i < vcpus; i++) { + char cpuname[32]; + + if (snprintf(cpuname, 32, "%s%u", CPU_PREFIX, i) <= 0) { + DPRINTF("failed to concat %s to %u", CPU_PREFIX, i); + goto fail; + } + + ft_begin_node(root, cpuname); + if (_copynode(root, cpu0path, NOLINUXPROPS) < 0) { + DPRINTF("failed to copynode @ path %s\n", cpu0path); + goto fail; + } + + shadow_mb_log = (int)log2((double)shadow_mb); + pft_size = shadow_mb_log + 20; + + val32[0] = cpu_to_be32((u32) 0); + val32[1] = cpu_to_be32((u32) pft_size); + ft_prop(root, "ibm,pft-size", val32, sizeof(val32)); + + if (cpu0 == -1) { + cpu0 = i; + /* make phandle for cpu0 */ + ft_prop_int(root, "linux,phandle", PHANDLE_CPU0); + } + /* xen CPUx node */ + ft_end_node(root); + } + + /* end cpus node */ + ft_end_node(root); + + /* end root node */ + ft_end_node(root); + + /* end of the tree */ + if (ft_end_tree(root) != 0) { + DPRINTF("failed to end tree\n"); + goto fail; + } + + /* write a copy of the tree to a file */ + if ((dtb_fh = fopen(DTB_FILE , "w")) == NULL) { + DPRINTF("failed to open %s", DTB_FILE); + goto fail; + } + + if (fwrite((const void *)bph, 1, bph->totalsize, dtb_fh) <= 0) { + DPRINTF("failed to write blob to file\n"); + goto fail; + } + + rc = 0; + goto out; + +fail: + free_devtree(bph); +out: + if (dtb_fh != NULL) + fclose(dtb_fh); + return rc; +}diff -r 0279229b6845 -r e4fda6c5e7a9 tools/libxc/powerpc64/ mk_flatdevtree.h--- /dev/null Thu Jan 01 00:00:00 1970 +0000+++ b/tools/libxc/powerpc64/mk_flatdevtree.h Thu Jan 11 13:39:27 2007 -0600@@ -0,0 +1,48 @@ +/*+ * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+ * + * Copyright IBM Corporation 2007 + * + * Authors: Ryan Harper <ryanh@xxxxxxxxxx> + */ + +#ifndef MK_FLATDEVTREE_H +#define MK_FLATDEVTREE_H + +#include "flatdevtree_env.h" +#include "flatdevtree.h" + +extern void free_devtree(struct boot_param_header *bph); +extern int make_devtree(struct ft_cxt *root, + uint32_t domid, + uint32_t mem_mb, + uint32_t vcpus, + unsigned long shadow_mb, + const char *bootargs); + +#define MAX_PATH 200 +#define BUFSIZE 1024 +#define BPH_SIZE 16*1024 + +#define PHANDLE_CPU0 1 +#define PHANDLE_RMA 2 +#define PHANDLE_XEN 3 + +#define HOST_PROC_DEVTREE "/proc/device-tree" +#define CPU_PREFIX "PowerPC,970@" +#define NOLINUXPROPS "(^ibm)|(^linux,)" +#define DTB_FILE "/tmp/domUoftree.out" + +#endif /* MK_FLATDEVTREE_H */ _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |