diff options
| author | Tom Rini <[email protected]> | 2023-08-25 17:52:59 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2023-08-25 17:52:59 -0400 |
| commit | 05763b71d2fcfe9729bf5ef0b14bd00c3af0c985 (patch) | |
| tree | 8a62bb1cda41f5fb2ff2cb0211e927e45645e18a /cmd | |
| parent | 7c6b18fb5494a1da2421b16c42d31fc466c38362 (diff) | |
| parent | 84b08afcbb8f8b4402b940d87bf5822984eedb3d (diff) | |
Merge branch '2023-08-25-add-persistent-config-editor-via-expo' into next
To quote the author:
So far cedit does not support reading and writing the configuration.
This series add several features related to this:
First, it adds support for using a file on a filesystem. This is in
FDT format and provides enough information to reset the cedit back to
the saved settings.
Second, it adds support for using the U-Boot environment. Since the
environment is generally saved across reboots, this feature provides an
easy way of storing the state on most boards. The variables all have a
'c.' prefix to avoid confusion with other variables.
Finally it adds support for using CMOS RAM. This is commonly used on x86
devices to store BIOS settings. The expo schema provides information on
the register layout.
Some other minor tweaks and improvements are included along the way.
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/cedit.c | 209 |
1 files changed, 205 insertions, 4 deletions
diff --git a/cmd/cedit.c b/cmd/cedit.c index 0cae304c4ad..2ff284f4cde 100644 --- a/cmd/cedit.c +++ b/cmd/cedit.c @@ -7,14 +7,29 @@ */ #include <common.h> +#include <abuf.h> +#include <cedit.h> #include <command.h> +#include <dm.h> #include <expo.h> #include <fs.h> +#include <malloc.h> +#include <mapmem.h> #include <dm/ofnode.h> #include <linux/sizes.h> struct expo *cur_exp; +static int check_cur_expo(void) +{ + if (!cur_exp) { + printf("No expo loaded\n"); + return -ENOENT; + } + + return 0; +} + static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -53,18 +68,192 @@ static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *fname; + struct abuf buf; + loff_t bytes; + int ret; + + if (argc < 4) + return CMD_RET_USAGE; + fname = argv[3]; + + if (check_cur_expo()) + return CMD_RET_FAILURE; + + ret = cedit_write_settings(cur_exp, &buf); + if (ret) { + printf("Failed to write settings: %dE\n", ret); + return CMD_RET_FAILURE; + } + + if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY)) + return CMD_RET_FAILURE; + + ret = fs_write(fname, map_to_sysmem(abuf_data(&buf)), 0, + abuf_size(&buf), &bytes); + if (ret) + return CMD_RET_FAILURE; + + 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_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_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_write_cmos(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + bool verbose = false; + int ret; + + if (check_cur_expo()) + return CMD_RET_FAILURE; + + if (argc > 1 && !strcmp(argv[1], "-v")) { + verbose = true; + argc--; + argv++; + } + + if (argc > 1) + ret = uclass_get_device_by_name(UCLASS_RTC, argv[1], &dev); + else + ret = uclass_first_device_err(UCLASS_RTC, &dev); + if (ret) { + printf("Failed to get RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + + if (cedit_write_settings_cmos(cur_exp, dev, verbose)) { + printf("Failed to write settings to CMOS\n"); + return CMD_RET_FAILURE; + } + + return 0; +} + +static int do_cedit_read_cmos(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + bool verbose = false; + int ret; + + if (check_cur_expo()) + return CMD_RET_FAILURE; + + if (argc > 1 && !strcmp(argv[1], "-v")) { + verbose = true; + argc--; + argv++; + } + + if (argc > 1) + ret = uclass_get_device_by_name(UCLASS_RTC, argv[1], &dev); + else + ret = uclass_first_device_err(UCLASS_RTC, &dev); + if (ret) { + printf("Failed to get RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + + ret = cedit_read_settings_cmos(cur_exp, dev, verbose); + if (ret) { + printf("Failed to read settings from CMOS: %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[]) { ofnode node; int ret; - if (!cur_exp) { - printf("No expo loaded\n"); + if (check_cur_expo()) return CMD_RET_FAILURE; - } - node = ofnode_path("/cedit-theme"); + node = ofnode_path("/bootstd/cedit-theme"); if (ofnode_valid(node)) { ret = expo_apply_theme(cur_exp, node); if (ret) @@ -84,10 +273,22 @@ static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_SYS_LONGHELP 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 read_env [-v] - read settings from env vars\n" + "cedit write_env [-v] - write settings to env vars\n" + "cedit read_cmos [-v] [dev] - read settings from CMOS RAM\n" + "cedit write_cmos [-v] [dev] - write settings to CMOS RAM\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(read_env, 2, 1, do_cedit_read_env), + U_BOOT_SUBCMD_MKENT(write_env, 2, 1, do_cedit_write_env), + U_BOOT_SUBCMD_MKENT(read_cmos, 2, 1, do_cedit_read_cmos), + U_BOOT_SUBCMD_MKENT(write_cmos, 2, 1, do_cedit_write_cmos), U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run), ); |
