From bcf2b7202e960e7fb3df8d5e8ed0d6fa00a5a9fa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 14 Aug 2023 16:40:36 -0600 Subject: [PATCH] expo: cedit: Support reading settings from environment vars Add a command to read cedit settings from environment variables so that they can be restored as part of the environment. Signed-off-by: Simon Glass --- boot/cedit.c | 45 +++++++++++++++++++++++++++++++++++++++++ cmd/cedit.c | 22 ++++++++++++++++++++ doc/usage/cmd/cedit.rst | 19 +++++++++++++++++ include/cedit.h | 8 ++++++++ test/boot/cedit.c | 12 ++++++++++- 5 files changed, 105 insertions(+), 1 deletion(-) diff --git a/boot/cedit.c b/boot/cedit.c index 9399c01cda..e3f6dc0039 100644 --- a/boot/cedit.c +++ b/boot/cedit.c @@ -439,3 +439,48 @@ int cedit_write_settings_env(struct expo *exp, bool verbose) return 0; } + +static int h_read_settings_env(struct scene_obj *obj, void *vpriv) +{ + struct cedit_iter_priv *priv = vpriv; + struct scene_obj_menu *menu; + char var[60]; + int val, ret; + + if (obj->type != SCENEOBJT_MENU) + return 0; + + menu = (struct scene_obj_menu *)obj; + val = menu->cur_item_id; + snprintf(var, sizeof(var), "c.%s", obj->name); + + val = env_get_ulong(var, 10, 0); + if (priv->verbose) + printf("%s=%d\n", var, val); + if (!val) + return log_msg_ret("get", -ENOENT); + + /* + * note that no validation is done here, to make sure the ID is valid + * and actually points to a menu item + */ + menu->cur_item_id = val; + + return 0; +} + +int cedit_read_settings_env(struct expo *exp, bool verbose) +{ + struct cedit_iter_priv priv; + int ret; + + /* write out the items */ + priv.verbose = verbose; + ret = expo_iter_scene_objs(exp, h_read_settings_env, &priv); + if (ret) { + log_debug("Failed to read settings from env (err=%d)\n", ret); + return log_msg_ret("set", ret); + } + + return 0; +} diff --git a/cmd/cedit.c b/cmd/cedit.c index 85629f7b83..b2548f44b5 100644 --- a/cmd/cedit.c +++ b/cmd/cedit.c @@ -156,6 +156,26 @@ static int do_cedit_write_env(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +static int do_cedit_read_env(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + bool verbose; + int ret; + + if (check_cur_expo()) + return CMD_RET_FAILURE; + + verbose = argc > 1 && !strcmp(argv[1], "-v"); + + ret = cedit_read_settings_env(cur_exp, verbose); + if (ret) { + printf("Failed to read settings from environment: %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[]) { @@ -187,6 +207,7 @@ static char cedit_help_text[] = "load - load config editor\n" "cedit read_fdt - read settings\n" "cedit write_fdt - write settings\n" + "cedit read_env [-v] - read settings from env vars\n" "cedit write_env [-v] - write settings to env vars\n" "cedit run - run config editor"; #endif /* CONFIG_SYS_LONGHELP */ @@ -195,6 +216,7 @@ 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(read_env, 2, 1, do_cedit_read_env), U_BOOT_SUBCMD_MKENT(write_env, 2, 1, do_cedit_write_env), 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 426470a82a..1f92b7306a 100644 --- a/doc/usage/cmd/cedit.rst +++ b/doc/usage/cmd/cedit.rst @@ -13,6 +13,7 @@ Synopis cedit write_fdt cedit read_fdt cedit write_env [-v] + cedit read_env [-v] Description ----------- @@ -53,6 +54,16 @@ cedit read_fdt Reads the user settings from a devicetree file and updates the cedit with those settings. +cedit read_env +~~~~~~~~~~~~~~ + +Reads the settings from the environment variables. For each menu item ``, +cedit looks for a variable called `c.` with the ID of the selected menu +item. + +The `-v` flag enables verbose mode, where each variable is printed after it is +read. + cedit write_env ~~~~~~~~~~~~~~~ @@ -91,6 +102,10 @@ That results in:: This shows settings being stored in the environment:: => cedit write_env -v + c.cpu-speed=7 + c.cpu-speed-str=2.5 GHz + c.power-loss=12 + c.power-loss-str=Memory => print ... c.cpu-speed=6 @@ -98,3 +113,7 @@ This shows settings being stored in the environment:: c.power-loss=10 c.power-loss-str=Always Off ... + + => cedit read_env -v + c.cpu-speed=7 + c.power-loss=12 diff --git a/include/cedit.h b/include/cedit.h index f261207e20..fe10e6c829 100644 --- a/include/cedit.h +++ b/include/cedit.h @@ -89,4 +89,12 @@ int cedit_read_settings(struct expo *exp, oftree tree); */ int cedit_write_settings_env(struct expo *exp, bool verbose); +/* + * cedit_read_settings_env() - Read settings from the environment + * + * @exp: Expo to read settings into + * @verbose: true to print each var before it is read + */ +int cedit_read_settings_env(struct expo *exp, bool verbose); + #endif /* __CEDIT_H */ diff --git a/test/boot/cedit.c b/test/boot/cedit.c index 26a69f0323..7cf0c3e4e9 100644 --- a/test/boot/cedit.c +++ b/test/boot/cedit.c @@ -114,7 +114,7 @@ static int cedit_fdt(struct unit_test_state *uts) } BOOTSTD_TEST(cedit_fdt, 0); -/* Check the cedit write_env command */ +/* Check the cedit write_env and read_env commands */ static int cedit_env(struct unit_test_state *uts) { struct video_priv *vid_priv; @@ -142,6 +142,16 @@ static int cedit_env(struct unit_test_state *uts) ut_asserteq(7, env_get_ulong("c.cpu-speed", 10, 0)); ut_asserteq_str("2.5 GHz", env_get("c.cpu-speed-str")); + /* reset the expo */ + menu->cur_item_id = ID_CPU_SPEED_1; + + ut_assertok(run_command("cedit read_env -v", 0)); + ut_assert_nextlinen("c.cpu-speed=7"); + ut_assert_nextlinen("c.power-loss=10"); + ut_assert_console_end(); + + ut_asserteq(ID_CPU_SPEED_2, menu->cur_item_id); + return 0; } BOOTSTD_TEST(cedit_env, 0); -- 2.39.5