* [PATCH] label: collect labels to __phandles__ node in interger format
@ 2025-09-01 12:22 yuan linyu
2025-09-29 2:33 ` yuanlinyu
0 siblings, 1 reply; 4+ messages in thread
From: yuan linyu @ 2025-09-01 12:22 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-compiler, yuan linyu
Currently labels are collect to __symbols__ node in path string format,
the libufdt have no support of it when do overlay.
Add a new method which collect labels in __phandles__ node which each
entry is an interger format, it will allow libufdt to keep labels when
do (stack) overlay.
The new method including below points,
1. add an option -P for dtc tool, it will create __phandles__ node and
labels in interger foramt
2. add new function in fdt_overlay.c to support merge __phandles__ node
3. add overlay test which test -P option
---
dtc.c | 18 +++-
dtc.h | 4 +-
libfdt/fdt_overlay.c | 250 ++++++++++++++++++++++++++++++++++++++-----
livetree.c | 76 +++++++++++--
tests/run_tests.sh | 84 +++++++++++++++
5 files changed, 392 insertions(+), 40 deletions(-)
diff --git a/dtc.c b/dtc.c
index b3445b7d6473..c62da2888a6f 100644
--- a/dtc.c
+++ b/dtc.c
@@ -18,6 +18,7 @@ int padsize; /* Additional padding to blob */
int alignsize; /* Additional padding to blob according to the alignsize */
int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
int generate_symbols; /* enable symbols & fixup support */
+int generate_phandles; /* collect phandles to __phandles node */
int generate_fixups; /* suppress generation of fixups on symbol support */
int auto_label_aliases; /* auto generate labels -> aliases */
int annotate; /* Level of annotation: 1 for input source location
@@ -47,7 +48,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
/* Usage related data. */
static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@LAThv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@PLAThv";
static struct option const usage_long_opts[] = {
{"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'},
@@ -67,6 +68,7 @@ static struct option const usage_long_opts[] = {
{"warning", a_argument, NULL, 'W'},
{"error", a_argument, NULL, 'E'},
{"symbols", no_argument, NULL, '@'},
+ {"phandles", no_argument, NULL, 'P'},
{"local-fixups", no_argument, NULL, 'L'},
{"auto-alias", no_argument, NULL, 'A'},
{"annotate", no_argument, NULL, 'T'},
@@ -105,6 +107,7 @@ static const char * const usage_opts_help[] = {
"\n\tEnable/disable warnings (prefix with \"no-\")",
"\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tEnable generation of symbols",
+ "\n\tEnable generation of phandles",
"\n\tPossibly generates a __local_fixups__ and a __fixups__ node at the root node",
"\n\tEnable auto-alias of labels",
"\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
@@ -255,6 +258,9 @@ int main(int argc, char *argv[])
generate_symbols = 1;
break;
+ case 'P':
+ generate_phandles = 1;
+ break;
case 'L':
generate_fixups = 1;
break;
@@ -336,10 +342,16 @@ int main(int argc, char *argv[])
process_checks(force, dti);
if (auto_label_aliases)
- generate_label_tree(dti, "aliases", false);
+ generate_label_tree(dti, "aliases");
+
+ if (generate_phandles || generate_symbols)
+ allocate_phandle(dti);
if (generate_symbols)
- generate_label_tree(dti, "__symbols__", true);
+ generate_label_tree(dti, "__symbols__");
+
+ if (generate_phandles)
+ generate_phandles_tree(dti, "__phandles__");
if (generate_fixups) {
generate_fixups_tree(dti, "__fixups__");
diff --git a/dtc.h b/dtc.h
index 3a220b9afc99..92689a6bb70e 100644
--- a/dtc.h
+++ b/dtc.h
@@ -339,7 +339,9 @@ struct dt_info *build_dt_info(unsigned int dtsflags,
struct reserve_info *reservelist,
struct node *tree, uint32_t boot_cpuid_phys);
void sort_tree(struct dt_info *dti);
-void generate_label_tree(struct dt_info *dti, const char *name, bool allocph);
+void allocate_phandle(struct dt_info *dti);
+void generate_label_tree(struct dt_info *dti, const char *name);
+void generate_phandles_tree(struct dt_info *dti, const char *name);
void generate_fixups_tree(struct dt_info *dti, const char *name);
void generate_local_fixups_tree(struct dt_info *dti, const char *name);
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index e6b9eb643958..c080bca8665e 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -305,10 +305,49 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)
delta);
}
+/**
+ * overlay_adjust_phandles_node - Adjust properties of __phandles__
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_phandles_node() update all the values of property
+ * in overlay __phandles__ node.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_adjust_phandles_node(void *fdto, uint32_t delta)
+{
+ int phandles;
+ int offset;
+
+ phandles = fdt_subnode_offset(fdto, 0, "__phandles__");
+ if (phandles < 0) {
+ if (phandles == -FDT_ERR_NOTFOUND)
+ return 0;
+
+ return phandles;
+ }
+
+ fdt_for_each_property_offset(offset, fdto, phandles) {
+ const fdt32_t *val;
+ const char *name;
+ int len;
+
+ val = fdt_getprop_by_offset(fdto, offset, &name, &len);
+ if (!val || len != sizeof(uint32_t))
+ return -FDT_ERR_BADOVERLAY;
+
+ fdt32_st((void *)(uintptr_t)val, fdt32_ld(val) + delta);
+ }
+
+ return 0;
+}
+
/**
* overlay_fixup_one_phandle - Set an overlay phandle to the base one
* @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
@@ -327,7 +366,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)
* 0 on success
* Negative error code on failure
*/
-static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
+static int overlay_fixup_one_phandle(void *fdto,
const char *path, uint32_t path_len,
const char *name, uint32_t name_len,
int poffset, uint32_t phandle)
@@ -335,9 +374,6 @@ static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
fdt32_t phandle_prop;
int fixup_off;
- if (symbols_off < 0)
- return symbols_off;
-
fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
if (fixup_off == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
@@ -351,6 +387,58 @@ static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
sizeof(phandle_prop));
}
+/**
+ * overlay_get_fixup_phandle - Get phandle for a lable from the base
+ * @fdt: Device tree blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @phandles_off: Node offset of the phandle node in the base device tree
+ * @label: label that need to resolve phandle
+ * @phandle: Phandle that resolved
+ *
+ * overlay_get_fixup_phandle() resolves a label phandle pointing to
+ * a node in the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_get_fixup_phandle(void *fdt, int symbols_off,
+ int phandles_off, const char *label, uint32_t *phandle)
+{
+ const fdt32_t *val;
+ const char *symbol_path;
+ int prop_len;
+ int symbol_off;
+
+ *phandle = (uint32_t)-1;
+ if (symbols_off == -FDT_ERR_NOTFOUND &&
+ phandles_off == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_NOTFOUND;
+
+ if (phandles_off != -FDT_ERR_NOTFOUND) {
+ val = fdt_getprop(fdt, phandles_off, label, &prop_len);
+ if (!val || prop_len != sizeof(*val))
+ return -FDT_ERR_INTERNAL;
+
+ *phandle = fdt32_ld_(val);
+ } else {
+ 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 || *phandle > FDT_MAX_PHANDLE)
+ return -FDT_ERR_NOTFOUND;
+
+ return 0;
+}
+
/**
* overlay_fixup_phandle - Set an overlay phandle to the base one
* @fdt: Base Device Tree blob
@@ -371,14 +459,12 @@ static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
* Negative error code on failure
*/
static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
- int property)
+ int phandles_off, int property)
{
const char *value;
const char *label;
int len;
- const char *symbol_path;
- int prop_len;
- int symbol_off;
+ int err;
uint32_t phandle;
value = fdt_getprop_by_offset(fdto, property,
@@ -390,17 +476,10 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
return len;
}
- 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;
+ err = overlay_get_fixup_phandle(fdt, symbols_off, phandles_off,
+ label, &phandle);
+ if (err < 0)
+ return err;
do {
const char *path, *name, *fixup_end;
@@ -441,7 +520,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
if ((*endptr != '\0') || (endptr <= (sep + 1)))
return -FDT_ERR_BADOVERLAY;
- ret = overlay_fixup_one_phandle(fdto, symbols_off,
+ ret = overlay_fixup_one_phandle(fdto,
path, path_len, name, name_len,
poffset, phandle);
if (ret)
@@ -470,7 +549,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
*/
static int overlay_fixup_phandles(void *fdt, void *fdto)
{
- int fixups_off, symbols_off;
+ int fixups_off, symbols_off, phandles_off;
int property;
/* We can have overlays without any fixups */
@@ -482,13 +561,18 @@ static int overlay_fixup_phandles(void *fdt, void *fdto)
/* And base DTs without symbols */
symbols_off = fdt_path_offset(fdt, "/__symbols__");
- if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
+ if (symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))
return symbols_off;
+ phandles_off = fdt_path_offset(fdt, "/__phandles__");
+ if (phandles_off < 0 && phandles_off != -FDT_ERR_NOTFOUND)
+ return phandles_off;
+
fdt_for_each_property_offset(property, fdto, fixups_off) {
int ret;
- ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
+ ret = overlay_fixup_phandle(fdt, fdto, symbols_off,
+ phandles_off, property);
if (ret)
return ret;
}
@@ -640,19 +724,62 @@ static int overlay_update_local_conflicting_references(void *fdto,
fdto_phandle);
}
+/**
+ * overlay_update_conflicting_phandles - resolve conflicting in __phandles__
+ * @fdto: Device tree overlay blob
+ * @fdtophandles: fdto __phandles__ node offset
+ * @fdt_phandle: Value to replace phandles with
+ * @fdto_phandle: Value to be replaced
+ *
+ * Replaces all values with value @fdto_phandle by @fdt_phandle.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_update_conflicting_phandles(void *fdto, int fdtophandles,
+ uint32_t fdt_phandle,
+ uint32_t fdto_phandle)
+{
+ int phandle_prop;
+
+ if (fdtophandles < 0)
+ return 0;
+
+ fdt_for_each_property_offset(phandle_prop, fdto, fdtophandles) {
+ const fdt32_t *phandle_val;
+ int phandle_len;
+ uint32_t phandle;
+
+ phandle_val = fdt_getprop_by_offset(fdto, phandle_prop,
+ NULL, &phandle_len);
+ if (!phandle_val || phandle_len != sizeof(uint32_t))
+ return -FDT_ERR_BADOVERLAY;
+
+ phandle = fdt32_ld(phandle_val);
+ if (phandle != fdto_phandle)
+ continue;
+
+ fdt32_st((void *)(uintptr_t)phandle_val, fdt_phandle);
+ }
+
+ return 0;
+}
+
/**
* overlay_prevent_phandle_overwrite_node - Helper function for overlay_prevent_phandle_overwrite
* @fdt: Base Device tree blob
* @fdtnode: Node in fdt that is checked for an overwrite
* @fdto: Device tree overlay blob
* @fdtonode: Node in fdto matching @fdtnode
+ * @fdtophandles: fdto __phandles__ offset
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode,
- void *fdto, int fdtonode)
+ void *fdto, int fdtonode, int fdtophandles)
{
uint32_t fdt_phandle, fdto_phandle;
int fdtochild;
@@ -673,6 +800,12 @@ static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode,
fdto_phandle);
if (ret)
return ret;
+
+ ret = overlay_update_conflicting_phandles(fdto, fdtophandles,
+ fdt_phandle,
+ fdto_phandle);
+ if (ret)
+ return ret;
}
fdt_for_each_subnode(fdtochild, fdto, fdtonode) {
@@ -689,7 +822,7 @@ static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode,
continue;
ret = overlay_prevent_phandle_overwrite_node(fdt, fdtchild,
- fdto, fdtochild);
+ fdto, fdtochild, fdtophandles);
if (ret)
return ret;
}
@@ -712,6 +845,7 @@ static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode,
*/
static int overlay_prevent_phandle_overwrite(void *fdt, void *fdto)
{
+ int fdtophandles = fdt_subnode_offset(fdto, 0, "__phandles__");
int fragment;
fdt_for_each_subnode(fragment, fdto, 0) {
@@ -737,7 +871,7 @@ static int overlay_prevent_phandle_overwrite(void *fdt, void *fdto)
return target;
ret = overlay_prevent_phandle_overwrite_node(fdt, target,
- fdto, overlay);
+ fdto, overlay, fdtophandles);
if (ret)
return ret;
}
@@ -1037,6 +1171,59 @@ static int overlay_symbol_update(void *fdt, void *fdto)
return 0;
}
+/**
+ * overlay_phandles_update - Update the phandles of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_phandles_update() updates the phandles of the base tree with the
+ * phandles of the applied overlay
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_phandles_update(void *fdt, void *fdto)
+{
+ int root_pha, ov_pha, prop, val_len;
+ int ret;
+ const char *val;
+ const char *name;
+ void *p;
+
+ ov_pha = fdt_subnode_offset(fdto, 0, "__phandles__");
+
+ /* if no overlay phandles exist no problem */
+ if (ov_pha < 0)
+ return 0;
+
+ root_pha = fdt_subnode_offset(fdt, 0, "__phandles__");
+
+ /* it no root symbols exist we should create them */
+ if (root_pha == -FDT_ERR_NOTFOUND)
+ root_pha = fdt_add_subnode(fdt, 0, "__phandles__");
+
+ /* any error is fatal now */
+ if (root_pha < 0)
+ return root_pha;
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset(prop, fdto, ov_pha) {
+ val = fdt_getprop_by_offset(fdto, prop, &name, &val_len);
+ if (!val)
+ return val_len;
+
+ ret = fdt_setprop_placeholder(fdt, root_pha, name,
+ sizeof(uint32_t), &p);
+ if (ret < 0)
+ return ret;
+
+ memcpy(p, val, sizeof(uint32_t));
+ }
+
+ return 0;
+}
+
int fdt_overlay_apply(void *fdt, void *fdto)
{
uint32_t delta;
@@ -1059,6 +1246,11 @@ int fdt_overlay_apply(void *fdt, void *fdto)
if (ret)
goto err;
+ /* Increase value of all properties in phandles node by delta */
+ ret = overlay_adjust_phandles_node(fdto, delta);
+ if (ret)
+ goto err;
+
/* Update fdto's phandles using symbols from fdt */
ret = overlay_fixup_phandles(fdt, fdto);
if (ret)
@@ -1073,6 +1265,10 @@ int fdt_overlay_apply(void *fdt, void *fdto)
if (ret)
goto err;
+ ret = overlay_phandles_update(fdt, fdto);
+ if (ret)
+ goto err;
+
ret = overlay_symbol_update(fdt, fdto);
if (ret)
goto err;
diff --git a/livetree.c b/livetree.c
index f328824c3bc6..7f6094a31dc6 100644
--- a/livetree.c
+++ b/livetree.c
@@ -908,12 +908,25 @@ static bool any_label_tree(struct dt_info *dti, struct node *node)
return false;
}
-static void generate_label_tree_internal(struct dt_info *dti,
- struct node *an, struct node *node,
- bool allocph)
+static void allocate_phandle_internal(struct dt_info *dti, struct node *node)
{
struct node *dt = dti->dt;
struct node *c;
+
+ /* if there are labels */
+ if (node->labels) {
+ /* force allocation of a phandle for this node */
+ (void)get_node_phandle(dt, node);
+ }
+
+ for_each_child(node, c)
+ allocate_phandle_internal(dti, c);
+}
+
+static void generate_label_tree_internal(struct dt_info *dti,
+ struct node *an, struct node *node)
+{
+ struct node *c;
struct property *p;
struct label *l;
@@ -939,14 +952,44 @@ static void generate_label_tree_internal(struct dt_info *dti,
NULL);
add_property(an, p);
}
+ }
- /* force allocation of a phandle for this node */
- if (allocph)
- (void)get_node_phandle(dt, node);
+ for_each_child(node, c)
+ generate_label_tree_internal(dti, an, c);
+}
+
+static void generate_phandles_tree_internal(struct dt_info *dti,
+ struct node *pn,
+ struct node *node)
+{
+ struct node *c;
+ struct property *p;
+ struct label *l;
+ struct data d;
+
+ /* if there are labels */
+ if (node->labels) {
+
+ /* now add the phandle for each label of the node */
+ for_each_label(node->labels, l) {
+ /* check whether the label already exists */
+ p = get_property(pn, l->label);
+ if (p) {
+ fprintf(stderr, "WARNING: label %s already"
+ " exists in /%s", l->label,
+ pn->name);
+ continue;
+ }
+
+ d = data_add_marker(empty_data, TYPE_UINT32, NULL);
+ d = data_append_cell(d, node->phandle);
+ p = build_property(l->label, d, NULL);
+ add_property(pn, p);
+ }
}
for_each_child(node, c)
- generate_label_tree_internal(dti, an, c, allocph);
+ generate_phandles_tree_internal(dti, pn, c);
}
static bool any_fixup_tree(struct dt_info *dti, struct node *node)
@@ -1112,12 +1155,27 @@ static int generate_local_fixups_tree_internal(struct dt_info *dti,
return ret;
}
-void generate_label_tree(struct dt_info *dti, const char *name, bool allocph)
+void allocate_phandle(struct dt_info *dti)
+{
+ if (!any_label_tree(dti, dti->dt))
+ return;
+ allocate_phandle_internal(dti, dti->dt);
+}
+
+void generate_label_tree(struct dt_info *dti, const char *name)
{
if (!any_label_tree(dti, dti->dt))
return;
generate_label_tree_internal(dti, build_root_node(dti->dt, name),
- dti->dt, allocph);
+ dti->dt);
+}
+
+void generate_phandles_tree(struct dt_info *dti, const char *name)
+{
+ if (!any_label_tree(dti, dti->dt))
+ return;
+ generate_phandles_tree_internal(dti, build_root_node(dti->dt, name),
+ dti->dt);
}
void generate_fixups_tree(struct dt_info *dti, const char *name)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index f07092b76b43..00fcecbe739a 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -1090,6 +1090,89 @@ fdtoverlay_tests() {
run_wrap_test test "$bd" = "$pd"
}
+fdtoverlay_phandles_tests() {
+ base="$SRCDIR/overlay_base.dts"
+ basedtb=overlay_base.fdoverlay.phandles.test.dtb
+ overlay="$SRCDIR/overlay_overlay_manual_fixups.dts"
+ overlaydtb=overlay_overlay_manual_fixups.fdoverlay.phandles.test.dtb
+ targetdtb=target.fdoverlay.phandles.test.dtb
+
+ run_dtc_test -P -I dts -O dtb -o $basedtb $base
+ run_dtc_test -P -I dts -O dtb -o $overlaydtb $overlay
+
+ # test that the new property is installed
+ run_fdtoverlay_test foobar "/test-node" "test-str-property" "-ts" ${basedtb} ${targetdtb} ${overlaydtb}
+
+ stacked_base="$SRCDIR/stacked_overlay_base.dts"
+ stacked_basedtb=stacked_overlay_base.fdtoverlay.phandles.test.dtb
+ stacked_bar="$SRCDIR/stacked_overlay_bar.dts"
+ stacked_bardtb=stacked_overlay_bar.fdtoverlay.phandles.test.dtb
+ stacked_baz="$SRCDIR/stacked_overlay_baz.dts"
+ stacked_bazdtb=stacked_overlay_baz.fdtoverlay.phandles.test.dtb
+ stacked_targetdtb1=stacked_overlay_target.fdtoverlay.phandles1.test.dtb
+ stacked_targetdtb2=stacked_overlay_target.fdtoverlay.phandles2.test.dtb
+ stacked_targetdtb3=stacked_overlay_target.fdtoverlay.phandles3.test.dtb
+
+ run_dtc_test -P -I dts -O dtb -o $stacked_basedtb $stacked_base
+ run_dtc_test -P -I dts -O dtb -o $stacked_bardtb $stacked_bar
+ run_dtc_test -P -I dts -O dtb -o $stacked_bazdtb $stacked_baz
+
+ # test that baz correctly inserted the property
+ run_fdtoverlay_test baz "/foonode/barnode/baznode" "baz-property" "-ts" ${stacked_basedtb} ${stacked_targetdtb1} ${stacked_bardtb} ${stacked_bazdtb}
+
+ # test that bar and baz are correctly appended to __phandles__
+ run_fdtoverlay_test "2" "/__phandles__" "bar" "-tu" ${stacked_basedtb} ${stacked_targetdtb2} ${stacked_bardtb}
+ run_fdtoverlay_test "3" "/__phandles__" "baz" "-tu" ${stacked_basedtb} ${stacked_targetdtb3} ${stacked_bardtb} ${stacked_bazdtb}
+
+ overlay_long_path="$SRCDIR/overlay_overlay_long_path.dts"
+ overlay_long_pathdtb=overlay_overlay_long_path.fdoverlay.phandles.test.dtb
+ target_long_pathdtb=overlay_overlay_long_path_target.fdoverlay.phandles.test.dtb
+ run_dtc_test -P -I dts -O dtb -o $overlay_long_pathdtb $overlay_long_path
+
+ # test that fdtoverlay manages to apply overlays with long target path
+ run_fdtoverlay_test lpath "/test-node/sub-test-node/sub-test-node-with-very-long-target-path/test-0" "prop" "-ts" ${basedtb} ${target_long_pathdtb} ${overlay_long_pathdtb}
+
+ # test adding a label to the root of a fragment
+ stacked_base_nolabel="$SRCDIR/stacked_overlay_base_nolabel.dts"
+ stacked_base_nolabeldtb=stacked_overlay_base_nolabel.phandles.test.dtb
+ stacked_addlabel="$SRCDIR/stacked_overlay_addlabel.dts"
+ stacked_addlabeldtb=stacked_overlay_addlabel.phandles.test.dtb
+ stacked_addlabel_targetdtb=stacked_overlay_target_nolabel.fdtoverlay.phandles.test.dtb
+
+ run_dtc_test -P -I dts -O dtb -o $stacked_base_nolabeldtb $stacked_base_nolabel
+ run_dtc_test -P -I dts -O dtb -o $stacked_addlabeldtb $stacked_addlabel
+
+ run_fdtoverlay_test baz "/foonode/barnode/baznode" "baz-property" "-ts" ${stacked_base_nolabeldtb} ${stacked_addlabel_targetdtb} ${stacked_addlabeldtb} ${stacked_bardtb} ${stacked_bazdtb}
+
+ # verify that phandles are not overwritten
+ run_dtc_test -P -I dts -O dtb -o overlay_base_phandle.phandles.test.dtb "$SRCDIR/overlay_base_phandle.dts"
+ run_dtc_test -P -I dts -O dtb -o overlay_overlay_phandle.phandles.test.dtb "$SRCDIR/overlay_overlay_phandle.dts"
+ run_wrap_test $FDTOVERLAY -i overlay_base_phandle.phandles.test.dtb -o overlay_base_phandleO.phandles.test.dtb overlay_overlay_phandle.phandles.test.dtb
+
+ pa=$($DTGET overlay_base_phandleO.phandles.test.dtb /a phandle)
+ pb=$($DTGET overlay_base_phandleO.phandles.test.dtb /b phandle)
+ pc=$($DTGET overlay_base_phandleO.phandles.test.dtb /c phandle)
+ pd=$($DTGET overlay_base_phandleO.phandles.test.dtb /d phandle)
+ ba=$($DTGET overlay_base_phandleO.phandles.test.dtb /b a)
+ bd=$($DTGET overlay_base_phandleO.phandles.test.dtb /b d)
+ cb=$($DTGET overlay_base_phandleO.phandles.test.dtb /c b)
+ da=$($DTGET overlay_base_phandleO.phandles.test.dtb /d a)
+ db=$($DTGET overlay_base_phandleO.phandles.test.dtb /d b)
+ dc=$($DTGET overlay_base_phandleO.phandles.test.dtb /d c)
+
+ shorten_echo "check phandle to noda a wasn't overwritten: "
+ run_wrap_test test "$ba-$da" = "$pa-$pa"
+
+ shorten_echo "check phandle to noda b wasn't overwritten: "
+ run_wrap_test test "$cb-$db" = "$pb-$pb"
+
+ shorten_echo "check phandle to noda c wasn't overwritten: "
+ run_wrap_test test "$dc" = "$pc"
+
+ shorten_echo "check phandle to noda d wasn't overwritten: "
+ run_wrap_test test "$bd" = "$pd"
+}
+
pylibfdt_tests () {
run_dtc_test -I dts -O dtb -o test_props.dtb "$SRCDIR/test_props.dts"
TMP=/tmp/tests.stderr.$$
@@ -1168,6 +1251,7 @@ for set in $TESTSETS; do
;;
"fdtoverlay")
fdtoverlay_tests
+ fdtoverlay_phandles_tests
;;
esac
done
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* RE: [PATCH] label: collect labels to __phandles__ node in interger format
2025-09-01 12:22 [PATCH] label: collect labels to __phandles__ node in interger format yuan linyu
@ 2025-09-29 2:33 ` yuanlinyu
2025-10-03 6:29 ` David Gibson
0 siblings, 1 reply; 4+ messages in thread
From: yuanlinyu @ 2025-09-29 2:33 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-compiler@vger.kernel.org
Hi David and other devicetree developer,
Could you help review this change ?
thanks
-----Original Message-----
From: yuanlinyu <yuanlinyu@honor.com>
Sent: Monday, September 1, 2025 8:23 PM
To: David Gibson <david@gibson.dropbear.id.au>
Cc: devicetree-compiler@vger.kernel.org; yuanlinyu <yuanlinyu@honor.com>
Subject: [PATCH] label: collect labels to __phandles__ node in interger format
Currently labels are collect to __symbols__ node in path string format,
the libufdt have no support of it when do overlay.
Add a new method which collect labels in __phandles__ node which each
entry is an interger format, it will allow libufdt to keep labels when
do (stack) overlay.
The new method including below points,
1. add an option -P for dtc tool, it will create __phandles__ node and
labels in interger foramt
2. add new function in fdt_overlay.c to support merge __phandles__ node
3. add overlay test which test -P option
---
dtc.c | 18 +++-
dtc.h | 4 +-
libfdt/fdt_overlay.c | 250 ++++++++++++++++++++++++++++++++++++++-----
livetree.c | 76 +++++++++++--
tests/run_tests.sh | 84 +++++++++++++++
5 files changed, 392 insertions(+), 40 deletions(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] label: collect labels to __phandles__ node in interger format
2025-09-29 2:33 ` yuanlinyu
@ 2025-10-03 6:29 ` David Gibson
2026-03-06 2:38 ` yuanlinyu
0 siblings, 1 reply; 4+ messages in thread
From: David Gibson @ 2025-10-03 6:29 UTC (permalink / raw)
To: yuanlinyu; +Cc: devicetree-compiler@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]
On Mon, Sep 29, 2025 at 02:33:19AM +0000, yuanlinyu wrote:
> Hi David and other devicetree developer,
>
> Could you help review this change ?
Sorry for the lack of reply. I'm not going to apply this. There's
currently a big discussion underway on this list (amongst others)
about better ways of doing runtime device tree modifications. ("Re:
Device tree representation of (hotplug) connectors: discussion at
ELCE").
My main point in that thread is that we need to reconsider the design
of this end-to-end, and not add more hacks on top of the overlay
mechanism which was never really designed for this.
>
> thanks
> -----Original Message-----
> From: yuanlinyu <yuanlinyu@honor.com>
> Sent: Monday, September 1, 2025 8:23 PM
> To: David Gibson <david@gibson.dropbear.id.au>
> Cc: devicetree-compiler@vger.kernel.org; yuanlinyu <yuanlinyu@honor.com>
> Subject: [PATCH] label: collect labels to __phandles__ node in interger format
>
> Currently labels are collect to __symbols__ node in path string format,
> the libufdt have no support of it when do overlay.
>
> Add a new method which collect labels in __phandles__ node which each
> entry is an interger format, it will allow libufdt to keep labels when
> do (stack) overlay.
>
> The new method including below points,
> 1. add an option -P for dtc tool, it will create __phandles__ node and
> labels in interger foramt
> 2. add new function in fdt_overlay.c to support merge __phandles__ node
> 3. add overlay test which test -P option
> ---
> dtc.c | 18 +++-
> dtc.h | 4 +-
> libfdt/fdt_overlay.c | 250 ++++++++++++++++++++++++++++++++++++++-----
> livetree.c | 76 +++++++++++--
> tests/run_tests.sh | 84 +++++++++++++++
> 5 files changed, 392 insertions(+), 40 deletions(-)
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread* RE: [PATCH] label: collect labels to __phandles__ node in interger format
2025-10-03 6:29 ` David Gibson
@ 2026-03-06 2:38 ` yuanlinyu
0 siblings, 0 replies; 4+ messages in thread
From: yuanlinyu @ 2026-03-06 2:38 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-compiler@vger.kernel.org
> From: David Gibson <david@gibson.dropbear.id.au>
> Sent: Friday, October 3, 2025 2:29 PM
> To: yuanlinyu <yuanlinyu@honor.com>
> Cc: devicetree-compiler@vger.kernel.org
> Subject: Re: [PATCH] label: collect labels to __phandles__ node in interger
> format
>
> On Mon, Sep 29, 2025 at 02:33:19AM +0000, yuanlinyu wrote:
> > Hi David and other devicetree developer,
> >
> > Could you help review this change ?
>
> Sorry for the lack of reply. I'm not going to apply this. There's currently a big
> discussion underway on this list (amongst others) about better ways of doing
> runtime device tree modifications. ("Re:
> Device tree representation of (hotplug) connectors: discussion at ELCE").
>
> My main point in that thread is that we need to reconsider the design of this
> end-to-end, and not add more hacks on top of the overlay mechanism which was
> never really designed for this.
Hi maintainer,
Is it possible to reconsider to take this change ?
Or could you share the idea to improve it ?
>
> >
> > thanks
> > -----Original Message-----
> > From: yuanlinyu <yuanlinyu@honor.com>
> > Sent: Monday, September 1, 2025 8:23 PM
> > To: David Gibson <david@gibson.dropbear.id.au>
> > Cc: devicetree-compiler@vger.kernel.org; yuanlinyu
> > <yuanlinyu@honor.com>
> > Subject: [PATCH] label: collect labels to __phandles__ node in
> > interger format
> >
> > Currently labels are collect to __symbols__ node in path string
> > format, the libufdt have no support of it when do overlay.
> >
> > Add a new method which collect labels in __phandles__ node which each
> > entry is an interger format, it will allow libufdt to keep labels when
> > do (stack) overlay.
> >
> > The new method including below points, 1. add an option -P for dtc
> > tool, it will create __phandles__ node and labels in interger foramt
> > 2. add new function in fdt_overlay.c to support merge __phandles__
> > node 3. add overlay test which test -P option
> > ---
> > dtc.c | 18 +++-
> > dtc.h | 4 +-
> > libfdt/fdt_overlay.c | 250 ++++++++++++++++++++++++++++++++++++++-----
> > livetree.c | 76 +++++++++++--
> > tests/run_tests.sh | 84 +++++++++++++++
> > 5 files changed, 392 insertions(+), 40 deletions(-)
>
> --
> David Gibson (he or they) | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
> | around.
> http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-06 2:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-01 12:22 [PATCH] label: collect labels to __phandles__ node in interger format yuan linyu
2025-09-29 2:33 ` yuanlinyu
2025-10-03 6:29 ` David Gibson
2026-03-06 2:38 ` yuanlinyu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox