diff mbox series

[v2] bootmenu: Allow to quit it via ESC/CTRL+C

Message ID 20201227000438.19133-1-pali@kernel.org
State Accepted
Commit 83a287a613f3f50aceaf8f0131402b5093368009
Delegated to: Tom Rini
Headers show
Series [v2] bootmenu: Allow to quit it via ESC/CTRL+C | expand

Commit Message

Pali Rohár Dec. 27, 2020, 12:04 a.m. UTC
When ESC/CTRL+C is pressed interrupt bootmenu and jump into U-Boot console.
As the last entry in bootmenu is always U-Boot console just choose the last
entry when ESC or CTRL+C is pressed.

ESC key is detected when either no other character appears after '\e'
within 10ms or when non-'[' appears after '\e'.

It is useful when bootmenu is part of boot process and you want to
interrupt boot process by scripts which control U-Boot (serial) console.

Signed-off-by: Pali Rohár <pali@kernel.org>

---
Changes in v2:
* Added support also for ESC key
---
 cmd/bootmenu.c | 42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

Comments

Simon Glass Dec. 29, 2020, 3:32 a.m. UTC | #1
On Sat, 26 Dec 2020 at 17:05, Pali Rohár <pali@kernel.org> wrote:
>
> When ESC/CTRL+C is pressed interrupt bootmenu and jump into U-Boot console.
> As the last entry in bootmenu is always U-Boot console just choose the last
> entry when ESC or CTRL+C is pressed.
>
> ESC key is detected when either no other character appears after '\e'
> within 10ms or when non-'[' appears after '\e'.
>
> It is useful when bootmenu is part of boot process and you want to
> interrupt boot process by scripts which control U-Boot (serial) console.
>
> Signed-off-by: Pali Rohár <pali@kernel.org>
>
> ---
> Changes in v2:
> * Added support also for ESC key
> ---
>  cmd/bootmenu.c | 42 +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 35 insertions(+), 7 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>
Tom Rini Jan. 18, 2021, 1:01 p.m. UTC | #2
On Sun, Dec 27, 2020 at 01:04:38AM +0100, Pali Rohár wrote:

> When ESC/CTRL+C is pressed interrupt bootmenu and jump into U-Boot console.
> As the last entry in bootmenu is always U-Boot console just choose the last
> entry when ESC or CTRL+C is pressed.
> 
> ESC key is detected when either no other character appears after '\e'
> within 10ms or when non-'[' appears after '\e'.
> 
> It is useful when bootmenu is part of boot process and you want to
> interrupt boot process by scripts which control U-Boot (serial) console.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 1ba7b622e5..409ef9a848 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -45,6 +45,7 @@  enum bootmenu_key {
 	KEY_UP,
 	KEY_DOWN,
 	KEY_SELECT,
+	KEY_QUIT,
 };
 
 static char *bootmenu_getoption(unsigned short int n)
@@ -109,6 +110,9 @@  static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
 			case '\r':
 				*key = KEY_SELECT;
 				break;
+			case 0x3: /* ^C */
+				*key = KEY_QUIT;
+				break;
 			default:
 				*key = KEY_NONE;
 				break;
@@ -136,13 +140,25 @@  static void bootmenu_loop(struct bootmenu_data *menu,
 {
 	int c;
 
-	while (!tstc()) {
-		WATCHDOG_RESET();
-		mdelay(10);
+	if (*esc == 1) {
+		if (tstc()) {
+			c = getchar();
+		} else {
+			WATCHDOG_RESET();
+			mdelay(10);
+			if (tstc())
+				c = getchar();
+			else
+				c = '\e';
+		}
+	} else {
+		while (!tstc()) {
+			WATCHDOG_RESET();
+			mdelay(10);
+		}
+		c = getchar();
 	}
 
-	c = getchar();
-
 	switch (*esc) {
 	case 0:
 		/* First char of ANSI escape sequence '\e' */
@@ -157,7 +173,9 @@  static void bootmenu_loop(struct bootmenu_data *menu,
 			*esc = 2;
 			*key = KEY_NONE;
 		} else {
-			*esc = 0;
+		/* Alone ESC key was pressed */
+			*key = KEY_QUIT;
+			*esc = (c == '\e') ? 1 : 0;
 		}
 		break;
 	case 2:
@@ -187,6 +205,10 @@  static void bootmenu_loop(struct bootmenu_data *menu,
 	/* enter key was pressed */
 	if (c == '\r')
 		*key = KEY_SELECT;
+
+	/* ^C was pressed */
+	if (c == 0x3)
+		*key = KEY_QUIT;
 }
 
 static char *bootmenu_choice_entry(void *data)
@@ -222,6 +244,12 @@  static char *bootmenu_choice_entry(void *data)
 			for (i = 0; i < menu->active; ++i)
 				iter = iter->next;
 			return iter->key;
+		case KEY_QUIT:
+			/* Quit by choosing the last entry - U-Boot console */
+			iter = menu->first;
+			while (iter->next)
+				iter = iter->next;
+			return iter->key;
 		default:
 			break;
 		}
@@ -389,7 +417,7 @@  static void menu_display_statusline(struct menu *m)
 	printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
 	puts(ANSI_CLEAR_LINE);
 	printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
-	puts("  Press UP/DOWN to move, ENTER to select");
+	puts("  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit");
 	puts(ANSI_CLEAR_LINE_TO_END);
 	printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
 	puts(ANSI_CLEAR_LINE);