Signed-off-by: Sascha Hauer <[email protected]>
---
 drivers/of/Makefile |    2 +-
 drivers/of/base.c   |  372 -----------------------------------------------
 drivers/of/dtb.c    |  401 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 402 insertions(+), 373 deletions(-)
 create mode 100644 drivers/of/dtb.c

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 5a5960d..fc71962 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,3 +1,3 @@
-obj-y += base.o
+obj-y += base.o dtb.o
 obj-$(CONFIG_GPIOLIB) += gpio.o
 obj-y += partition.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd463e9..8138a91 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -969,378 +969,6 @@ out:
        return dn;
 }
 
-static inline uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, 
int size)
-{
-       dt += size;
-       dt = ALIGN(dt, 4);
-
-       if (dt > f->off_dt_struct + f->size_dt_struct)
-               return 0;
-
-       return dt;
-}
-
-static inline char *dt_string(struct fdt_header *f, char *strstart, uint32_t 
ofs)
-{
-       if (ofs > f->size_dt_strings)
-               return NULL;
-       else
-               return strstart + ofs;
-}
-
-/**
- * of_unflatten_dtb - unflatten a dtb binary blob
- * @root - node in which the fdt blob should be merged into or NULL
- * @infdt - the fdt blob to unflatten
- *
- * Parse a flat device tree binary blob and return a pointer to the
- * unflattened tree.
- */
-struct device_node *of_unflatten_dtb(struct device_node *root, void *infdt)
-{
-       const void *nodep;      /* property node pointer */
-       uint32_t tag;           /* tag */
-       int  len;               /* length of the property */
-       const struct fdt_property *fdt_prop;
-       const char *pathp, *name;
-       struct device_node *node = NULL, *n;
-       struct property *p;
-       uint32_t dt_struct;
-       struct fdt_node_header *fnh;
-       void *dt_strings;
-       struct fdt_header f;
-       int ret, merge = 0;
-       unsigned int maxlen;
-       struct fdt_header *fdt = infdt;
-
-       if (fdt->magic != cpu_to_fdt32(FDT_MAGIC)) {
-               pr_err("bad magic: 0x%08x\n", fdt32_to_cpu(fdt->magic));
-               return ERR_PTR(-EINVAL);
-       }
-
-       if (fdt->version != cpu_to_fdt32(17)) {
-               pr_err("bad dt version: 0x%08x\n", fdt32_to_cpu(fdt->version));
-               return ERR_PTR(-EINVAL);
-       }
-
-       f.totalsize = fdt32_to_cpu(fdt->totalsize);
-       f.off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct);
-       f.size_dt_struct = fdt32_to_cpu(fdt->size_dt_struct);
-       f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
-       f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
-
-       if (f.off_dt_struct + f.size_dt_struct > f.totalsize) {
-               pr_err("unflatten: dt size exceeds total size\n");
-               return ERR_PTR(-ESPIPE);
-       }
-
-       if (f.off_dt_strings + f.size_dt_strings > f.totalsize) {
-               pr_err("unflatten: string size exceeds total size\n");
-               return ERR_PTR(-ESPIPE);
-       }
-
-       dt_struct = f.off_dt_struct;
-       dt_strings = (void *)fdt + f.off_dt_strings;
-
-       if (root) {
-               pr_debug("unflatten: merging into existing tree\n");
-               merge = 1;
-       } else {
-               root = of_new_node(NULL, NULL);
-               if (!root)
-                       return ERR_PTR(-ENOMEM);
-       }
-
-       while (1) {
-               tag = be32_to_cpu(*(uint32_t *)(infdt + dt_struct));
-
-               switch (tag) {
-               case FDT_BEGIN_NODE:
-                       fnh = infdt + dt_struct;
-                       pathp = name = fnh->name;
-                       maxlen = (unsigned long)fdt + f.off_dt_struct +
-                               f.size_dt_struct - (unsigned long)name;
-
-                       len = strnlen(name, maxlen + 1);
-                       if (len > maxlen) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       dt_struct = dt_struct_advance(&f, dt_struct,
-                                       sizeof(struct fdt_node_header) + len + 
1);
-                       if (!dt_struct) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       if (!node) {
-                               node = root;
-                       } else {
-                               if (merge && (n = of_find_child_by_name(node, 
pathp)))
-                                       node = n;
-                               else
-                                       node = of_new_node(node, pathp);
-                       }
-
-                       break;
-
-               case FDT_END_NODE:
-                       if (!node) {
-                               pr_err("unflatten: too many end nodes\n");
-                               ret = -EINVAL;
-                               goto err;
-                       }
-
-                       node = node->parent;
-
-                       dt_struct = dt_struct_advance(&f, dt_struct, 
FDT_TAGSIZE);
-                       if (!dt_struct) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       break;
-
-               case FDT_PROP:
-                       fdt_prop = infdt + dt_struct;
-                       len = fdt32_to_cpu(fdt_prop->len);
-                       nodep = fdt_prop->data;
-
-                       name = dt_string(&f, dt_strings, 
fdt32_to_cpu(fdt_prop->nameoff));
-                       if (!name) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       dt_struct = dt_struct_advance(&f, dt_struct,
-                                       sizeof(struct fdt_property) + len);
-                       if (!dt_struct) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       if (merge && (p = of_find_property(node, name))) {
-                               free(p->value);
-                               p->value = xzalloc(len);
-                               memcpy(p->value, nodep, len);
-                       } else {
-                               of_new_property(node, name, nodep, len);
-                       }
-
-                       break;
-
-               case FDT_NOP:
-                       dt_struct = dt_struct_advance(&f, dt_struct, 
FDT_TAGSIZE);
-                       if (!dt_struct) {
-                               ret = -ESPIPE;
-                               goto err;
-                       }
-
-                       break;
-
-               case FDT_END:
-                       return root;
-
-               default:
-                       pr_err("unflatten: Unknown tag 0x%08X\n", tag);
-                       ret = -EINVAL;
-                       goto err;
-               }
-       }
-err:
-       of_free(root);
-
-       return ERR_PTR(ret);
-}
-
-struct fdt {
-       void *dt;
-       uint32_t dt_nextofs;
-       uint32_t dt_size;
-       char *strings;
-       uint32_t str_nextofs;
-       uint32_t str_size;
-};
-
-static inline uint32_t dt_next_ofs(uint32_t curofs, uint32_t len)
-{
-       return ALIGN(curofs + len, 4);
-}
-
-static int lstrcpy(char *dest, const char *src)
-{
-       int len = 0;
-       int maxlen = 1023;
-
-       while (*src) {
-               *dest++ = *src++;
-               len++;
-               if (!maxlen)
-                       return -ENOSPC;
-               maxlen--;
-       }
-
-       return len;
-}
-
-static int fdt_ensure_space(struct fdt *fdt, int dtsize)
-{
-       /*
-        * We assume strings and names have a maximum length of 1024
-        * whereas properties can be longer. We allocate new memory
-        * if we have less than 1024 bytes (+ the property size left.
-        */
-       if (fdt->str_size - fdt->str_nextofs < 1024) {
-               fdt->strings = realloc(fdt->strings, fdt->str_size * 2);
-               if (!fdt->strings)
-                       return -ENOMEM;
-               fdt->str_size *= 2;
-       }
-
-       if (fdt->dt_size - fdt->dt_nextofs < 1024 + dtsize) {
-               fdt->dt = realloc(fdt->dt, fdt->dt_size * 2);
-               if (!fdt->dt)
-                       return -ENOMEM;
-               fdt->dt_size *= 2;
-       }
-
-       return 0;
-}
-
-static inline int dt_add_string(struct fdt *fdt, const char *str)
-{
-       uint32_t ret;
-       int len;
-
-       if (fdt_ensure_space(fdt, 0) < 0)
-               return -ENOMEM;
-
-       len = lstrcpy(fdt->strings + fdt->str_nextofs, str);
-       if (len < 0)
-               return -ENOSPC;
-
-       ret = fdt->str_nextofs;
-
-       fdt->str_nextofs += len + 1;
-
-       return ret;
-}
-
-static int __of_flatten_dtb(struct fdt *fdt, struct device_node *node)
-{
-       struct property *p;
-       struct device_node *n;
-       int ret;
-       unsigned int len;
-       struct fdt_node_header *nh = fdt->dt + fdt->dt_nextofs;
-
-       if (fdt_ensure_space(fdt, 0) < 0)
-               return -ENOMEM;
-
-       nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
-       len = lstrcpy(nh->name, node->name);
-       fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs, 4 + len + 1);
-
-       list_for_each_entry(p, &node->properties, list) {
-               struct fdt_property *fp;
-
-               if (fdt_ensure_space(fdt, p->length) < 0)
-                       return -ENOMEM;
-
-               fp = fdt->dt + fdt->dt_nextofs;
-
-               fp->tag = cpu_to_fdt32(FDT_PROP);
-               fp->len = cpu_to_fdt32(p->length);
-               fp->nameoff = cpu_to_fdt32(dt_add_string(fdt, p->name));
-               memcpy(fp->data, p->value, p->length);
-               fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs,
-                               sizeof(struct fdt_property) + p->length);
-       }
-
-       list_for_each_entry(n, &node->children, parent_list) {
-               ret = __of_flatten_dtb(fdt, n);
-               if (ret)
-                       return ret;
-       }
-
-       nh = fdt->dt + fdt->dt_nextofs;
-       nh->tag = cpu_to_fdt32(FDT_END_NODE);
-       fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs,
-                       sizeof(struct fdt_node_header));
-
-       if (fdt_ensure_space(fdt, 0) < 0)
-               return -ENOMEM;
-
-       return 0;
-}
-
-/**
- * of_flatten_dtb - flatten a barebox internal devicetree to a dtb
- * @node - the root node of the tree to be unflattened
- */
-void *of_flatten_dtb(struct device_node *node)
-{
-       int ret;
-       struct fdt_header header = {};
-       struct fdt fdt = {};
-       uint32_t ofs;
-       struct fdt_node_header *nh;
-
-       header.magic = cpu_to_fdt32(FDT_MAGIC);
-       header.version = cpu_to_fdt32(0x11);
-       header.last_comp_version = cpu_to_fdt32(0x10);
-
-       fdt.dt = xzalloc(SZ_64K);
-       fdt.dt_size = SZ_64K;
-
-       fdt.strings = xzalloc(SZ_64K);
-       fdt.str_size = SZ_64K;
-
-       ofs = sizeof(struct fdt_header);
-
-       header.off_mem_rsvmap = cpu_to_fdt32(ofs);
-       ofs += sizeof(struct fdt_reserve_entry);
-
-       fdt.dt_nextofs = ofs;
-
-       ret = __of_flatten_dtb(&fdt, node);
-       if (ret)
-               goto out_free;
-       nh = fdt.dt + fdt.dt_nextofs;
-       nh->tag = cpu_to_fdt32(FDT_END);
-       fdt.dt_nextofs = dt_next_ofs(fdt.dt_nextofs, sizeof(struct 
fdt_node_header));
-
-       header.size_dt_strings = cpu_to_fdt32(fdt.str_nextofs);
-       header.size_dt_struct = cpu_to_fdt32(fdt.dt_nextofs);
-
-       header.off_dt_struct = cpu_to_fdt32(ofs);
-
-       header.off_dt_strings = cpu_to_fdt32(fdt.dt_nextofs);
-
-       if (fdt.dt_size - fdt.dt_nextofs < fdt.str_nextofs) {
-               fdt.dt = realloc(fdt.dt, fdt.dt_nextofs + fdt.str_nextofs);
-               if (!fdt.dt)
-                       goto out_free;
-       }
-
-       memcpy(fdt.dt + fdt.dt_nextofs, fdt.strings, fdt.str_nextofs);
-
-       header.totalsize = cpu_to_fdt32(fdt.dt_nextofs + fdt.str_nextofs);
-
-       memcpy(fdt.dt, &header, sizeof(header));
-
-       free(fdt.strings);
-
-       return fdt.dt;
-
-out_free:
-       free(fdt.strings);
-       free(fdt.dt);
-
-       return NULL;
-}
-
 int of_device_is_stdout_path(struct device_d *dev)
 {
        struct device_node *dn;
diff --git a/drivers/of/dtb.c b/drivers/of/dtb.c
new file mode 100644
index 0000000..671ea63
--- /dev/null
+++ b/drivers/of/dtb.c
@@ -0,0 +1,401 @@
+/*
+ * dtb.c - flat devicetree functions
+ *
+ * Copyright (c) 2013 Sascha Hauer <[email protected]>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#include <common.h>
+#include <of.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <init.h>
+#include <memory.h>
+#include <sizes.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+
+static inline uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, 
int size)
+{
+       dt += size;
+       dt = ALIGN(dt, 4);
+
+       if (dt > f->off_dt_struct + f->size_dt_struct)
+               return 0;
+
+       return dt;
+}
+
+static inline char *dt_string(struct fdt_header *f, char *strstart, uint32_t 
ofs)
+{
+       if (ofs > f->size_dt_strings)
+               return NULL;
+       else
+               return strstart + ofs;
+}
+
+/**
+ * of_unflatten_dtb - unflatten a dtb binary blob
+ * @root - node in which the fdt blob should be merged into or NULL
+ * @infdt - the fdt blob to unflatten
+ *
+ * Parse a flat device tree binary blob and return a pointer to the
+ * unflattened tree.
+ */
+struct device_node *of_unflatten_dtb(struct device_node *root, void *infdt)
+{
+       const void *nodep;      /* property node pointer */
+       uint32_t tag;           /* tag */
+       int  len;               /* length of the property */
+       const struct fdt_property *fdt_prop;
+       const char *pathp, *name;
+       struct device_node *node = NULL, *n;
+       struct property *p;
+       uint32_t dt_struct;
+       struct fdt_node_header *fnh;
+       void *dt_strings;
+       struct fdt_header f;
+       int ret, merge = 0;
+       unsigned int maxlen;
+       struct fdt_header *fdt = infdt;
+
+       if (fdt->magic != cpu_to_fdt32(FDT_MAGIC)) {
+               pr_err("bad magic: 0x%08x\n", fdt32_to_cpu(fdt->magic));
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (fdt->version != cpu_to_fdt32(17)) {
+               pr_err("bad dt version: 0x%08x\n", fdt32_to_cpu(fdt->version));
+               return ERR_PTR(-EINVAL);
+       }
+
+       f.totalsize = fdt32_to_cpu(fdt->totalsize);
+       f.off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct);
+       f.size_dt_struct = fdt32_to_cpu(fdt->size_dt_struct);
+       f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
+       f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
+
+       if (f.off_dt_struct + f.size_dt_struct > f.totalsize) {
+               pr_err("unflatten: dt size exceeds total size\n");
+               return ERR_PTR(-ESPIPE);
+       }
+
+       if (f.off_dt_strings + f.size_dt_strings > f.totalsize) {
+               pr_err("unflatten: string size exceeds total size\n");
+               return ERR_PTR(-ESPIPE);
+       }
+
+       dt_struct = f.off_dt_struct;
+       dt_strings = (void *)fdt + f.off_dt_strings;
+
+       if (root) {
+               pr_debug("unflatten: merging into existing tree\n");
+               merge = 1;
+       } else {
+               root = of_new_node(NULL, NULL);
+               if (!root)
+                       return ERR_PTR(-ENOMEM);
+       }
+
+       while (1) {
+               tag = be32_to_cpu(*(uint32_t *)(infdt + dt_struct));
+
+               switch (tag) {
+               case FDT_BEGIN_NODE:
+                       fnh = infdt + dt_struct;
+                       pathp = name = fnh->name;
+                       maxlen = (unsigned long)fdt + f.off_dt_struct +
+                               f.size_dt_struct - (unsigned long)name;
+
+                       len = strnlen(name, maxlen + 1);
+                       if (len > maxlen) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       dt_struct = dt_struct_advance(&f, dt_struct,
+                                       sizeof(struct fdt_node_header) + len + 
1);
+                       if (!dt_struct) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       if (!node) {
+                               node = root;
+                       } else {
+                               if (merge && (n = of_find_child_by_name(node, 
pathp)))
+                                       node = n;
+                               else
+                                       node = of_new_node(node, pathp);
+                       }
+
+                       break;
+
+               case FDT_END_NODE:
+                       if (!node) {
+                               pr_err("unflatten: too many end nodes\n");
+                               ret = -EINVAL;
+                               goto err;
+                       }
+
+                       node = node->parent;
+
+                       dt_struct = dt_struct_advance(&f, dt_struct, 
FDT_TAGSIZE);
+                       if (!dt_struct) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       break;
+
+               case FDT_PROP:
+                       fdt_prop = infdt + dt_struct;
+                       len = fdt32_to_cpu(fdt_prop->len);
+                       nodep = fdt_prop->data;
+
+                       name = dt_string(&f, dt_strings, 
fdt32_to_cpu(fdt_prop->nameoff));
+                       if (!name) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       dt_struct = dt_struct_advance(&f, dt_struct,
+                                       sizeof(struct fdt_property) + len);
+                       if (!dt_struct) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       if (merge && (p = of_find_property(node, name))) {
+                               free(p->value);
+                               p->value = xzalloc(len);
+                               memcpy(p->value, nodep, len);
+                       } else {
+                               of_new_property(node, name, nodep, len);
+                       }
+
+                       break;
+
+               case FDT_NOP:
+                       dt_struct = dt_struct_advance(&f, dt_struct, 
FDT_TAGSIZE);
+                       if (!dt_struct) {
+                               ret = -ESPIPE;
+                               goto err;
+                       }
+
+                       break;
+
+               case FDT_END:
+                       return root;
+
+               default:
+                       pr_err("unflatten: Unknown tag 0x%08X\n", tag);
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+err:
+       of_free(root);
+
+       return ERR_PTR(ret);
+}
+
+struct fdt {
+       void *dt;
+       uint32_t dt_nextofs;
+       uint32_t dt_size;
+       char *strings;
+       uint32_t str_nextofs;
+       uint32_t str_size;
+};
+
+static inline uint32_t dt_next_ofs(uint32_t curofs, uint32_t len)
+{
+       return ALIGN(curofs + len, 4);
+}
+
+static int lstrcpy(char *dest, const char *src)
+{
+       int len = 0;
+       int maxlen = 1023;
+
+       while (*src) {
+               *dest++ = *src++;
+               len++;
+               if (!maxlen)
+                       return -ENOSPC;
+               maxlen--;
+       }
+
+       return len;
+}
+
+static int fdt_ensure_space(struct fdt *fdt, int dtsize)
+{
+       /*
+        * We assume strings and names have a maximum length of 1024
+        * whereas properties can be longer. We allocate new memory
+        * if we have less than 1024 bytes (+ the property size left.
+        */
+       if (fdt->str_size - fdt->str_nextofs < 1024) {
+               fdt->strings = realloc(fdt->strings, fdt->str_size * 2);
+               if (!fdt->strings)
+                       return -ENOMEM;
+               fdt->str_size *= 2;
+       }
+
+       if (fdt->dt_size - fdt->dt_nextofs < 1024 + dtsize) {
+               fdt->dt = realloc(fdt->dt, fdt->dt_size * 2);
+               if (!fdt->dt)
+                       return -ENOMEM;
+               fdt->dt_size *= 2;
+       }
+
+       return 0;
+}
+
+static inline int dt_add_string(struct fdt *fdt, const char *str)
+{
+       uint32_t ret;
+       int len;
+
+       if (fdt_ensure_space(fdt, 0) < 0)
+               return -ENOMEM;
+
+       len = lstrcpy(fdt->strings + fdt->str_nextofs, str);
+       if (len < 0)
+               return -ENOSPC;
+
+       ret = fdt->str_nextofs;
+
+       fdt->str_nextofs += len + 1;
+
+       return ret;
+}
+
+static int __of_flatten_dtb(struct fdt *fdt, struct device_node *node)
+{
+       struct property *p;
+       struct device_node *n;
+       int ret;
+       unsigned int len;
+       struct fdt_node_header *nh = fdt->dt + fdt->dt_nextofs;
+
+       if (fdt_ensure_space(fdt, 0) < 0)
+               return -ENOMEM;
+
+       nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+       len = lstrcpy(nh->name, node->name);
+       fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs, 4 + len + 1);
+
+       list_for_each_entry(p, &node->properties, list) {
+               struct fdt_property *fp;
+
+               if (fdt_ensure_space(fdt, p->length) < 0)
+                       return -ENOMEM;
+
+               fp = fdt->dt + fdt->dt_nextofs;
+
+               fp->tag = cpu_to_fdt32(FDT_PROP);
+               fp->len = cpu_to_fdt32(p->length);
+               fp->nameoff = cpu_to_fdt32(dt_add_string(fdt, p->name));
+               memcpy(fp->data, p->value, p->length);
+               fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs,
+                               sizeof(struct fdt_property) + p->length);
+       }
+
+       list_for_each_entry(n, &node->children, parent_list) {
+               ret = __of_flatten_dtb(fdt, n);
+               if (ret)
+                       return ret;
+       }
+
+       nh = fdt->dt + fdt->dt_nextofs;
+       nh->tag = cpu_to_fdt32(FDT_END_NODE);
+       fdt->dt_nextofs = dt_next_ofs(fdt->dt_nextofs,
+                       sizeof(struct fdt_node_header));
+
+       if (fdt_ensure_space(fdt, 0) < 0)
+               return -ENOMEM;
+
+       return 0;
+}
+
+/**
+ * of_flatten_dtb - flatten a barebox internal devicetree to a dtb
+ * @node - the root node of the tree to be unflattened
+ */
+void *of_flatten_dtb(struct device_node *node)
+{
+       int ret;
+       struct fdt_header header = {};
+       struct fdt fdt = {};
+       uint32_t ofs;
+       struct fdt_node_header *nh;
+
+       header.magic = cpu_to_fdt32(FDT_MAGIC);
+       header.version = cpu_to_fdt32(0x11);
+       header.last_comp_version = cpu_to_fdt32(0x10);
+
+       fdt.dt = xzalloc(SZ_64K);
+       fdt.dt_size = SZ_64K;
+
+       fdt.strings = xzalloc(SZ_64K);
+       fdt.str_size = SZ_64K;
+
+       ofs = sizeof(struct fdt_header);
+
+       header.off_mem_rsvmap = cpu_to_fdt32(ofs);
+       ofs += sizeof(struct fdt_reserve_entry);
+
+       fdt.dt_nextofs = ofs;
+
+       ret = __of_flatten_dtb(&fdt, node);
+       if (ret)
+               goto out_free;
+       nh = fdt.dt + fdt.dt_nextofs;
+       nh->tag = cpu_to_fdt32(FDT_END);
+       fdt.dt_nextofs = dt_next_ofs(fdt.dt_nextofs, sizeof(struct 
fdt_node_header));
+
+       header.size_dt_strings = cpu_to_fdt32(fdt.str_nextofs);
+       header.size_dt_struct = cpu_to_fdt32(fdt.dt_nextofs);
+
+       header.off_dt_struct = cpu_to_fdt32(ofs);
+
+       header.off_dt_strings = cpu_to_fdt32(fdt.dt_nextofs);
+
+       if (fdt.dt_size - fdt.dt_nextofs < fdt.str_nextofs) {
+               fdt.dt = realloc(fdt.dt, fdt.dt_nextofs + fdt.str_nextofs);
+               if (!fdt.dt)
+                       goto out_free;
+       }
+
+       memcpy(fdt.dt + fdt.dt_nextofs, fdt.strings, fdt.str_nextofs);
+
+       header.totalsize = cpu_to_fdt32(fdt.dt_nextofs + fdt.str_nextofs);
+
+       memcpy(fdt.dt, &header, sizeof(header));
+
+       free(fdt.strings);
+
+       return fdt.dt;
+
+out_free:
+       free(fdt.strings);
+       free(fdt.dt);
+
+       return NULL;
+}
-- 
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to