mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-30 18:05:48 +01:00 
			
		
		
		
	expo: cedit: Support writing settings to environment vars
Add a command to write cedit settings to environment variables so that they can be stored with 'saveenv'. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							
								
								
									
										97
									
								
								boot/cedit.c
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								boot/cedit.c
									
									
									
									
									
								
							| @@ -13,6 +13,7 @@ | |||||||
| #include <cedit.h> | #include <cedit.h> | ||||||
| #include <cli.h> | #include <cli.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
|  | #include <env.h> | ||||||
| #include <expo.h> | #include <expo.h> | ||||||
| #include <menu.h> | #include <menu.h> | ||||||
| #include <video.h> | #include <video.h> | ||||||
| @@ -24,10 +25,12 @@ | |||||||
|  * |  * | ||||||
|  * @buf: Buffer to use when writing settings to the devicetree |  * @buf: Buffer to use when writing settings to the devicetree | ||||||
|  * @node: Node to read from when reading settings from devicetree |  * @node: Node to read from when reading settings from devicetree | ||||||
|  |  * @verbose: true to show writing to environment variables | ||||||
|  */ |  */ | ||||||
| struct cedit_iter_priv { | struct cedit_iter_priv { | ||||||
| 	struct abuf *buf; | 	struct abuf *buf; | ||||||
| 	ofnode node; | 	ofnode node; | ||||||
|  | 	bool verbose; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id) | int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id) | ||||||
| @@ -209,6 +212,30 @@ static int check_space(int ret, struct abuf *buf) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int get_cur_menuitem_text(const struct scene_obj_menu *menu, | ||||||
|  | 				 const char **strp) | ||||||
|  | { | ||||||
|  | 	struct scene *scn = menu->obj.scene; | ||||||
|  | 	const struct scene_menitem *mi; | ||||||
|  | 	const struct scene_obj_txt *txt; | ||||||
|  | 	const char *str; | ||||||
|  |  | ||||||
|  | 	mi = scene_menuitem_find(menu, menu->cur_item_id); | ||||||
|  | 	if (!mi) | ||||||
|  | 		return log_msg_ret("mi", -ENOENT); | ||||||
|  |  | ||||||
|  | 	txt = scene_obj_find(scn, mi->label_id, SCENEOBJT_TEXT); | ||||||
|  | 	if (!txt) | ||||||
|  | 		return log_msg_ret("txt", -ENOENT); | ||||||
|  |  | ||||||
|  | 	str = expo_get_str(scn->expo, txt->str_id); | ||||||
|  | 	if (!str) | ||||||
|  | 		return log_msg_ret("str", -ENOENT); | ||||||
|  | 	*strp = str; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int h_write_settings(struct scene_obj *obj, void *vpriv) | static int h_write_settings(struct scene_obj *obj, void *vpriv) | ||||||
| { | { | ||||||
| 	struct cedit_iter_priv *priv = vpriv; | 	struct cedit_iter_priv *priv = vpriv; | ||||||
| @@ -221,9 +248,6 @@ static int h_write_settings(struct scene_obj *obj, void *vpriv) | |||||||
| 		break; | 		break; | ||||||
| 	case SCENEOBJT_MENU: { | 	case SCENEOBJT_MENU: { | ||||||
| 		const struct scene_obj_menu *menu; | 		const struct scene_obj_menu *menu; | ||||||
| 		const struct scene_obj_txt *txt; |  | ||||||
| 		struct scene *scn = obj->scene; |  | ||||||
| 		const struct scene_menitem *mi; |  | ||||||
| 		const char *str; | 		const char *str; | ||||||
| 		char name[80]; | 		char name[80]; | ||||||
| 		int ret, i; | 		int ret, i; | ||||||
| @@ -243,17 +267,9 @@ static int h_write_settings(struct scene_obj *obj, void *vpriv) | |||||||
| 		if (ret) | 		if (ret) | ||||||
| 			return log_msg_ret("wrt", -EFAULT); | 			return log_msg_ret("wrt", -EFAULT); | ||||||
|  |  | ||||||
| 		mi = scene_menuitem_find(menu, menu->cur_item_id); | 		ret = get_cur_menuitem_text(menu, &str); | ||||||
| 		if (!mi) | 		if (ret) | ||||||
| 			return log_msg_ret("mi", -ENOENT); | 			return log_msg_ret("mis", ret); | ||||||
|  |  | ||||||
| 		txt = scene_obj_find(scn, mi->label_id, SCENEOBJT_TEXT); |  | ||||||
| 		if (!txt) |  | ||||||
| 			return log_msg_ret("txt", -ENOENT); |  | ||||||
|  |  | ||||||
| 		str = expo_get_str(scn->expo, txt->str_id); |  | ||||||
| 		if (!str) |  | ||||||
| 			return log_msg_ret("str", -ENOENT); |  | ||||||
|  |  | ||||||
| 		snprintf(name, sizeof(name), "%s-str", obj->name); | 		snprintf(name, sizeof(name), "%s-str", obj->name); | ||||||
| 		ret = -EAGAIN; | 		ret = -EAGAIN; | ||||||
| @@ -370,3 +386,56 @@ int cedit_read_settings(struct expo *exp, oftree tree) | |||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int h_write_settings_env(struct scene_obj *obj, void *vpriv) | ||||||
|  | { | ||||||
|  | 	const struct scene_obj_menu *menu; | ||||||
|  | 	struct cedit_iter_priv *priv = vpriv; | ||||||
|  | 	char name[80], var[60]; | ||||||
|  | 	const char *str; | ||||||
|  | 	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); | ||||||
|  |  | ||||||
|  | 	if (priv->verbose) | ||||||
|  | 		printf("%s=%d\n", var, val); | ||||||
|  |  | ||||||
|  | 	ret = env_set_ulong(var, val); | ||||||
|  | 	if (ret) | ||||||
|  | 		return log_msg_ret("set", ret); | ||||||
|  |  | ||||||
|  | 	ret = get_cur_menuitem_text(menu, &str); | ||||||
|  | 	if (ret) | ||||||
|  | 		return log_msg_ret("mis", ret); | ||||||
|  |  | ||||||
|  | 	snprintf(name, sizeof(name), "c.%s-str", obj->name); | ||||||
|  | 	if (priv->verbose) | ||||||
|  | 		printf("%s=%s\n", name, str); | ||||||
|  |  | ||||||
|  | 	ret = env_set(name, str); | ||||||
|  | 	if (ret) | ||||||
|  | 		return log_msg_ret("st2", ret); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cedit_write_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_write_settings_env, &priv); | ||||||
|  | 	if (ret) { | ||||||
|  | 		log_debug("Failed to write settings to env (err=%d)\n", ret); | ||||||
|  | 		return log_msg_ret("set", ret); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								cmd/cedit.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								cmd/cedit.c
									
									
									
									
									
								
							| @@ -136,6 +136,26 @@ static int do_cedit_read_fdt(struct cmd_tbl *cmdtp, int flag, int argc, | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int do_cedit_write_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_write_settings_env(cur_exp, verbose); | ||||||
|  | 	if (ret) { | ||||||
|  | 		printf("Failed to write settings to environment: %dE\n", ret); | ||||||
|  | 		return CMD_RET_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, | static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, | ||||||
| 			char *const argv[]) | 			char *const argv[]) | ||||||
| { | { | ||||||
| @@ -167,6 +187,7 @@ static char cedit_help_text[] = | |||||||
| 	"load <interface> <dev[:part]> <filename>   - load config editor\n" | 	"load <interface> <dev[:part]> <filename>   - load config editor\n" | ||||||
| 	"cedit read_fdt <i/f> <dev[:part]> <filename>     - read settings\n" | 	"cedit read_fdt <i/f> <dev[:part]> <filename>     - read settings\n" | ||||||
| 	"cedit write_fdt <i/f> <dev[:part]> <filename>    - write settings\n" | 	"cedit write_fdt <i/f> <dev[:part]> <filename>    - write settings\n" | ||||||
|  | 	"cedit write_env [-v]                             - write settings to env vars\n" | ||||||
| 	"cedit run                                        - run config editor"; | 	"cedit run                                        - run config editor"; | ||||||
| #endif /* CONFIG_SYS_LONGHELP */ | #endif /* CONFIG_SYS_LONGHELP */ | ||||||
|  |  | ||||||
| @@ -174,5 +195,6 @@ 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(load, 5, 1, do_cedit_load), | ||||||
| 	U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt), | 	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(write_fdt, 5, 1, do_cedit_write_fdt), | ||||||
|  | 	U_BOOT_SUBCMD_MKENT(write_env, 2, 1, do_cedit_write_env), | ||||||
| 	U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run), | 	U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run), | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ Synopis | |||||||
|     cedit run |     cedit run | ||||||
|     cedit write_fdt <dev[:part]> <filename> |     cedit write_fdt <dev[:part]> <filename> | ||||||
|     cedit read_fdt <dev[:part]> <filename> |     cedit read_fdt <dev[:part]> <filename> | ||||||
|  |     cedit write_env [-v] | ||||||
|  |  | ||||||
| Description | Description | ||||||
| ----------- | ----------- | ||||||
| @@ -52,6 +53,19 @@ cedit read_fdt | |||||||
| Reads the user settings from a devicetree file and updates the cedit with those | Reads the user settings from a devicetree file and updates the cedit with those | ||||||
| settings. | settings. | ||||||
|  |  | ||||||
|  | cedit write_env | ||||||
|  | ~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | Writes the settings to environment variables. For each menu item the selected | ||||||
|  | ID and its text string are written, similar to: | ||||||
|  |  | ||||||
|  |    setenv c.<name> <selected_id> | ||||||
|  |    setenv c.<name>-str <selected_id's text string> | ||||||
|  |  | ||||||
|  | The `-v` flag enables verbose mode, where each variable is printed before it is | ||||||
|  | set. | ||||||
|  |  | ||||||
|  |  | ||||||
| Example | Example | ||||||
| ------- | ------- | ||||||
|  |  | ||||||
| @@ -73,3 +87,14 @@ That results in:: | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     => cedit read_fdt hostfs - settings.dtb |     => cedit read_fdt hostfs - settings.dtb | ||||||
|  |  | ||||||
|  | This shows settings being stored in the environment:: | ||||||
|  |  | ||||||
|  |     => cedit write_env -v | ||||||
|  |     => print | ||||||
|  |     ... | ||||||
|  |     c.cpu-speed=6 | ||||||
|  |     c.cpu-speed-str=2 GHz | ||||||
|  |     c.power-loss=10 | ||||||
|  |     c.power-loss-str=Always Off | ||||||
|  |     ... | ||||||
|   | |||||||
| @@ -80,4 +80,13 @@ int cedit_write_settings(struct expo *exp, struct abuf *buf); | |||||||
|  */ |  */ | ||||||
| int cedit_read_settings(struct expo *exp, oftree tree); | int cedit_read_settings(struct expo *exp, oftree tree); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * cedit_write_settings_env() - Write settings to envrionment variables | ||||||
|  |  * | ||||||
|  |  * @exp: Expo to write settings from | ||||||
|  |  * @verbose: true to print each var as it is set | ||||||
|  |  * Return: 0 if OK, -ve on error | ||||||
|  |  */ | ||||||
|  | int cedit_write_settings_env(struct expo *exp, bool verbose); | ||||||
|  |  | ||||||
| #endif /* __CEDIT_H */ | #endif /* __CEDIT_H */ | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <cedit.h> | #include <cedit.h> | ||||||
|  | #include <env.h> | ||||||
| #include <expo.h> | #include <expo.h> | ||||||
| #include <mapmem.h> | #include <mapmem.h> | ||||||
| #include <dm/ofnode.h> | #include <dm/ofnode.h> | ||||||
| @@ -112,3 +113,35 @@ static int cedit_fdt(struct unit_test_state *uts) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| BOOTSTD_TEST(cedit_fdt, 0); | BOOTSTD_TEST(cedit_fdt, 0); | ||||||
|  |  | ||||||
|  | /* Check the cedit write_env command */ | ||||||
|  | static int cedit_env(struct unit_test_state *uts) | ||||||
|  | { | ||||||
|  | 	struct video_priv *vid_priv; | ||||||
|  | 	extern struct expo *cur_exp; | ||||||
|  | 	struct scene_obj_menu *menu; | ||||||
|  | 	struct scene *scn; | ||||||
|  |  | ||||||
|  | 	console_record_reset_enable(); | ||||||
|  | 	ut_assertok(run_command("cedit load hostfs - cedit.dtb", 0)); | ||||||
|  |  | ||||||
|  | 	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_env -v", 0)); | ||||||
|  | 	ut_assert_nextlinen("c.cpu-speed=7"); | ||||||
|  | 	ut_assert_nextlinen("c.cpu-speed-str=2.5 GHz"); | ||||||
|  | 	ut_assert_nextlinen("c.power-loss=10"); | ||||||
|  | 	ut_assert_nextlinen("c.power-loss-str=Always Off"); | ||||||
|  | 	ut_assert_console_end(); | ||||||
|  |  | ||||||
|  | 	ut_asserteq(7, env_get_ulong("c.cpu-speed", 10, 0)); | ||||||
|  | 	ut_asserteq_str("2.5 GHz", env_get("c.cpu-speed-str")); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | BOOTSTD_TEST(cedit_env, 0); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user