summaryrefslogtreecommitdiff
path: root/EmbeddedPkg/Library/FdtLib
diff options
context:
space:
mode:
authorMichael Kubacki <michael.kubacki@microsoft.com>2021-12-05 14:53:56 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-07 17:24:28 +0000
commite7108d0e9655b1795c94ac372b0449f28dd907df (patch)
treeb153716589979b9e42e9b85281ff8b7511ba272f /EmbeddedPkg/Library/FdtLib
parent731c67e1d77b7741a91762d17659fc9fbcb9e305 (diff)
downloadedk2-e7108d0e9655b1795c94ac372b0449f28dd907df.zip
edk2-e7108d0e9655b1795c94ac372b0449f28dd907df.tar.gz
edk2-e7108d0e9655b1795c94ac372b0449f28dd907df.tar.bz2
EmbeddedPkg: Apply uncrustify changes
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the EmbeddedPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
Diffstat (limited to 'EmbeddedPkg/Library/FdtLib')
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt.c397
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_addresses.c66
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c45
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_overlay.c2041
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_ro.c1272
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_rw.c891
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_strerror.c68
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_strtoul.c35
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_sw.c445
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_wip.c168
-rw-r--r--EmbeddedPkg/Library/FdtLib/libfdt_internal.h84
11 files changed, 3220 insertions, 2292 deletions
diff --git a/EmbeddedPkg/Library/FdtLib/fdt.c b/EmbeddedPkg/Library/FdtLib/fdt.c
index 29756a8..56a9787 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt.c
@@ -55,197 +55,276 @@
#include "libfdt_internal.h"
-int fdt_check_header(const void *fdt)
+int
+fdt_check_header (
+ const void *fdt
+ )
{
- if (fdt_magic(fdt) == FDT_MAGIC) {
- /* Complete tree */
- if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
- /* Unfinished sequential-write blob */
- if (fdt_size_dt_struct(fdt) == 0)
- return -FDT_ERR_BADSTATE;
- } else {
- return -FDT_ERR_BADMAGIC;
- }
-
- return 0;
+ if (fdt_magic (fdt) == FDT_MAGIC) {
+ /* Complete tree */
+ if (fdt_version (fdt) < FDT_FIRST_SUPPORTED_VERSION) {
+ return -FDT_ERR_BADVERSION;
+ }
+
+ if (fdt_last_comp_version (fdt) > FDT_LAST_SUPPORTED_VERSION) {
+ return -FDT_ERR_BADVERSION;
+ }
+ } else if (fdt_magic (fdt) == FDT_SW_MAGIC) {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct (fdt) == 0) {
+ return -FDT_ERR_BADSTATE;
+ }
+ } else {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
}
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
+const void *
+fdt_offset_ptr (
+ const void *fdt,
+ int offset,
+ unsigned int len
+ )
{
- unsigned absoffset = offset + fdt_off_dt_struct(fdt);
-
- if ((absoffset < offset)
- || ((absoffset + len) < absoffset)
- || (absoffset + len) > fdt_totalsize(fdt))
- return NULL;
-
- if (fdt_version(fdt) >= 0x11)
- if (((offset + len) < offset)
- || ((offset + len) > fdt_size_dt_struct(fdt)))
- return NULL;
-
- return _fdt_offset_ptr(fdt, offset);
+ unsigned absoffset = offset + fdt_off_dt_struct (fdt);
+
+ if ( (absoffset < offset)
+ || ((absoffset + len) < absoffset)
+ || ((absoffset + len) > fdt_totalsize (fdt)))
+ {
+ return NULL;
+ }
+
+ if (fdt_version (fdt) >= 0x11) {
+ if ( ((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct (fdt)))
+ {
+ return NULL;
+ }
+ }
+
+ return _fdt_offset_ptr (fdt, offset);
}
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+uint32_t
+fdt_next_tag (
+ const void *fdt,
+ int startoffset,
+ int *nextoffset
+ )
{
- const fdt32_t *tagp, *lenp;
- uint32_t tag;
- int offset = startoffset;
- const char *p;
-
- *nextoffset = -FDT_ERR_TRUNCATED;
- tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (!tagp)
- return FDT_END; /* premature end */
- tag = fdt32_to_cpu(*tagp);
- offset += FDT_TAGSIZE;
-
- *nextoffset = -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_BEGIN_NODE:
- /* skip name */
- do {
- p = fdt_offset_ptr(fdt, offset++, 1);
- } while (p && (*p != '\0'));
- if (!p)
- return FDT_END; /* premature end */
- break;
-
- case FDT_PROP:
- lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (!lenp)
- return FDT_END; /* premature end */
- /* skip-name offset, length and value */
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
- + fdt32_to_cpu(*lenp);
- break;
-
- case FDT_END:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
-
- default:
- return FDT_END;
- }
-
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
- return FDT_END; /* premature end */
-
- *nextoffset = FDT_TAGALIGN(offset);
- return tag;
+ const fdt32_t *tagp, *lenp;
+ uint32_t tag;
+ int offset = startoffset;
+ const char *p;
+
+ *nextoffset = -FDT_ERR_TRUNCATED;
+ tagp = fdt_offset_ptr (fdt, offset, FDT_TAGSIZE);
+ if (!tagp) {
+ return FDT_END; /* premature end */
+ }
+
+ tag = fdt32_to_cpu (*tagp);
+ offset += FDT_TAGSIZE;
+
+ *nextoffset = -FDT_ERR_BADSTRUCTURE;
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ /* skip name */
+ do {
+ p = fdt_offset_ptr (fdt, offset++, 1);
+ } while (p && (*p != '\0'));
+
+ if (!p) {
+ return FDT_END; /* premature end */
+ }
+
+ break;
+
+ case FDT_PROP:
+ lenp = fdt_offset_ptr (fdt, offset, sizeof (*lenp));
+ if (!lenp) {
+ return FDT_END; /* premature end */
+ }
+
+ /* skip-name offset, length and value */
+ offset += sizeof (struct fdt_property) - FDT_TAGSIZE
+ + fdt32_to_cpu (*lenp);
+ break;
+
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return FDT_END;
+ }
+
+ if (!fdt_offset_ptr (fdt, startoffset, offset - startoffset)) {
+ return FDT_END; /* premature end */
+ }
+
+ *nextoffset = FDT_TAGALIGN (offset);
+ return tag;
}
-int _fdt_check_node_offset(const void *fdt, int offset)
+int
+_fdt_check_node_offset (
+ const void *fdt,
+ int offset
+ )
{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
- return -FDT_ERR_BADOFFSET;
+ if ( (offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag (fdt, offset, &offset) != FDT_BEGIN_NODE))
+ {
+ return -FDT_ERR_BADOFFSET;
+ }
- return offset;
+ return offset;
}
-int _fdt_check_prop_offset(const void *fdt, int offset)
+int
+_fdt_check_prop_offset (
+ const void *fdt,
+ int offset
+ )
{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
- return -FDT_ERR_BADOFFSET;
+ if ( (offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag (fdt, offset, &offset) != FDT_PROP))
+ {
+ return -FDT_ERR_BADOFFSET;
+ }
- return offset;
+ return offset;
}
-int fdt_next_node(const void *fdt, int offset, int *depth)
+int
+fdt_next_node (
+ const void *fdt,
+ int offset,
+ int *depth
+ )
{
- int nextoffset = 0;
- uint32_t tag;
-
- if (offset >= 0)
- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
- return nextoffset;
-
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- case FDT_BEGIN_NODE:
- if (depth)
- (*depth)++;
- break;
-
- case FDT_END_NODE:
- if (depth && ((--(*depth)) < 0))
- return nextoffset;
- break;
-
- case FDT_END:
- if ((nextoffset >= 0)
- || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
- return -FDT_ERR_NOTFOUND;
- else
- return nextoffset;
- }
- } while (tag != FDT_BEGIN_NODE);
-
- return offset;
+ int nextoffset = 0;
+ uint32_t tag;
+
+ if (offset >= 0) {
+ if ((nextoffset = _fdt_check_node_offset (fdt, offset)) < 0) {
+ return nextoffset;
+ }
+ }
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ case FDT_BEGIN_NODE:
+ if (depth) {
+ (*depth)++;
+ }
+
+ break;
+
+ case FDT_END_NODE:
+ if (depth && ((--(*depth)) < 0)) {
+ return nextoffset;
+ }
+
+ break;
+
+ case FDT_END:
+ if ( (nextoffset >= 0)
+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
+ {
+ return -FDT_ERR_NOTFOUND;
+ } else {
+ return nextoffset;
+ }
+ }
+ } while (tag != FDT_BEGIN_NODE);
+
+ return offset;
}
-int fdt_first_subnode(const void *fdt, int offset)
+int
+fdt_first_subnode (
+ const void *fdt,
+ int offset
+ )
{
- int depth = 0;
+ int depth = 0;
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth != 1)
- return -FDT_ERR_NOTFOUND;
+ offset = fdt_next_node (fdt, offset, &depth);
+ if ((offset < 0) || (depth != 1)) {
+ return -FDT_ERR_NOTFOUND;
+ }
- return offset;
+ return offset;
}
-int fdt_next_subnode(const void *fdt, int offset)
+int
+fdt_next_subnode (
+ const void *fdt,
+ int offset
+ )
{
- int depth = 1;
-
- /*
- * With respect to the parent, the depth of the next subnode will be
- * the same as the last.
- */
- do {
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth < 1)
- return -FDT_ERR_NOTFOUND;
- } while (depth > 1);
-
- return offset;
+ int depth = 1;
+
+ /*
+ * With respect to the parent, the depth of the next subnode will be
+ * the same as the last.
+ */
+ do {
+ offset = fdt_next_node (fdt, offset, &depth);
+ if ((offset < 0) || (depth < 1)) {
+ return -FDT_ERR_NOTFOUND;
+ }
+ } while (depth > 1);
+
+ return offset;
}
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+const char *
+_fdt_find_string (
+ const char *strtab,
+ int tabsize,
+ const char *s
+ )
{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
- const char *p;
-
- for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
- return p;
- return NULL;
+ int len = strlen (s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++) {
+ if (memcmp (p, s, len) == 0) {
+ return p;
+ }
+ }
+
+ return NULL;
}
-int fdt_move(const void *fdt, void *buf, int bufsize)
+int
+fdt_move (
+ const void *fdt,
+ void *buf,
+ int bufsize
+ )
{
- FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER (fdt);
- if (fdt_totalsize(fdt) > bufsize)
- return -FDT_ERR_NOSPACE;
+ if (fdt_totalsize (fdt) > bufsize) {
+ return -FDT_ERR_NOSPACE;
+ }
- memmove(buf, fdt, fdt_totalsize(fdt));
- return 0;
+ memmove (buf, fdt, fdt_totalsize (fdt));
+ return 0;
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_addresses.c b/EmbeddedPkg/Library/FdtLib/fdt_addresses.c
index f48da28..a0f531a 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_addresses.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_addresses.c
@@ -55,42 +55,56 @@
#include "libfdt_internal.h"
-int fdt_address_cells(const void *fdt, int nodeoffset)
+int
+fdt_address_cells (
+ const void *fdt,
+ int nodeoffset
+ )
{
- const fdt32_t *ac;
- int val;
- int len;
+ const fdt32_t *ac;
+ int val;
+ int len;
- ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
- if (!ac)
- return 2;
+ ac = fdt_getprop (fdt, nodeoffset, "#address-cells", &len);
+ if (!ac) {
+ return 2;
+ }
- if (len != sizeof(*ac))
- return -FDT_ERR_BADNCELLS;
+ if (len != sizeof (*ac)) {
+ return -FDT_ERR_BADNCELLS;
+ }
- val = fdt32_to_cpu(*ac);
- if ((val <= 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
+ val = fdt32_to_cpu (*ac);
+ if ((val <= 0) || (val > FDT_MAX_NCELLS)) {
+ return -FDT_ERR_BADNCELLS;
+ }
- return val;
+ return val;
}
-int fdt_size_cells(const void *fdt, int nodeoffset)
+int
+fdt_size_cells (
+ const void *fdt,
+ int nodeoffset
+ )
{
- const fdt32_t *sc;
- int val;
- int len;
+ const fdt32_t *sc;
+ int val;
+ int len;
- sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
- if (!sc)
- return 2;
+ sc = fdt_getprop (fdt, nodeoffset, "#size-cells", &len);
+ if (!sc) {
+ return 2;
+ }
- if (len != sizeof(*sc))
- return -FDT_ERR_BADNCELLS;
+ if (len != sizeof (*sc)) {
+ return -FDT_ERR_BADNCELLS;
+ }
- val = fdt32_to_cpu(*sc);
- if ((val < 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
+ val = fdt32_to_cpu (*sc);
+ if ((val < 0) || (val > FDT_MAX_NCELLS)) {
+ return -FDT_ERR_BADNCELLS;
+ }
- return val;
+ return val;
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c b/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
index 634b436..65a128f 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
@@ -55,29 +55,38 @@
#include "libfdt_internal.h"
-int fdt_create_empty_tree(void *buf, int bufsize)
+int
+fdt_create_empty_tree (
+ void *buf,
+ int bufsize
+ )
{
- int err;
+ int err;
- err = fdt_create(buf, bufsize);
- if (err)
- return err;
+ err = fdt_create (buf, bufsize);
+ if (err) {
+ return err;
+ }
- err = fdt_finish_reservemap(buf);
- if (err)
- return err;
+ err = fdt_finish_reservemap (buf);
+ if (err) {
+ return err;
+ }
- err = fdt_begin_node(buf, "");
- if (err)
- return err;
+ err = fdt_begin_node (buf, "");
+ if (err) {
+ return err;
+ }
- err = fdt_end_node(buf);
- if (err)
- return err;
+ err = fdt_end_node (buf);
+ if (err) {
+ return err;
+ }
- err = fdt_finish(buf);
- if (err)
- return err;
+ err = fdt_finish (buf);
+ if (err) {
+ return err;
+ }
- return fdt_open_into(buf, buf, bufsize);
+ return fdt_open_into (buf, buf, bufsize);
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_overlay.c b/EmbeddedPkg/Library/FdtLib/fdt_overlay.c
index 804852c..0e6b871 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_overlay.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_overlay.c
@@ -1,914 +1,1127 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2016 Free Electrons
- * Copyright (C) 2016 NextThing Co.
- *
- * 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_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-/**
- * overlay_get_target_phandle - retrieves the target phandle of a fragment
- * @fdto: pointer to the device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- *
- * overlay_get_target_phandle() retrieves the target phandle of an
- * overlay fragment when that fragment uses a phandle (target
- * property) instead of a path (target-path property).
- *
- * returns:
- * the phandle pointed by the target property
- * 0, if the phandle was not found
- * -1, if the phandle was malformed
- */
-static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
-{
- const fdt32_t *val;
- int len;
-
- val = fdt_getprop(fdto, fragment, "target", &len);
- if (!val)
- return 0;
-
- if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
- return (uint32_t)-1;
-
- return fdt32_to_cpu(*val);
-}
-
-/**
- * overlay_get_target - retrieves the offset of a fragment's target
- * @fdt: Base device tree blob
- * @fdto: Device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- * @pathp: pointer which receives the path of the target (or NULL)
- *
- * overlay_get_target() retrieves the target offset in the base
- * device tree of a fragment, no matter how the actual targetting is
- * done (through a phandle or a path)
- *
- * returns:
- * the targetted node offset in the base device tree
- * Negative error code on error
- */
-static int overlay_get_target(const void *fdt, const void *fdto,
- int fragment, char const **pathp)
-{
- uint32_t phandle;
- const char *path = NULL;
- int path_len = 0, ret;
-
- /* Try first to do a phandle based lookup */
- phandle = overlay_get_target_phandle(fdto, fragment);
- if (phandle == (uint32_t)-1)
- return -FDT_ERR_BADPHANDLE;
-
- /* no phandle, try path */
- if (!phandle) {
- /* And then a path based lookup */
- path = fdt_getprop(fdto, fragment, "target-path", &path_len);
- if (path)
- ret = fdt_path_offset(fdt, path);
- else
- ret = path_len;
- } else
- ret = fdt_node_offset_by_phandle(fdt, phandle);
-
- /*
- * If we haven't found either a target or a
- * target-path property in a node that contains a
- * __overlay__ subnode (we wouldn't be called
- * otherwise), consider it a improperly written
- * overlay
- */
- if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
- ret = -FDT_ERR_BADOVERLAY;
-
- /* return on error */
- if (ret < 0)
- return ret;
-
- /* return pointer to path (if available) */
- if (pathp)
- *pathp = path ? path : NULL;
-
- return ret;
-}
-
-/**
- * overlay_phandle_add_offset - Increases a phandle by an offset
- * @fdt: Base device tree blob
- * @node: Device tree overlay blob
- * @name: Name of the property to modify (phandle or linux,phandle)
- * @delta: offset to apply
- *
- * overlay_phandle_add_offset() increments a node phandle by a given
- * offset.
- *
- * returns:
- * 0 on success.
- * Negative error code on error
- */
-static int overlay_phandle_add_offset(void *fdt, int node,
- const char *name, uint32_t delta)
-{
- const fdt32_t *val;
- uint32_t adj_val;
- int len;
-
- val = fdt_getprop(fdt, node, name, &len);
- if (!val)
- return len;
-
- if (len != sizeof(*val))
- return -FDT_ERR_BADPHANDLE;
-
- adj_val = fdt32_to_cpu(*val);
- if ((adj_val + delta) < adj_val)
- return -FDT_ERR_NOPHANDLES;
-
- adj_val += delta;
- if (adj_val == (uint32_t)-1)
- return -FDT_ERR_NOPHANDLES;
-
- return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
-}
-
-/**
- * overlay_adjust_node_phandles - Offsets the phandles of a node
- * @fdto: Device tree overlay blob
- * @node: Offset of the node we want to adjust
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_node_phandles() adds a constant to all the phandles
- * of a given node. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_adjust_node_phandles(void *fdto, int node,
- uint32_t delta)
-{
- int child;
- int ret;
-
- ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
- if (ret && ret != -FDT_ERR_NOTFOUND)
- return ret;
-
- ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
- if (ret && ret != -FDT_ERR_NOTFOUND)
- return ret;
-
- fdt_for_each_subnode(child, fdto, node) {
- ret = overlay_adjust_node_phandles(fdto, child, delta);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_local_phandles() adds a constant to all the
- * phandles of an overlay. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
-{
- /*
- * Start adjusting the phandles from the overlay root
- */
- return overlay_adjust_node_phandles(fdto, 0, delta);
-}
-
-/**
- * overlay_update_local_node_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @tree_node: Node offset of the node to operate on
- * @fixup_node: Node offset of the matching local fixups node
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_nodes_references() update the phandles
- * pointing to a node within the device tree overlay by adding a
- * constant delta.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_update_local_node_references(void *fdto,
- int tree_node,
- int fixup_node,
- uint32_t delta)
-{
- int fixup_prop;
- int fixup_child;
- int ret;
-
- fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
- const fdt32_t *fixup_val;
- const char *tree_val;
- const char *name;
- int fixup_len;
- int tree_len;
- int i;
-
- fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
- &name, &fixup_len);
- if (!fixup_val)
- return fixup_len;
-
- if (fixup_len % sizeof(uint32_t))
- return -FDT_ERR_BADOVERLAY;
-
- tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
- if (!tree_val) {
- if (tree_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
-
- return tree_len;
- }
-
- for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
- fdt32_t adj_val;
- uint32_t poffset;
-
- poffset = fdt32_to_cpu(fixup_val[i]);
-
- /*
- * phandles to fixup can be unaligned.
- *
- * Use a memcpy for the architectures that do
- * not support unaligned accesses.
- */
- memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
-
- adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
-
- ret = fdt_setprop_inplace_namelen_partial(fdto,
- tree_node,
- name,
- strlen(name),
- poffset,
- &adj_val,
- sizeof(adj_val));
- if (ret == -FDT_ERR_NOSPACE)
- return -FDT_ERR_BADOVERLAY;
-
- if (ret)
- return ret;
- }
- }
-
- fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
- const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
- NULL);
- int tree_child;
-
- tree_child = fdt_subnode_offset(fdto, tree_node,
- fixup_child_name);
- if (tree_child == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
- if (tree_child < 0)
- return tree_child;
-
- ret = overlay_update_local_node_references(fdto,
- tree_child,
- fixup_child,
- delta);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_update_local_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_references() update all the phandles pointing
- * to a node within the device tree overlay by adding a constant
- * delta to not conflict with the base overlay.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_update_local_references(void *fdto, uint32_t delta)
-{
- int fixups;
-
- fixups = fdt_path_offset(fdto, "/__local_fixups__");
- if (fixups < 0) {
- /* There's no local phandles to adjust, bail out */
- if (fixups == -FDT_ERR_NOTFOUND)
- return 0;
-
- return fixups;
- }
-
- /*
- * Update our local references from the root of the tree
- */
- return overlay_update_local_node_references(fdto, 0, fixups,
- delta);
-}
-
-/**
- * overlay_fixup_one_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @path: Path to a node holding a phandle in the overlay
- * @path_len: number of path characters to consider
- * @name: Name of the property holding the phandle reference in the overlay
- * @name_len: number of name characters to consider
- * @poffset: Offset within the overlay property where the phandle is stored
- * @label: Label of the node referenced by the phandle
- *
- * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
- * a node in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_one_phandle(void *fdt, void *fdto,
- int symbols_off,
- const char *path, uint32_t path_len,
- const char *name, uint32_t name_len,
- int poffset, const char *label)
-{
- const char *symbol_path;
- uint32_t phandle;
- fdt32_t phandle_prop;
- int symbol_off, fixup_off;
- int prop_len;
-
- if (symbols_off < 0)
- return symbols_off;
-
- symbol_path = fdt_getprop(fdt, symbols_off, label,
- &prop_len);
- if (!symbol_path)
- return prop_len;
-
- symbol_off = fdt_path_offset(fdt, symbol_path);
- if (symbol_off < 0)
- return symbol_off;
-
- phandle = fdt_get_phandle(fdt, symbol_off);
- if (!phandle)
- return -FDT_ERR_NOTFOUND;
-
- fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
- if (fixup_off == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
- if (fixup_off < 0)
- return fixup_off;
-
- phandle_prop = cpu_to_fdt32(phandle);
- return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
- name, name_len, poffset,
- &phandle_prop,
- sizeof(phandle_prop));
-};
-
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-
-/**
- * overlay_fixup_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @property: Property offset in the overlay holding the list of fixups
- *
- * overlay_fixup_phandle() resolves all the overlay phandles pointed
- * to in a __fixups__ property, and updates them to match the phandles
- * in use in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
- int property)
-{
- const char *value;
- const char *label;
- int len;
-
- value = fdt_getprop_by_offset(fdto, property,
- &label, &len);
- if (!value) {
- if (len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
-
- return len;
- }
-
- do {
- const char *path, *name, *fixup_end;
- const char *fixup_str = value;
- uint32_t path_len, name_len;
- uint32_t fixup_len;
- char *sep, *endptr;
- int poffset, ret;
-
- fixup_end = memchr(value, '\0', len);
- if (!fixup_end)
- return -FDT_ERR_BADOVERLAY;
- fixup_len = fixup_end - fixup_str;
-
- len -= fixup_len + 1;
- value += fixup_len + 1;
-
- path = fixup_str;
- sep = memchr(fixup_str, ':', fixup_len);
- if (!sep || *sep != ':')
- return -FDT_ERR_BADOVERLAY;
-
- path_len = sep - path;
- if (path_len == (fixup_len - 1))
- return -FDT_ERR_BADOVERLAY;
-
- fixup_len -= path_len + 1;
- name = sep + 1;
- sep = memchr(name, ':', fixup_len);
- if (!sep || *sep != ':')
- return -FDT_ERR_BADOVERLAY;
-
- name_len = sep - name;
- if (!name_len)
- return -FDT_ERR_BADOVERLAY;
-
- poffset = strtoul(sep + 1, &endptr, 10);
- if ((*endptr != '\0') || (endptr <= (sep + 1)))
- return -FDT_ERR_BADOVERLAY;
-
- ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
- path, path_len, name, name_len,
- poffset, label);
- if (ret)
- return ret;
- } while (len > 0);
-
- return 0;
-}
-
-/**
- * overlay_fixup_phandles - Resolve the overlay phandles to the base
- * device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_fixup_phandles() resolves all the overlay phandles pointing
- * to nodes in the base device tree.
- *
- * This is one of the steps of the device tree overlay application
- * process, when you want all the phandles in the overlay to point to
- * the actual base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_phandles(void *fdt, void *fdto)
-{
- int fixups_off, symbols_off;
- int property;
-
- /* We can have overlays without any fixups */
- fixups_off = fdt_path_offset(fdto, "/__fixups__");
- if (fixups_off == -FDT_ERR_NOTFOUND)
- return 0; /* nothing to do */
- if (fixups_off < 0)
- return fixups_off;
-
- /* And base DTs without symbols */
- symbols_off = fdt_path_offset(fdt, "/__symbols__");
- if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
- return symbols_off;
-
- fdt_for_each_property_offset(property, fdto, fixups_off) {
- int ret;
-
- ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_apply_node - Merges a node into the base device tree
- * @fdt: Base Device Tree blob
- * @target: Node offset in the base device tree to apply the fragment to
- * @fdto: Device tree overlay blob
- * @node: Node offset in the overlay holding the changes to merge
- *
- * overlay_apply_node() merges a node into a target base device tree
- * node pointed.
- *
- * This is part of the final step in the device tree overlay
- * application process, when all the phandles have been adjusted and
- * resolved and you just have to merge overlay into the base device
- * tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_apply_node(void *fdt, int target,
- void *fdto, int node)
-{
- int property;
- int subnode;
-
- fdt_for_each_property_offset(property, fdto, node) {
- const char *name;
- const void *prop;
- int prop_len;
- int ret;
-
- prop = fdt_getprop_by_offset(fdto, property, &name,
- &prop_len);
- if (prop_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
- if (prop_len < 0)
- return prop_len;
-
- ret = fdt_setprop(fdt, target, name, prop, prop_len);
- if (ret)
- return ret;
- }
-
- fdt_for_each_subnode(subnode, fdto, node) {
- const char *name = fdt_get_name(fdto, subnode, NULL);
- int nnode;
- int ret;
-
- nnode = fdt_add_subnode(fdt, target, name);
- if (nnode == -FDT_ERR_EXISTS) {
- nnode = fdt_subnode_offset(fdt, target, name);
- if (nnode == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
- }
-
- if (nnode < 0)
- return nnode;
-
- ret = overlay_apply_node(fdt, nnode, fdto, subnode);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_merge - Merge an overlay into its base device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_merge() merges an overlay into its base device tree.
- *
- * This is the next to last step in the device tree overlay application
- * process, when all the phandles have been adjusted and resolved and
- * you just have to merge overlay into the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_merge(void *fdt, void *fdto)
-{
- int fragment;
-
- fdt_for_each_subnode(fragment, fdto, 0) {
- int overlay;
- int target;
- int ret;
-
- /*
- * Each fragments will have an __overlay__ node. If
- * they don't, it's not supposed to be merged
- */
- overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
- if (overlay == -FDT_ERR_NOTFOUND)
- continue;
-
- if (overlay < 0)
- return overlay;
-
- target = overlay_get_target(fdt, fdto, fragment, NULL);
- if (target < 0)
- return target;
-
- ret = overlay_apply_node(fdt, target, fdto, overlay);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int get_path_len(const void *fdt, int nodeoffset)
-{
- int len = 0, namelen;
- const char *name;
-
- FDT_CHECK_HEADER(fdt);
-
- for (;;) {
- name = fdt_get_name(fdt, nodeoffset, &namelen);
- if (!name)
- return namelen;
-
- /* root? we're done */
- if (namelen == 0)
- break;
-
- nodeoffset = fdt_parent_offset(fdt, nodeoffset);
- if (nodeoffset < 0)
- return nodeoffset;
- len += namelen + 1;
- }
-
- /* in case of root pretend it's "/" */
- if (len == 0)
- len++;
- return len;
-}
-
-/**
- * overlay_symbol_update - Update the symbols of base tree after a merge
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_symbol_update() updates the symbols of the base tree with the
- * symbols of the applied overlay
- *
- * This is the last step in the device tree overlay application
- * process, allowing the reference of overlay symbols by subsequent
- * overlay operations.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_symbol_update(void *fdt, void *fdto)
-{
- int root_sym, ov_sym, prop, path_len, fragment, target;
- int len, frag_name_len, ret, rel_path_len;
- const char *s, *e;
- const char *path;
- const char *name;
- const char *frag_name;
- const char *rel_path;
- const char *target_path;
- char *buf;
- void *p;
-
- ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
-
- /* if no overlay symbols exist no problem */
- if (ov_sym < 0)
- return 0;
-
- root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
-
- /* it no root symbols exist we should create them */
- if (root_sym == -FDT_ERR_NOTFOUND)
- root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
-
- /* any error is fatal now */
- if (root_sym < 0)
- return root_sym;
-
- /* iterate over each overlay symbol */
- fdt_for_each_property_offset(prop, fdto, ov_sym) {
- path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
- if (!path)
- return path_len;
-
- /* verify it's a string property (terminated by a single \0) */
- if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
- return -FDT_ERR_BADVALUE;
-
- /* keep end marker to avoid strlen() */
- e = path + path_len;
-
- /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
-
- if (*path != '/')
- return -FDT_ERR_BADVALUE;
-
- /* get fragment name first */
- s = strchr(path + 1, '/');
- if (!s)
- return -FDT_ERR_BADOVERLAY;
-
- frag_name = path + 1;
- frag_name_len = s - path - 1;
-
- /* verify format; safe since "s" lies in \0 terminated prop */
- len = sizeof("/__overlay__/") - 1;
- if ((e - s) < len || memcmp(s, "/__overlay__/", len))
- return -FDT_ERR_BADOVERLAY;
-
- rel_path = s + len;
- rel_path_len = e - rel_path;
-
- /* find the fragment index in which the symbol lies */
- ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
- frag_name_len);
- /* not found? */
- if (ret < 0)
- return -FDT_ERR_BADOVERLAY;
- fragment = ret;
-
- /* an __overlay__ subnode must exist */
- ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
- if (ret < 0)
- return -FDT_ERR_BADOVERLAY;
-
- /* get the target of the fragment */
- ret = overlay_get_target(fdt, fdto, fragment, &target_path);
- if (ret < 0)
- return ret;
- target = ret;
-
- /* if we have a target path use */
- if (!target_path) {
- ret = get_path_len(fdt, target);
- if (ret < 0)
- return ret;
- len = ret;
- } else {
- len = strlen(target_path);
- }
-
- ret = fdt_setprop_placeholder(fdt, root_sym, name,
- len + (len > 1) + rel_path_len + 1, &p);
- if (ret < 0)
- return ret;
-
- if (!target_path) {
- /* again in case setprop_placeholder changed it */
- ret = overlay_get_target(fdt, fdto, fragment, &target_path);
- if (ret < 0)
- return ret;
- target = ret;
- }
-
- buf = p;
- if (len > 1) { /* target is not root */
- if (!target_path) {
- ret = fdt_get_path(fdt, target, buf, len + 1);
- if (ret < 0)
- return ret;
- } else
- memcpy(buf, target_path, len + 1);
-
- } else
- len--;
-
- buf[len] = '/';
- memcpy(buf + len + 1, rel_path, rel_path_len);
- buf[len + 1 + rel_path_len] = '\0';
- }
-
- return 0;
-}
-
-int fdt_overlay_apply(void *fdt, void *fdto)
-{
- uint32_t delta = fdt_get_max_phandle(fdt);
- int ret;
-
- FDT_CHECK_HEADER(fdt);
- FDT_CHECK_HEADER(fdto);
-
- ret = overlay_adjust_local_phandles(fdto, delta);
- if (ret)
- goto err;
-
- ret = overlay_update_local_references(fdto, delta);
- if (ret)
- goto err;
-
- ret = overlay_fixup_phandles(fdt, fdto);
- if (ret)
- goto err;
-
- ret = overlay_merge(fdt, fdto);
- if (ret)
- goto err;
-
- ret = overlay_symbol_update(fdt, fdto);
- if (ret)
- goto err;
-
- /*
- * The overlay has been damaged, erase its magic.
- */
- fdt_set_magic(fdto, ~0);
-
- return 0;
-
-err:
- /*
- * The overlay might have been damaged, erase its magic.
- */
- fdt_set_magic(fdto, ~0);
-
- /*
- * The base device tree might have been damaged, erase its
- * magic.
- */
- fdt_set_magic(fdt, ~0);
-
- return ret;
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2016 Free Electrons
+ * Copyright (C) 2016 NextThing Co.
+ *
+ * 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_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+/**
+ * overlay_get_target_phandle - retrieves the target phandle of a fragment
+ * @fdto: pointer to the device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ *
+ * overlay_get_target_phandle() retrieves the target phandle of an
+ * overlay fragment when that fragment uses a phandle (target
+ * property) instead of a path (target-path property).
+ *
+ * returns:
+ * the phandle pointed by the target property
+ * 0, if the phandle was not found
+ * -1, if the phandle was malformed
+ */
+static uint32_t
+overlay_get_target_phandle (
+ const void *fdto,
+ int fragment
+ )
+{
+ const fdt32_t *val;
+ int len;
+
+ val = fdt_getprop (fdto, fragment, "target", &len);
+ if (!val) {
+ return 0;
+ }
+
+ if ((len != sizeof (*val)) || (fdt32_to_cpu (*val) == (uint32_t)-1)) {
+ return (uint32_t)-1;
+ }
+
+ return fdt32_to_cpu (*val);
+}
+
+/**
+ * overlay_get_target - retrieves the offset of a fragment's target
+ * @fdt: Base device tree blob
+ * @fdto: Device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
+ *
+ * overlay_get_target() retrieves the target offset in the base
+ * device tree of a fragment, no matter how the actual targetting is
+ * done (through a phandle or a path)
+ *
+ * returns:
+ * the targetted node offset in the base device tree
+ * Negative error code on error
+ */
+static int
+overlay_get_target (
+ const void *fdt,
+ const void *fdto,
+ int fragment,
+ char const **pathp
+ )
+{
+ uint32_t phandle;
+ const char *path = NULL;
+ int path_len = 0, ret;
+
+ /* Try first to do a phandle based lookup */
+ phandle = overlay_get_target_phandle (fdto, fragment);
+ if (phandle == (uint32_t)-1) {
+ return -FDT_ERR_BADPHANDLE;
+ }
+
+ /* no phandle, try path */
+ if (!phandle) {
+ /* And then a path based lookup */
+ path = fdt_getprop (fdto, fragment, "target-path", &path_len);
+ if (path) {
+ ret = fdt_path_offset (fdt, path);
+ } else {
+ ret = path_len;
+ }
+ } else {
+ ret = fdt_node_offset_by_phandle (fdt, phandle);
+ }
+
+ /*
+ * If we haven't found either a target or a
+ * target-path property in a node that contains a
+ * __overlay__ subnode (we wouldn't be called
+ * otherwise), consider it a improperly written
+ * overlay
+ */
+ if ((ret < 0) && (path_len == -FDT_ERR_NOTFOUND)) {
+ ret = -FDT_ERR_BADOVERLAY;
+ }
+
+ /* return on error */
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* return pointer to path (if available) */
+ if (pathp) {
+ *pathp = path ? path : NULL;
+ }
+
+ return ret;
+}
+
+/**
+ * overlay_phandle_add_offset - Increases a phandle by an offset
+ * @fdt: Base device tree blob
+ * @node: Device tree overlay blob
+ * @name: Name of the property to modify (phandle or linux,phandle)
+ * @delta: offset to apply
+ *
+ * overlay_phandle_add_offset() increments a node phandle by a given
+ * offset.
+ *
+ * returns:
+ * 0 on success.
+ * Negative error code on error
+ */
+static int
+overlay_phandle_add_offset (
+ void *fdt,
+ int node,
+ const char *name,
+ uint32_t delta
+ )
+{
+ const fdt32_t *val;
+ uint32_t adj_val;
+ int len;
+
+ val = fdt_getprop (fdt, node, name, &len);
+ if (!val) {
+ return len;
+ }
+
+ if (len != sizeof (*val)) {
+ return -FDT_ERR_BADPHANDLE;
+ }
+
+ adj_val = fdt32_to_cpu (*val);
+ if ((adj_val + delta) < adj_val) {
+ return -FDT_ERR_NOPHANDLES;
+ }
+
+ adj_val += delta;
+ if (adj_val == (uint32_t)-1) {
+ return -FDT_ERR_NOPHANDLES;
+ }
+
+ return fdt_setprop_inplace_u32 (fdt, node, name, adj_val);
+}
+
+/**
+ * overlay_adjust_node_phandles - Offsets the phandles of a node
+ * @fdto: Device tree overlay blob
+ * @node: Offset of the node we want to adjust
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_node_phandles() adds a constant to all the phandles
+ * of a given node. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_adjust_node_phandles (
+ void *fdto,
+ int node,
+ uint32_t delta
+ )
+{
+ int child;
+ int ret;
+
+ ret = overlay_phandle_add_offset (fdto, node, "phandle", delta);
+ if (ret && (ret != -FDT_ERR_NOTFOUND)) {
+ return ret;
+ }
+
+ ret = overlay_phandle_add_offset (fdto, node, "linux,phandle", delta);
+ if (ret && (ret != -FDT_ERR_NOTFOUND)) {
+ return ret;
+ }
+
+ fdt_for_each_subnode (child, fdto, node) {
+ ret = overlay_adjust_node_phandles (fdto, child, delta);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_local_phandles() adds a constant to all the
+ * phandles of an overlay. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_adjust_local_phandles (
+ void *fdto,
+ uint32_t delta
+ )
+{
+ /*
+ * Start adjusting the phandles from the overlay root
+ */
+ return overlay_adjust_node_phandles (fdto, 0, delta);
+}
+
+/**
+ * overlay_update_local_node_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @tree_node: Node offset of the node to operate on
+ * @fixup_node: Node offset of the matching local fixups node
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_nodes_references() update the phandles
+ * pointing to a node within the device tree overlay by adding a
+ * constant delta.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_update_local_node_references (
+ void *fdto,
+ int tree_node,
+ int fixup_node,
+ uint32_t delta
+ )
+{
+ int fixup_prop;
+ int fixup_child;
+ int ret;
+
+ fdt_for_each_property_offset (fixup_prop, fdto, fixup_node) {
+ const fdt32_t *fixup_val;
+ const char *tree_val;
+ const char *name;
+ int fixup_len;
+ int tree_len;
+ int i;
+
+ fixup_val = fdt_getprop_by_offset (
+ fdto,
+ fixup_prop,
+ &name,
+ &fixup_len
+ );
+ if (!fixup_val) {
+ return fixup_len;
+ }
+
+ if (fixup_len % sizeof (uint32_t)) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ tree_val = fdt_getprop (fdto, tree_node, name, &tree_len);
+ if (!tree_val) {
+ if (tree_len == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ return tree_len;
+ }
+
+ for (i = 0; i < (fixup_len / sizeof (uint32_t)); i++) {
+ fdt32_t adj_val;
+ uint32_t poffset;
+
+ poffset = fdt32_to_cpu (fixup_val[i]);
+
+ /*
+ * phandles to fixup can be unaligned.
+ *
+ * Use a memcpy for the architectures that do
+ * not support unaligned accesses.
+ */
+ memcpy (&adj_val, tree_val + poffset, sizeof (adj_val));
+
+ adj_val = cpu_to_fdt32 (fdt32_to_cpu (adj_val) + delta);
+
+ ret = fdt_setprop_inplace_namelen_partial (
+ fdto,
+ tree_node,
+ name,
+ strlen (name),
+ poffset,
+ &adj_val,
+ sizeof (adj_val)
+ );
+ if (ret == -FDT_ERR_NOSPACE) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+
+ fdt_for_each_subnode (fixup_child, fdto, fixup_node) {
+ const char *fixup_child_name = fdt_get_name (
+ fdto,
+ fixup_child,
+ NULL
+ );
+ int tree_child;
+
+ tree_child = fdt_subnode_offset (
+ fdto,
+ tree_node,
+ fixup_child_name
+ );
+ if (tree_child == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ if (tree_child < 0) {
+ return tree_child;
+ }
+
+ ret = overlay_update_local_node_references (
+ fdto,
+ tree_child,
+ fixup_child,
+ delta
+ );
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_update_local_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_references() update all the phandles pointing
+ * to a node within the device tree overlay by adding a constant
+ * delta to not conflict with the base overlay.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_update_local_references (
+ void *fdto,
+ uint32_t delta
+ )
+{
+ int fixups;
+
+ fixups = fdt_path_offset (fdto, "/__local_fixups__");
+ if (fixups < 0) {
+ /* There's no local phandles to adjust, bail out */
+ if (fixups == -FDT_ERR_NOTFOUND) {
+ return 0;
+ }
+
+ return fixups;
+ }
+
+ /*
+ * Update our local references from the root of the tree
+ */
+ return overlay_update_local_node_references (
+ fdto,
+ 0,
+ fixups,
+ delta
+ );
+}
+
+/**
+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @path: Path to a node holding a phandle in the overlay
+ * @path_len: number of path characters to consider
+ * @name: Name of the property holding the phandle reference in the overlay
+ * @name_len: number of name characters to consider
+ * @poffset: Offset within the overlay property where the phandle is stored
+ * @label: Label of the node referenced by the phandle
+ *
+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
+ * a node in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_fixup_one_phandle (
+ void *fdt,
+ void *fdto,
+ int symbols_off,
+ const char *path,
+ uint32_t path_len,
+ const char *name,
+ uint32_t name_len,
+ int poffset,
+ const char *label
+ )
+{
+ const char *symbol_path;
+ uint32_t phandle;
+ fdt32_t phandle_prop;
+ int symbol_off, fixup_off;
+ int prop_len;
+
+ if (symbols_off < 0) {
+ return symbols_off;
+ }
+
+ symbol_path = fdt_getprop (
+ fdt,
+ symbols_off,
+ label,
+ &prop_len
+ );
+ if (!symbol_path) {
+ return prop_len;
+ }
+
+ symbol_off = fdt_path_offset (fdt, symbol_path);
+ if (symbol_off < 0) {
+ return symbol_off;
+ }
+
+ phandle = fdt_get_phandle (fdt, symbol_off);
+ if (!phandle) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ fixup_off = fdt_path_offset_namelen (fdto, path, path_len);
+ if (fixup_off == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ if (fixup_off < 0) {
+ return fixup_off;
+ }
+
+ phandle_prop = cpu_to_fdt32 (phandle);
+ return fdt_setprop_inplace_namelen_partial (
+ fdto,
+ fixup_off,
+ name,
+ name_len,
+ poffset,
+ &phandle_prop,
+ sizeof (phandle_prop)
+ );
+}
+
+unsigned long
+strtoul (
+ const char *nptr,
+ char **endptr,
+ int base
+ );
+
+/**
+ * overlay_fixup_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @property: Property offset in the overlay holding the list of fixups
+ *
+ * overlay_fixup_phandle() resolves all the overlay phandles pointed
+ * to in a __fixups__ property, and updates them to match the phandles
+ * in use in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_fixup_phandle (
+ void *fdt,
+ void *fdto,
+ int symbols_off,
+ int property
+ )
+{
+ const char *value;
+ const char *label;
+ int len;
+
+ value = fdt_getprop_by_offset (
+ fdto,
+ property,
+ &label,
+ &len
+ );
+ if (!value) {
+ if (len == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_INTERNAL;
+ }
+
+ return len;
+ }
+
+ do {
+ const char *path, *name, *fixup_end;
+ const char *fixup_str = value;
+ uint32_t path_len, name_len;
+ uint32_t fixup_len;
+ char *sep, *endptr;
+ int poffset, ret;
+
+ fixup_end = memchr (value, '\0', len);
+ if (!fixup_end) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ fixup_len = fixup_end - fixup_str;
+
+ len -= fixup_len + 1;
+ value += fixup_len + 1;
+
+ path = fixup_str;
+ sep = memchr (fixup_str, ':', fixup_len);
+ if (!sep || (*sep != ':')) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ path_len = sep - path;
+ if (path_len == (fixup_len - 1)) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ fixup_len -= path_len + 1;
+ name = sep + 1;
+ sep = memchr (name, ':', fixup_len);
+ if (!sep || (*sep != ':')) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ name_len = sep - name;
+ if (!name_len) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ poffset = strtoul (sep + 1, &endptr, 10);
+ if ((*endptr != '\0') || (endptr <= (sep + 1))) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ ret = overlay_fixup_one_phandle (
+ fdt,
+ fdto,
+ symbols_off,
+ path,
+ path_len,
+ name,
+ name_len,
+ poffset,
+ label
+ );
+ if (ret) {
+ return ret;
+ }
+ } while (len > 0);
+
+ return 0;
+}
+
+/**
+ * overlay_fixup_phandles - Resolve the overlay phandles to the base
+ * device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_fixup_phandles() resolves all the overlay phandles pointing
+ * to nodes in the base device tree.
+ *
+ * This is one of the steps of the device tree overlay application
+ * process, when you want all the phandles in the overlay to point to
+ * the actual base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_fixup_phandles (
+ void *fdt,
+ void *fdto
+ )
+{
+ int fixups_off, symbols_off;
+ int property;
+
+ /* We can have overlays without any fixups */
+ fixups_off = fdt_path_offset (fdto, "/__fixups__");
+ if (fixups_off == -FDT_ERR_NOTFOUND) {
+ return 0; /* nothing to do */
+ }
+
+ if (fixups_off < 0) {
+ return fixups_off;
+ }
+
+ /* And base DTs without symbols */
+ symbols_off = fdt_path_offset (fdt, "/__symbols__");
+ if (((symbols_off < 0) && (symbols_off != -FDT_ERR_NOTFOUND))) {
+ return symbols_off;
+ }
+
+ fdt_for_each_property_offset (property, fdto, fixups_off) {
+ int ret;
+
+ ret = overlay_fixup_phandle (fdt, fdto, symbols_off, property);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_apply_node - Merges a node into the base device tree
+ * @fdt: Base Device Tree blob
+ * @target: Node offset in the base device tree to apply the fragment to
+ * @fdto: Device tree overlay blob
+ * @node: Node offset in the overlay holding the changes to merge
+ *
+ * overlay_apply_node() merges a node into a target base device tree
+ * node pointed.
+ *
+ * This is part of the final step in the device tree overlay
+ * application process, when all the phandles have been adjusted and
+ * resolved and you just have to merge overlay into the base device
+ * tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_apply_node (
+ void *fdt,
+ int target,
+ void *fdto,
+ int node
+ )
+{
+ int property;
+ int subnode;
+
+ fdt_for_each_property_offset (property, fdto, node) {
+ const char *name;
+ const void *prop;
+ int prop_len;
+ int ret;
+
+ prop = fdt_getprop_by_offset (
+ fdto,
+ property,
+ &name,
+ &prop_len
+ );
+ if (prop_len == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_INTERNAL;
+ }
+
+ if (prop_len < 0) {
+ return prop_len;
+ }
+
+ ret = fdt_setprop (fdt, target, name, prop, prop_len);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ fdt_for_each_subnode (subnode, fdto, node) {
+ const char *name = fdt_get_name (fdto, subnode, NULL);
+ int nnode;
+ int ret;
+
+ nnode = fdt_add_subnode (fdt, target, name);
+ if (nnode == -FDT_ERR_EXISTS) {
+ nnode = fdt_subnode_offset (fdt, target, name);
+ if (nnode == -FDT_ERR_NOTFOUND) {
+ return -FDT_ERR_INTERNAL;
+ }
+ }
+
+ if (nnode < 0) {
+ return nnode;
+ }
+
+ ret = overlay_apply_node (fdt, nnode, fdto, subnode);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_merge - Merge an overlay into its base device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_merge() merges an overlay into its base device tree.
+ *
+ * This is the next to last step in the device tree overlay application
+ * process, when all the phandles have been adjusted and resolved and
+ * you just have to merge overlay into the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_merge (
+ void *fdt,
+ void *fdto
+ )
+{
+ int fragment;
+
+ fdt_for_each_subnode (fragment, fdto, 0) {
+ int overlay;
+ int target;
+ int ret;
+
+ /*
+ * Each fragments will have an __overlay__ node. If
+ * they don't, it's not supposed to be merged
+ */
+ overlay = fdt_subnode_offset (fdto, fragment, "__overlay__");
+ if (overlay == -FDT_ERR_NOTFOUND) {
+ continue;
+ }
+
+ if (overlay < 0) {
+ return overlay;
+ }
+
+ target = overlay_get_target (fdt, fdto, fragment, NULL);
+ if (target < 0) {
+ return target;
+ }
+
+ ret = overlay_apply_node (fdt, target, fdto, overlay);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int
+get_path_len (
+ const void *fdt,
+ int nodeoffset
+ )
+{
+ int len = 0, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER (fdt);
+
+ for ( ; ;) {
+ name = fdt_get_name (fdt, nodeoffset, &namelen);
+ if (!name) {
+ return namelen;
+ }
+
+ /* root? we're done */
+ if (namelen == 0) {
+ break;
+ }
+
+ nodeoffset = fdt_parent_offset (fdt, nodeoffset);
+ if (nodeoffset < 0) {
+ return nodeoffset;
+ }
+
+ len += namelen + 1;
+ }
+
+ /* in case of root pretend it's "/" */
+ if (len == 0) {
+ len++;
+ }
+
+ return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int
+overlay_symbol_update (
+ void *fdt,
+ void *fdto
+ )
+{
+ int root_sym, ov_sym, prop, path_len, fragment, target;
+ int len, frag_name_len, ret, rel_path_len;
+ const char *s, *e;
+ const char *path;
+ const char *name;
+ const char *frag_name;
+ const char *rel_path;
+ const char *target_path;
+ char *buf;
+ void *p;
+
+ ov_sym = fdt_subnode_offset (fdto, 0, "__symbols__");
+
+ /* if no overlay symbols exist no problem */
+ if (ov_sym < 0) {
+ return 0;
+ }
+
+ root_sym = fdt_subnode_offset (fdt, 0, "__symbols__");
+
+ /* it no root symbols exist we should create them */
+ if (root_sym == -FDT_ERR_NOTFOUND) {
+ root_sym = fdt_add_subnode (fdt, 0, "__symbols__");
+ }
+
+ /* any error is fatal now */
+ if (root_sym < 0) {
+ return root_sym;
+ }
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset (prop, fdto, ov_sym) {
+ path = fdt_getprop_by_offset (fdto, prop, &name, &path_len);
+ if (!path) {
+ return path_len;
+ }
+
+ /* verify it's a string property (terminated by a single \0) */
+ if ((path_len < 1) || (memchr (path, '\0', path_len) != &path[path_len - 1])) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ /* keep end marker to avoid strlen() */
+ e = path + path_len;
+
+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+ if (*path != '/') {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ /* get fragment name first */
+ s = strchr (path + 1, '/');
+ if (!s) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ frag_name = path + 1;
+ frag_name_len = s - path - 1;
+
+ /* verify format; safe since "s" lies in \0 terminated prop */
+ len = sizeof ("/__overlay__/") - 1;
+ if (((e - s) < len) || memcmp (s, "/__overlay__/", len)) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ rel_path = s + len;
+ rel_path_len = e - rel_path;
+
+ /* find the fragment index in which the symbol lies */
+ ret = fdt_subnode_offset_namelen (
+ fdto,
+ 0,
+ frag_name,
+ frag_name_len
+ );
+ /* not found? */
+ if (ret < 0) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ fragment = ret;
+
+ /* an __overlay__ subnode must exist */
+ ret = fdt_subnode_offset (fdto, fragment, "__overlay__");
+ if (ret < 0) {
+ return -FDT_ERR_BADOVERLAY;
+ }
+
+ /* get the target of the fragment */
+ ret = overlay_get_target (fdt, fdto, fragment, &target_path);
+ if (ret < 0) {
+ return ret;
+ }
+
+ target = ret;
+
+ /* if we have a target path use */
+ if (!target_path) {
+ ret = get_path_len (fdt, target);
+ if (ret < 0) {
+ return ret;
+ }
+
+ len = ret;
+ } else {
+ len = strlen (target_path);
+ }
+
+ ret = fdt_setprop_placeholder (
+ fdt,
+ root_sym,
+ name,
+ len + (len > 1) + rel_path_len + 1,
+ &p
+ );
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (!target_path) {
+ /* again in case setprop_placeholder changed it */
+ ret = overlay_get_target (fdt, fdto, fragment, &target_path);
+ if (ret < 0) {
+ return ret;
+ }
+
+ target = ret;
+ }
+
+ buf = p;
+ if (len > 1) {
+ /* target is not root */
+ if (!target_path) {
+ ret = fdt_get_path (fdt, target, buf, len + 1);
+ if (ret < 0) {
+ return ret;
+ }
+ } else {
+ memcpy (buf, target_path, len + 1);
+ }
+ } else {
+ len--;
+ }
+
+ buf[len] = '/';
+ memcpy (buf + len + 1, rel_path, rel_path_len);
+ buf[len + 1 + rel_path_len] = '\0';
+ }
+
+ return 0;
+}
+
+int
+fdt_overlay_apply (
+ void *fdt,
+ void *fdto
+ )
+{
+ uint32_t delta = fdt_get_max_phandle (fdt);
+ int ret;
+
+ FDT_CHECK_HEADER (fdt);
+ FDT_CHECK_HEADER (fdto);
+
+ ret = overlay_adjust_local_phandles (fdto, delta);
+ if (ret) {
+ goto err;
+ }
+
+ ret = overlay_update_local_references (fdto, delta);
+ if (ret) {
+ goto err;
+ }
+
+ ret = overlay_fixup_phandles (fdt, fdto);
+ if (ret) {
+ goto err;
+ }
+
+ ret = overlay_merge (fdt, fdto);
+ if (ret) {
+ goto err;
+ }
+
+ ret = overlay_symbol_update (fdt, fdto);
+ if (ret) {
+ goto err;
+ }
+
+ /*
+ * The overlay has been damaged, erase its magic.
+ */
+ fdt_set_magic (fdto, ~0);
+
+ return 0;
+
+err:
+
+ /*
+ * The overlay might have been damaged, erase its magic.
+ */
+ fdt_set_magic (fdto, ~0);
+
+ /*
+ * The base device tree might have been damaged, erase its
+ * magic.
+ */
+ fdt_set_magic (fdt, ~0);
+
+ return ret;
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_ro.c b/EmbeddedPkg/Library/FdtLib/fdt_ro.c
index 9413f50..30aac37 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_ro.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_ro.c
@@ -55,649 +55,909 @@
#include "libfdt_internal.h"
-static int _fdt_nodename_eq(const void *fdt, int offset,
- const char *s, int len)
+static int
+_fdt_nodename_eq (
+ const void *fdt,
+ int offset,
+ const char *s,
+ int len
+ )
{
- const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+ const char *p = fdt_offset_ptr (fdt, offset + FDT_TAGSIZE, len+1);
- if (!p)
- /* short match */
- return 0;
+ if (!p) {
+ /* short match */
+ return 0;
+ }
- if (memcmp(p, s, len) != 0)
- return 0;
+ if (memcmp (p, s, len) != 0) {
+ return 0;
+ }
- if (p[len] == '\0')
- return 1;
- else if (!memchr(s, '@', len) && (p[len] == '@'))
- return 1;
- else
- return 0;
+ if (p[len] == '\0') {
+ return 1;
+ } else if (!memchr (s, '@', len) && (p[len] == '@')) {
+ return 1;
+ } else {
+ return 0;
+ }
}
-const char *fdt_string(const void *fdt, int stroffset)
+const char *
+fdt_string (
+ const void *fdt,
+ int stroffset
+ )
{
- return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+ return (const char *)fdt + fdt_off_dt_strings (fdt) + stroffset;
}
-static int _fdt_string_eq(const void *fdt, int stroffset,
- const char *s, int len)
+static int
+_fdt_string_eq (
+ const void *fdt,
+ int stroffset,
+ const char *s,
+ int len
+ )
{
- const char *p = fdt_string(fdt, stroffset);
+ const char *p = fdt_string (fdt, stroffset);
- return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+ return (strlen (p) == len) && (memcmp (p, s, len) == 0);
}
-uint32_t fdt_get_max_phandle(const void *fdt)
+uint32_t
+fdt_get_max_phandle (
+ const void *fdt
+ )
{
- uint32_t max_phandle = 0;
- int offset;
+ uint32_t max_phandle = 0;
+ int offset;
- for (offset = fdt_next_node(fdt, -1, NULL);;
- offset = fdt_next_node(fdt, offset, NULL)) {
- uint32_t phandle;
+ for (offset = fdt_next_node (fdt, -1, NULL); ;
+ offset = fdt_next_node (fdt, offset, NULL))
+ {
+ uint32_t phandle;
- if (offset == -FDT_ERR_NOTFOUND)
- return max_phandle;
+ if (offset == -FDT_ERR_NOTFOUND) {
+ return max_phandle;
+ }
- if (offset < 0)
- return (uint32_t)-1;
+ if (offset < 0) {
+ return (uint32_t)-1;
+ }
- phandle = fdt_get_phandle(fdt, offset);
- if (phandle == (uint32_t)-1)
- continue;
+ phandle = fdt_get_phandle (fdt, offset);
+ if (phandle == (uint32_t)-1) {
+ continue;
+ }
- if (phandle > max_phandle)
- max_phandle = phandle;
- }
+ if (phandle > max_phandle) {
+ max_phandle = phandle;
+ }
+ }
- return 0;
+ return 0;
}
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
+int
+fdt_get_mem_rsv (
+ const void *fdt,
+ int n,
+ uint64_t *address,
+ uint64_t *size
+ )
{
- FDT_CHECK_HEADER(fdt);
- *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
- *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
- return 0;
+ FDT_CHECK_HEADER (fdt);
+ *address = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->address);
+ *size = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->size);
+ return 0;
}
-int fdt_num_mem_rsv(const void *fdt)
+int
+fdt_num_mem_rsv (
+ const void *fdt
+ )
{
- int i = 0;
+ int i = 0;
- while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
- i++;
- return i;
-}
-
-static int _nextprop(const void *fdt, int offset)
-{
- uint32_t tag;
- int nextoffset;
-
- do {
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_END:
- if (nextoffset >= 0)
- return -FDT_ERR_BADSTRUCTURE;
- else
- return nextoffset;
+ while (fdt64_to_cpu (_fdt_mem_rsv (fdt, i)->size) != 0) {
+ i++;
+ }
- case FDT_PROP:
- return offset;
- }
- offset = nextoffset;
- } while (tag == FDT_NOP);
-
- return -FDT_ERR_NOTFOUND;
+ return i;
}
-int fdt_subnode_offset_namelen(const void *fdt, int offset,
- const char *name, int namelen)
+static int
+_nextprop (
+ const void *fdt,
+ int offset
+ )
{
- int depth;
-
- FDT_CHECK_HEADER(fdt);
-
- for (depth = 0;
- (offset >= 0) && (depth >= 0);
- offset = fdt_next_node(fdt, offset, &depth))
- if ((depth == 1)
- && _fdt_nodename_eq(fdt, offset, name, namelen))
- return offset;
-
- if (depth < 0)
- return -FDT_ERR_NOTFOUND;
- return offset; /* error */
-}
-
-int fdt_subnode_offset(const void *fdt, int parentoffset,
- const char *name)
-{
- return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
-{
- const char *end = path + namelen;
- const char *p = path;
- int offset = 0;
-
- FDT_CHECK_HEADER(fdt);
-
- /* see if we have an alias */
- if (*path != '/') {
- const char *q = memchr(path, '/', end - p);
+ uint32_t tag;
+ int nextoffset;
- if (!q)
- q = end;
+ do {
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
- p = fdt_get_alias_namelen(fdt, p, q - p);
- if (!p)
- return -FDT_ERR_BADPATH;
- offset = fdt_path_offset(fdt, p);
+ switch (tag) {
+ case FDT_END:
+ if (nextoffset >= 0) {
+ return -FDT_ERR_BADSTRUCTURE;
+ } else {
+ return nextoffset;
+ }
- p = q;
- }
+ case FDT_PROP:
+ return offset;
+ }
- while (p < end) {
- const char *q;
+ offset = nextoffset;
+ } while (tag == FDT_NOP);
- while (*p == '/') {
- p++;
- if (p == end)
- return offset;
- }
- q = memchr(p, '/', end - p);
- if (! q)
- q = end;
-
- offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
- if (offset < 0)
- return offset;
-
- p = q;
- }
-
- return offset;
+ return -FDT_ERR_NOTFOUND;
}
-int fdt_path_offset(const void *fdt, const char *path)
+int
+fdt_subnode_offset_namelen (
+ const void *fdt,
+ int offset,
+ const char *name,
+ int namelen
+ )
{
- return fdt_path_offset_namelen(fdt, path, strlen(path));
-}
+ int depth;
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
-{
- const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
- int err;
+ FDT_CHECK_HEADER (fdt);
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
+ for (depth = 0;
+ (offset >= 0) && (depth >= 0);
+ offset = fdt_next_node (fdt, offset, &depth))
+ {
+ if ( (depth == 1)
+ && _fdt_nodename_eq (fdt, offset, name, namelen))
+ {
+ return offset;
+ }
+ }
- if (len)
- *len = strlen(nh->name);
+ if (depth < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
- return nh->name;
-
- fail:
- if (len)
- *len = err;
- return NULL;
+ return offset; /* error */
}
-int fdt_first_property_offset(const void *fdt, int nodeoffset)
+int
+fdt_subnode_offset (
+ const void *fdt,
+ int parentoffset,
+ const char *name
+ )
{
- int offset;
-
- if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return offset;
-
- return _nextprop(fdt, offset);
+ return fdt_subnode_offset_namelen (fdt, parentoffset, name, strlen (name));
}
-int fdt_next_property_offset(const void *fdt, int offset)
+int
+fdt_path_offset_namelen (
+ const void *fdt,
+ const char *path,
+ int namelen
+ )
{
- if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
- return offset;
+ const char *end = path + namelen;
+ const char *p = path;
+ int offset = 0;
- return _nextprop(fdt, offset);
-}
+ FDT_CHECK_HEADER (fdt);
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp)
-{
- int err;
- const struct fdt_property *prop;
-
- if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
- if (lenp)
- *lenp = err;
- return NULL;
- }
+ /* see if we have an alias */
+ if (*path != '/') {
+ const char *q = memchr (path, '/', end - p);
- prop = _fdt_offset_ptr(fdt, offset);
+ if (!q) {
+ q = end;
+ }
- if (lenp)
- *lenp = fdt32_to_cpu(prop->len);
+ p = fdt_get_alias_namelen (fdt, p, q - p);
+ if (!p) {
+ return -FDT_ERR_BADPATH;
+ }
- return prop;
-}
+ offset = fdt_path_offset (fdt, p);
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int offset,
- const char *name,
- int namelen, int *lenp)
-{
- for (offset = fdt_first_property_offset(fdt, offset);
- (offset >= 0);
- (offset = fdt_next_property_offset(fdt, offset))) {
- const struct fdt_property *prop;
+ p = q;
+ }
- if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
- offset = -FDT_ERR_INTERNAL;
- break;
- }
- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
- name, namelen))
- return prop;
- }
+ while (p < end) {
+ const char *q;
- if (lenp)
- *lenp = offset;
- return NULL;
-}
+ while (*p == '/') {
+ p++;
+ if (p == end) {
+ return offset;
+ }
+ }
-const struct fdt_property *fdt_get_property(const void *fdt,
- int nodeoffset,
- const char *name, int *lenp)
-{
- return fdt_get_property_namelen(fdt, nodeoffset, name,
- strlen(name), lenp);
-}
+ q = memchr (p, '/', end - p);
+ if (!q) {
+ q = end;
+ }
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp)
-{
- const struct fdt_property *prop;
+ offset = fdt_subnode_offset_namelen (fdt, offset, p, q-p);
+ if (offset < 0) {
+ return offset;
+ }
- prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (!prop)
- return NULL;
+ p = q;
+ }
- return prop->data;
+ return offset;
}
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp)
+int
+fdt_path_offset (
+ const void *fdt,
+ const char *path
+ )
{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_by_offset(fdt, offset, lenp);
- if (!prop)
- return NULL;
- if (namep)
- *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
- return prop->data;
+ return fdt_path_offset_namelen (fdt, path, strlen (path));
}
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp)
+const char *
+fdt_get_name (
+ const void *fdt,
+ int nodeoffset,
+ int *len
+ )
{
- return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
-}
+ const struct fdt_node_header *nh = _fdt_offset_ptr (fdt, nodeoffset);
+ int err;
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
-{
- const fdt32_t *php;
- int len;
+ if ( ((err = fdt_check_header (fdt)) != 0)
+ || ((err = _fdt_check_node_offset (fdt, nodeoffset)) < 0))
+ {
+ goto fail;
+ }
- /* FIXME: This is a bit sub-optimal, since we potentially scan
- * over all the properties twice. */
- php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
- if (!php || (len != sizeof(*php))) {
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
- }
+ if (len) {
+ *len = strlen (nh->name);
+ }
- return fdt32_to_cpu(*php);
-}
+ return nh->name;
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen)
-{
- int aliasoffset;
+fail:
+ if (len) {
+ *len = err;
+ }
- aliasoffset = fdt_path_offset(fdt, "/aliases");
- if (aliasoffset < 0)
- return NULL;
-
- return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
-}
-
-const char *fdt_get_alias(const void *fdt, const char *name)
-{
- return fdt_get_alias_namelen(fdt, name, strlen(name));
+ return NULL;
}
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
+int
+fdt_first_property_offset (
+ const void *fdt,
+ int nodeoffset
+ )
{
- int pdepth = 0, p = 0;
- int offset, depth, namelen;
- const char *name;
+ int offset;
- FDT_CHECK_HEADER(fdt);
+ if ((offset = _fdt_check_node_offset (fdt, nodeoffset)) < 0) {
+ return offset;
+ }
- if (buflen < 2)
- return -FDT_ERR_NOSPACE;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- while (pdepth > depth) {
- do {
- p--;
- } while (buf[p-1] != '/');
- pdepth--;
- }
-
- if (pdepth >= depth) {
- name = fdt_get_name(fdt, offset, &namelen);
- if (!name)
- return namelen;
- if ((p + namelen + 1) <= buflen) {
- memcpy(buf + p, name, namelen);
- p += namelen;
- buf[p++] = '/';
- pdepth++;
- }
- }
-
- if (offset == nodeoffset) {
- if (pdepth < (depth + 1))
- return -FDT_ERR_NOSPACE;
-
- if (p > 1) /* special case so that root path is "/", not "" */
- p--;
- buf[p] = '\0';
- return 0;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
+ return _nextprop (fdt, offset);
}
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth)
+int
+fdt_next_property_offset (
+ const void *fdt,
+ int offset
+ )
{
- int offset, depth;
- int supernodeoffset = -FDT_ERR_INTERNAL;
-
- FDT_CHECK_HEADER(fdt);
-
- if (supernodedepth < 0)
- return -FDT_ERR_NOTFOUND;
+ if ((offset = _fdt_check_prop_offset (fdt, offset)) < 0) {
+ return offset;
+ }
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- if (depth == supernodedepth)
- supernodeoffset = offset;
-
- if (offset == nodeoffset) {
- if (nodedepth)
- *nodedepth = depth;
-
- if (supernodedepth > depth)
- return -FDT_ERR_NOTFOUND;
- else
- return supernodeoffset;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_depth(const void *fdt, int nodeoffset)
-{
- int nodedepth;
- int err;
-
- err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
- if (err)
- return (err < 0) ? err : -FDT_ERR_INTERNAL;
- return nodedepth;
+ return _nextprop (fdt, offset);
}
-int fdt_parent_offset(const void *fdt, int nodeoffset)
+const struct fdt_property *
+fdt_get_property_by_offset (
+ const void *fdt,
+ int offset,
+ int *lenp
+ )
{
- int nodedepth = fdt_node_depth(fdt, nodeoffset);
+ int err;
+ const struct fdt_property *prop;
- if (nodedepth < 0)
- return nodedepth;
- return fdt_supernode_atdepth_offset(fdt, nodeoffset,
- nodedepth - 1, NULL);
-}
+ if ((err = _fdt_check_prop_offset (fdt, offset)) < 0) {
+ if (lenp) {
+ *lenp = err;
+ }
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen)
-{
- int offset;
- const void *val;
- int len;
+ return NULL;
+ }
- FDT_CHECK_HEADER(fdt);
+ prop = _fdt_offset_ptr (fdt, offset);
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_getprop(), then if that didn't
- * find what we want, we scan over them again making our way
- * to the next node. Still it's the easiest to implement
- * approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- val = fdt_getprop(fdt, offset, propname, &len);
- if (val && (len == proplen)
- && (memcmp(val, propval, len) == 0))
- return offset;
- }
+ if (lenp) {
+ *lenp = fdt32_to_cpu (prop->len);
+ }
- return offset; /* error from fdt_next_node() */
+ return prop;
}
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
+const struct fdt_property *
+fdt_get_property_namelen (
+ const void *fdt,
+ int offset,
+ const char *name,
+ int namelen,
+ int *lenp
+ )
{
- int offset;
+ for (offset = fdt_first_property_offset (fdt, offset);
+ (offset >= 0);
+ (offset = fdt_next_property_offset (fdt, offset)))
+ {
+ const struct fdt_property *prop;
- if ((phandle == 0) || (phandle == -1))
- return -FDT_ERR_BADPHANDLE;
+ if (!(prop = fdt_get_property_by_offset (fdt, offset, lenp))) {
+ offset = -FDT_ERR_INTERNAL;
+ break;
+ }
- FDT_CHECK_HEADER(fdt);
+ if (_fdt_string_eq (
+ fdt,
+ fdt32_to_cpu (prop->nameoff),
+ name,
+ namelen
+ ))
+ {
+ return prop;
+ }
+ }
- /* FIXME: The algorithm here is pretty horrible: we
- * potentially scan each property of a node in
- * fdt_get_phandle(), then if that didn't find what
- * we want, we scan over them again making our way to the next
- * node. Still it's the easiest to implement approach;
- * performance can come later. */
- for (offset = fdt_next_node(fdt, -1, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- if (fdt_get_phandle(fdt, offset) == phandle)
- return offset;
- }
+ if (lenp) {
+ *lenp = offset;
+ }
- return offset; /* error from fdt_next_node() */
+ return NULL;
}
-int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
+const struct fdt_property *
+fdt_get_property (
+ const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int *lenp
+ )
{
- int len = strlen(str);
- const char *p;
-
- while (listlen >= len) {
- if (memcmp(str, strlist, len+1) == 0)
- return 1;
- p = memchr(strlist, '\0', listlen);
- if (!p)
- return 0; /* malformed strlist.. */
- listlen -= (p-strlist) + 1;
- strlist = p + 1;
- }
- return 0;
+ return fdt_get_property_namelen (
+ fdt,
+ nodeoffset,
+ name,
+ strlen (name),
+ lenp
+ );
}
-int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
+const void *
+fdt_getprop_namelen (
+ const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen,
+ int *lenp
+ )
{
- const char *list, *end;
- int length, count = 0;
-
- list = fdt_getprop(fdt, nodeoffset, property, &length);
- if (!list)
- return length;
+ const struct fdt_property *prop;
- end = list + length;
+ prop = fdt_get_property_namelen (fdt, nodeoffset, name, namelen, lenp);
+ if (!prop) {
+ return NULL;
+ }
- while (list < end) {
- length = strnlen(list, end - list) + 1;
-
- /* Abort if the last string isn't properly NUL-terminated. */
- if (list + length > end)
- return -FDT_ERR_BADVALUE;
+ return prop->data;
+}
+
+const void *
+fdt_getprop_by_offset (
+ const void *fdt,
+ int offset,
+ const char **namep,
+ int *lenp
+ )
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset (fdt, offset, lenp);
+ if (!prop) {
+ return NULL;
+ }
+
+ if (namep) {
+ *namep = fdt_string (fdt, fdt32_to_cpu (prop->nameoff));
+ }
+
+ return prop->data;
+}
+
+const void *
+fdt_getprop (
+ const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int *lenp
+ )
+{
+ return fdt_getprop_namelen (fdt, nodeoffset, name, strlen (name), lenp);
+}
+
+uint32_t
+fdt_get_phandle (
+ const void *fdt,
+ int nodeoffset
+ )
+{
+ const fdt32_t *php;
+ int len;
+
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop (fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof (*php))) {
+ php = fdt_getprop (fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof (*php))) {
+ return 0;
+ }
+ }
+
+ return fdt32_to_cpu (*php);
+}
+
+const char *
+fdt_get_alias_namelen (
+ const void *fdt,
+ const char *name,
+ int namelen
+ )
+{
+ int aliasoffset;
+
+ aliasoffset = fdt_path_offset (fdt, "/aliases");
+ if (aliasoffset < 0) {
+ return NULL;
+ }
+
+ return fdt_getprop_namelen (fdt, aliasoffset, name, namelen, NULL);
+}
+
+const char *
+fdt_get_alias (
+ const void *fdt,
+ const char *name
+ )
+{
+ return fdt_get_alias_namelen (fdt, name, strlen (name));
+}
+
+int
+fdt_get_path (
+ const void *fdt,
+ int nodeoffset,
+ char *buf,
+ int buflen
+ )
+{
+ int pdepth = 0, p = 0;
+ int offset, depth, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER (fdt);
+
+ if (buflen < 2) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node (fdt, offset, &depth))
+ {
+ while (pdepth > depth) {
+ do {
+ p--;
+ } while (buf[p-1] != '/');
+
+ pdepth--;
+ }
+
+ if (pdepth >= depth) {
+ name = fdt_get_name (fdt, offset, &namelen);
+ if (!name) {
+ return namelen;
+ }
+
+ if ((p + namelen + 1) <= buflen) {
+ memcpy (buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ pdepth++;
+ }
+ }
+
+ if (offset == nodeoffset) {
+ if (pdepth < (depth + 1)) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ if (p > 1) {
+ /* special case so that root path is "/", not "" */
+ p--;
+ }
+
+ buf[p] = '\0';
+ return 0;
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) {
+ return -FDT_ERR_BADOFFSET;
+ } else if (offset == -FDT_ERR_BADOFFSET) {
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int
+fdt_supernode_atdepth_offset (
+ const void *fdt,
+ int nodeoffset,
+ int supernodedepth,
+ int *nodedepth
+ )
+{
+ int offset, depth;
+ int supernodeoffset = -FDT_ERR_INTERNAL;
+
+ FDT_CHECK_HEADER (fdt);
+
+ if (supernodedepth < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node (fdt, offset, &depth))
+ {
+ if (depth == supernodedepth) {
+ supernodeoffset = offset;
+ }
+
+ if (offset == nodeoffset) {
+ if (nodedepth) {
+ *nodedepth = depth;
+ }
+
+ if (supernodedepth > depth) {
+ return -FDT_ERR_NOTFOUND;
+ } else {
+ return supernodeoffset;
+ }
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) {
+ return -FDT_ERR_BADOFFSET;
+ } else if (offset == -FDT_ERR_BADOFFSET) {
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int
+fdt_node_depth (
+ const void *fdt,
+ int nodeoffset
+ )
+{
+ int nodedepth;
+ int err;
+
+ err = fdt_supernode_atdepth_offset (fdt, nodeoffset, 0, &nodedepth);
+ if (err) {
+ return (err < 0) ? err : -FDT_ERR_INTERNAL;
+ }
+
+ return nodedepth;
+}
+
+int
+fdt_parent_offset (
+ const void *fdt,
+ int nodeoffset
+ )
+{
+ int nodedepth = fdt_node_depth (fdt, nodeoffset);
+
+ if (nodedepth < 0) {
+ return nodedepth;
+ }
+
+ return fdt_supernode_atdepth_offset (
+ fdt,
+ nodeoffset,
+ nodedepth - 1,
+ NULL
+ );
+}
+
+int
+fdt_node_offset_by_prop_value (
+ const void *fdt,
+ int startoffset,
+ const char *propname,
+ const void *propval,
+ int proplen
+ )
+{
+ int offset;
+ const void *val;
+ int len;
+
+ FDT_CHECK_HEADER (fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_getprop(), then if that didn't
+ * find what we want, we scan over them again making our way
+ * to the next node. Still it's the easiest to implement
+ * approach; performance can come later. */
+ for (offset = fdt_next_node (fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node (fdt, offset, NULL))
+ {
+ val = fdt_getprop (fdt, offset, propname, &len);
+ if ( val && (len == proplen)
+ && (memcmp (val, propval, len) == 0))
+ {
+ return offset;
+ }
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int
+fdt_node_offset_by_phandle (
+ const void *fdt,
+ uint32_t phandle
+ )
+{
+ int offset;
+
+ if ((phandle == 0) || (phandle == -1)) {
+ return -FDT_ERR_BADPHANDLE;
+ }
+
+ FDT_CHECK_HEADER (fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node (fdt, -1, NULL);
+ offset >= 0;
+ offset = fdt_next_node (fdt, offset, NULL))
+ {
+ if (fdt_get_phandle (fdt, offset) == phandle) {
+ return offset;
+ }
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int
+fdt_stringlist_contains (
+ const char *strlist,
+ int listlen,
+ const char *str
+ )
+{
+ int len = strlen (str);
+ const char *p;
+
+ while (listlen >= len) {
+ if (memcmp (str, strlist, len+1) == 0) {
+ return 1;
+ }
+
+ p = memchr (strlist, '\0', listlen);
+ if (!p) {
+ return 0; /* malformed strlist.. */
+ }
+
+ listlen -= (p-strlist) + 1;
+ strlist = p + 1;
+ }
+
+ return 0;
+}
+
+int
+fdt_stringlist_count (
+ const void *fdt,
+ int nodeoffset,
+ const char *property
+ )
+{
+ const char *list, *end;
+ int length, count = 0;
+
+ list = fdt_getprop (fdt, nodeoffset, property, &length);
+ if (!list) {
+ return length;
+ }
+
+ end = list + length;
+
+ while (list < end) {
+ length = strnlen (list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end) {
+ return -FDT_ERR_BADVALUE;
+ }
- list += length;
- count++;
- }
+ list += length;
+ count++;
+ }
- return count;
+ return count;
}
-int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
- const char *string)
+int
+fdt_stringlist_search (
+ const void *fdt,
+ int nodeoffset,
+ const char *property,
+ const char *string
+ )
{
- int length, len, idx = 0;
- const char *list, *end;
+ int length, len, idx = 0;
+ const char *list, *end;
- list = fdt_getprop(fdt, nodeoffset, property, &length);
- if (!list)
- return length;
+ list = fdt_getprop (fdt, nodeoffset, property, &length);
+ if (!list) {
+ return length;
+ }
- len = strlen(string) + 1;
- end = list + length;
+ len = strlen (string) + 1;
+ end = list + length;
- while (list < end) {
- length = strnlen(list, end - list) + 1;
+ while (list < end) {
+ length = strnlen (list, end - list) + 1;
- /* Abort if the last string isn't properly NUL-terminated. */
- if (list + length > end)
- return -FDT_ERR_BADVALUE;
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end) {
+ return -FDT_ERR_BADVALUE;
+ }
- if (length == len && memcmp(list, string, length) == 0)
- return idx;
+ if ((length == len) && (memcmp (list, string, length) == 0)) {
+ return idx;
+ }
- list += length;
- idx++;
- }
+ list += length;
+ idx++;
+ }
- return -FDT_ERR_NOTFOUND;
+ return -FDT_ERR_NOTFOUND;
}
-const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
- const char *property, int idx,
- int *lenp)
+const char *
+fdt_stringlist_get (
+ const void *fdt,
+ int nodeoffset,
+ const char *property,
+ int idx,
+ int *lenp
+ )
{
- const char *list, *end;
- int length;
+ const char *list, *end;
+ int length;
- list = fdt_getprop(fdt, nodeoffset, property, &length);
- if (!list) {
- if (lenp)
- *lenp = length;
+ list = fdt_getprop (fdt, nodeoffset, property, &length);
+ if (!list) {
+ if (lenp) {
+ *lenp = length;
+ }
- return NULL;
- }
+ return NULL;
+ }
- end = list + length;
+ end = list + length;
- while (list < end) {
- length = strnlen(list, end - list) + 1;
+ while (list < end) {
+ length = strnlen (list, end - list) + 1;
- /* Abort if the last string isn't properly NUL-terminated. */
- if (list + length > end) {
- if (lenp)
- *lenp = -FDT_ERR_BADVALUE;
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end) {
+ if (lenp) {
+ *lenp = -FDT_ERR_BADVALUE;
+ }
- return NULL;
- }
+ return NULL;
+ }
- if (idx == 0) {
- if (lenp)
- *lenp = length - 1;
+ if (idx == 0) {
+ if (lenp) {
+ *lenp = length - 1;
+ }
- return list;
- }
+ return list;
+ }
- list += length;
- idx--;
- }
+ list += length;
+ idx--;
+ }
- if (lenp)
- *lenp = -FDT_ERR_NOTFOUND;
+ if (lenp) {
+ *lenp = -FDT_ERR_NOTFOUND;
+ }
- return NULL;
+ return NULL;
}
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible)
+int
+fdt_node_check_compatible (
+ const void *fdt,
+ int nodeoffset,
+ const char *compatible
+ )
{
- const void *prop;
- int len;
+ const void *prop;
+ int len;
+
+ prop = fdt_getprop (fdt, nodeoffset, "compatible", &len);
+ if (!prop) {
+ return len;
+ }
- prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
- if (!prop)
- return len;
-
- return !fdt_stringlist_contains(prop, len, compatible);
+ return !fdt_stringlist_contains (prop, len, compatible);
}
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible)
+int
+fdt_node_offset_by_compatible (
+ const void *fdt,
+ int startoffset,
+ const char *compatible
+ )
{
- int offset, err;
-
- FDT_CHECK_HEADER(fdt);
+ int offset, err;
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_node_check_compatible(), then if
- * that didn't find what we want, we scan over them again
- * making our way to the next node. Still it's the easiest to
- * implement approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- err = fdt_node_check_compatible(fdt, offset, compatible);
- if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
- return err;
- else if (err == 0)
- return offset;
- }
+ FDT_CHECK_HEADER (fdt);
- return offset; /* error from fdt_next_node() */
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_node_check_compatible(), then if
+ * that didn't find what we want, we scan over them again
+ * making our way to the next node. Still it's the easiest to
+ * implement approach; performance can come later. */
+ for (offset = fdt_next_node (fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node (fdt, offset, NULL))
+ {
+ err = fdt_node_check_compatible (fdt, offset, compatible);
+ if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) {
+ return err;
+ } else if (err == 0) {
+ return offset;
+ }
+ }
+
+ return offset; /* error from fdt_next_node() */
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_rw.c b/EmbeddedPkg/Library/FdtLib/fdt_rw.c
index 863f2b2..cb5088a 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_rw.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_rw.c
@@ -55,451 +55,632 @@
#include "libfdt_internal.h"
-static int _fdt_blocks_misordered(const void *fdt,
- int mem_rsv_size, int struct_size)
+static int
+_fdt_blocks_misordered (
+ const void *fdt,
+ int mem_rsv_size,
+ int struct_size
+ )
{
- return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
- || (fdt_off_dt_struct(fdt) <
- (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
- || (fdt_off_dt_strings(fdt) <
- (fdt_off_dt_struct(fdt) + struct_size))
- || (fdt_totalsize(fdt) <
- (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+ return (fdt_off_mem_rsvmap (fdt) < FDT_ALIGN (sizeof (struct fdt_header), 8))
+ || (fdt_off_dt_struct (fdt) <
+ (fdt_off_mem_rsvmap (fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings (fdt) <
+ (fdt_off_dt_struct (fdt) + struct_size))
+ || (fdt_totalsize (fdt) <
+ (fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt)));
}
-static int _fdt_rw_check_header(void *fdt)
+static int
+_fdt_rw_check_header (
+ void *fdt
+ )
{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_version(fdt) < 17)
- return -FDT_ERR_BADVERSION;
- if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
- fdt_size_dt_struct(fdt)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_version(fdt) > 17)
- fdt_set_version(fdt, 17);
-
- return 0;
+ FDT_CHECK_HEADER (fdt);
+
+ if (fdt_version (fdt) < 17) {
+ return -FDT_ERR_BADVERSION;
+ }
+
+ if (_fdt_blocks_misordered (
+ fdt,
+ sizeof (struct fdt_reserve_entry),
+ fdt_size_dt_struct (fdt)
+ ))
+ {
+ return -FDT_ERR_BADLAYOUT;
+ }
+
+ if (fdt_version (fdt) > 17) {
+ fdt_set_version (fdt, 17);
+ }
+
+ return 0;
}
#define FDT_RW_CHECK_HEADER(fdt) \
- { \
- int __err; \
- if ((__err = _fdt_rw_check_header(fdt)) != 0) \
- return __err; \
- }
-
-static inline int _fdt_data_size(void *fdt)
+ { \
+ int __err; \
+ if ((__err = _fdt_rw_check_header(fdt)) != 0) \
+ return __err; \
+ }
+
+static inline int
+_fdt_data_size (
+ void *fdt
+ )
{
- return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ return fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
}
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+static int
+_fdt_splice (
+ void *fdt,
+ void *splicepoint,
+ int oldlen,
+ int newlen
+ )
{
- char *p = splicepoint;
- char *end = (char *)fdt + _fdt_data_size(fdt);
-
- if (((p + oldlen) < p) || ((p + oldlen) > end))
- return -FDT_ERR_BADOFFSET;
- if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
- return -FDT_ERR_BADOFFSET;
- if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
- return -FDT_ERR_NOSPACE;
- memmove(p + newlen, p + oldlen, end - p - oldlen);
- return 0;
-}
+ char *p = splicepoint;
+ char *end = (char *)fdt + _fdt_data_size (fdt);
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
- int oldn, int newn)
-{
- int delta = (newn - oldn) * sizeof(*p);
- int err;
- err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
- if (err)
- return err;
- fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
-}
+ if (((p + oldlen) < p) || ((p + oldlen) > end)) {
+ return -FDT_ERR_BADOFFSET;
+ }
-static int _fdt_splice_struct(void *fdt, void *p,
- int oldlen, int newlen)
-{
- int delta = newlen - oldlen;
- int err;
+ if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) {
+ return -FDT_ERR_BADOFFSET;
+ }
- if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
- return err;
+ if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize (fdt))) {
+ return -FDT_ERR_NOSPACE;
+ }
- fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
+ memmove (p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
}
-static int _fdt_splice_string(void *fdt, int newlen)
+static int
+_fdt_splice_mem_rsv (
+ void *fdt,
+ struct fdt_reserve_entry *p,
+ int oldn,
+ int newn
+ )
{
- void *p = (char *)fdt
- + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
- int err;
+ int delta = (newn - oldn) * sizeof (*p);
+ int err;
- if ((err = _fdt_splice(fdt, p, 0, newlen)))
- return err;
+ err = _fdt_splice (fdt, p, oldn * sizeof (*p), newn * sizeof (*p));
+ if (err) {
+ return err;
+ }
- fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
- return 0;
+ fdt_set_off_dt_struct (fdt, fdt_off_dt_struct (fdt) + delta);
+ fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
+ return 0;
}
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int
+_fdt_splice_struct (
+ void *fdt,
+ void *p,
+ int oldlen,
+ int newlen
+ )
{
- char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
- const char *p;
- char *new;
- int len = strlen(s) + 1;
- int err;
-
- p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
- if (p)
- /* found it */
- return (p - strtab);
-
- new = strtab + fdt_size_dt_strings(fdt);
- err = _fdt_splice_string(fdt, len);
- if (err)
- return err;
-
- memcpy(new, s, len);
- return (new - strtab);
-}
-
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
+ int delta = newlen - oldlen;
+ int err;
- re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
- err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
- if (err)
- return err;
+ if ((err = _fdt_splice (fdt, p, oldlen, newlen))) {
+ return err;
+ }
- re->address = cpu_to_fdt64(address);
- re->size = cpu_to_fdt64(size);
- return 0;
+ fdt_set_size_dt_struct (fdt, fdt_size_dt_struct (fdt) + delta);
+ fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
+ return 0;
}
-int fdt_del_mem_rsv(void *fdt, int n)
+static int
+_fdt_splice_string (
+ void *fdt,
+ int newlen
+ )
{
- struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+ void *p = (char *)fdt
+ + fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
+ int err;
- FDT_RW_CHECK_HEADER(fdt);
+ if ((err = _fdt_splice (fdt, p, 0, newlen))) {
+ return err;
+ }
- if (n >= fdt_num_mem_rsv(fdt))
- return -FDT_ERR_NOTFOUND;
+ fdt_set_size_dt_strings (fdt, fdt_size_dt_strings (fdt) + newlen);
+ return 0;
+}
- return _fdt_splice_mem_rsv(fdt, re, 1, 0);
+static int
+_fdt_find_add_string (
+ void *fdt,
+ const char *s
+ )
+{
+ char *strtab = (char *)fdt + fdt_off_dt_strings (fdt);
+ const char *p;
+ char *new;
+ int len = strlen (s) + 1;
+ int err;
+
+ p = _fdt_find_string (strtab, fdt_size_dt_strings (fdt), s);
+ if (p) {
+ /* found it */
+ return (p - strtab);
+ }
+
+ new = strtab + fdt_size_dt_strings (fdt);
+ err = _fdt_splice_string (fdt, len);
+ if (err) {
+ return err;
+ }
+
+ memcpy (new, s, len);
+ return (new - strtab);
}
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+int
+fdt_add_mem_rsv (
+ void *fdt,
+ uint64_t address,
+ uint64_t size
+ )
{
- int oldlen;
- int err;
+ struct fdt_reserve_entry *re;
+ int err;
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (!*prop)
- return oldlen;
+ FDT_RW_CHECK_HEADER (fdt);
- if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(len))))
- return err;
+ re = _fdt_mem_rsv_w (fdt, fdt_num_mem_rsv (fdt));
+ err = _fdt_splice_mem_rsv (fdt, re, 0, 1);
+ if (err) {
+ return err;
+ }
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
+ re->address = cpu_to_fdt64 (address);
+ re->size = cpu_to_fdt64 (size);
+ return 0;
}
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+int
+fdt_del_mem_rsv (
+ void *fdt,
+ int n
+ )
{
- int proplen;
- int nextoffset;
- int namestroff;
- int err;
-
- if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return nextoffset;
+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w (fdt, n);
- namestroff = _fdt_find_add_string(fdt, name);
- if (namestroff < 0)
- return namestroff;
+ FDT_RW_CHECK_HEADER (fdt);
- *prop = _fdt_offset_ptr_w(fdt, nextoffset);
- proplen = sizeof(**prop) + FDT_TAGALIGN(len);
+ if (n >= fdt_num_mem_rsv (fdt)) {
+ return -FDT_ERR_NOTFOUND;
+ }
- err = _fdt_splice_struct(fdt, *prop, 0, proplen);
- if (err)
- return err;
-
- (*prop)->tag = cpu_to_fdt32(FDT_PROP);
- (*prop)->nameoff = cpu_to_fdt32(namestroff);
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
+ return _fdt_splice_mem_rsv (fdt, re, 1, 0);
}
-int fdt_set_name(void *fdt, int nodeoffset, const char *name)
+static int
+_fdt_resize_property (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ int len,
+ struct fdt_property **prop
+ )
{
- char *namep;
- int oldlen, newlen;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
- if (!namep)
- return oldlen;
-
- newlen = strlen(name);
+ int oldlen;
+ int err;
+
+ *prop = fdt_get_property_w (fdt, nodeoffset, name, &oldlen);
+ if (!*prop) {
+ return oldlen;
+ }
+
+ if ((err = _fdt_splice_struct (
+ fdt,
+ (*prop)->data,
+ FDT_TAGALIGN (oldlen),
+ FDT_TAGALIGN (len)
+ )))
+ {
+ return err;
+ }
+
+ (*prop)->len = cpu_to_fdt32 (len);
+ return 0;
+}
- err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
- FDT_TAGALIGN(newlen+1));
- if (err)
- return err;
+static int
+_fdt_add_property (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ int len,
+ struct fdt_property **prop
+ )
+{
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
+
+ if ((nextoffset = _fdt_check_node_offset (fdt, nodeoffset)) < 0) {
+ return nextoffset;
+ }
+
+ namestroff = _fdt_find_add_string (fdt, name);
+ if (namestroff < 0) {
+ return namestroff;
+ }
+
+ *prop = _fdt_offset_ptr_w (fdt, nextoffset);
+ proplen = sizeof (**prop) + FDT_TAGALIGN (len);
+
+ err = _fdt_splice_struct (fdt, *prop, 0, proplen);
+ if (err) {
+ return err;
+ }
+
+ (*prop)->tag = cpu_to_fdt32 (FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32 (namestroff);
+ (*prop)->len = cpu_to_fdt32 (len);
+ return 0;
+}
- memcpy(namep, name, newlen+1);
- return 0;
+int
+fdt_set_name (
+ void *fdt,
+ int nodeoffset,
+ const char *name
+ )
+{
+ char *namep;
+ int oldlen, newlen;
+ int err;
+
+ FDT_RW_CHECK_HEADER (fdt);
+
+ namep = (char *)(uintptr_t)fdt_get_name (fdt, nodeoffset, &oldlen);
+ if (!namep) {
+ return oldlen;
+ }
+
+ newlen = strlen (name);
+
+ err = _fdt_splice_struct (
+ fdt,
+ namep,
+ FDT_TAGALIGN (oldlen+1),
+ FDT_TAGALIGN (newlen+1)
+ );
+ if (err) {
+ return err;
+ }
+
+ memcpy (namep, name, newlen+1);
+ return 0;
}
-int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
- int len, void **prop_data)
+int
+fdt_setprop_placeholder (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ int len,
+ void **prop_data
+ )
{
- struct fdt_property *prop;
- int err;
+ struct fdt_property *prop;
+ int err;
+
+ FDT_RW_CHECK_HEADER (fdt);
- FDT_RW_CHECK_HEADER(fdt);
+ err = _fdt_resize_property (fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND) {
+ err = _fdt_add_property (fdt, nodeoffset, name, len, &prop);
+ }
- err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
- if (err == -FDT_ERR_NOTFOUND)
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
+ if (err) {
+ return err;
+ }
- *prop_data = prop->data;
- return 0;
+ *prop_data = prop->data;
+ return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int
+fdt_setprop (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ const void *val,
+ int len
+ )
{
- void *prop_data;
- int err;
+ void *prop_data;
+ int err;
- err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
- if (err)
- return err;
+ err = fdt_setprop_placeholder (fdt, nodeoffset, name, len, &prop_data);
+ if (err) {
+ return err;
+ }
- if (len)
- memcpy(prop_data, val, len);
- return 0;
+ if (len) {
+ memcpy (prop_data, val, len);
+ }
+
+ return 0;
}
-int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int
+fdt_appendprop (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ const void *val,
+ int len
+ )
{
- struct fdt_property *prop;
- int err, oldlen, newlen;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (prop) {
- newlen = len + oldlen;
- err = _fdt_splice_struct(fdt, prop->data,
- FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(newlen));
- if (err)
- return err;
- prop->len = cpu_to_fdt32(newlen);
- memcpy(prop->data + oldlen, val, len);
- } else {
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
- memcpy(prop->data, val, len);
- }
- return 0;
+ struct fdt_property *prop;
+ int err, oldlen, newlen;
+
+ FDT_RW_CHECK_HEADER (fdt);
+
+ prop = fdt_get_property_w (fdt, nodeoffset, name, &oldlen);
+ if (prop) {
+ newlen = len + oldlen;
+ err = _fdt_splice_struct (
+ fdt,
+ prop->data,
+ FDT_TAGALIGN (oldlen),
+ FDT_TAGALIGN (newlen)
+ );
+ if (err) {
+ return err;
+ }
+
+ prop->len = cpu_to_fdt32 (newlen);
+ memcpy (prop->data + oldlen, val, len);
+ } else {
+ err = _fdt_add_property (fdt, nodeoffset, name, len, &prop);
+ if (err) {
+ return err;
+ }
+
+ memcpy (prop->data, val, len);
+ }
+
+ return 0;
}
-int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+int
+fdt_delprop (
+ void *fdt,
+ int nodeoffset,
+ const char *name
+ )
{
- struct fdt_property *prop;
- int len, proplen;
+ struct fdt_property *prop;
+ int len, proplen;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (!prop)
- return len;
+ prop = fdt_get_property_w (fdt, nodeoffset, name, &len);
+ if (!prop) {
+ return len;
+ }
- proplen = sizeof(*prop) + FDT_TAGALIGN(len);
- return _fdt_splice_struct(fdt, prop, proplen, 0);
+ proplen = sizeof (*prop) + FDT_TAGALIGN (len);
+ return _fdt_splice_struct (fdt, prop, proplen, 0);
}
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen)
+int
+fdt_add_subnode_namelen (
+ void *fdt,
+ int parentoffset,
+ const char *name,
+ int namelen
+ )
{
- struct fdt_node_header *nh;
- int offset, nextoffset;
- int nodelen;
- int err;
- uint32_t tag;
- fdt32_t *endtag;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
- if (offset >= 0)
- return -FDT_ERR_EXISTS;
- else if (offset != -FDT_ERR_NOTFOUND)
- return offset;
-
- /* Try to place the new node after the parent's properties */
- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- } while ((tag == FDT_PROP) || (tag == FDT_NOP));
-
- nh = _fdt_offset_ptr_w(fdt, offset);
- nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
-
- err = _fdt_splice_struct(fdt, nh, 0, nodelen);
- if (err)
- return err;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
- memcpy(nh->name, name, namelen);
- endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
- *endtag = cpu_to_fdt32(FDT_END_NODE);
-
- return offset;
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ fdt32_t *endtag;
+
+ FDT_RW_CHECK_HEADER (fdt);
+
+ offset = fdt_subnode_offset_namelen (fdt, parentoffset, name, namelen);
+ if (offset >= 0) {
+ return -FDT_ERR_EXISTS;
+ } else if (offset != -FDT_ERR_NOTFOUND) {
+ return offset;
+ }
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag (fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
+ } while ((tag == FDT_PROP) || (tag == FDT_NOP));
+
+ nh = _fdt_offset_ptr_w (fdt, offset);
+ nodelen = sizeof (*nh) + FDT_TAGALIGN (namelen+1) + FDT_TAGSIZE;
+
+ err = _fdt_splice_struct (fdt, nh, 0, nodelen);
+ if (err) {
+ return err;
+ }
+
+ nh->tag = cpu_to_fdt32 (FDT_BEGIN_NODE);
+ memset (nh->name, 0, FDT_TAGALIGN (namelen+1));
+ memcpy (nh->name, name, namelen);
+ endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32 (FDT_END_NODE);
+
+ return offset;
}
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+int
+fdt_add_subnode (
+ void *fdt,
+ int parentoffset,
+ const char *name
+ )
{
- return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+ return fdt_add_subnode_namelen (fdt, parentoffset, name, strlen (name));
}
-int fdt_del_node(void *fdt, int nodeoffset)
+int
+fdt_del_node (
+ void *fdt,
+ int nodeoffset
+ )
{
- int endoffset;
+ int endoffset;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
+ endoffset = _fdt_node_end_offset (fdt, nodeoffset);
+ if (endoffset < 0) {
+ return endoffset;
+ }
- return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
- endoffset - nodeoffset, 0);
+ return _fdt_splice_struct (
+ fdt,
+ _fdt_offset_ptr_w (fdt, nodeoffset),
+ endoffset - nodeoffset,
+ 0
+ );
}
-static void _fdt_packblocks(const char *old, char *new,
- int mem_rsv_size, int struct_size)
+static void
+_fdt_packblocks (
+ const char *old,
+ char *new,
+ int mem_rsv_size,
+ int struct_size
+ )
{
- int mem_rsv_off, struct_off, strings_off;
-
- mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
- struct_off = mem_rsv_off + mem_rsv_size;
- strings_off = struct_off + struct_size;
-
- memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
- fdt_set_off_mem_rsvmap(new, mem_rsv_off);
-
- memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
- fdt_set_off_dt_struct(new, struct_off);
- fdt_set_size_dt_struct(new, struct_size);
-
- memmove(new + strings_off, old + fdt_off_dt_strings(old),
- fdt_size_dt_strings(old));
- fdt_set_off_dt_strings(new, strings_off);
- fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
+ int mem_rsv_off, struct_off, strings_off;
+
+ mem_rsv_off = FDT_ALIGN (sizeof (struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
+
+ memmove (new + mem_rsv_off, old + fdt_off_mem_rsvmap (old), mem_rsv_size);
+ fdt_set_off_mem_rsvmap (new, mem_rsv_off);
+
+ memmove (new + struct_off, old + fdt_off_dt_struct (old), struct_size);
+ fdt_set_off_dt_struct (new, struct_off);
+ fdt_set_size_dt_struct (new, struct_size);
+
+ memmove (
+ new + strings_off,
+ old + fdt_off_dt_strings (old),
+ fdt_size_dt_strings (old)
+ );
+ fdt_set_off_dt_strings (new, strings_off);
+ fdt_set_size_dt_strings (new, fdt_size_dt_strings (old));
}
-int fdt_open_into(const void *fdt, void *buf, int bufsize)
+int
+fdt_open_into (
+ const void *fdt,
+ void *buf,
+ int bufsize
+ )
{
- int err;
- int mem_rsv_size, struct_size;
- int newsize;
- const char *fdtstart = fdt;
- const char *fdtend = fdtstart + fdt_totalsize(fdt);
- char *tmp;
-
- FDT_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
-
- if (fdt_version(fdt) >= 17) {
- struct_size = fdt_size_dt_struct(fdt);
- } else {
- struct_size = 0;
- while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
- ;
- if (struct_size < 0)
- return struct_size;
- }
-
- if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
- /* no further work necessary */
- err = fdt_move(fdt, buf, bufsize);
- if (err)
- return err;
- fdt_set_version(buf, 17);
- fdt_set_size_dt_struct(buf, struct_size);
- fdt_set_totalsize(buf, bufsize);
- return 0;
- }
-
- /* Need to reorder */
- newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
- + struct_size + fdt_size_dt_strings(fdt);
-
- if (bufsize < newsize)
- return -FDT_ERR_NOSPACE;
-
- /* First attempt to build converted tree at beginning of buffer */
- tmp = buf;
- /* But if that overlaps with the old tree... */
- if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
- /* Try right after the old tree instead */
- tmp = (char *)(uintptr_t)fdtend;
- if ((tmp + newsize) > ((char *)buf + bufsize))
- return -FDT_ERR_NOSPACE;
- }
-
- _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
- memmove(buf, tmp, newsize);
-
- fdt_set_magic(buf, FDT_MAGIC);
- fdt_set_totalsize(buf, bufsize);
- fdt_set_version(buf, 17);
- fdt_set_last_comp_version(buf, 16);
- fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
-
- return 0;
+ int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ const char *fdtstart = fdt;
+ const char *fdtend = fdtstart + fdt_totalsize (fdt);
+ char *tmp;
+
+ FDT_CHECK_HEADER (fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv (fdt)+1)
+ * sizeof (struct fdt_reserve_entry);
+
+ if (fdt_version (fdt) >= 17) {
+ struct_size = fdt_size_dt_struct (fdt);
+ } else {
+ struct_size = 0;
+ while (fdt_next_tag (fdt, struct_size, &struct_size) != FDT_END) {
+ }
+
+ if (struct_size < 0) {
+ return struct_size;
+ }
+ }
+
+ if (!_fdt_blocks_misordered (fdt, mem_rsv_size, struct_size)) {
+ /* no further work necessary */
+ err = fdt_move (fdt, buf, bufsize);
+ if (err) {
+ return err;
+ }
+
+ fdt_set_version (buf, 17);
+ fdt_set_size_dt_struct (buf, struct_size);
+ fdt_set_totalsize (buf, bufsize);
+ return 0;
+ }
+
+ /* Need to reorder */
+ newsize = FDT_ALIGN (sizeof (struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings (fdt);
+
+ if (bufsize < newsize) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ /* First attempt to build converted tree at beginning of buffer */
+ tmp = buf;
+ /* But if that overlaps with the old tree... */
+ if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
+ /* Try right after the old tree instead */
+ tmp = (char *)(uintptr_t)fdtend;
+ if ((tmp + newsize) > ((char *)buf + bufsize)) {
+ return -FDT_ERR_NOSPACE;
+ }
+ }
+
+ _fdt_packblocks (fdt, tmp, mem_rsv_size, struct_size);
+ memmove (buf, tmp, newsize);
+
+ fdt_set_magic (buf, FDT_MAGIC);
+ fdt_set_totalsize (buf, bufsize);
+ fdt_set_version (buf, 17);
+ fdt_set_last_comp_version (buf, 16);
+ fdt_set_boot_cpuid_phys (buf, fdt_boot_cpuid_phys (fdt));
+
+ return 0;
}
-int fdt_pack(void *fdt)
+int
+fdt_pack (
+ void *fdt
+ )
{
- int mem_rsv_size;
+ int mem_rsv_size;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
- _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
- fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+ mem_rsv_size = (fdt_num_mem_rsv (fdt)+1)
+ * sizeof (struct fdt_reserve_entry);
+ _fdt_packblocks (fdt, fdt, mem_rsv_size, fdt_size_dt_struct (fdt));
+ fdt_set_totalsize (fdt, _fdt_data_size (fdt));
- return 0;
+ return 0;
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_strerror.c b/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
index 3041e2e..cb07f61 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
@@ -56,47 +56,51 @@
#include "libfdt_internal.h"
struct fdt_errtabent {
- const char *str;
+ const char *str;
};
#define FDT_ERRTABENT(val) \
- [(val)] = { .str = #val, }
+ [(val)] = { .str = #val, }
-static struct fdt_errtabent fdt_errtable[] = {
- FDT_ERRTABENT(FDT_ERR_NOTFOUND),
- FDT_ERRTABENT(FDT_ERR_EXISTS),
- FDT_ERRTABENT(FDT_ERR_NOSPACE),
+static struct fdt_errtabent fdt_errtable[] = {
+ FDT_ERRTABENT (FDT_ERR_NOTFOUND),
+ FDT_ERRTABENT (FDT_ERR_EXISTS),
+ FDT_ERRTABENT (FDT_ERR_NOSPACE),
- FDT_ERRTABENT(FDT_ERR_BADOFFSET),
- FDT_ERRTABENT(FDT_ERR_BADPATH),
- FDT_ERRTABENT(FDT_ERR_BADPHANDLE),
- FDT_ERRTABENT(FDT_ERR_BADSTATE),
+ FDT_ERRTABENT (FDT_ERR_BADOFFSET),
+ FDT_ERRTABENT (FDT_ERR_BADPATH),
+ FDT_ERRTABENT (FDT_ERR_BADPHANDLE),
+ FDT_ERRTABENT (FDT_ERR_BADSTATE),
- FDT_ERRTABENT(FDT_ERR_TRUNCATED),
- FDT_ERRTABENT(FDT_ERR_BADMAGIC),
- FDT_ERRTABENT(FDT_ERR_BADVERSION),
- FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
- FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
- FDT_ERRTABENT(FDT_ERR_INTERNAL),
- FDT_ERRTABENT(FDT_ERR_BADNCELLS),
- FDT_ERRTABENT(FDT_ERR_BADVALUE),
- FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
- FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
+ FDT_ERRTABENT (FDT_ERR_TRUNCATED),
+ FDT_ERRTABENT (FDT_ERR_BADMAGIC),
+ FDT_ERRTABENT (FDT_ERR_BADVERSION),
+ FDT_ERRTABENT (FDT_ERR_BADSTRUCTURE),
+ FDT_ERRTABENT (FDT_ERR_BADLAYOUT),
+ FDT_ERRTABENT (FDT_ERR_INTERNAL),
+ FDT_ERRTABENT (FDT_ERR_BADNCELLS),
+ FDT_ERRTABENT (FDT_ERR_BADVALUE),
+ FDT_ERRTABENT (FDT_ERR_BADOVERLAY),
+ FDT_ERRTABENT (FDT_ERR_NOPHANDLES),
};
-#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
+#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-const char *fdt_strerror(int errval)
+const char *
+fdt_strerror (
+ int errval
+ )
{
- if (errval > 0)
- return "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
+ if (errval > 0) {
+ return "<valid offset/length>";
+ } else if (errval == 0) {
+ return "<no error>";
+ } else if (errval > -FDT_ERRTABSIZE) {
+ const char *s = fdt_errtable[-errval].str;
- if (s)
- return s;
- }
+ if (s) {
+ return s;
+ }
+ }
- return "<unknown error>";
+ return "<unknown error>";
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_strtoul.c b/EmbeddedPkg/Library/FdtLib/fdt_strtoul.c
index 3e60c27..e615d6f 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_strtoul.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_strtoul.c
@@ -9,24 +9,29 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
-unsigned long strtoul(const char *nptr, char **endptr, int base)
+unsigned long
+strtoul (
+ const char *nptr,
+ char **endptr,
+ int base
+ )
{
- RETURN_STATUS Status;
- UINTN ReturnValue;
+ RETURN_STATUS Status;
+ UINTN ReturnValue;
- ASSERT (base == 10 || base == 16);
+ ASSERT (base == 10 || base == 16);
- if (base == 10) {
- Status = AsciiStrDecimalToUintnS (nptr, endptr, &ReturnValue);
- } else if (base == 16) {
- Status = AsciiStrHexToUintnS (nptr, endptr, &ReturnValue);
- } else {
- Status = RETURN_INVALID_PARAMETER;
- }
+ if (base == 10) {
+ Status = AsciiStrDecimalToUintnS (nptr, endptr, &ReturnValue);
+ } else if (base == 16) {
+ Status = AsciiStrHexToUintnS (nptr, endptr, &ReturnValue);
+ } else {
+ Status = RETURN_INVALID_PARAMETER;
+ }
- if (RETURN_ERROR (Status)) {
- return MAX_UINTN;
- }
+ if (RETURN_ERROR (Status)) {
+ return MAX_UINTN;
+ }
- return ReturnValue;
+ return ReturnValue;
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_sw.c b/EmbeddedPkg/Library/FdtLib/fdt_sw.c
index 3c2c710..6bcdd1f 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_sw.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_sw.c
@@ -55,246 +55,321 @@
#include "libfdt_internal.h"
-static int _fdt_sw_check_header(void *fdt)
+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;
+ 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 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;
+ int offset = fdt_size_dt_struct (fdt);
+ int spaceleft;
- spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- - fdt_size_dt_strings(fdt);
+ spaceleft = fdt_totalsize (fdt) - fdt_off_dt_struct (fdt)
+ - fdt_size_dt_strings (fdt);
- if ((offset + len < offset) || (offset + len > spaceleft))
- return NULL;
+ if ((offset + len < offset) || (offset + len > spaceleft)) {
+ return NULL;
+ }
- fdt_set_size_dt_struct(fdt, offset + len);
- return _fdt_offset_ptr_w(fdt, offset);
+ fdt_set_size_dt_struct (fdt, offset + len);
+ return _fdt_offset_ptr_w (fdt, offset);
}
-int fdt_create(void *buf, int bufsize)
+int
+fdt_create (
+ void *buf,
+ int bufsize
+ )
{
- void *fdt = buf;
-
- if (bufsize < sizeof(struct fdt_header))
- return -FDT_ERR_NOSPACE;
-
- memset(buf, 0, bufsize);
-
- fdt_set_magic(fdt, FDT_SW_MAGIC);
- fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
- fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
- fdt_set_totalsize(fdt, bufsize);
-
- fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
- sizeof(struct fdt_reserve_entry)));
- fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
- fdt_set_off_dt_strings(fdt, bufsize);
-
- return 0;
+ void *fdt = buf;
+
+ if (bufsize < sizeof (struct fdt_header)) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ memset (buf, 0, bufsize);
+
+ fdt_set_magic (fdt, FDT_SW_MAGIC);
+ fdt_set_version (fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version (fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_totalsize (fdt, bufsize);
+
+ fdt_set_off_mem_rsvmap (
+ fdt,
+ FDT_ALIGN (
+ sizeof (struct fdt_header),
+ sizeof (struct fdt_reserve_entry)
+ )
+ );
+ fdt_set_off_dt_struct (fdt, fdt_off_mem_rsvmap (fdt));
+ fdt_set_off_dt_strings (fdt, bufsize);
+
+ return 0;
}
-int fdt_resize(void *fdt, void *buf, int bufsize)
+int
+fdt_resize (
+ void *fdt,
+ void *buf,
+ int bufsize
+ )
{
- size_t headsize, tailsize;
- char *oldtail, *newtail;
+ size_t headsize, tailsize;
+ char *oldtail, *newtail;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- headsize = fdt_off_dt_struct(fdt);
- tailsize = fdt_size_dt_strings(fdt);
+ headsize = fdt_off_dt_struct (fdt);
+ tailsize = fdt_size_dt_strings (fdt);
- if ((headsize + tailsize) > bufsize)
- return -FDT_ERR_NOSPACE;
+ if ((headsize + tailsize) > bufsize) {
+ return -FDT_ERR_NOSPACE;
+ }
- oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
- newtail = (char *)buf + bufsize - tailsize;
+ oldtail = (char *)fdt + fdt_totalsize (fdt) - tailsize;
+ newtail = (char *)buf + bufsize - tailsize;
- /* Two cases to avoid clobbering data if the old and new
- * buffers partially overlap */
- if (buf <= fdt) {
- memmove(buf, fdt, headsize);
- memmove(newtail, oldtail, tailsize);
- } else {
- memmove(newtail, oldtail, tailsize);
- memmove(buf, fdt, headsize);
- }
+ /* Two cases to avoid clobbering data if the old and new
+ * buffers partially overlap */
+ if (buf <= fdt) {
+ memmove (buf, fdt, headsize);
+ memmove (newtail, oldtail, tailsize);
+ } else {
+ memmove (newtail, oldtail, tailsize);
+ memmove (buf, fdt, headsize);
+ }
- fdt_set_off_dt_strings(buf, bufsize);
- fdt_set_totalsize(buf, bufsize);
+ fdt_set_off_dt_strings (buf, bufsize);
+ fdt_set_totalsize (buf, bufsize);
- return 0;
+ return 0;
}
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+int
+fdt_add_reservemap_entry (
+ void *fdt,
+ uint64_t addr,
+ uint64_t size
+ )
{
- struct fdt_reserve_entry *re;
- int offset;
+ struct fdt_reserve_entry *re;
+ int offset;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- if (fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADSTATE;
+ if (fdt_size_dt_struct (fdt)) {
+ return -FDT_ERR_BADSTATE;
+ }
- offset = fdt_off_dt_struct(fdt);
- if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
- return -FDT_ERR_NOSPACE;
+ offset = fdt_off_dt_struct (fdt);
+ if ((offset + sizeof (*re)) > fdt_totalsize (fdt)) {
+ return -FDT_ERR_NOSPACE;
+ }
- re = (struct fdt_reserve_entry *)((char *)fdt + offset);
- re->address = cpu_to_fdt64(addr);
- re->size = cpu_to_fdt64(size);
+ re = (struct fdt_reserve_entry *)((char *)fdt + offset);
+ re->address = cpu_to_fdt64 (addr);
+ re->size = cpu_to_fdt64 (size);
- fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
+ fdt_set_off_dt_struct (fdt, offset + sizeof (*re));
- return 0;
+ return 0;
}
-int fdt_finish_reservemap(void *fdt)
+int
+fdt_finish_reservemap (
+ void *fdt
+ )
{
- return fdt_add_reservemap_entry(fdt, 0, 0);
+ return fdt_add_reservemap_entry (fdt, 0, 0);
}
-int fdt_begin_node(void *fdt, const char *name)
+int
+fdt_begin_node (
+ void *fdt,
+ const char *name
+ )
{
- struct fdt_node_header *nh;
- int namelen = strlen(name) + 1;
+ struct fdt_node_header *nh;
+ int namelen = strlen (name) + 1;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
- if (! nh)
- return -FDT_ERR_NOSPACE;
+ nh = _fdt_grab_space (fdt, sizeof (*nh) + FDT_TAGALIGN (namelen));
+ if (!nh) {
+ return -FDT_ERR_NOSPACE;
+ }
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memcpy(nh->name, name, namelen);
- return 0;
+ nh->tag = cpu_to_fdt32 (FDT_BEGIN_NODE);
+ memcpy (nh->name, name, namelen);
+ return 0;
}
-int fdt_end_node(void *fdt)
+int
+fdt_end_node (
+ void *fdt
+ )
{
- fdt32_t *en;
+ fdt32_t *en;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- en = _fdt_grab_space(fdt, FDT_TAGSIZE);
- if (! en)
- return -FDT_ERR_NOSPACE;
+ en = _fdt_grab_space (fdt, FDT_TAGSIZE);
+ if (!en) {
+ return -FDT_ERR_NOSPACE;
+ }
- *en = cpu_to_fdt32(FDT_END_NODE);
- return 0;
+ *en = cpu_to_fdt32 (FDT_END_NODE);
+ return 0;
}
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int
+_fdt_find_add_string (
+ void *fdt,
+ const char *s
+ )
{
- char *strtab = (char *)fdt + fdt_totalsize(fdt);
- const char *p;
- int strtabsize = fdt_size_dt_strings(fdt);
- int len = strlen(s) + 1;
- int struct_top, offset;
-
- p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
- if (p)
- return p - strtab;
-
- /* Add it */
- offset = -strtabsize - len;
- struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- if (fdt_totalsize(fdt) + offset < struct_top)
- return 0; /* no more room :( */
-
- memcpy(strtab + offset, s, len);
- fdt_set_size_dt_strings(fdt, strtabsize + len);
- return offset;
+ char *strtab = (char *)fdt + fdt_totalsize (fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings (fdt);
+ int len = strlen (s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string (strtab - strtabsize, strtabsize, s);
+ if (p) {
+ return p - strtab;
+ }
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct (fdt) + fdt_size_dt_struct (fdt);
+ if (fdt_totalsize (fdt) + offset < struct_top) {
+ return 0; /* no more room :( */
+ }
+
+ memcpy (strtab + offset, s, len);
+ fdt_set_size_dt_strings (fdt, strtabsize + len);
+ return offset;
}
-int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
+int
+fdt_property_placeholder (
+ void *fdt,
+ const char *name,
+ int len,
+ void **valp
+ )
{
- struct fdt_property *prop;
- int nameoff;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nameoff = _fdt_find_add_string(fdt, name);
- if (nameoff == 0)
- return -FDT_ERR_NOSPACE;
-
- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
- if (! prop)
- return -FDT_ERR_NOSPACE;
-
- prop->tag = cpu_to_fdt32(FDT_PROP);
- prop->nameoff = cpu_to_fdt32(nameoff);
- prop->len = cpu_to_fdt32(len);
- *valp = prop->data;
- return 0;
+ struct fdt_property *prop;
+ int nameoff;
+
+ FDT_SW_CHECK_HEADER (fdt);
+
+ nameoff = _fdt_find_add_string (fdt, name);
+ if (nameoff == 0) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ prop = _fdt_grab_space (fdt, sizeof (*prop) + FDT_TAGALIGN (len));
+ if (!prop) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ prop->tag = cpu_to_fdt32 (FDT_PROP);
+ prop->nameoff = cpu_to_fdt32 (nameoff);
+ prop->len = cpu_to_fdt32 (len);
+ *valp = prop->data;
+ return 0;
}
-int fdt_property(void *fdt, const char *name, const void *val, int len)
+int
+fdt_property (
+ void *fdt,
+ const char *name,
+ const void *val,
+ int len
+ )
{
- void *ptr;
- int ret;
-
- ret = fdt_property_placeholder(fdt, name, len, &ptr);
- if (ret)
- return ret;
- memcpy(ptr, val, len);
- return 0;
+ void *ptr;
+ int ret;
+
+ ret = fdt_property_placeholder (fdt, name, len, &ptr);
+ if (ret) {
+ return ret;
+ }
+
+ memcpy (ptr, val, len);
+ return 0;
}
-int fdt_finish(void *fdt)
+int
+fdt_finish (
+ void *fdt
+ )
{
- char *p = (char *)fdt;
- fdt32_t *end;
- int oldstroffset, newstroffset;
- uint32_t tag;
- int offset, nextoffset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- /* Add terminator */
- end = _fdt_grab_space(fdt, sizeof(*end));
- if (! end)
- return -FDT_ERR_NOSPACE;
- *end = cpu_to_fdt32(FDT_END);
-
- /* Relocate the string table */
- oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
- newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
- fdt_set_off_dt_strings(fdt, newstroffset);
-
- /* Walk the structure, correcting string offsets */
- offset = 0;
- while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
- if (tag == FDT_PROP) {
- struct fdt_property *prop =
- _fdt_offset_ptr_w(fdt, offset);
- int nameoff;
-
- nameoff = fdt32_to_cpu(prop->nameoff);
- nameoff += fdt_size_dt_strings(fdt);
- prop->nameoff = cpu_to_fdt32(nameoff);
- }
- offset = nextoffset;
- }
- if (nextoffset < 0)
- return nextoffset;
-
- /* Finally, adjust the header */
- fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
- fdt_set_magic(fdt, FDT_MAGIC);
- return 0;
+ char *p = (char *)fdt;
+ fdt32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ FDT_SW_CHECK_HEADER (fdt);
+
+ /* Add terminator */
+ end = _fdt_grab_space (fdt, sizeof (*end));
+ if (!end) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ *end = cpu_to_fdt32 (FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize (fdt) - fdt_size_dt_strings (fdt);
+ newstroffset = fdt_off_dt_struct (fdt) + fdt_size_dt_struct (fdt);
+ memmove (p + newstroffset, p + oldstroffset, fdt_size_dt_strings (fdt));
+ fdt_set_off_dt_strings (fdt, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag (fdt, offset, &nextoffset)) != FDT_END) {
+ if (tag == FDT_PROP) {
+ struct fdt_property *prop =
+ _fdt_offset_ptr_w (fdt, offset);
+ int nameoff;
+
+ nameoff = fdt32_to_cpu (prop->nameoff);
+ nameoff += fdt_size_dt_strings (fdt);
+ prop->nameoff = cpu_to_fdt32 (nameoff);
+ }
+
+ offset = nextoffset;
+ }
+
+ if (nextoffset < 0) {
+ return nextoffset;
+ }
+
+ /* Finally, adjust the header */
+ fdt_set_totalsize (fdt, newstroffset + fdt_size_dt_strings (fdt));
+ fdt_set_magic (fdt, FDT_MAGIC);
+ return 0;
}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_wip.c b/EmbeddedPkg/Library/FdtLib/fdt_wip.c
index 6e39807..8447706 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_wip.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_wip.c
@@ -55,85 +55,135 @@
#include "libfdt_internal.h"
-int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
- const char *name, int namelen,
- uint32_t idx, const void *val,
- int len)
+int
+fdt_setprop_inplace_namelen_partial (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen,
+ uint32_t idx,
+ const void *val,
+ int len
+ )
{
- void *propval;
- int proplen;
-
- propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
- &proplen);
- if (!propval)
- return proplen;
-
- if (proplen < (len + idx))
- return -FDT_ERR_NOSPACE;
-
- memcpy((char *)propval + idx, val, len);
- return 0;
+ void *propval;
+ int proplen;
+
+ propval = fdt_getprop_namelen_w (
+ fdt,
+ nodeoffset,
+ name,
+ namelen,
+ &proplen
+ );
+ if (!propval) {
+ return proplen;
+ }
+
+ if (proplen < (len + idx)) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ memcpy ((char *)propval + idx, val, len);
+ return 0;
}
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int
+fdt_setprop_inplace (
+ void *fdt,
+ int nodeoffset,
+ const char *name,
+ const void *val,
+ int len
+ )
{
- const void *propval;
- int proplen;
-
- propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
- if (!propval)
- return proplen;
-
- if (proplen != len)
- return -FDT_ERR_NOSPACE;
-
- return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
- strlen(name), 0,
- val, len);
+ const void *propval;
+ int proplen;
+
+ propval = fdt_getprop (fdt, nodeoffset, name, &proplen);
+ if (!propval) {
+ return proplen;
+ }
+
+ if (proplen != len) {
+ return -FDT_ERR_NOSPACE;
+ }
+
+ return fdt_setprop_inplace_namelen_partial (
+ fdt,
+ nodeoffset,
+ name,
+ strlen (name),
+ 0,
+ val,
+ len
+ );
}
-static void _fdt_nop_region(void *start, int len)
+static void
+_fdt_nop_region (
+ void *start,
+ int len
+ )
{
- fdt32_t *p;
+ fdt32_t *p;
- for (p = start; (char *)p < ((char *)start + len); p++)
- *p = cpu_to_fdt32(FDT_NOP);
+ for (p = start; (char *)p < ((char *)start + len); p++) {
+ *p = cpu_to_fdt32 (FDT_NOP);
+ }
}
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+int
+fdt_nop_property (
+ void *fdt,
+ int nodeoffset,
+ const char *name
+ )
{
- struct fdt_property *prop;
- int len;
+ struct fdt_property *prop;
+ int len;
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (!prop)
- return len;
+ prop = fdt_get_property_w (fdt, nodeoffset, name, &len);
+ if (!prop) {
+ return len;
+ }
- _fdt_nop_region(prop, len + sizeof(*prop));
+ _fdt_nop_region (prop, len + sizeof (*prop));
- return 0;
+ return 0;
}
-int _fdt_node_end_offset(void *fdt, int offset)
+int
+_fdt_node_end_offset (
+ void *fdt,
+ int offset
+ )
{
- int depth = 0;
+ int depth = 0;
- while ((offset >= 0) && (depth >= 0))
- offset = fdt_next_node(fdt, offset, &depth);
+ while ((offset >= 0) && (depth >= 0)) {
+ offset = fdt_next_node (fdt, offset, &depth);
+ }
- return offset;
+ return offset;
}
-int fdt_nop_node(void *fdt, int nodeoffset)
+int
+fdt_nop_node (
+ void *fdt,
+ int nodeoffset
+ )
{
- int endoffset;
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
- endoffset - nodeoffset);
- return 0;
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset (fdt, nodeoffset);
+ if (endoffset < 0) {
+ return endoffset;
+ }
+
+ _fdt_nop_region (
+ fdt_offset_ptr_w (fdt, nodeoffset, 0),
+ endoffset - nodeoffset
+ );
+ return 0;
}
diff --git a/EmbeddedPkg/Library/FdtLib/libfdt_internal.h b/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
index f82227a..f3c8958 100644
--- a/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
+++ b/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
@@ -1,5 +1,6 @@
#ifndef _LIBFDT_INTERNAL_H
#define _LIBFDT_INTERNAL_H
+
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -52,44 +53,81 @@
*/
#include <fdt.h>
-#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
+#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
#define FDT_CHECK_HEADER(fdt) \
- { \
- int __err; \
- if ((__err = fdt_check_header(fdt)) != 0) \
- return __err; \
- }
+ { \
+ int __err; \
+ if ((__err = fdt_check_header(fdt)) != 0) \
+ return __err; \
+ }
+
+int
+_fdt_check_node_offset (
+ const void *fdt,
+ int offset
+ );
+
+int
+_fdt_check_prop_offset (
+ const void *fdt,
+ int offset
+ );
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
+const char *
+_fdt_find_string (
+ const char *strtab,
+ int tabsize,
+ const char *s
+ );
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+int
+_fdt_node_end_offset (
+ void *fdt,
+ int nodeoffset
+ );
+
+static inline const void *
+_fdt_offset_ptr (
+ const void *fdt,
+ int offset
+ )
{
- return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
+ return (const char *)fdt + fdt_off_dt_struct (fdt) + offset;
}
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+static inline void *
+_fdt_offset_ptr_w (
+ void *fdt,
+ int offset
+ )
{
- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+ return (void *)(uintptr_t)_fdt_offset_ptr (fdt, offset);
}
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+static inline const struct fdt_reserve_entry *
+_fdt_mem_rsv (
+ const void *fdt,
+ int n
+ )
{
- const struct fdt_reserve_entry *rsv_table =
- (const struct fdt_reserve_entry *)
- ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
+ const struct fdt_reserve_entry *rsv_table =
+ (const struct fdt_reserve_entry *)
+ ((const char *)fdt + fdt_off_mem_rsvmap (fdt));
- return rsv_table + n;
+ return rsv_table + n;
}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+
+static inline struct fdt_reserve_entry *
+_fdt_mem_rsv_w (
+ void *fdt,
+ int n
+ )
{
- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+ return (void *)(uintptr_t)_fdt_mem_rsv (fdt, n);
}
-#define FDT_SW_MAGIC (~FDT_MAGIC)
+#define FDT_SW_MAGIC (~FDT_MAGIC)
#endif /* _LIBFDT_INTERNAL_H */