mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +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 <cli.h> | ||||
| #include <dm.h> | ||||
| #include <env.h> | ||||
| #include <expo.h> | ||||
| #include <menu.h> | ||||
| #include <video.h> | ||||
| @@ -24,10 +25,12 @@ | ||||
|  * | ||||
|  * @buf: Buffer to use when writing settings to the devicetree | ||||
|  * @node: Node to read from when reading settings from devicetree | ||||
|  * @verbose: true to show writing to environment variables | ||||
|  */ | ||||
| struct cedit_iter_priv { | ||||
| 	struct abuf *buf; | ||||
| 	ofnode node; | ||||
| 	bool verbose; | ||||
| }; | ||||
|  | ||||
| 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; | ||||
| } | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	struct cedit_iter_priv *priv = vpriv; | ||||
| @@ -221,9 +248,6 @@ static int h_write_settings(struct scene_obj *obj, void *vpriv) | ||||
| 		break; | ||||
| 	case SCENEOBJT_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; | ||||
| 		char name[80]; | ||||
| 		int ret, i; | ||||
| @@ -243,17 +267,9 @@ static int h_write_settings(struct scene_obj *obj, void *vpriv) | ||||
| 		if (ret) | ||||
| 			return log_msg_ret("wrt", -EFAULT); | ||||
|  | ||||
| 		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); | ||||
| 		ret = get_cur_menuitem_text(menu, &str); | ||||
| 		if (ret) | ||||
| 			return log_msg_ret("mis", ret); | ||||
|  | ||||
| 		snprintf(name, sizeof(name), "%s-str", obj->name); | ||||
| 		ret = -EAGAIN; | ||||
| @@ -370,3 +386,56 @@ int cedit_read_settings(struct expo *exp, oftree tree) | ||||
|  | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| 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, | ||||
| 			char *const argv[]) | ||||
| { | ||||
| @@ -167,6 +187,7 @@ static char cedit_help_text[] = | ||||
| 	"load <interface> <dev[:part]> <filename>   - load config editor\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_env [-v]                             - write settings to env vars\n" | ||||
| 	"cedit run                                        - run config editor"; | ||||
| #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(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_env, 2, 1, do_cedit_write_env), | ||||
| 	U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run), | ||||
| ); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ Synopis | ||||
|     cedit run | ||||
|     cedit write_fdt <dev[:part]> <filename> | ||||
|     cedit read_fdt <dev[:part]> <filename> | ||||
|     cedit write_env [-v] | ||||
|  | ||||
| Description | ||||
| ----------- | ||||
| @@ -52,6 +53,19 @@ cedit read_fdt | ||||
| Reads the user settings from a devicetree file and updates the cedit with those | ||||
| 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 | ||||
| ------- | ||||
|  | ||||
| @@ -73,3 +87,14 @@ That results in:: | ||||
|     } | ||||
|  | ||||
|     => 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); | ||||
|  | ||||
| /** | ||||
|  * 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 */ | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <common.h> | ||||
| #include <cedit.h> | ||||
| #include <env.h> | ||||
| #include <expo.h> | ||||
| #include <mapmem.h> | ||||
| #include <dm/ofnode.h> | ||||
| @@ -112,3 +113,35 @@ static int cedit_fdt(struct unit_test_state *uts) | ||||
| 	return 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