diff options
author | 2025-03-24 17:15:05 +0530 | |
---|---|---|
committer | 2025-09-14 20:56:33 -0400 | |
commit | ba795890a396af944214f309b950e99b779fdddc (patch) | |
tree | 5b6cf2471a2fc81d0d192ecf6132c39912dce4ae | |
parent | 5a2289d227124e32202522dfba96f7404fae7973 (diff) |
libfdt: overlay_merge: Fix phandle errors with proper path fix
Add debug logs for more debugging.
Change-Id: I54c23072fbf6f32b5ca3ae97d7a598b1cfeddca2
Signed-off-by: Wasim Nazir <quic_wasimn@quicinc.com>
-rw-r--r-- | libfdt/fdt_overlay.c | 348 |
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; } |