lib: libufdt: add libufdt library to lk source.
Change to port libufdt library to lk code for DTB overlay
feature.
Change-Id: I8e93834e97ba3a9326ff70a9fb43b7e74bda5ab3
diff --git a/lib/libufdt/fdt_internal.h b/lib/libufdt/fdt_internal.h
new file mode 100644
index 0000000..1ac9d68
--- /dev/null
+++ b/lib/libufdt/fdt_internal.h
@@ -0,0 +1,145 @@
+#ifndef FDT_INTERNAL_H
+#define FDT_INTERNAL_H
+
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library 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 library 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 library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "libfdt.h"
+#include "libufdt_sysdeps.h"
+
+
+/*
+ * Most of the codes below are copied from external/dtc/libfdt/libfdt_internal.h
+ * and external/dtc/libfdt/fdt_sw.c .
+ */
+
+#define FDT_ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
+#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
+
+static inline const void *_fdt_offset_ptr(const void *fdt, int offset) {
+ return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+static inline void *_fdt_offset_ptr_w(void *fdt, int offset) {
+ return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+}
+
+#define FDT_SW_MAGIC (~FDT_MAGIC)
+
+static int _fdt_sw_check_header(void *fdt) {
+ if (fdt_magic(fdt) != FDT_SW_MAGIC) return -FDT_ERR_BADMAGIC;
+ /* FIXME: should check more details about the header state */
+ return 0;
+}
+
+#define FDT_SW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = _fdt_sw_check_header(fdt)) != 0) return err; \
+ }
+
+static void *_fdt_grab_space(void *fdt, size_t len) {
+ int offset = fdt_size_dt_struct(fdt);
+ int spaceleft;
+
+ spaceleft =
+ fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) - fdt_size_dt_strings(fdt);
+
+ if ((offset + (int)len < offset) || (offset + (int)len > spaceleft))
+ return NULL;
+
+ fdt_set_size_dt_struct(fdt, offset + len);
+ return _fdt_offset_ptr_w(fdt, offset);
+}
+
+static int _fdt_add_string(void *fdt, const char *s) {
+ char *strtab = (char *)fdt + fdt_totalsize(fdt);
+ int strtabsize = fdt_size_dt_strings(fdt);
+ int len = dto_strlen(s) + 1;
+ int struct_top, offset;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ if (fdt_totalsize(fdt) + offset < (size_t)struct_top)
+ return 0; /* no more room :( */
+
+ dto_memcpy(strtab + offset, s, len);
+ fdt_set_size_dt_strings(fdt, strtabsize + len);
+ return offset;
+}
+
+/*
+ * From Google, speed up fdt_property() by passing nameoff to the function.
+ * Adds new string to fdt if *pnameoff is 0.
+ * Otherwise, use the nameoff provided.
+ */
+static int fast_fdt_sw_property(void *fdt, const char *name, const void *val,
+ int len, int *pnameoff,
+ struct fdt_property **prop_ptr) {
+ FDT_SW_CHECK_HEADER(fdt);
+
+ if (*pnameoff == 0) {
+ *pnameoff = _fdt_add_string(fdt, name);
+ if (*pnameoff == 0) return -FDT_ERR_NOSPACE;
+ }
+
+ *prop_ptr = _fdt_grab_space(fdt, sizeof(**prop_ptr) + FDT_TAGALIGN(len));
+ if (*prop_ptr == NULL) return -FDT_ERR_NOSPACE;
+
+ (*prop_ptr)->tag = cpu_to_fdt32(FDT_PROP);
+ (*prop_ptr)->nameoff = cpu_to_fdt32(*pnameoff);
+ (*prop_ptr)->len = cpu_to_fdt32(len);
+ dto_memcpy((*prop_ptr)->data, val, len);
+ return 0;
+}
+
+#endif /* FDT_INTERNAL_H */