diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index fe8d61e56c..3485765368 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 +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 +Signed-off-by: Weijie Gao +--- + 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 +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 +--- + 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 +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 +--- + 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 } 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 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 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 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 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 /* * 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 { 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 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 { 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 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 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 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 /** * 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 /* '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 /** * 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 /** * 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 */