summaryrefslogtreecommitdiff
path: root/libfdt/fdt_overlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'libfdt/fdt_overlay.c')
-rw-r--r--libfdt/fdt_overlay.c348
1 files changed, 262 insertions, 86 deletions
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index d491f00..644d16b 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -12,17 +12,33 @@
#include "libfdt_internal.h"
-#undef DEBUG
+//#define DEBUG
+//#define VERBOSE
+//#define VERY_VERBOSE
#ifdef DEBUG
-#define dprintf(x...) printf(x)
+#define dprintf(x...) printf("DEBUG: " x)
#else
#define dprintf(x...)
#endif
+#ifdef VERBOSE
+#define vdprintf(x...) printf("VERBOSE: " x)
+#else
+#define vdprintf(x...)
+#endif
+
+#ifdef VERY_VERBOSE
+#define vvdprintf(x...) printf("VERY_VERBOSE: " x)
+#else
+#define vvdprintf(x...)
+#endif
+
#define MAX_BUF_SIZE 256
#define MAX_ULONG ((unsigned long)~0UL)
+static bool find_node_str(const char *path_str, const char *node);
+
/**
* overlay_get_target_phandle - retrieves the target phandle of a fragment
* @fdto: pointer to the device tree overlay blob
@@ -233,6 +249,10 @@ static int overlay_update_local_node_references(void *fdto,
fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
&name, &fixup_len);
+ vdprintf
+ ("%s: %d: +fdto-getprop_by_offset(prop=%d from node=%s) fixup_len %d\n",
+ __func__, __LINE__, fixup_prop, fdt_get_name(fdto, fixup_node, NULL),
+ fixup_len);
if (!fixup_val)
return fixup_len;
@@ -241,6 +261,10 @@ static int overlay_update_local_node_references(void *fdto,
fixup_len /= sizeof(uint32_t);
tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
+ vdprintf
+ ("%s: %d: +fdto-getprop(name=%s from node=%s) tree_val(%s), tree_len(%d)\n",
+ __func__, __LINE__, name, fdt_get_name(fdto, fixup_node, NULL), tree_val,
+ tree_len);
if (!tree_val) {
if (tree_len == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
@@ -271,6 +295,10 @@ static int overlay_update_local_node_references(void *fdto,
poffset,
&adj_val,
sizeof(adj_val));
+ vdprintf
+ ("%s: %d: +fdto-setprop_inplace_namelen_partial, name %s, "
+ "off %u, val %u, ret %d\n", __func__, __LINE__,
+ name, poffset, fdt32_to_cpu(adj_val), ret);
if (ret == -FDT_ERR_NOSPACE)
return -FDT_ERR_BADOVERLAY;
@@ -286,6 +314,10 @@ static int overlay_update_local_node_references(void *fdto,
tree_child = fdt_subnode_offset(fdto, tree_node,
fixup_child_name);
+ vdprintf
+ ("%s: %d: +fdto-subnode_offset(fixup_child=%s from node=%s), ret %d\n",
+ __func__, __LINE__, fixup_child_name,
+ fdt_get_name(fdto, tree_node, NULL), tree_child);
if (tree_child == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
if (tree_child < 0)
@@ -324,6 +356,8 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)
int fixups;
fixups = fdt_path_offset(fdto, "/__local_fixups__");
+ dprintf("%s: +fdto_path_offset for /__local_fixups__ %d\n", __func__,
+ fixups);
if (fixups < 0) {
/* There's no local phandles to adjust, bail out */
if (fixups == -FDT_ERR_NOTFOUND)
@@ -379,24 +413,38 @@ static int overlay_fixup_one_phandle(void *fdt, void *fdto,
symbol_path = fdt_getprop(fdt, symbols_off, label,
&prop_len);
+ vvdprintf("%s: %d: +fdt - path(%s), name(%s), label(%s) sym_path(%s)\n",
+ __func__, __LINE__, path, name, label, symbol_path);
if (!symbol_path)
return prop_len;
symbol_off = fdt_path_offset(fdt, symbol_path);
+ vvdprintf
+ ("%s: %d: +fdt - path(%s), name(%s), sym_path(%s), symbol_off(%d)\n",
+ __func__, __LINE__, path, name, symbol_path, symbol_off);
if (symbol_off < 0)
return symbol_off;
phandle = fdt_get_phandle(fdt, symbol_off);
+ vvdprintf
+ ("%s: %d: +fdt - path(%s), name(%s), sym_path(%s), phandle(%u)\n",
+ __func__, __LINE__, path, name, symbol_path, phandle);
if (!phandle)
return -FDT_ERR_NOTFOUND;
fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
+ vvdprintf
+ ("%s: %d: +fdto - path(%s), name(%s), sym_path(%s), fixup_off(%u)\n",
+ __func__, __LINE__, path, name, symbol_path, fixup_off);
if (fixup_off == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
if (fixup_off < 0)
return fixup_off;
phandle_prop = cpu_to_fdt32(phandle);
+ vvdprintf
+ ("%s: %d: +ftdo - setprop: path(%s), name(%s), sym_path(%s), phandle_prop(%u)\n",
+ __func__, __LINE__, path, name, symbol_path, phandle_prop);
return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
name, name_len, poffset,
&phandle_prop,
@@ -492,7 +540,8 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
* device tree
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
- * @merge: Both input blobs are overlay blobs that are being merged
+ * @merge_olay_max_phdl: Pointer to max phandle value for merged blobs,
+ * Both input blobs are overlay blobs that are being merged
*
* overlay_fixup_phandles() resolves all the overlay phandles pointing
* to nodes in the base device tree.
@@ -505,13 +554,16 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
* 0 on success
* Negative error code on failure
*/
-static int overlay_fixup_phandles(void *fdt, void *fdto, int merge)
+static int overlay_fixup_phandles(void *fdt, void *fdto,
+ uint32_t merge_olay_max_phdl)
{
int fixups_off, symbols_off;
int property, ret = 0;
/* We can have overlays without any fixups */
fixups_off = fdt_path_offset(fdto, "/__fixups__");
+ dprintf("%s: +fdto_path_offset for /__fixups__ %d\n", __func__,
+ fixups_off);
if (fixups_off == -FDT_ERR_NOTFOUND)
return 0; /* nothing to do */
if (fixups_off < 0)
@@ -519,13 +571,15 @@ static int overlay_fixup_phandles(void *fdt, void *fdto, int merge)
/* And base DTs without symbols */
symbols_off = fdt_path_offset(fdt, "/__symbols__");
+ dprintf("%s: +fdt_path_offset for /__symbols__ %d\n", __func__,
+ symbols_off);
if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
return symbols_off;
fdt_for_each_property_offset(property, fdto, fixups_off) {
ret = overlay_fixup_phandle(fdt, fdto, symbols_off,
property, fixups_off);
- if (ret && (!merge || ret != -FDT_ERR_NOTFOUND))
+ if (ret && (!merge_olay_max_phdl || ret != -FDT_ERR_NOTFOUND))
return ret;
}
@@ -583,12 +637,26 @@ static int overlay_apply_node(void *fdt, int target,
nnode = fdt_add_subnode(fdt, target, name);
if (nnode == -FDT_ERR_EXISTS) {
nnode = fdt_subnode_offset(fdt, target, name);
- if (nnode == -FDT_ERR_NOTFOUND)
+ if (nnode == -FDT_ERR_NOTFOUND) {
+ dprintf
+ ("%s: %d: +subnode_offset failed: fdto-subnode(%s) "
+ "to fdt target %d, nnode %d\n",
+ __func__, __LINE__, name, target, nnode);
return -FDT_ERR_INTERNAL;
+ }
}
- if (nnode < 0)
+ if (nnode < 0) {
+ dprintf
+ ("%s: %d: ++subnode add/offset failed: fdto-subnode(%s) "
+ "to fdt target %d, nnode %d\n",
+ __func__, __LINE__, name, target, nnode);
return nnode;
+ }
+ vdprintf
+ ("%s: %d: ++subnode add/offset fdto-subnode(%s) to fdt "
+ "target %d, nnode %d\n",
+ __func__, __LINE__, name, target, nnode);
ret = overlay_apply_node(fdt, nnode, fdto, subnode);
if (ret)
@@ -629,14 +697,20 @@ static int copy_node(void *fdt, void *fdto, int fdt_parent,
parent = fdt_add_subnode(fdt, fdt_parent, name);
}
+ vdprintf
+ ("%s: No skip: In fdt-parent-node(%s) add fdto-child(%s), parent %d\n",
+ __func__, fdt_get_name(fdt, fdt_parent, NULL), name, parent);
if (parent < 0)
return parent;
} else {
parent = fdt_parent;
+ vdprintf
+ ("%s: Skip: In fdt-parent-node(%s), skip fdto-child(%s), parent %d\n",
+ __func__, fdt_get_name(fdt, fdt_parent, NULL), name, parent);
}
fdt_for_each_property_offset(prop, fdto, fdto_child) {
- int ret, fdt_len = 0;
+ int ret;
const char *value, *pname;
void *p;
@@ -644,10 +718,11 @@ static int copy_node(void *fdt, void *fdto, int fdt_parent,
if (!value)
return len;
- if (fdt_getprop(fdt, parent, pname, &fdt_len))
- len += fdt_len;
-
ret = fdt_setprop_placeholder(fdt, parent, pname, len, &p);
+ vvdprintf
+ ("%s: +setprop: In fdt-parent-node(%s), add fdto-prop(%s), "
+ "value(%s), ret %d\n", __func__, fdt_get_name(fdt, parent, NULL),
+ pname, value, ret);
if (ret)
return ret;
@@ -737,12 +812,15 @@ static int add_phandle(void *fdt, char *node_name, uint32_t phandle)
}
static int copy_fragment_to_base(void *fdt, void *fdto,
- int fragment, uint32_t *max_phandle,
+ int fragment, uint32_t *merge_olay_max_phdl,
unsigned long *base_fragment_count)
{
char name[MAX_BUF_SIZE];
int ret;
- uint32_t target_phandle = *max_phandle;
+ uint32_t target_phandle = *merge_olay_max_phdl;
+
+ if (merge_olay_max_phdl == NULL)
+ return -FDT_ERR_BADPHANDLE;
ret = get_fragment_name(fdto, fragment, name, sizeof(name));
if (ret)
@@ -752,6 +830,8 @@ static int copy_fragment_to_base(void *fdt, void *fdto,
if (ret)
return ret;
+ vdprintf("%s: -copy_node: fdto-fragment(%s) to fdt-fragment(%s)\n",
+ __func__, fdt_get_name(fdto, fragment, NULL), name);
ret = copy_node(fdt, fdto, 0, fragment, name, 0);
if (ret)
return ret;
@@ -765,7 +845,7 @@ static int copy_fragment_to_base(void *fdt, void *fdto,
if (ret)
return ret;
- return (++(*max_phandle) == UINT32_MAX ||
+ return (++(*merge_olay_max_phdl) == UINT32_MAX ||
++(*base_fragment_count) == ULONG_MAX) ?
-FDT_ERR_BADOVERLAY : 0;
}
@@ -788,13 +868,12 @@ static int count_fragments(void *fdt, unsigned long *max_base_fragments);
* 0 on success
* Negative error code on failure
*/
-static int overlay_merge(void *fdt, void *fdto, int merge,
- uint32_t *max_phandle)
+static int overlay_merge(void *fdt, void *fdto, uint32_t *merge_olay_max_phdl)
{
int fragment, ret;
unsigned long base_fragment_count = 0;
- if (merge) {
+ if (merge_olay_max_phdl) {
ret = count_fragments(fdt, &base_fragment_count);
/* no fragments in base dtb? then nothing to rename */
if (ret && ret != -FDT_ERR_NOTFOUND)
@@ -820,7 +899,8 @@ static int overlay_merge(void *fdt, void *fdto, int merge,
target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL);
if (target < 0) {
- if (!merge || target != -FDT_ERR_BADPHANDLE)
+ if (!merge_olay_max_phdl
+ || target != -FDT_ERR_BADPHANDLE)
return target;
/*
@@ -830,8 +910,11 @@ static int overlay_merge(void *fdt, void *fdto, int merge,
* overlay during a subsequent overlay operation of
* combined blob on another base blob.
*/
+ vdprintf
+ ("%s: -copy_fragment_to_base: fdto-fragment(%s)\n",
+ __func__, fdt_get_name(fdto, fragment, NULL));
ret = copy_fragment_to_base(fdt, fdto, fragment,
- max_phandle,
+ merge_olay_max_phdl,
&base_fragment_count);
if (ret)
return ret;
@@ -839,6 +922,9 @@ static int overlay_merge(void *fdt, void *fdto, int merge,
continue;
}
+ vdprintf
+ ("%s: -overlay_apply_node: fdto-fragment(%s) to fdt-target %d\n",
+ __func__, fdt_get_name(fdto, fragment, NULL), target);
ret = overlay_apply_node(fdt, target, fdto, overlay);
if (ret)
return ret;
@@ -879,6 +965,8 @@ static int get_path_len(const void *fdt, int nodeoffset)
* overlay_symbol_update - Update the symbols of base tree after a merge
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
+ * @merge_olay_max_phdl: Pointer to max phandle value for merged blobs,
+ * Both input blobs are overlay blobs that are being merged
*
* overlay_symbol_update() updates the symbols of the base tree with the
* symbols of the applied overlay
@@ -891,15 +979,16 @@ static int get_path_len(const void *fdt, int nodeoffset)
* 0 on success
* Negative error code on failure
*/
-static int overlay_symbol_update(void *fdt, void *fdto, uint32_t max_phandle)
+static int overlay_symbol_update(void *fdt, void *fdto,
+ uint32_t merge_olay_max_phdl)
{
int root_sym, ov_sym, prop, next_prop, path_len, fragment, target;
- int len, frag_name_len, ret, rel_path_len, rel_path_len1 = 0;
+ int len, frag_name_len, ret, rel_path_len, rel_path_len_olay = 0;
const char *s, *e;
const char *path;
const char *name;
const char *frag_name;
- const char *rel_path, *rel_path1 = NULL;
+ const char *rel_path, *rel_path_olay = NULL;
const char *target_path;
char *buf;
void *p;
@@ -960,9 +1049,9 @@ static int overlay_symbol_update(void *fdt, void *fdto, uint32_t max_phandle)
rel_path = s + len;
rel_path_len = e - rel_path - 1;
- if (max_phandle != 0) {
- rel_path1 = s + 1;
- rel_path_len1 = e - rel_path1 - 1;
+ if (merge_olay_max_phdl != 0) {
+ rel_path_olay = s + 1;
+ rel_path_len_olay = e - rel_path_olay - 1;
}
} else if ((e - s) == len
&& (memcmp(s, "/__overlay__", len - 1) == 0)) {
@@ -993,19 +1082,27 @@ static int overlay_symbol_update(void *fdt, void *fdto, uint32_t max_phandle)
if (ret < 0)
return ret;
- if (rel_path1) {
+ target = ret;
+
+ /* Before proceeding further, check if you need to update
+ * rel_path for dtbo-dtbo merging case
+ */
+ if (rel_path_olay) {
uint32_t phandle =
overlay_get_target_phandle(fdto, fragment);
- int base_symbol_found = (phandle < max_phandle);
+ int base_symbol_found = (phandle < merge_olay_max_phdl);
+ /* For new nodes we need the overlay string in path */
if (!base_symbol_found) {
- rel_path = rel_path1;
- rel_path_len = rel_path_len1;
+ vdprintf
+ ("%s: fdto: name(%s), rel_path(%s) changed "
+ "to rel_path_olay(%s)\n",
+ __func__, name, rel_path, rel_path_olay);
+ rel_path = rel_path_olay;
+ rel_path_len = rel_path_len_olay;
}
}
- target = ret;
-
/* if we have a target path use */
if (!target_path) {
ret = get_path_len(fdt, target);
@@ -1019,6 +1116,9 @@ static int overlay_symbol_update(void *fdt, void *fdto, uint32_t max_phandle)
ret = fdt_setprop_placeholder(fdt, root_sym, name,
len + (len >
1) + rel_path_len + 1, &p);
+ vvdprintf
+ ("%s: +fdt-setprop: for fdto-name(%s), rel_path(%s), "
+ "rel_path_olay(%s)\n", __func__, name, rel_path, rel_path_olay);
if (ret < 0)
return ret;
@@ -1041,12 +1141,15 @@ static int overlay_symbol_update(void *fdt, void *fdto, uint32_t max_phandle)
} else
memcpy(buf, target_path, len + 1);
- } else
+ } else {
len--;
+ }
buf[len] = '/';
memcpy(buf + len + 1, rel_path, rel_path_len);
buf[len + 1 + rel_path_len] = '\0';
+ vdprintf("%s: fdt-final-path: for name(%s) is (%s)\n", __func__,
+ name, buf);
prop = next_prop;
}
@@ -1063,26 +1166,33 @@ int fdt_overlay_apply(void *fdt, void *fdto)
FDT_RO_PROBE(fdto);
ret = fdt_find_max_phandle(fdt, &delta);
+ dprintf("%s: *** +max_phandle %d, ret %d ***\n", __func__, delta, ret);
if (ret)
goto err;
ret = overlay_adjust_local_phandles(fdto, delta);
+ dprintf("%s: *** +adjust_local_phandles, ret %d ***\n", __func__, ret);
if (ret)
goto err;
ret = overlay_update_local_references(fdto, delta);
+ dprintf("%s: *** +update_local_references, ret %d ***\n", __func__,
+ ret);
if (ret)
goto err;
ret = overlay_fixup_phandles(fdt, fdto, 0);
+ dprintf("%s: *** +fixup_phandles(0), ret %d ***\n", __func__, ret);
if (ret)
goto err;
- ret = overlay_merge(fdt, fdto, 0, NULL);
+ ret = overlay_merge(fdt, fdto, NULL);
+ dprintf("%s: *** merge(0), ret %d ***\n", __func__, ret);
if (ret)
goto err;
ret = overlay_symbol_update(fdt, fdto, 0);
+ dprintf("%s: *** symbol_update(0), ret %d ***\n", __func__, ret);
if (ret)
goto err;
@@ -1090,6 +1200,7 @@ int fdt_overlay_apply(void *fdt, void *fdto)
* The overlay has been damaged, erase its magic.
*/
fdt_set_magic(fdto, ~0);
+ dprintf("%s *** completed successfully! ***\n", __func__);
return 0;
@@ -1104,6 +1215,7 @@ err:
* magic.
*/
fdt_set_magic(fdt, ~0);
+ dprintf("%s *** failed with ret %d ***\n", __func__, ret);
return ret;
}
@@ -1203,15 +1315,16 @@ static void *get_next_component(const char **p, int *len, char sep)
static int lookup_target_path(void *fdt, void *fdto, const char *fragment,
int frag_name_len, char *buf, int buf_len,
- int *target_phandle)
+ int *target_off, int *root_path)
{
int offset, ret, target, len;
const char *target_path;
- static const char fragstr[] = "fragment";
+ static const char fragstr[] = "fragment@";
int fragstrlen = sizeof(fragstr) - 1;
memset(buf, 0, buf_len);
+ /* Check fdto-fragment has fragment string */
if (frag_name_len < fragstrlen || memcmp(fragment, fragstr, fragstrlen))
return -FDT_ERR_BADOVERLAY;
@@ -1234,8 +1347,8 @@ static int lookup_target_path(void *fdt, void *fdto, const char *fragment,
return ret;
target = ret;
- if (target_phandle)
- *target_phandle = ret;
+ if (target_off)
+ *target_off = ret;
/* if we have a target path use */
if (!target_path) {
@@ -1259,13 +1372,19 @@ static int lookup_target_path(void *fdt, void *fdto, const char *fragment,
}
+ /* Check fdt-path is having fragments or it part of root path */
+ if (root_path && find_node_str(buf, fragstr))
+ *root_path = 0;
+ else
+ *root_path = 1;
+
return 0;
}
static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
int snippet_len, char *buf, int buflen,
int *ignore, int base_symbol_found,
- uint32_t max_phandle)
+ uint32_t merge_olay_max_phdl)
{
const char *snippet_o = snippet;
const char *path, *fragment, *prop_name, *prop_val, *rel_path;
@@ -1275,6 +1394,7 @@ static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
static const char tprop[] = "target";
static const char frag[] = "/fragment";
static const char olay[] = "/__overlay__";
+ int root_path = 0;
/* Validate format:
* path_to_node : prop_name : prop_offset
@@ -1294,9 +1414,10 @@ static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
if (path_len < sizeof(frag) - 1 || memcmp(path, frag, sizeof(frag) - 1))
return -FDT_ERR_BADOVERLAY;
- if (base_symbol_found &&
- prop_len == sizeof(tprop) - 1 &&
- !memcmp(prop_name, tprop, sizeof(tprop) - 1)) {
+ vdprintf("%s: snippet(%s): fdto-prop(%s), val(%s)\n", __func__,
+ snippet_o, prop_name, prop_val);
+ if (base_symbol_found && prop_len == sizeof(tprop) - 1
+ && !memcmp(prop_name, tprop, sizeof(tprop) - 1)) {
*ignore = 1;
return 0;
}
@@ -1305,8 +1426,6 @@ static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
// check if there is a '/' besides the first one in node_path
sep = memchr(fragment + 1, '/', path_len - 1);
if (sep) {
- int fragment_target_found = 0;
-
fragment_len = sep - fragment;
path_len -= (sep - fragment);
if (path_len < sizeof(olay) - 1
@@ -1328,19 +1447,8 @@ static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
"__overlay__");
if (ret < 0)
return -FDT_ERR_BADOVERLAY;
-
- /* get the target of the fragment */
- ret = overlay_get_target(fdt, fdto, frag_offset, NULL);
- if (ret < 0)
- return ret;
-
- fragment_target_found = (ret < max_phandle);
}
-
- if (fragment_target_found)
- rel_path = sep + sizeof(olay) - 1;
- else
- rel_path = sep;
+ rel_path = sep;
} else {
rel_path = fragment + path_len;
fragment_len = path_len;
@@ -1352,16 +1460,29 @@ static int fixup_snippet_update(void *fdt, void *fdto, const char *snippet,
ret =
lookup_target_path(fdt, fdto, fragment + 1, fragment_len - 1, buf,
- buflen, NULL);
+ buflen, NULL, &root_path);
if (ret)
return ret;
+ /* Only single overlay should be present in path */
+ if (find_node_str(buf, "__overlay__")
+ && find_node_str(rel_path, "__overlay__")) {
+ if (sep)
+ rel_path = sep + sizeof(olay) - 1;
+ }
+
rem = buflen - strlen(buf);
if (rel_path_len >= rem)
return -FDT_ERR_INTERNAL;
sep = buf + strlen(buf);
+ vvdprintf
+ ("%s: fdt-new_path(%s), sep(%s), rel_path(%s): hit-case %d, root_path %d\n",
+ __func__, buf, sep, rel_path, base_symbol_found, root_path);
memcpy(sep, rel_path, rel_path_len);
+ vdprintf
+ ("%s: fdt-final-new_path(%s), sep(%s), rel_path(%s): hit-case %d\n",
+ __func__, buf, sep, rel_path, base_symbol_found);
return 0;
}
@@ -1458,6 +1579,27 @@ static const char *next_node(const char **path, int *path_len, int *node_len)
return node;
}
+static bool find_node_str(const char *path_str, const char *ip_str)
+{
+ const char *path, *node_str;
+ int path_len = 0, node_len = 0, ip_str_len = 0;
+
+ path = path_str;
+ path_len = strlen(path);
+ ip_str_len = strlen(ip_str);
+
+ while ((node_str = next_node(&path, &path_len, &node_len))) {
+ if (node_len >= ip_str_len
+ && !memcmp(node_str, ip_str, ip_str_len)) {
+ vvdprintf("%s: Node(%s) present in path(%s)\n",
+ __func__, ip_str, path_str);
+ return true;
+ }
+ }
+
+ return false;
+}
+
static int convert_to_u32(const char *p, uint32_t *val)
{
char *endptr;
@@ -1506,17 +1648,26 @@ static int add_to_local_fixups(void *fdt, const char *snippet)
if (parent < 0)
return parent;
+ vdprintf("%s: fdt-add snippet(%s)\n", __func__, snippet);
while ((node = next_node(&path, &path_len, &node_len))) {
int offset;
offset =
fdt_subnode_offset_namelen(fdt, parent, node, node_len);
- if (offset < 0)
+ if (offset < 0) {
offset =
fdt_add_subnode_namelen(fdt, parent, node,
node_len);
+ if (offset < 0)
+ dprintf
+ ("%s: +fdt-add_subnode failed: node(%s), offset %d\n",
+ __func__, node, offset);
+ }
if (offset < 0)
return offset;
+ vdprintf
+ ("%s: ++fdt-subnode offset/add: node(%s), fdt-node(%s) offset %d\n",
+ __func__, node, fdt_get_name(fdt, offset, NULL), offset);
parent = offset;
}
@@ -1530,10 +1681,13 @@ static int add_to_local_fixups(void *fdt, const char *snippet)
if (ret >= prop_len)
return -FDT_ERR_INTERNAL;
+ vdprintf("%s: -fdt-appendprop: prop(%s), val (%d)\n", __func__, buf,
+ val);
return fdt_appendprop_u32(fdt, parent, buf, val);
}
-static int overlay_fixups_update(void *fdt, void *fdto, uint32_t max_phandle)
+static int overlay_fixups_update(void *fdt, void *fdto,
+ uint32_t merge_olay_max_phdl)
{
int ov_fixup, root_fixup, prop;
@@ -1555,8 +1709,8 @@ static int overlay_fixups_update(void *fdt, void *fdto, uint32_t max_phandle)
base_symbol_found =
prop_exists_in_node(fdt, "/__symbols__", label);
- dprintf
- ("%s: Checking prop label %s val %s base_symbol_found %d\n",
+ vdprintf
+ ("%s: Checking +fdto-prop-label(%s) val(%s), fdt-symbol-hit %d\n",
__func__, label, prop_val, base_symbol_found);
while ((snippet =
@@ -1569,21 +1723,29 @@ static int overlay_fixups_update(void *fdt, void *fdto, uint32_t max_phandle)
snippet_len, new_val,
sizeof(new_val), &ignore,
base_symbol_found,
- max_phandle);
- dprintf
- ("%s: fixup_snippet %s new_val %s ret %d ignore %d\n",
- __func__, snippet, new_val, ret, ignore);
+ merge_olay_max_phdl);
+ vdprintf
+ ("%s: +fixup_snippet(%s) label(%s) new_val(%s) "
+ "ret %d ignore %d\n", __func__, snippet, label,
+ ignore ? "NA" : new_val, ret, ignore);
if (ret)
return ret;
if (ignore)
continue;
- if (!base_symbol_found)
+ if (!base_symbol_found) {
+ vdprintf
+ ("%s: non-hitcase: -fdt-add_to_fixups: "
+ "label(%s) new_val(%s) ret %d\n",
+ __func__, label, new_val, ret);
ret = add_to_fixups(fdt, new_val, label);
- else
+ } else {
+ vdprintf
+ ("%s: hitcase: -fdt-add_to_local_fixups: "
+ "new_val(%s) ret %d\n", __func__, new_val, ret);
ret = add_to_local_fixups(fdt, new_val);
-
+ }
if (ret)
return ret;
}
@@ -1593,9 +1755,10 @@ static int overlay_fixups_update(void *fdt, void *fdto, uint32_t max_phandle)
}
static int overlay_local_fixups_update(void *fdt, void *fdto,
- uint32_t max_phandle)
+ uint32_t merge_olay_max_phdl)
{
int ov_lfixups, root_lfixups, node, ret;
+ int root_path = 0;
ov_lfixups = fdt_subnode_offset(fdto, 0, "__local_fixups__");
if (ov_lfixups == -FDT_ERR_NOTFOUND)
@@ -1609,18 +1772,22 @@ static int overlay_local_fixups_update(void *fdt, void *fdto,
return root_lfixups;
fdt_for_each_subnode(node, fdto, ov_lfixups) {
- int len, child_node, target_phandle, parent_node;
+ int len, child_node, parent_node;
int skip_fdto_child = 0;
- int base_symbol_found;
const char *name = fdt_get_name(fdto, node, &len);
char buf[MAX_BUF_SIZE];
ret = lookup_target_path(fdt, fdto, name, strlen(name),
- buf, sizeof(buf), &target_phandle);
+ buf, sizeof(buf), NULL, &root_path);
if (ret)
return ret;
- base_symbol_found = !(target_phandle >= max_phandle);
+ /* We want to skip dtbo overlay child in two cases
+ * i.e When target path doesn't have fragment@ or __overlay__
+ * strings
+ */
+ if (root_path || find_node_str(buf, "__overlay__"))
+ skip_fdto_child = 1;
parent_node = add_to_local_fixups(fdt, buf);
if (parent_node < 0)
@@ -1630,9 +1797,14 @@ static int overlay_local_fixups_update(void *fdt, void *fdto,
if (child_node < 0)
return -FDT_ERR_BADOVERLAY;
- if (base_symbol_found)
- skip_fdto_child = 1;
-
+ vdprintf
+ ("%s: copy_node: In fdt-parent-path(%s) copy fdto-child-fragment(%s), "
+ "root_path %d\n", __func__, buf, name, root_path);
+ vdprintf
+ ("%s: copy_node: In fdt-parent-node(%s) copy fdto-child-node(%s) "
+ "but skip-fdto-first-node=%d\n",
+ __func__, fdt_get_name(fdt, parent_node, NULL),
+ fdt_get_name(fdto, child_node, NULL), skip_fdto_child);
ret = copy_node(fdt, fdto, parent_node, child_node,
NULL, skip_fdto_child);
if (ret)
@@ -1657,10 +1829,12 @@ int fdt_overlay_merge(void *fdt, void *fdto, int *fdto_nospace)
if (UINT32_MAX - delta < delta0)
return -FDT_ERR_BADOVERLAY;
max_phandle = delta + delta0 + 1;
- dprintf("delta %u max_phandle %u\n", delta, max_phandle);
+ dprintf("%s: *** delta %u & delta0 %u, max_phandle %u ***\n", __func__,
+ delta, delta0, max_phandle);
ret = overlay_adjust_local_phandles(fdto, delta);
- dprintf("adjust_local_phandles %d\n", ret);
+ dprintf("%s: *** fdto-adjust_local_phandles, ret %d ***\n", __func__,
+ ret);
if (ret) {
if (ret == -FDT_ERR_NOSPACE)
*fdto_nospace = 1;
@@ -1668,38 +1842,39 @@ int fdt_overlay_merge(void *fdt, void *fdto, int *fdto_nospace)
}
ret = overlay_update_local_references(fdto, delta);
- dprintf("update_local_references %d\n", ret);
+ dprintf("%s: *** fdto-update_local_references, ret %d ***\n", __func__,
+ ret);
if (ret) {
if (ret == -FDT_ERR_NOSPACE)
*fdto_nospace = 1;
goto err;
}
- ret = overlay_fixup_phandles(fdt, fdto, 1);
- dprintf("fixup_phandles %d\n", ret);
+ ret = overlay_fixup_phandles(fdt, fdto, max_phandle);
+ dprintf("%s: *** fixup_phandles(1), ret %d ***\n", __func__, ret);
if (ret && ret != -FDT_ERR_NOTFOUND)
goto err;
- ret = overlay_merge(fdt, fdto, 1, &max_phandle);
- dprintf("overlay_merge %d\n", ret);
+ ret = overlay_merge(fdt, fdto, &max_phandle);
+ dprintf("%s: *** merge(1), ret %d ***\n", __func__, ret);
if (ret)
goto err;
/* local_fixups node is optional */
max_phandle = delta + delta0 + 1;
ret = overlay_symbol_update(fdt, fdto, max_phandle);
- dprintf("overlay_symbol_update %d\n", ret);
+ dprintf("%s: *** symbol_update, ret %d ***\n", __func__, ret);
if (ret)
goto err;
/* fixups node is optional */
ret = overlay_fixups_update(fdt, fdto, max_phandle);
- dprintf("overlay_fixups_update %d\n", ret);
+ dprintf("%s: *** fixups_update, ret %d ***\n", __func__, ret);
if (ret < 0 && ret != -FDT_ERR_NOTFOUND)
goto err;
ret = overlay_local_fixups_update(fdt, fdto, max_phandle);
- dprintf("overlay_local_fixups_update %d\n", ret);
+ dprintf("%s: *** local_fixups_update, ret %d ***\n", __func__, ret);
if (ret < 0 && ret != -FDT_ERR_NOTFOUND)
goto err;
@@ -1708,7 +1883,7 @@ int fdt_overlay_merge(void *fdt, void *fdto, int *fdto_nospace)
*/
fdt_set_magic(fdto, ~0);
- dprintf("overlay_merge completed successfully!\n");
+ dprintf("%s *** completed successfully! ***\n", __func__);
return 0;
err:
@@ -1723,6 +1898,7 @@ err:
*/
if (!*fdto_nospace)
fdt_set_magic(fdt, ~0);
+ dprintf("%sĀ failed with ret %d ***\n", __func__, ret);
return ret;
}