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