From 472317cb12e534f56b631365987934960dfb0a3f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 14 Aug 2023 16:40:34 -0600 Subject: [PATCH] expo: cedit: Support reading settings from a file Add a command to read cedit settings from a devicetree file. Signed-off-by: Simon Glass --- boot/cedit.c | 52 +++++++++++++++++++++++++++++++++++++++++ cmd/cedit.c | 39 +++++++++++++++++++++++++++++++ doc/usage/cmd/cedit.rst | 8 +++++++ include/cedit.h | 13 +++++++++++ test/boot/cedit.c | 22 ++++++++++++++--- 5 files changed, 131 insertions(+), 3 deletions(-) diff --git a/boot/cedit.c b/boot/cedit.c index 4dd79a2263..6a74a38098 100644 --- a/boot/cedit.c +++ b/boot/cedit.c @@ -23,9 +23,11 @@ * struct cedit_iter_priv - private data for cedit operations * * @buf: Buffer to use when writing settings to the devicetree + * @node: Node to read from when reading settings from devicetree */ struct cedit_iter_priv { struct abuf *buf; + ofnode node; }; int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id) @@ -318,3 +320,53 @@ int cedit_write_settings(struct expo *exp, struct abuf *buf) return 0; } + +static int h_read_settings(struct scene_obj *obj, void *vpriv) +{ + struct cedit_iter_priv *priv = vpriv; + ofnode node = priv->node; + + switch (obj->type) { + case SCENEOBJT_NONE: + case SCENEOBJT_IMAGE: + case SCENEOBJT_TEXT: + break; + case SCENEOBJT_MENU: { + struct scene_obj_menu *menu; + uint val; + + if (ofnode_read_u32(node, obj->name, &val)) + return log_msg_ret("rd", -ENOENT); + menu = (struct scene_obj_menu *)obj; + menu->cur_item_id = val; + + break; + } + } + + return 0; +} + +int cedit_read_settings(struct expo *exp, oftree tree) +{ + struct cedit_iter_priv priv; + ofnode root, node; + int ret; + + root = oftree_root(tree); + if (!ofnode_valid(root)) + return log_msg_ret("roo", -ENOENT); + node = ofnode_find_subnode(root, CEDIT_NODE_NAME); + if (!ofnode_valid(node)) + return log_msg_ret("pat", -ENOENT); + + /* read in the items */ + priv.node = node; + ret = expo_iter_scene_objs(exp, h_read_settings, &priv); + if (ret) { + log_debug("Failed to read settings (err=%d)\n", ret); + return log_msg_ret("set", ret); + } + + return 0; +} diff --git a/cmd/cedit.c b/cmd/cedit.c index 18cc8ba191..a155e080b1 100644 --- a/cmd/cedit.c +++ b/cmd/cedit.c @@ -99,6 +99,43 @@ static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +static int do_cedit_read_fdt(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *fname; + void *buf; + oftree tree; + ulong size; + int ret; + + if (argc < 4) + return CMD_RET_USAGE; + fname = argv[3]; + + ret = fs_load_alloc(argv[1], argv[2], argv[3], SZ_1M, 0, &buf, &size); + if (ret) { + printf("File not found\n"); + return CMD_RET_FAILURE; + } + + tree = oftree_from_fdt(buf); + if (!oftree_valid(tree)) { + free(buf); + printf("Cannot create oftree\n"); + return CMD_RET_FAILURE; + } + + ret = cedit_read_settings(cur_exp, tree); + oftree_dispose(tree); + free(buf); + if (ret) { + printf("Failed to read settings: %dE\n", ret); + return CMD_RET_FAILURE; + } + + return 0; +} + static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -128,12 +165,14 @@ static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_SYS_LONGHELP static char cedit_help_text[] = "load - load config editor\n" + "cedit read_fdt - read settings\n" "cedit write_fdt - write settings\n" "cedit run - run config editor"; #endif /* CONFIG_SYS_LONGHELP */ U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text, U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load), + U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt), U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt), U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run), ); diff --git a/doc/usage/cmd/cedit.rst b/doc/usage/cmd/cedit.rst index 0581594831..0a9f620b59 100644 --- a/doc/usage/cmd/cedit.rst +++ b/doc/usage/cmd/cedit.rst @@ -11,6 +11,7 @@ Synopis cedit load cedit run cedit write_fdt + cedit read_fdt Description ----------- @@ -45,6 +46,11 @@ cedit write_fdt Writes the current user settings to a devicetree file. For each menu item the selected ID and its text string are written. +cedit read_fdt +~~~~~~~~~~~~~~ + +Reads the user settings from a devicetree file and updates the cedit with those +settings. Example ------- @@ -65,3 +71,5 @@ That results in:: power-loss-str = "Always Off"; }; } + + => cedit read_fdt hostfs - settings.dtb diff --git a/include/cedit.h b/include/cedit.h index 6086e30200..bb6e87d4af 100644 --- a/include/cedit.h +++ b/include/cedit.h @@ -7,6 +7,8 @@ #ifndef __CEDIT_H #define __CEDIT_H +#include + struct abuf; struct expo; struct scene; @@ -67,4 +69,15 @@ int cedit_prepare(struct expo *exp, struct video_priv **vid_privp, */ int cedit_write_settings(struct expo *exp, struct abuf *buf); +/** + * cedit_read_settings() - Read settings in FDT format + * + * Read an FDT with the settings + * + * @exp: Expo to read settings into + * @tree: Tree to read from + * Return: 0 if OK, -ve on error + */ +int cedit_read_settings(struct expo *exp, oftree tree); + #endif /* __CEDIT_H */ diff --git a/test/boot/cedit.c b/test/boot/cedit.c index 1dd78c6415..659c47ed35 100644 --- a/test/boot/cedit.c +++ b/test/boot/cedit.c @@ -54,11 +54,12 @@ static int cedit_base(struct unit_test_state *uts) } BOOTSTD_TEST(cedit_base, 0); -/* Check the cedit write_fdt commands */ +/* Check the cedit write_fdt and read_fdt commands */ static int cedit_fdt(struct unit_test_state *uts) { struct video_priv *vid_priv; extern struct expo *cur_exp; + struct scene_obj_menu *menu; ulong addr = 0x1000; struct ofprop prop; struct scene *scn; @@ -72,6 +73,11 @@ static int cedit_fdt(struct unit_test_state *uts) ut_asserteq(ID_SCENE1, cedit_prepare(cur_exp, &vid_priv, &scn)); + /* get a menu to fiddle with */ + menu = scene_obj_find(scn, ID_CPU_SPEED, SCENEOBJT_MENU); + ut_assertnonnull(menu); + menu->cur_item_id = ID_CPU_SPEED_2; + ut_assertok(run_command("cedit write_fdt hostfs - settings.dtb", 0)); ut_assertok(run_commandf("load hostfs - %lx settings.dtb", addr)); ut_assert_nextlinen("1024 bytes read"); @@ -80,9 +86,9 @@ static int cedit_fdt(struct unit_test_state *uts) tree = oftree_from_fdt(fdt); node = ofnode_find_subnode(oftree_root(tree), CEDIT_NODE_NAME); - ut_asserteq(ID_CPU_SPEED_1, + ut_asserteq(ID_CPU_SPEED_2, ofnode_read_u32_default(node, "cpu-speed", 0)); - ut_asserteq_str("2 GHz", ofnode_read_string(node, "cpu-speed-str")); + ut_asserteq_str("2.5 GHz", ofnode_read_string(node, "cpu-speed-str")); ut_assert(ofnode_valid(node)); /* There should only be 4 properties */ @@ -93,6 +99,16 @@ static int cedit_fdt(struct unit_test_state *uts) ut_assert_console_end(); + /* reset the expo */ + menu->cur_item_id = ID_CPU_SPEED_1; + + /* load in the settings and make sure they update */ + ut_assertok(run_command("cedit read_fdt hostfs - settings.dtb", 0)); + ut_asserteq(ID_CPU_SPEED_2, menu->cur_item_id); + + ut_assertnonnull(menu); + ut_assert_console_end(); + return 0; } BOOTSTD_TEST(cedit_fdt, 0); -- 2.39.5