<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Fri, 28 Mar 2025 at 16:52, Patrice Chotard <<a href="mailto:patrice.chotard@foss.st.com">patrice.chotard@foss.st.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Since introduction of OF_UPSTREAM flag, U-Boot's dtc must be able<br>
to compile Kernel's device tree.<br>
<br>
Since kernel commit 7de129f5389b ("ARM: dts: stm32: stm32mp151a-prtt1l:<br>
Fix QSPI configuration"), label relative path references has been<br>
introduced. These label relative path references is not supported<br>
by current U-Boot dtc version 1.5.0: (see mailing list discussion [1]).<br>
<br>
In order to support such label relative patch references<br>
adds following commit from upstream DTC tree:<br></blockquote><div><br></div><div>Maybe we need to rebase to the latest upstream dtc, I'm not sure pulling in a random set of bits from upstream is the right way to do things as it's brings things selectively which may bring along other issues.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
commit 651410e54cb9 ("util: introduce xstrndup helper")<br>
commit ec7986e682cf ("dtc: introduce label relative path references")<br>
<br>
[1] <a href="https://lore.kernel.org/all/20250115144428.GZ3476@bill-the-cat/T/" rel="noreferrer" target="_blank">https://lore.kernel.org/all/20250115144428.GZ3476@bill-the-cat/T/</a><br>
<br>
Signed-off-by: Patrice Chotard <<a href="mailto:patrice.chotard@foss.st.com" target="_blank">patrice.chotard@foss.st.com</a>><br>
Cc: Tom Rini <<a href="mailto:trini@konsulko.com" target="_blank">trini@konsulko.com</a>><br>
Cc: Simon Glass <<a href="mailto:sjg@chromium.org" target="_blank">sjg@chromium.org</a>><br>
---<br>
<br>
 scripts/dtc/dtc-lexer.l  |  2 +-<br>
 scripts/dtc/dtc-parser.y | 13 +++++++++++++<br>
 scripts/dtc/livetree.c   | 33 ++++++++++++++++++++++++++++++---<br>
 scripts/dtc/util.c       | 11 +++++++++++<br>
 scripts/dtc/util.h       |  1 +<br>
 5 files changed, 56 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l<br>
index d3694d6cf20..d34e1b04220 100644<br>
--- a/scripts/dtc/dtc-lexer.l<br>
+++ b/scripts/dtc/dtc-lexer.l<br>
@@ -215,7 +215,7 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);<br>
                        return DT_REF;<br>
                }<br>
<br>
-<*>"&{/"{PATHCHAR}*\}  {       /* new-style path reference */<br>
+<*>"&{"{PATHCHAR}*\}   {       /* new-style path reference */<br>
                        yytext[yyleng-1] = '\0';<br>
                        DPRINT("Ref: %s\n", yytext+2);<br>
                        yylval.labelref = xstrdup(yytext+2);<br>
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y<br>
index 011a5b25539..b3b9c83873d 100644<br>
--- a/scripts/dtc/dtc-parser.y<br>
+++ b/scripts/dtc/dtc-parser.y<br>
@@ -34,6 +34,12 @@ extern void yyerror(char const *s);<br>
<br>
 extern struct dt_info *parser_output;<br>
 extern bool treesource_error;<br>
+<br>
+static bool is_ref_relative(const char *ref)<br>
+{<br>
+       return ref[0] != '/' && strchr(&ref[1], '/');<br>
+}<br>
+<br>
 %}<br>
<br>
 %union {<br>
@@ -176,12 +182,17 @@ devicetree:<br>
                         */<br>
                        if (!($<flags>-1 & DTSF_PLUGIN))<br>
                                ERROR(&@2, "Label or path %s not found", $1);<br>
+                       else if (is_ref_relative($1))<br>
+                               ERROR(&@2, "Label-relative reference %s not supported in plugin", $1);<br>
                        $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);<br>
                }<br>
        | devicetree DT_LABEL DT_REF nodedef<br>
                {<br>
                        struct node *target = get_node_by_ref($1, $3);<br>
<br>
+                       if (($<flags>-1 & DTSF_PLUGIN) && is_ref_relative($3))<br>
+                               ERROR(&@2, "Label-relative reference %s not supported in plugin", $3);<br>
+<br>
                        if (target) {<br>
                                add_label(&target->labels, $2);<br>
                                merge_nodes(target, $4);<br>
@@ -197,6 +208,8 @@ devicetree:<br>
                         * so $-1 is what we want (plugindecl)<br>
                         */<br>
                        if ($<flags>-1 & DTSF_PLUGIN) {<br>
+                               if (is_ref_relative($2))<br>
+                                       ERROR(&@2, "Label-relative reference %s not supported in plugin", $2);<br>
                                add_orphan_node($1, $3, $2);<br>
                        } else {<br>
                                struct node *target = get_node_by_ref($1, $2);<br>
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c<br>
index ba06ef348be..4cfc2adccdd 100644<br>
--- a/scripts/dtc/livetree.c<br>
+++ b/scripts/dtc/livetree.c<br>
@@ -583,12 +583,39 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)<br>
<br>
 struct node *get_node_by_ref(struct node *tree, const char *ref)<br>
 {<br>
+       struct node *target = tree;<br>
+       const char *label = NULL, *path = NULL;<br>
+<br>
        if (streq(ref, "/"))<br>
                return tree;<br>
-       else if (ref[0] == '/')<br>
-               return get_node_by_path(tree, ref);<br>
+<br>
+       if (ref[0] == '/')<br>
+               path = ref;<br>
        else<br>
-               return get_node_by_label(tree, ref);<br>
+               label = ref;<br>
+<br>
+       if (label) {<br>
+               const char *slash = strchr(label, '/');<br>
+               char *buf = NULL;<br>
+<br>
+               if (slash) {<br>
+                       buf = xstrndup(label, slash - label);<br>
+                       label = buf;<br>
+                       path = slash + 1;<br>
+               }<br>
+<br>
+               target = get_node_by_label(tree, label);<br>
+<br>
+               free(buf);<br>
+<br>
+               if (!target)<br>
+                       return NULL;<br>
+       }<br>
+<br>
+       if (path)<br>
+               target = get_node_by_path(target, path);<br>
+<br>
+       return target;<br>
 }<br>
<br>
 cell_t get_node_phandle(struct node *root, struct node *node)<br>
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c<br>
index 23334d39bb6..25d4db1e8c2 100644<br>
--- a/scripts/dtc/util.c<br>
+++ b/scripts/dtc/util.c<br>
@@ -46,6 +46,17 @@ char *xstrdup(const char *s)<br>
        return d;<br>
 }<br>
<br>
+char *xstrndup(const char *s, size_t n)<br>
+{<br>
+       size_t len = strnlen(s, n) + 1;<br>
+       char *d = xmalloc(len);<br>
+<br>
+       memcpy(d, s, len - 1);<br>
+       d[len - 1] = '\0';<br>
+<br>
+       return d;<br>
+}<br>
+<br>
 /* based in part from (3) vsnprintf */<br>
 int xasprintf(char **strp, const char *fmt, ...)<br>
 {<br>
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h<br>
index 211d584435d..23e32962385 100644<br>
--- a/scripts/dtc/util.h<br>
+++ b/scripts/dtc/util.h<br>
@@ -70,6 +70,7 @@ static inline void *xrealloc(void *p, size_t len)<br>
 }<br>
<br>
 extern char *xstrdup(const char *s);<br>
+extern char *xstrndup(const char *s, size_t len);<br>
<br>
 extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);<br>
 extern char *join_path(const char *path, const char *name);<br>
-- <br>
2.25.1<br>
<br>
</blockquote></div></div>