diff options
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/Kconfig | 14 | ||||
| -rw-r--r-- | boot/Makefile | 1 | ||||
| -rw-r--r-- | boot/cedit.c | 163 | ||||
| -rw-r--r-- | boot/expo_build.c | 3 | ||||
| -rw-r--r-- | boot/scene.c | 12 | ||||
| -rw-r--r-- | boot/scene_internal.h | 8 |
6 files changed, 200 insertions, 1 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index a643a3d1286..c8b8f36d835 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1630,4 +1630,18 @@ config SAVE_PREV_BL_INITRAMFS_START_ADDR If no initramfs was provided by previous bootloader, no env variables will be created. +menu "Configuration editor" + +config CEDIT + bool "Configuration editor" + depends on BOOTSTD + help + Provides a way to deal with board configuration and present it to + the user for adjustment. + + This is intended to provide both graphical and text-based user + interfaces, but only graphical is support at present. + +endmenu # Configuration editor + endmenu # Booting diff --git a/boot/Makefile b/boot/Makefile index 28c4e55ca65..f828f870a37 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -33,6 +33,7 @@ ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o +obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o endif obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o diff --git a/boot/cedit.c b/boot/cedit.c new file mode 100644 index 00000000000..ee24658917b --- /dev/null +++ b/boot/cedit.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Implementation of configuration editor + * + * Copyright 2023 Google LLC + * Written by Simon Glass <[email protected]> + */ + +#include <common.h> +#include <cli.h> +#include <dm.h> +#include <expo.h> +#include <menu.h> +#include <video.h> +#include <linux/delay.h> +#include "scene_internal.h" + +int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id) +{ + struct scene_obj_txt *txt; + struct scene_obj *obj; + struct scene *scn; + int y; + + scn = expo_lookup_scene_id(exp, scene_id); + if (!scn) + return log_msg_ret("scn", -ENOENT); + + txt = scene_obj_find_by_name(scn, "prompt"); + if (txt) + scene_obj_set_pos(scn, txt->obj.id, 0, vpriv->ysize - 50); + + txt = scene_obj_find_by_name(scn, "title"); + if (txt) + scene_obj_set_pos(scn, txt->obj.id, 200, 10); + + y = 100; + list_for_each_entry(obj, &scn->obj_head, sibling) { + if (obj->type == SCENEOBJT_MENU) { + scene_obj_set_pos(scn, obj->id, 50, y); + scene_menu_arrange(scn, (struct scene_obj_menu *)obj); + y += 50; + } + } + + return 0; +} + +int cedit_run(struct expo *exp) +{ + struct cli_ch_state s_cch, *cch = &s_cch; + struct video_priv *vid_priv; + uint scene_id; + struct udevice *dev; + struct scene *scn; + bool done; + int ret; + + cli_ch_init(cch); + + /* For now we only support a video console */ + ret = uclass_first_device_err(UCLASS_VIDEO, &dev); + if (ret) + return log_msg_ret("vid", ret); + ret = expo_set_display(exp, dev); + if (ret) + return log_msg_ret("dis", ret); + + ret = expo_first_scene_id(exp); + if (ret < 0) + return log_msg_ret("scn", ret); + scene_id = ret; + + ret = expo_set_scene_id(exp, scene_id); + if (ret) + return log_msg_ret("sid", ret); + + exp->popup = true; + + /* This is not supported for now */ + if (0) + expo_set_text_mode(exp, true); + + vid_priv = dev_get_uclass_priv(dev); + + scn = expo_lookup_scene_id(exp, scene_id); + scene_highlight_first(scn); + + cedit_arange(exp, vid_priv, scene_id); + + ret = expo_calc_dims(exp); + if (ret) + return log_msg_ret("dim", ret); + + done = false; + do { + struct expo_action act; + int ichar, key; + + ret = expo_render(exp); + if (ret) + break; + + ichar = cli_ch_process(cch, 0); + if (!ichar) { + while (!ichar && !tstc()) { + schedule(); + mdelay(2); + ichar = cli_ch_process(cch, -ETIMEDOUT); + } + if (!ichar) { + ichar = getchar(); + ichar = cli_ch_process(cch, ichar); + } + } + + key = 0; + if (ichar) { + key = bootmenu_conv_key(ichar); + if (key == BKEY_NONE) + key = ichar; + } + if (!key) + continue; + + ret = expo_send_key(exp, key); + if (ret) + break; + + ret = expo_action_get(exp, &act); + if (!ret) { + switch (act.type) { + case EXPOACT_POINT_OBJ: + scene_set_highlight_id(scn, act.select.id); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_OPEN: + scene_set_open(scn, act.select.id, true); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_CLOSE: + scene_set_open(scn, act.select.id, false); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_SELECT: + scene_set_open(scn, scn->highlight_id, false); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_QUIT: + log_debug("quitting\n"); + done = true; + break; + default: + break; + } + } + } while (!done); + + if (ret) + return log_msg_ret("end", ret); + + return 0; +} diff --git a/boot/expo_build.c b/boot/expo_build.c index 7e61ab06a8d..22f62eb54bc 100644 --- a/boot/expo_build.c +++ b/boot/expo_build.c @@ -376,7 +376,8 @@ int expo_build(ofnode root, struct expo **expp) ret = read_strings(&info, root); if (ret) return log_msg_ret("str", ret); - list_strings(&info); + if (_DEBUG) + list_strings(&info); ret = expo_new("name", NULL, &exp); if (ret) diff --git a/boot/scene.c b/boot/scene.c index 6fbc1fc578c..e52333371f9 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -92,6 +92,18 @@ void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type) return NULL; } +void *scene_obj_find_by_name(struct scene *scn, const char *name) +{ + struct scene_obj *obj; + + list_for_each_entry(obj, &scn->obj_head, sibling) { + if (!strcmp(name, obj->name)) + return obj; + } + + return NULL; +} + int scene_obj_add(struct scene *scn, const char *name, uint id, enum scene_obj_t type, uint size, struct scene_obj **objp) { diff --git a/boot/scene_internal.h b/boot/scene_internal.h index dc98ecd0214..fb1ea5533b9 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -41,6 +41,14 @@ uint resolve_id(struct expo *exp, uint id); void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type); /** + * scene_obj_find_by_name() - Find an object in a scene by name + * + * @scn: Scene to search + * @name: Name to search for + */ +void *scene_obj_find_by_name(struct scene *scn, const char *name); + +/** * scene_obj_add() - Add a new object to a scene * * @scn: Scene to update |
