These tests exercise the merging of the __symbols__ table from a overlay into the target device tree.
Signed-off-by: Stefan Kerkmann <[email protected]> --- test/self/Makefile | 3 ++ test/self/of_overlay.c | 90 ++++++++++++++++++++++++++++++++++ test/self/of_overlay_with_symbols.dts | 14 ++++++ test/self/of_overlay_with_symbols.dtso | 43 ++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/test/self/Makefile b/test/self/Makefile index f912afe5a6..f6cec81011 100644 --- a/test/self/Makefile +++ b/test/self/Makefile @@ -11,6 +11,9 @@ CFLAGS_printf.o += -Wno-format-security -Wno-format obj-$(CONFIG_SELFTEST_PROGRESS_NOTIFIER) += progress-notifier.o obj-$(CONFIG_SELFTEST_OF_MANIPULATION) += of_manipulation.o of_manipulation.dtb.o obj-$(CONFIG_SELFTEST_OF_OVERLAY) += of_overlay.o +# Enforce generation of __symbols__ table for overlay tests +DTC_FLAGS_of_overlay_with_symbols := -@ +obj-$(CONFIG_SELFTEST_OF_OVERLAY) += of_overlay_with_symbols.dtb.o of_overlay_with_symbols.dtbo.o obj-$(CONFIG_SELFTEST_ENVIRONMENT_VARIABLES) += envvar.o obj-$(CONFIG_SELFTEST_FS_RAMFS) += ramfs.o obj-$(CONFIG_SELFTEST_DIRFD) += dirfd.o diff --git a/test/self/of_overlay.c b/test/self/of_overlay.c index d60898358f..2804c936c0 100644 --- a/test/self/of_overlay.c +++ b/test/self/of_overlay.c @@ -10,7 +10,97 @@ BSELFTEST_GLOBALS(); +extern char __dtb_of_overlay_with_symbols_start[], + __dtb_of_overlay_with_symbols_end[]; +extern char __dtbo_of_overlay_with_symbols_start[], + __dtbo_of_overlay_with_symbols_end[]; + +static struct device_node *unflatten(char *start, char *end) +{ + struct device_node *root; + + root = of_unflatten_dtb(start, end - start); + if (IS_ERR(root)) { + pr_err("failed to unflatten dtb"); + return NULL; + } + + return root; +} + +static bool test_setup(struct device_node **root, struct device_node **overlay, + char *dtb_start, char *dtb_end, char *dtbo_start, + char *dtbo_end) +{ + *root = unflatten(dtb_start, dtb_end); + if (!assert_cond(*root != NULL)) + return false; + + *overlay = unflatten(dtbo_start, dtbo_end); + if (!assert_cond(*overlay != NULL)) { + of_delete_node(*root); + return false; + } + + return true; +} + +static void test_of_overlay_symbol_without_overlay(void) +{ + struct device_node *root, *overlay, *symbols; + const char *path; + int ret; + + if (!test_setup(&root, &overlay, __dtb_of_overlay_with_symbols_start, + __dtb_of_overlay_with_symbols_end, + __dtbo_of_overlay_with_symbols_start, + __dtbo_of_overlay_with_symbols_end)) + return; + + ret = of_overlay_apply_tree(root, overlay); + assert_inteq(ret, 0); + + symbols = of_get_child_by_name(root, "__symbols__"); + assert_cond(symbols != NULL); + + assert_inteq(of_property_read_string(symbols, "added", &path), 0); + assert_inteq(of_property_read_string(symbols, "toplevel", &path), + -EINVAL); + assert_inteq(of_property_read_string(symbols, "target", &path), 0); + + of_delete_node(overlay); + of_delete_node(root); +} + +static void test_of_overlay_symbol_outside_overlay(void) +{ + struct device_node *root, *overlay, *symbols; + const char *path; + int ret; + + if (!test_setup(&root, &overlay, __dtb_of_overlay_with_symbols_start, + __dtb_of_overlay_with_symbols_end, + __dtbo_of_overlay_with_symbols_start, + __dtbo_of_overlay_with_symbols_end)) + return; + + ret = of_overlay_apply_tree(root, overlay); + assert_inteq(ret, 0); + + symbols = of_get_child_by_name(root, "__symbols__"); + assert_cond(symbols != NULL); + + assert_inteq(of_property_read_string(symbols, "added", &path), 0); + assert_inteq(of_property_read_string(symbols, "local", &path), -EINVAL); + assert_inteq(of_property_read_string(symbols, "outside", &path), -EINVAL); + + of_delete_node(overlay); + of_delete_node(root); +} + static void test_of_overlay(void) { + test_of_overlay_symbol_without_overlay(); + test_of_overlay_symbol_outside_overlay(); } bselftest(core, test_of_overlay); diff --git a/test/self/of_overlay_with_symbols.dts b/test/self/of_overlay_with_symbols.dts new file mode 100644 index 0000000000..ac568025ed --- /dev/null +++ b/test/self/of_overlay_with_symbols.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; + +/ { + target: target-node { + existing-child { + old-prop = "old"; + }; + }; + + phandle_target: phandle-target-node { + }; +}; diff --git a/test/self/of_overlay_with_symbols.dtso b/test/self/of_overlay_with_symbols.dtso new file mode 100644 index 0000000000..9f26e31aee --- /dev/null +++ b/test/self/of_overlay_with_symbols.dtso @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; +/plugin/; + +/ { + /* label that ends up in no fragment at all */ + toplevel: toplevel-node {}; + + fragment@0 { + target-path = "/target-node"; + + __overlay__ { + /* label that resolves into an __overlay__ */ + added: added-by-fragment0 {}; + }; + }; + + fragment@1 { + target-path = "/target-node"; + + localinfo { + /* label below a fragment but outside its __overlay__ */ + local: subnode {}; + }; + + __overlay__ { + added-by-fragment1 {}; + }; + }; + + fragment@2 { + target-path = "/target-node"; + + __overlay__ { + added-by-fragment2 {}; + }; + + __overlay__extra { + outside: subnode {}; + }; + }; +}; -- 2.47.3
