[openwrt/openwrt] uboot-mediatek: import patches improving menu navigation
LEDE Commits
lede-commits at lists.infradead.org
Sat Nov 2 15:34:01 PDT 2024
dangole pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/5745b7e81579183d0c3e270ac155eb853677169c
commit 5745b7e81579183d0c3e270ac155eb853677169c
Author: Daniel Golle <daniel at makrotopia.org>
AuthorDate: Thu Oct 31 21:08:10 2024 +0000
uboot-mediatek: import patches improving menu navigation
Using the arrow keys to navigate the U-Boot menu often leads to being
dropped into the U-Boot shell unexpectedly.
This can be prevented in most cases by improving the logic to detect the
arrow key ESC sequence and only reprinting the menu if actually needed.
Also enable CONFIG_SERIAL_RX_BUFFER for all boards as it helps preventing
the remaining cases.
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
package/boot/uboot-mediatek/Makefile | 3 +-
...e-logic-checking-whether-ESC-key-is-press.patch | 63 ++++++++++++
...pport-to-check-if-menu-needs-to-be-reprin.patch | 112 +++++++++++++++++++++
.../patches/012-bootmenu-add-reprint-check.patch | 75 ++++++++++++++
...nu-add-ability-to-select-item-by-shortkey.patch | 45 +++++----
.../patches/211-cmd-bootmenu-custom-title.patch | 8 +-
6 files changed, 279 insertions(+), 27 deletions(-)
diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile
index 62979724c2..ab08126b51 100644
--- a/package/boot/uboot-mediatek/Makefile
+++ b/package/boot/uboot-mediatek/Makefile
@@ -844,7 +844,8 @@ UBOOT_TARGETS := \
UBOOT_CUSTOMIZE_CONFIG := \
--disable TOOLS_KWBIMAGE \
--disable TOOLS_LIBCRYPTO \
- --disable TOOLS_MKEFICAPSULE
+ --disable TOOLS_MKEFICAPSULE \
+ --enable SERIAL_RX_BUFFER
ifdef CONFIG_TARGET_mediatek
UBOOT_MAKE_FLAGS += $(UBOOT_IMAGE:.fip=.bin)
diff --git a/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch b/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch
new file mode 100644
index 0000000000..f3589c4622
--- /dev/null
+++ b/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch
@@ -0,0 +1,63 @@
+From 72b4ba8417d33516b8489bac3c90dbbbf781a3d2 Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao at mediatek.com>
+Date: Tue, 29 Oct 2024 17:47:10 +0800
+Subject: [PATCH 1/3] menu: fix the logic checking whether ESC key is pressed
+
+It's observed that the bootmenu on a serial console sometimes
+incorrectly quitted with superfluous characters filled to command
+line input:
+
+> *** U-Boot Boot Menu ***
+>
+> 1. Startup system (Default)
+> 2. Upgrade firmware
+> 3. Upgrade ATF BL2
+> 4. Upgrade ATF FIP
+> 5. Load image
+> 0. U-Boot console
+>
+>
+> Press UP/DOWN to move, ENTER to select, ESC to quit
+>MT7988> [B
+
+Analysis shows it was caused by the wrong logic of bootmenu_loop:
+
+At first the bootmenu_loop received the first ESC char correctly.
+
+However, during the second call to bootmenu_loop, there's no data
+in the UART Rx FIFO. Due to the low baudrate, the second char of
+the down array key sequence hasn't be fully received.
+
+But bootmenu_loop just did a mdelay(10), and then treated it as a
+single ESC key press event. It didn't even try tstc() again after
+the 10ms timeout.
+
+This patch fixes this issue by letting bootmenu_loop check tstc()
+twice.
+
+Tested-By: E Shattow <lucent at gmail.com>
+Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
+---
+ common/menu.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/common/menu.c
++++ b/common/menu.c
+@@ -525,14 +525,15 @@ enum bootmenu_key bootmenu_loop(struct b
+ struct cli_ch_state *cch)
+ {
+ enum bootmenu_key key;
+- int c;
++ int c, errchar = 0;
+
+ c = cli_ch_process(cch, 0);
+ if (!c) {
+ while (!c && !tstc()) {
+ schedule();
+ mdelay(10);
+- c = cli_ch_process(cch, -ETIMEDOUT);
++ c = cli_ch_process(cch, errchar);
++ errchar = -ETIMEDOUT;
+ }
+ if (!c) {
+ c = getchar();
diff --git a/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch b/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch
new file mode 100644
index 0000000000..9d356ff0b4
--- /dev/null
+++ b/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch
@@ -0,0 +1,112 @@
+From f1cbdd3330f0055dfbff0ef7d86276c4cc3cff2a Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao at mediatek.com>
+Date: Tue, 29 Oct 2024 17:47:16 +0800
+Subject: [PATCH 2/3] menu: add support to check if menu needs to be reprinted
+
+This patch adds a new callback named need_reprint for menu.
+The need_reprint will be called before printing the menu. If the
+callback exists and returns FALSE, menu printing will be canceled.
+
+This is very useful if the menu was not changed. It can save time
+for serial-based menu to handle more input data.
+
+Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
+---
+ boot/pxe_utils.c | 2 +-
+ cmd/bootmenu.c | 2 +-
+ cmd/eficonfig.c | 2 +-
+ common/menu.c | 11 +++++++++++
+ include/menu.h | 1 +
+ 5 files changed, 15 insertions(+), 3 deletions(-)
+
+--- a/boot/pxe_utils.c
++++ b/boot/pxe_utils.c
+@@ -1449,7 +1449,7 @@ static struct menu *pxe_menu_to_menu(str
+ * Create a menu and add items for all the labels.
+ */
+ m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10),
+- cfg->prompt, NULL, label_print, NULL, NULL);
++ cfg->prompt, NULL, label_print, NULL, NULL, NULL);
+ if (!m)
+ return NULL;
+
+--- a/cmd/bootmenu.c
++++ b/cmd/bootmenu.c
+@@ -506,7 +506,7 @@ static enum bootmenu_ret bootmenu_show(i
+
+ menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline,
+ bootmenu_print_entry, bootmenu_choice_entry,
+- bootmenu);
++ NULL, bootmenu);
+ if (!menu) {
+ bootmenu_destroy(bootmenu);
+ return BOOTMENU_RET_FAIL;
+--- a/cmd/eficonfig.c
++++ b/cmd/eficonfig.c
+@@ -443,7 +443,7 @@ efi_status_t eficonfig_process_common(st
+ efi_menu->menu_desc = menu_desc;
+
+ menu = menu_create(NULL, 0, 1, display_statusline, item_data_print,
+- item_choice, efi_menu);
++ item_choice, NULL, efi_menu);
+ if (!menu)
+ return EFI_INVALID_PARAMETER;
+
+--- a/common/menu.c
++++ b/common/menu.c
+@@ -43,6 +43,7 @@ struct menu {
+ void (*display_statusline)(struct menu *);
+ void (*item_data_print)(void *);
+ char *(*item_choice)(void *);
++ bool (*need_reprint)(void *);
+ void *item_choice_data;
+ struct list_head items;
+ int item_cnt;
+@@ -117,6 +118,11 @@ static inline void *menu_item_destroy(st
+ */
+ static inline void menu_display(struct menu *m)
+ {
++ if (m->need_reprint) {
++ if (!m->need_reprint(m->item_choice_data))
++ return;
++ }
++
+ if (m->title) {
+ puts(m->title);
+ putc('\n');
+@@ -362,6 +368,9 @@ int menu_item_add(struct menu *m, char *
+ * item. Returns a key string corresponding to the chosen item or NULL if
+ * no item has been selected.
+ *
++ * need_reprint - If not NULL, will be called before printing the menu.
++ * Returning FALSE means the menu does not need reprint.
++ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
+ * Returns a pointer to the menu if successful, or NULL if there is
+@@ -371,6 +380,7 @@ struct menu *menu_create(char *title, in
+ void (*display_statusline)(struct menu *),
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
++ bool (*need_reprint)(void *),
+ void *item_choice_data)
+ {
+ struct menu *m;
+@@ -386,6 +396,7 @@ struct menu *menu_create(char *title, in
+ m->display_statusline = display_statusline;
+ m->item_data_print = item_data_print;
+ m->item_choice = item_choice;
++ m->need_reprint = need_reprint;
+ m->item_choice_data = item_choice_data;
+ m->item_cnt = 0;
+
+--- a/include/menu.h
++++ b/include/menu.h
+@@ -13,6 +13,7 @@ struct menu *menu_create(char *title, in
+ void (*display_statusline)(struct menu *),
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
++ bool (*need_reprint)(void *),
+ void *item_choice_data);
+ int menu_default_set(struct menu *m, char *item_key);
+ int menu_get_choice(struct menu *m, void **choice);
diff --git a/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch b/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch
new file mode 100644
index 0000000000..8f4db3a82e
--- /dev/null
+++ b/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch
@@ -0,0 +1,75 @@
+From 702752cfae954648d6133bdff19283343b3339ef Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao at mediatek.com>
+Date: Tue, 29 Oct 2024 17:47:22 +0800
+Subject: [PATCH 3/3] bootmenu: add reprint check
+
+Record the last active menu item and check if it equals to the
+current selected item before reprint.
+
+Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
+---
+ cmd/bootmenu.c | 16 +++++++++++++++-
+ include/menu.h | 1 +
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/cmd/bootmenu.c
++++ b/cmd/bootmenu.c
+@@ -103,11 +103,13 @@ static char *bootmenu_choice_entry(void
+
+ switch (key) {
+ case BKEY_UP:
++ menu->last_active = menu->active;
+ if (menu->active > 0)
+ --menu->active;
+ /* no menu key selected, regenerate menu */
+ return NULL;
+ case BKEY_DOWN:
++ menu->last_active = menu->active;
+ if (menu->active < menu->count - 1)
+ ++menu->active;
+ /* no menu key selected, regenerate menu */
+@@ -133,6 +135,17 @@ static char *bootmenu_choice_entry(void
+ return NULL;
+ }
+
++static bool bootmenu_need_reprint(void *data)
++{
++ struct bootmenu_data *menu = data;
++ bool need_reprint;
++
++ need_reprint = menu->last_active != menu->active;
++ menu->last_active = menu->active;
++
++ return need_reprint;
++}
++
+ static void bootmenu_destroy(struct bootmenu_data *menu)
+ {
+ struct bootmenu_entry *iter = menu->first;
+@@ -332,6 +345,7 @@ static struct bootmenu_data *bootmenu_cr
+
+ menu->delay = delay;
+ menu->active = 0;
++ menu->last_active = -1;
+ menu->first = NULL;
+
+ default_str = env_get("bootmenu_default");
+@@ -506,7 +520,7 @@ static enum bootmenu_ret bootmenu_show(i
+
+ menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline,
+ bootmenu_print_entry, bootmenu_choice_entry,
+- NULL, bootmenu);
++ bootmenu_need_reprint, bootmenu);
+ if (!menu) {
+ bootmenu_destroy(bootmenu);
+ return BOOTMENU_RET_FAIL;
+--- a/include/menu.h
++++ b/include/menu.h
+@@ -40,6 +40,7 @@ int menu_show(int bootdelay);
+ struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
++ int last_active; /* last active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+ };
diff --git a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch b/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
index 4aa4318493..47e158b521 100644
--- a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
+++ b/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
@@ -35,7 +35,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
}
switch (key) {
-@@ -112,6 +113,12 @@ static char *bootmenu_choice_entry(void
+@@ -114,6 +115,12 @@ static char *bootmenu_choice_entry(void
++menu->active;
/* no menu key selected, regenerate menu */
return NULL;
@@ -48,7 +48,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
case BKEY_SELECT:
iter = menu->first;
for (i = 0; i < menu->active; ++i)
-@@ -169,6 +176,9 @@ static int prepare_bootmenu_entry(struct
+@@ -182,6 +189,9 @@ static int prepare_bootmenu_entry(struct
unsigned short int i = *index;
struct bootmenu_entry *entry = NULL;
struct bootmenu_entry *iter = *current;
@@ -58,7 +58,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
while ((option = bootmenu_getoption(i))) {
-@@ -183,11 +193,24 @@ static int prepare_bootmenu_entry(struct
+@@ -196,11 +206,24 @@ static int prepare_bootmenu_entry(struct
if (!entry)
return -ENOMEM;
@@ -84,15 +84,15 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
entry->command = strdup(sep + 1);
if (!entry->command) {
-@@ -333,6 +356,7 @@ static struct bootmenu_data *bootmenu_cr
- menu->delay = delay;
+@@ -347,6 +370,7 @@ static struct bootmenu_data *bootmenu_cr
menu->active = 0;
+ menu->last_active = -1;
menu->first = NULL;
+ menu->last_choiced = false;
default_str = env_get("bootmenu_default");
if (default_str)
-@@ -368,9 +392,9 @@ static struct bootmenu_data *bootmenu_cr
+@@ -382,9 +406,9 @@ static struct bootmenu_data *bootmenu_cr
/* Add Quit entry if exiting bootmenu is disabled */
if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
@@ -106,7 +106,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
free(entry);
--- a/common/menu.c
+++ b/common/menu.c
-@@ -48,6 +48,33 @@ struct menu {
+@@ -49,6 +49,33 @@ struct menu {
int item_cnt;
};
@@ -140,7 +140,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
/*
* An iterator function for menu items. callback will be called for each item
* in m, with m, a pointer to the item, and extra being passed to callback. If
-@@ -426,7 +453,7 @@ int menu_destroy(struct menu *m)
+@@ -437,7 +464,7 @@ int menu_destroy(struct menu *m)
}
enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
@@ -149,7 +149,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
{
enum bootmenu_key key = BKEY_NONE;
int i, c;
-@@ -461,6 +488,19 @@ enum bootmenu_key bootmenu_autoboot_loop
+@@ -472,6 +499,19 @@ enum bootmenu_key bootmenu_autoboot_loop
break;
default:
key = BKEY_NONE;
@@ -169,7 +169,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
break;
}
break;
-@@ -481,7 +521,8 @@ enum bootmenu_key bootmenu_autoboot_loop
+@@ -492,7 +532,8 @@ enum bootmenu_key bootmenu_autoboot_loop
return key;
}
@@ -179,7 +179,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
{
enum bootmenu_key key;
-@@ -513,6 +554,20 @@ enum bootmenu_key bootmenu_conv_key(int
+@@ -524,6 +565,20 @@ enum bootmenu_key bootmenu_conv_key(int
case ' ':
key = BKEY_SPACE;
break;
@@ -200,15 +200,16 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
default:
key = BKEY_NONE;
break;
-@@ -522,11 +577,16 @@ enum bootmenu_key bootmenu_conv_key(int
+@@ -533,11 +588,17 @@ enum bootmenu_key bootmenu_conv_key(int
}
enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
- struct cli_ch_state *cch)
-+ struct cli_ch_state *cch, int *choice)
++ struct cli_ch_state *cch,
++ int *choice)
{
enum bootmenu_key key;
- int c;
+ int c, errchar = 0;
+ if (menu->last_choiced) {
+ menu->last_choiced = false;
@@ -218,7 +219,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
c = cli_ch_process(cch, 0);
if (!c) {
while (!c && !tstc()) {
-@@ -540,7 +600,7 @@ enum bootmenu_key bootmenu_loop(struct b
+@@ -552,7 +613,7 @@ enum bootmenu_key bootmenu_loop(struct b
}
}
@@ -238,7 +239,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
struct cli_ch_state;
struct menu;
-@@ -19,6 +21,8 @@ int menu_get_choice(struct menu *m, void
+@@ -20,6 +22,8 @@ int menu_get_choice(struct menu *m, void
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
int menu_default_choice(struct menu *m, void **choice);
@@ -247,15 +248,15 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
/**
* menu_show() Show a boot menu
-@@ -41,6 +45,7 @@ struct bootmenu_data {
- int active; /* active menu entry */
+@@ -43,6 +47,7 @@ struct bootmenu_data {
+ int last_active; /* last active menu entry */
int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */
+ bool last_choiced;
};
/** enum bootmenu_key - keys that can be returned by the bootmenu */
-@@ -51,6 +56,7 @@ enum bootmenu_key {
+@@ -53,6 +58,7 @@ enum bootmenu_key {
BKEY_SELECT,
BKEY_QUIT,
BKEY_SAVE,
@@ -263,7 +264,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
/* 'extra' keys, which are used by menus but not cedit */
BKEY_PLUS,
-@@ -81,7 +87,7 @@ enum bootmenu_key {
+@@ -83,7 +89,7 @@ enum bootmenu_key {
* anything else: KEY_NONE
*/
enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
@@ -272,7 +273,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
/**
* bootmenu_loop() - handle waiting for a keypress when autoboot is disabled
-@@ -107,7 +113,7 @@ enum bootmenu_key bootmenu_autoboot_loop
+@@ -109,7 +115,7 @@ enum bootmenu_key bootmenu_autoboot_loop
* Space: BKEY_SPACE
*/
enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
@@ -281,7 +282,7 @@ Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
/**
* bootmenu_conv_key() - Convert a U-Boot keypress into a menu key
-@@ -115,6 +121,7 @@ enum bootmenu_key bootmenu_loop(struct b
+@@ -117,6 +123,7 @@ enum bootmenu_key bootmenu_loop(struct b
* @ichar: Keypress to convert (ASCII, including control characters)
* Returns: Menu key that corresponds to @ichar, or BKEY_NONE if none
*/
diff --git a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
index 76ff745e93..be06832ea1 100644
--- a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
+++ b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
@@ -1,6 +1,6 @@
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
-@@ -451,7 +451,11 @@ static void menu_display_statusline(stru
+@@ -465,7 +465,11 @@ static void menu_display_statusline(stru
printf(ANSI_CURSOR_POSITION, 1, 1);
puts(ANSI_CLEAR_LINE);
printf(ANSI_CURSOR_POSITION, 2, 3);
@@ -13,7 +13,7 @@
puts(ANSI_CLEAR_LINE_TO_END);
printf(ANSI_CURSOR_POSITION, 3, 1);
puts(ANSI_CLEAR_LINE);
-@@ -536,6 +540,7 @@ static enum bootmenu_ret bootmenu_show(i
+@@ -550,6 +554,7 @@ static enum bootmenu_ret bootmenu_show(i
return BOOTMENU_RET_FAIL;
}
@@ -23,8 +23,8 @@
goto cleanup;
--- a/include/menu.h
+++ b/include/menu.h
-@@ -45,6 +45,7 @@ struct bootmenu_data {
- int active; /* active menu entry */
+@@ -47,6 +47,7 @@ struct bootmenu_data {
+ int last_active; /* last active menu entry */
int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */
+ char *mtitle; /* custom menu title */
More information about the lede-commits
mailing list