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

[Xen-changelog] [xen-unstable] [LIBXC][POWERPC] Update to latest flatdev

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [LIBXC][POWERPC] Update to latest flatdevtree snapshot.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 Sep 2006 10:03:05 +0000
Delivery-date: Tue, 19 Sep 2006 03:03:54 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Node ID a22a7797e0ba0a9e65d1ad5039c559212597f74d
# Parent  2ebf55e419c917e66cbd5dae804dd05739e1f39e
[LIBXC][POWERPC] Update to latest flatdevtree snapshot.

Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 tools/libxc/powerpc64/Makefile          |    2 
 tools/libxc/powerpc64/flatdevtree.c     |  636 ++++++++++++++++++++++++++++++++
 tools/libxc/powerpc64/flatdevtree.h     |  106 +++++
 tools/libxc/powerpc64/flatdevtree_env.h |   94 ++++
 tools/libxc/powerpc64/xc_linux_build.c  |   90 ++--
 5 files changed, 882 insertions(+), 46 deletions(-)

diff -r 2ebf55e419c9 -r a22a7797e0ba tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Thu Sep 07 21:46:33 2006 -0400
+++ b/tools/libxc/powerpc64/Makefile    Thu Sep 07 17:25:52 2006 -0500
@@ -1,4 +1,4 @@ GUEST_SRCS-y += powerpc64/xc_linux_build
 GUEST_SRCS-y += powerpc64/xc_linux_build.c
-GUEST_SRCS-y += powerpc64/ft_build.c
+GUEST_SRCS-y += powerpc64/flatdevtree.c
 
 CTRL_SRCS-y += powerpc64/xc_memory.c
diff -r 2ebf55e419c9 -r a22a7797e0ba tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c    Thu Sep 07 21:46:33 2006 -0400
+++ b/tools/libxc/powerpc64/xc_linux_build.c    Thu Sep 07 17:25:52 2006 -0500
@@ -33,7 +33,8 @@
 #include <xg_private.h>
 #include <xenctrl.h>
 
-#include "ft_build.h"
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
 
 #define INITRD_ADDR (24UL << 20)
 #define DEVTREE_ADDR (16UL << 20)
@@ -164,64 +165,63 @@ static int load_devtree(
     xen_pfn_t *page_array,
     void *devtree,
     unsigned long devtree_addr,
-    unsigned long initrd_base,
+    uint64_t initrd_base,
     unsigned long initrd_len,
     start_info_t *si,
     unsigned long si_addr)
 {
     uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
     struct boot_param_header *header;
-    uint64_t *prop;
+    void *chosen;
+    void *xen;
+    uint64_t initrd_end = initrd_base + initrd_len;
     unsigned int devtree_size;
-    unsigned int proplen;
     int rc = 0;
+
+    DPRINTF("adding initrd props\n");
+
+    chosen = ft_find_node(devtree, "/chosen");
+    if (chosen == NULL) {
+        DPRINTF("couldn't find /chosen\n");
+        return -1;
+    }
+
+    xen = ft_find_node(devtree, "/xen");
+    if (xen == NULL) {
+        DPRINTF("couldn't find /xen\n");
+        return -1;
+    }
+
+    /* initrd-start */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
+            &initrd_base, sizeof(initrd_base));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
+        return rc;
+    }
+
+    /* initrd-end */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
+            &initrd_end, sizeof(initrd_end));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
+        return rc;
+    }
+
+    /* start-info (XXX being removed soon) */
+    rc = ft_set_prop(&devtree, xen, "start-info",
+            start_info, sizeof(start_info));
+    if (rc < 0) {
+        DPRINTF("couldn't set /xen/start-info\n");
+        return rc;
+    }
 
     header = devtree;
     devtree_size = header->totalsize;
 
-    DPRINTF("adding initrd props\n");
-
-       /* initrd-start */
-    prop = ft_get_prop(devtree, "/chosen/linux,initrd-start", &proplen);
-    if (prop == NULL) {
-        DPRINTF("couldn't find linux,initrd-start\n");
-        return -1;
-    }
-    if (proplen != sizeof(*prop)) {
-        DPRINTF("couldn't set linux,initrd-start (size %d)\n", proplen);
-        return -1;
-    }
-    *prop = initrd_base;
-
-       /* initrd-end */
-    prop = ft_get_prop(devtree, "/chosen/linux,initrd-end", &proplen);
-    if (prop == NULL) {
-        DPRINTF("couldn't find linux,initrd-end\n");
-        return -1;
-    }
-    if (proplen != sizeof(*prop)) {
-        DPRINTF("couldn't set linux,initrd-end (size %d)\n", proplen);
-        return -1;
-    }
-    *prop = initrd_base + initrd_len;
-
-       /* start-info (XXX being removed soon) */
-    prop = ft_get_prop(devtree, "/xen/start-info", &proplen);
-    if (prop == NULL) {
-        DPRINTF("couldn't find /xen/start-info\n");
-        return -1;
-    }
-    if (proplen != sizeof(start_info)) {
-        DPRINTF("couldn't set /xen/start-info (size %d)\n", proplen);
-        return -1;
-    }
-    memcpy(prop, start_info, proplen);
-
     DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
-    rc = install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
+    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
                        devtree_size);
-
-    return rc;
 }
 
 unsigned long spin_list[] = {
diff -r 2ebf55e419c9 -r a22a7797e0ba tools/libxc/powerpc64/flatdevtree.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/flatdevtree.c       Thu Sep 07 17:25:52 2006 -0500
@@ -0,0 +1,636 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright Pantelis Antoniou 2006
+ * Copyright (C) IBM Corporation 2006
+ * 2006 (c) MontaVista, Software, Inc.
+ *
+ * Authors: Pantelis Antoniou <pantelis@xxxxxxxxxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Mark A. Greer <mgreer@xxxxxxxxxx>
+ */
+
+#include "flatdevtree.h"
+
+/* Set ptrs to current one's info; return addr of next one */
+static u32 *ft_next(u32 *p, const u32 *p_strings, const u32 version,
+               u32 **tagpp, char **namepp, char **datapp, u32 **sizepp)
+{
+       u32 sz;
+
+       *namepp = NULL;
+       *datapp = NULL;
+       *sizepp = NULL;
+       *tagpp = p;
+
+       switch (be32_to_cpu(*p++)) { /* Tag */
+       case OF_DT_BEGIN_NODE:
+               *namepp = (char *)p;
+               p = (u32 *)_ALIGN((unsigned long)p + strlen((char *)p) + 1, 4);
+               break;
+       case OF_DT_PROP:
+               sz = be32_to_cpu(*p);
+               *sizepp = p++;
+               *namepp = (char *)p_strings + be32_to_cpu(*p++);
+               if ((version < 0x10) && (sz >= 8))
+                       p = (u32 *)_ALIGN((unsigned long)p, 8);
+               *datapp = (char *)p;
+               p = (u32 *)_ALIGN((unsigned long)p + sz, 4);
+               break;
+       case OF_DT_END_NODE:
+       case OF_DT_NOP:
+               break;
+       case OF_DT_END:
+       default:
+               p = NULL;
+               break;
+       }
+
+       return p;
+}
+
+static void ft_put_word(struct ft_cxt *cxt, u32 v)
+{
+       if (cxt->overflow)      /* do nothing */
+               return;
+
+       /* check for overflow */
+       if (cxt->p + 4 > cxt->pstr) {
+               cxt->overflow = 1;
+               return;
+       }
+
+       *(u32 *) cxt->p = cpu_to_be32(v);
+       cxt->p += 4;
+}
+
+static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
+{
+       char *p;
+
+       if (cxt->overflow)      /* do nothing */
+               return;
+
+       /* next pointer pos */
+       p = (char *) _ALIGN((unsigned long)cxt->p + sz, 4);
+
+       /* check for overflow */
+       if (p > cxt->pstr) {
+               cxt->overflow = 1;
+               return;
+       }
+
+       memcpy(cxt->p, data, sz);
+       if ((sz & 3) != 0)
+               memset(cxt->p + sz, 0, 4 - (sz & 3));
+       cxt->p = p;
+}
+
+void ft_begin_node(struct ft_cxt *cxt, const char *name)
+{
+       ft_put_word(cxt, OF_DT_BEGIN_NODE);
+       ft_put_bin(cxt, name, strlen(name) + 1);
+}
+
+void ft_end_node(struct ft_cxt *cxt)
+{
+       ft_put_word(cxt, OF_DT_END_NODE);
+}
+
+void ft_nop(struct ft_cxt *cxt)
+{
+       ft_put_word(cxt, OF_DT_NOP);
+}
+
+static int lookup_string(struct ft_cxt *cxt, const char *name)
+{
+       char *p;
+
+       p = cxt->pstr;
+       while (p < cxt->pstr_begin) {
+               if (strcmp(p, (char *)name) == 0)
+                       return p - cxt->p_begin;
+               p += strlen(p) + 1;
+       }
+
+       return -1;
+}
+
+void ft_prop(struct ft_cxt *cxt, const char *name,
+               const void *data, unsigned int sz)
+{
+       int len, off;
+
+       if (cxt->overflow)
+               return;
+
+       len = strlen(name) + 1;
+
+       off = lookup_string(cxt, name);
+       if (off == -1) {
+               /* check if we have space */
+               if (cxt->p + 12 + sz + len > cxt->pstr) {
+                       cxt->overflow = 1;
+                       return;
+               }
+
+               cxt->pstr -= len;
+               memcpy(cxt->pstr, name, len);
+               off = cxt->pstr - cxt->p_begin;
+       }
+
+       /* now put offset from beginning of *STRUCTURE* */
+       /* will be fixed up at the end */
+       ft_put_word(cxt, OF_DT_PROP);
+       ft_put_word(cxt, sz);
+       ft_put_word(cxt, off);
+       ft_put_bin(cxt, data, sz);
+}
+
+void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
+{
+       ft_prop(cxt, name, str, strlen(str) + 1);
+}
+
+void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
+{
+       u32 v = cpu_to_be32((u32) val);
+
+       ft_prop(cxt, name, &v, 4);
+}
+
+/* start construction of the flat OF tree */
+void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size)
+{
+       struct boot_param_header *bph = blob;
+       u32 off;
+
+       /* clear the cxt */
+       memset(cxt, 0, sizeof(*cxt));
+
+       cxt->bph = bph;
+       cxt->max_size = max_size;
+
+       /* zero everything in the header area */
+       memset(bph, 0, sizeof(*bph));
+
+       bph->magic = cpu_to_be32(OF_DT_HEADER);
+       bph->version = cpu_to_be32(0x10);
+       bph->last_comp_version = cpu_to_be32(0x10);
+
+       /* start pointers */
+       cxt->pres_begin = (char *) _ALIGN((unsigned long)(bph + 1), 8);
+       cxt->pres = cxt->pres_begin;
+
+       off = (unsigned long)cxt->pres_begin - (unsigned long)bph;
+       bph->off_mem_rsvmap = cpu_to_be32(off);
+
+       ((u64 *) cxt->pres)[0] = 0;     /* phys = 0, size = 0, terminate */
+       ((u64 *) cxt->pres)[1] = 0;
+
+       cxt->p_anchor = cxt->pres + 16; /* over the terminator */
+}
+
+/* add a reserver physical area to the rsvmap */
+void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
+{
+       ((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, 
terminate */
+       ((u64 *) cxt->pres)[1] = cpu_to_be64(size);
+
+       cxt->pres += 18;        /* advance */
+
+       ((u64 *) cxt->pres)[0] = 0;     /* phys = 0, size = 0, terminate */
+       ((u64 *) cxt->pres)[1] = 0;
+
+       /* keep track of size */
+       cxt->res_size = cxt->pres + 16 - cxt->pres_begin;
+
+       cxt->p_anchor = cxt->pres + 16; /* over the terminator */
+}
+
+void ft_begin_tree(struct ft_cxt *cxt)
+{
+       cxt->p_begin = cxt->p_anchor;
+       cxt->pstr_begin = (char *)cxt->bph + cxt->max_size;     /* point at the 
end */
+
+       cxt->p = cxt->p_begin;
+       cxt->pstr = cxt->pstr_begin;
+}
+
+int ft_end_tree(struct ft_cxt *cxt)
+{
+       struct boot_param_header *bph = cxt->bph;
+       int off, sz, sz1;
+       u32 tag, v;
+       char *p;
+
+       ft_put_word(cxt, OF_DT_END);
+
+       if (cxt->overflow)
+               return -ENOMEM;
+
+       /* size of the areas */
+       cxt->struct_size = cxt->p - cxt->p_begin;
+       cxt->strings_size = cxt->pstr_begin - cxt->pstr;
+
+       /* the offset we must move */
+       off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size;
+
+       /* the new strings start */
+       cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
+
+       /* move the whole string area */
+       memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size);
+
+       /* now perform the fixup of the strings */
+       p = cxt->p_begin;
+       while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) {
+               p += 4;
+
+               if (tag == OF_DT_BEGIN_NODE) {
+                       p = (char *) _ALIGN((unsigned long)p + strlen(p) + 1, 
4);
+                       continue;
+               }
+
+               if (tag == OF_DT_END_NODE || tag == OF_DT_NOP)
+                       continue;
+
+               if (tag != OF_DT_PROP)
+                       return -EINVAL;
+
+               sz = be32_to_cpu(*(u32 *) p);
+               p += 4;
+
+               v = be32_to_cpu(*(u32 *) p);
+               v -= off;
+               *(u32 *) p = cpu_to_be32(v);    /* move down */
+               p += 4;
+
+               p = (char *) _ALIGN((unsigned long)p + sz, 4);
+       }
+
+       /* fix sizes */
+       p = (char *)cxt->bph;
+       sz = (cxt->pstr_begin + cxt->strings_size) - p;
+       sz1 = _ALIGN(sz, 16);   /* align at 16 bytes */
+       if (sz != sz1)
+               memset(p + sz, 0, sz1 - sz);
+       bph->totalsize = cpu_to_be32(sz1);
+       bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p);
+       bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p);
+
+       /* the new strings start */
+       cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
+       cxt->pstr = cxt->pstr_begin + cxt->strings_size;
+
+       return 0;
+}
+
+/**********************************************************************/
+
+static inline int isprint(int c)
+{
+       return c >= 0x20 && c <= 0x7e;
+}
+
+static int is_printable_string(const void *data, int len)
+{
+       const char *s = data;
+       const char *ss;
+
+       /* zero length is not */
+       if (len == 0)
+               return 0;
+
+       /* must terminate with zero */
+       if (s[len - 1] != '\0')
+               return 0;
+
+       ss = s;
+       while (*s && isprint(*s))
+               s++;
+
+       /* not zero, or not done yet */
+       if (*s != '\0' || (s + 1 - ss) < len)
+               return 0;
+
+       return 1;
+}
+
+static void print_data(const void *data, int len)
+{
+       int i;
+       const char *s;
+
+       /* no data, don't print */
+       if (len == 0)
+               return;
+
+       if (is_printable_string(data, len)) {
+               printf(" = \"%s\"", (char *)data);
+               return;
+       }
+
+       switch (len) {
+       case 1:         /* byte */
+               printf(" = <0x%02x>", (*(char *) data) & 0xff);
+               break;
+       case 2:         /* half-word */
+               printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
+               break;
+       case 4:         /* word */
+               printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               break;
+       case 8:         /* double-word */
+               printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data));
+               break;
+       default:                /* anything else... hexdump */
+               printf(" = [");
+               for (i = 0, s = data; i < len; i++)
+                       printf("%02x%s", s[i], i < len - 1 ? " " : "");
+               printf("]");
+
+               break;
+       }
+}
+
+void ft_dump_blob(const void *bphp)
+{
+       const struct boot_param_header *bph = bphp;
+       const u64 *p_rsvmap = (const u64 *)
+               ((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
+       const u32 *p_struct = (const u32 *)
+               ((const char *)bph + be32_to_cpu(bph->off_dt_struct));
+       const u32 *p_strings = (const u32 *)
+               ((const char *)bph + be32_to_cpu(bph->off_dt_strings));
+       const u32 version = be32_to_cpu(bph->version);
+       u32 i, *p, *tagp, *sizep;
+       char *namep, *datap;
+       int depth, shift;
+       u64 addr, size;
+
+
+       if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
+               /* not valid tree */
+               return;
+       }
+
+       depth = 0;
+       shift = 4;
+
+       for (i = 0;; i++) {
+               addr = be64_to_cpu(p_rsvmap[i * 2]);
+               size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
+               if (addr == 0 && size == 0)
+                       break;
+
+               printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);
+       }
+
+       p = (u32 *)p_struct;
+       while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
+                                       &sizep)) != NULL)
+               switch (be32_to_cpu(*tagp)) {
+               case OF_DT_BEGIN_NODE:
+                       printf("%*s%s {\n", depth * shift, "", namep);
+                       depth++;
+                       break;
+               case OF_DT_END_NODE:
+                       depth--;
+                       printf("%*s};\n", depth * shift, "");
+                       break;
+               case OF_DT_NOP:
+                       printf("%*s[NOP]\n", depth * shift, "");
+                       break;
+               case OF_DT_END:
+                       break;
+               case OF_DT_PROP:
+                       printf("%*s%s", depth * shift, "", namep);
+                       print_data(datap, *sizep);
+                       printf(";\n");
+                       break;
+               default:
+                       fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",
+                               depth * shift, "", *tagp);
+                       return;
+               }
+}
+
+void ft_backtrack_node(struct ft_cxt *cxt)
+{
+       if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
+               return;         /* XXX only for node */
+
+       cxt->p -= 4;
+}
+
+/* note that the root node of the blob is "peeled" off */
+void ft_merge_blob(struct ft_cxt *cxt, void *blob)
+{
+       struct boot_param_header *bph = (struct boot_param_header *)blob;
+       u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
+       u32 *p_strings =
+               (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
+       const u32 version = be32_to_cpu(bph->version);
+       u32 *p, *tagp, *sizep;
+       char *namep, *datap;
+       int depth;
+
+       if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
+               return;         /* XXX only for node */
+
+       cxt->p -= 4;
+
+       depth = 0;
+       p = p_struct;
+       while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
+                                       &sizep)) != NULL)
+               switch (be32_to_cpu(*tagp)) {
+               case OF_DT_BEGIN_NODE:
+                       if (depth++ > 0)
+                               ft_begin_node(cxt, namep);
+                       break;
+               case OF_DT_END_NODE:
+                       ft_end_node(cxt);
+                       if (--depth == 0)
+                               return;
+                       break;
+               case OF_DT_PROP:
+                       ft_prop(cxt, namep, datap, *sizep);
+                       break;
+               }
+}
+
+/**********************************************************************/
+
+void *ft_find_node(const void *bphp, const char *srch_path)
+{
+       const struct boot_param_header *bph = bphp;
+       u32 *p_struct = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));
+       u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
+       u32 version = be32_to_cpu(bph->version);
+       u32 *p, *tagp, *sizep;
+       char *namep, *datap;
+       static char path[MAX_PATH_LEN];
+
+       path[0] = '\0';
+       p = p_struct;
+
+       while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
+                                       &sizep)) != NULL)
+               switch (be32_to_cpu(*tagp)) {
+               case OF_DT_BEGIN_NODE:
+                       strcat(path, namep);
+                       if (!strcmp(path, srch_path))
+                               return tagp;
+                       strcat(path, "/");
+                       break;
+               case OF_DT_END_NODE:
+                       ft_parentize(path, 1);
+                       break;
+               }
+       return NULL;
+}
+
+int ft_get_prop(const void *bphp, const void *node, const char *propname,
+               void *buf, const unsigned int buflen)
+{
+       const struct boot_param_header *bph = bphp;
+       u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
+       u32 version = be32_to_cpu(bph->version);
+       u32 *p, *tagp, *sizep, size;
+       char *namep, *datap;
+       int depth;
+
+       depth = 0;
+       p = (u32 *)node;
+
+       while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
+                                       &sizep)) != NULL)
+               switch (be32_to_cpu(*tagp)) {
+               case OF_DT_BEGIN_NODE:
+                       depth++;
+                       break;
+               case OF_DT_PROP:
+                       if ((depth == 1) && !strcmp(namep, propname)) {
+                               size = min(be32_to_cpu(*sizep), (u32)buflen);
+                               memcpy(buf, datap, size);
+                               return size;
+                       }
+                       break;
+               case OF_DT_END_NODE:
+                       if (--depth <= 0)
+                               return -1;
+                       break;
+               }
+       return -1;
+}
+
+static void ft_modify_prop(void **bphpp, char *datap, u32 *old_prop_sizep,
+               const char *buf, const unsigned int buflen)
+{
+       u32 old_prop_data_len, new_prop_data_len;
+
+       old_prop_data_len = _ALIGN(be32_to_cpu(*old_prop_sizep), 4);
+       new_prop_data_len = _ALIGN(buflen, 4);
+
+       /* Check if new prop data fits in old prop data area */
+       if (new_prop_data_len == old_prop_data_len) {
+               memcpy(datap, buf, buflen);
+               *old_prop_sizep = cpu_to_be32(buflen);
+       } else {
+               /* Need to alloc new area to put larger or smaller ft */
+               struct boot_param_header *old_bph = *bphpp, *new_bph;
+               u32 *old_tailp, *new_tailp, *new_datap;
+               u32 old_total_size, new_total_size, head_len, tail_len, diff, v;
+
+               old_total_size = be32_to_cpu(old_bph->totalsize);
+               head_len = (u32)(datap - (char *)old_bph);
+               tail_len = old_total_size - (head_len + old_prop_data_len);
+               old_tailp = (u32 *)(datap + old_prop_data_len);
+               new_total_size = head_len + new_prop_data_len + tail_len;
+
+               if (!(new_bph = malloc(new_total_size))) {
+                       printf("Can't alloc space for new ft\n");
+                       ft_exit(-ENOSPC);
+               }
+
+               new_datap = (u32 *)((char *)new_bph + head_len);
+               new_tailp = (u32 *)((char *)new_datap + new_prop_data_len);
+
+               memcpy(new_bph, *bphpp, head_len);
+               memcpy(new_datap, buf, buflen);
+               memcpy(new_tailp, old_tailp, tail_len);
+
+               *(new_datap - 2) = cpu_to_be32(buflen); /* Set prop size */
+
+               new_bph->totalsize = cpu_to_be32(new_total_size);
+               diff = new_prop_data_len - old_prop_data_len;
+
+               if (be32_to_cpu(old_bph->off_dt_strings)
+                               > be32_to_cpu(old_bph->off_dt_struct)) {
+                       v = be32_to_cpu(new_bph->off_dt_strings);
+                       new_bph->off_dt_strings = cpu_to_be32(v + diff);
+               }
+
+               if (be32_to_cpu(old_bph->off_mem_rsvmap)
+                               > be32_to_cpu(old_bph->off_dt_struct)) {
+                       v = be32_to_cpu(new_bph->off_mem_rsvmap);
+                       new_bph->off_mem_rsvmap = cpu_to_be32(v + diff);
+               }
+
+               ft_free(*bphpp, old_total_size);
+               *bphpp = new_bph;
+       }
+}
+
+/*
+ * - Only modifies existing properties.
+ * - The dev tree passed in may be freed and a new one allocated
+ *   (and *bphpp set to location of new dev tree).
+ */
+int ft_set_prop(void **bphpp, const void *node, const char *propname,
+               const void *buf, const unsigned int buflen)
+{
+       struct boot_param_header *bph = *bphpp;
+       u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
+       u32 version = be32_to_cpu(bph->version);
+       u32 *p, *tagp, *sizep;
+       char *namep, *datap;
+       int depth;
+
+       depth = 0;
+       p = (u32 *)node;
+
+       while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
+                                       &sizep)) != NULL)
+               switch (be32_to_cpu(*tagp)) {
+               case OF_DT_BEGIN_NODE:
+                       depth++;
+                       break;
+               case OF_DT_PROP:
+                       if ((depth == 1) && !strcmp(namep, propname)) {
+                               ft_modify_prop(bphpp, datap, sizep, buf,
+                                               buflen);
+                               return be32_to_cpu(*sizep);
+                       }
+                       break;
+               case OF_DT_END_NODE:
+                       if (--depth <= 0)
+                               return -1;
+                       break;
+               }
+       return -1;
+}
diff -r 2ebf55e419c9 -r a22a7797e0ba tools/libxc/powerpc64/flatdevtree.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/flatdevtree.h       Thu Sep 07 17:25:52 2006 -0500
@@ -0,0 +1,106 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _FLATDEVTREE_H_
+#define _FLATDEVTREE_H_
+
+#include "flatdevtree_env.h"
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER            0xd00dfeed      /* marker */
+#define OF_DT_BEGIN_NODE        0x1     /* Start of node, full name */
+#define OF_DT_END_NODE          0x2     /* End node */
+#define OF_DT_PROP              0x3     /* Property: name off, size, content */
+#define OF_DT_NOP               0x4     /* nop */
+#define OF_DT_END               0x9
+
+#define OF_DT_VERSION           0x10
+
+struct boot_param_header {
+       u32 magic;              /* magic word OF_DT_HEADER */
+       u32 totalsize;          /* total size of DT block */
+       u32 off_dt_struct;      /* offset to structure */
+       u32 off_dt_strings;     /* offset to strings */
+       u32 off_mem_rsvmap;     /* offset to memory reserve map */
+       u32 version;            /* format version */
+       u32 last_comp_version;  /* last compatible version */
+       /* version 2 fields below */
+       u32 boot_cpuid_phys;    /* Physical CPU id we're booting on */
+       /* version 3 fields below */
+       u32 dt_strings_size;    /* size of the DT strings block */
+};
+
+struct ft_cxt {
+       struct boot_param_header *bph;
+       int max_size;           /* maximum size of tree */
+       int overflow;           /* set when this happens */
+       char *p, *pstr, *pres;  /* running pointers */
+       char *p_begin, *pstr_begin, *pres_begin;        /* starting pointers */
+       char *p_anchor;         /* start of constructed area */
+       int struct_size, strings_size, res_size;
+};
+
+void ft_begin_node(struct ft_cxt *cxt, const char *name);
+void ft_end_node(struct ft_cxt *cxt);
+
+void ft_begin_tree(struct ft_cxt *cxt);
+int ft_end_tree(struct ft_cxt *cxt);
+
+void ft_nop(struct ft_cxt *cxt);
+void ft_prop(struct ft_cxt *cxt, const char *name,
+             const void *data, unsigned int sz);
+void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
+void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
+void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
+void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+
+void ft_dump_blob(const void *bphp);
+void ft_merge_blob(struct ft_cxt *cxt, void *blob);
+
+void *ft_find_node(const void *bphp, const char *srch_path);
+int ft_get_prop(const void *bphp, const void *node, const char *propname,
+               void *buf, const unsigned int buflen);
+int ft_set_prop(void **bphp, const void *node, const char *propname,
+               const void *buf, const unsigned int buflen);
+
+static inline char *ft_strrchr(const char *s, int c)
+{
+       const char *p = s + strlen(s);
+
+       do {
+               if (*p == (char)c)
+                       return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+
+/* 'path' is modified */
+static inline void ft_parentize(char *path, int leave_slash)
+{
+       char *s = &path[strlen(path) - 1];
+
+       if (*s == '/')
+               *s = '\0';
+       s = ft_strrchr(path, '/');
+       if (s != NULL) {
+               if (leave_slash)
+                       s[1] = '\0';
+               else if (s[0] == '/')
+                       s[0] = '\0';
+       }
+}
+
+#endif /* FLATDEVTREE_H */
diff -r 2ebf55e419c9 -r a22a7797e0ba tools/libxc/powerpc64/flatdevtree_env.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/flatdevtree_env.h   Thu Sep 07 17:25:52 2006 -0500
@@ -0,0 +1,94 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _FLATDEVTREE_ENV_H_
+#define _FLATDEVTREE_ENV_H_
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <endian.h>
+#include <errno.h>
+
+#define MAX_PATH_LEN 1024
+
+#define _ALIGN(addr,size)       (((addr)+(size)-1)&(~((size)-1)))
+
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+static inline u16 swab16(u16 x)
+{
+       return  (((u16)(x) & (u16)0x00ffU) << 8) |
+                       (((u16)(x) & (u16)0xff00U) >> 8);
+}
+
+static inline u32 swab32(u32 x)
+{
+       return  (((u32)(x) & (u32)0x000000ffUL) << 24) |
+                       (((u32)(x) & (u32)0x0000ff00UL) <<  8) |
+                       (((u32)(x) & (u32)0x00ff0000UL) >>  8) |
+                       (((u32)(x) & (u32)0xff000000UL) >> 24);
+}
+
+static inline u64 swab64(u64 x)
+{
+       return  (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) |
+                       (u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) |
+                       (u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) |
+                       (u64)(((u64)(x) & (u64)0x00000000ff000000ULL) <<  8) |
+                       (u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >>  8) |
+                       (u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) |
+                       (u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) |
+                       (u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56);
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_be16(x) swab16(x)
+#define be16_to_cpu(x) swab16(x)
+#define cpu_to_be32(x) swab32(x)
+#define be32_to_cpu(x) swab32(x)
+#define cpu_to_be64(x) swab64(x)
+#define be64_to_cpu(x) swab64(x)
+#else
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be64(x) (x)
+#define be64_to_cpu(x) (x)
+#endif
+
+static inline void ft_exit(int code)
+{
+       exit(code);
+}
+
+static inline void ft_free(void *ptr, int len)
+{
+       free(ptr);
+}
+
+static inline u32 min(u32 a, u32 b)
+{
+       if (a < b)
+               return a;
+       return b;
+}
+
+#endif /* _FLATDEVTREE_ENV_H_ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [LIBXC][POWERPC] Update to latest flatdevtree snapshot., Xen patchbot-unstable <=