From 2675c5896a612df474c69e15a5d1b1eb6831b24c Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 7 Oct 2024 16:05:16 +0200 Subject: [PATCH 1/2] allow paths in fdt_path_offset to begin with a &label reference When using the CLI tools fdtget and fdtput, or other tools built on top of libfdt (such as perhaps scripts written in Python), it can be convenient to refer to a node by a label rather than having to know the full path from the root. Signed-off-by: Rasmus Villemoes --- libfdt/fdt_ro.c | 8 ++++++-- libfdt/libfdt.h | 14 ++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index b78c4e4..3af4f4e 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -258,14 +258,18 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) if (!can_assume(VALID_INPUT) && namelen <= 0) return -FDT_ERR_BADPATH; - /* see if we have an alias */ + /* see if we have an alias or symbol */ if (*path != '/') { const char *q = memchr(path, '/', end - p); if (!q) q = end; - p = fdt_get_alias_namelen(fdt, p, q - p); + if (*p == '&') + p = fdt_get_symbol_namelen(fdt, p + 1, q - p - 1); + else + p = fdt_get_alias_namelen(fdt, p, q - p); + if (!p) return -FDT_ERR_BADPATH; offset = fdt_path_offset(fdt, p); diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index 7a10f66..629c3b0 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -570,9 +570,10 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * address). * * If the path is not absolute (i.e. does not begin with '/'), the - * first component is treated as an alias. That is, the property by - * that name is looked up in the /aliases node, and the value of that - * property used in place of that first component. + * first component is treated as an alias (or, if it begins with '&', + * the rest is treated as a symbol). That is, the property by that + * name is looked up in the /aliases (or /__symbols__) node, and the + * value of that property used in place of that first component. * * For example, for this small fragment * @@ -592,12 +593,17 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * * /soc@0/i2c@30a40000/eeprom@52 * i2c2/eeprom@52 + * &foo/eeprom@52 + * &bar + * + * The latter two only work if the device tree blob has been compiled + * with the -@ dtc option. * * returns: * structure block offset of the node with the requested path (>=0), on * success * -FDT_ERR_BADPATH, given path does not begin with '/' and the first - * component is not a valid alias + * component is not a valid alias or symbol * -FDT_ERR_NOTFOUND, if the requested node does not exist * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, From eb2fc27703eca50d42695793528809e27472bddc Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 7 Oct 2024 16:05:27 +0200 Subject: [PATCH 2/2] tests: add basic tests of fdtget/fdtput with &label syntax We obviously need to build some dtbs with -@ to do these tests. In order to still test all the old functionality on blobs built without -@, simply run all fdtget/fdtput tests twice, with/without -@, and for the few new test cases that rely on -@, check that they fail when the blob is not built with -@. Signed-off-by: Rasmus Villemoes --- tests/run_tests.sh | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 2e172d7..996cad6 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -886,9 +886,10 @@ dtbs_equal_tests () { } fdtget_tests () { + at="$1" dts=label01.dts dtb=$dts.fdtget.test.dtb - run_dtc_test -O dtb -o $dtb "$SRCDIR/$dts" + run_dtc_test $at -O dtb -o $dtb "$SRCDIR/$dts" # run_fdtget_test [] run_fdtget_test "MyBoardName" $dtb / model @@ -907,6 +908,11 @@ fdtget_tests () { # Here the property size is not a multiple of 4 bytes, so it should fail run_wrap_error_test $DTGET -tlx $dtb /randomnode mixed run_fdtget_test "6162 6300 1234 0 a 0 b 0 c" -thx $dtb /randomnode mixed + if [ -n "$at" ]; then + run_fdtget_test "6162 6300 1234 0 a 0 b 0 c" -thx $dtb "&node" mixed + else + run_wrap_error_test $DTGET -thx $dtb "&node" mixed + fi run_fdtget_test "61 62 63 0 12 34 0 0 0 a 0 0 0 b 0 0 0 c" \ -thhx $dtb /randomnode mixed run_wrap_error_test $DTGET -ts $dtb /randomnode doctor-who @@ -922,12 +928,13 @@ fdtget_tests () { } fdtput_tests () { + at="$1" dts=label01.dts dtb=$dts.fdtput.test.dtb text="$SRCDIR/lorem.txt" # Allow just enough space for $text - run_dtc_test -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" + run_dtc_test $at -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" # run_fdtput_test run_fdtput_test "a_model" $dtb / model -ts "a_model" @@ -941,12 +948,19 @@ fdtput_tests () { run_fdtput_test "a0b0c0d deeaae ef000000" $dtb /randomnode blob \ -tx "a0b0c0d deeaae ef000000" run_fdtput_test "$(cat $text)" $dtb /randomnode blob -ts "$(cat $text)" + if [ -n "$at" ]; then + run_fdtput_test "y" $dtb '&node' x -ts "y" + run_fdtput_test "z" $dtb '&node/child' x -ts "z" + else + run_wrap_error_test $DTPUT $dtb '&node' x -ts "y" + run_wrap_error_test $DTPUT $dtb '&node/child' x -ts "z" + fi # Test expansion of the blob when insufficient room for property run_fdtput_test "$(cat $text $text)" $dtb /randomnode blob -ts "$(cat $text $text)" # Start again with a fresh dtb - run_dtc_test -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" + run_dtc_test $at -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" # Node creation run_wrap_error_test $DTPUT $dtb -c /baldrick sod @@ -974,7 +988,7 @@ fdtput_tests () { run_wrap_test $DTPUT $dtb -cp /chosen/son # Start again with a fresh dtb - run_dtc_test -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" + run_dtc_test $at -O dtb -p $($STATSZ $text) -o $dtb "$SRCDIR/$dts" # Node delete run_wrap_test $DTPUT $dtb -c /chosen/node1 /chosen/node2 /chosen/node3 @@ -1152,10 +1166,12 @@ for set in $TESTSETS; do dtbs_equal_tests ;; "fdtget") - fdtget_tests + fdtget_tests "" + fdtget_tests "-@" ;; "fdtput") - fdtput_tests + fdtput_tests "" + fdtput_tests "-@" ;; "fdtdump") fdtdump_tests