[PATCH v3 06/11] efi_loader: move console-input helpers to efi_app_common

Heinrich Schuchardt heinrich.schuchardt at canonical.com
Sun Jun 28 10:28:04 CEST 2026


Move the shared console-input helpers to efi_app_common:

* efi_drain_input() - drain the console input queue
* efi_input_yn()    - read a y/n/ESC key from the user
* efi_input()       - read a UTF-16 string from the console

The common efi_input_yn() calls efi_drain_input() once at entry,
replacing the open-coded cin->reset() calls that each application
previously duplicated.

dbginfodump and smbiosdump had no efi_drain_input() call in their
command loops; add the call so the console queue is drained before
each prompt, fixing a latent input-echo artefact.

The common state is extended with a cin pointer (initialized by
efi_app_init from sys_table->con_in) so the helpers can access the
console-input protocol without additional parameters.

Remove the now-duplicate static definitions from dtbdump, initrddump,
smbiosdump and dbginfodump.

smbiosdump: fix kernel-doc tag for command_loop() from "command_loop -"
to "command_loop() -" to follow the kernel-doc convention.

Reviewed-by: Simon Glass <sjg at chromium.org>
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
v3:
	actually add drain_input() to dbginfodump
v2:
	new patch
---
 lib/efi_loader/dbginfodump.c    |  62 +-----------------
 lib/efi_loader/dtbdump.c        | 109 --------------------------------
 lib/efi_loader/efi_app_common.c |  88 ++++++++++++++++++++++++++
 lib/efi_loader/efi_app_common.h |  29 +++++++++
 lib/efi_loader/initrddump.c     | 109 --------------------------------
 lib/efi_loader/smbiosdump.c     | 108 +------------------------------
 6 files changed, 120 insertions(+), 385 deletions(-)

diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c
index 2dcff2a11fe..b39d47ff9bb 100644
--- a/lib/efi_loader/dbginfodump.c
+++ b/lib/efi_loader/dbginfodump.c
@@ -14,7 +14,6 @@
 #define BUFFER_SIZE 64
 
 static struct efi_simple_text_output_protocol *cout;
-static struct efi_simple_text_input_protocol *cin;
 static efi_handle_t handle;
 static struct efi_system_table *systable;
 static struct efi_boot_services *bs;
@@ -83,65 +82,6 @@ static void printp(void *p)
 	print(str);
 }
 
-/**
- * efi_input() - read string from console
- *
- * @buffer:		input buffer
- * @buffer_size:	buffer size
- * Return:		status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_uintn_t pos = 0;
-	u16 outbuf[2] = u" ";
-	efi_status_t ret;
-
-	/* Drain the console input */
-	ret = cin->reset(cin, true);
-	*buffer = 0;
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			print(u"\r\nAborted\r\n");
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		switch (key.unicode_char) {
-		case 0x08: /* Backspace */
-			if (pos) {
-				buffer[pos--] = 0;
-				print(u"\b \b");
-			}
-			break;
-		case 0x0a: /* Linefeed */
-		case 0x0d: /* Carriage return */
-			print(u"\r\n");
-			return EFI_SUCCESS;
-		default:
-			break;
-		}
-		/* Ignore surrogate codes */
-		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-			continue;
-		if (key.unicode_char >= 0x20 &&
-		    pos < buffer_size - 1) {
-			*outbuf = key.unicode_char;
-			buffer[pos++] = key.unicode_char;
-			buffer[pos] = 0;
-			print(outbuf);
-		}
-	}
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -277,7 +217,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 	handle = image_handle;
 	systable = systab;
 	cout = systable->con_out;
-	cin = systable->con_in;
 	bs = systable->boottime;
 
 	cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
@@ -298,6 +237,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 		u16 *pos;
 		efi_uintn_t ret;
 
+		efi_drain_input();
 		print(u"=> ");
 		ret = efi_input(command, sizeof(command));
 		if (ret == EFI_ABORTED)
diff --git a/lib/efi_loader/dtbdump.c b/lib/efi_loader/dtbdump.c
index 1468955eb8c..716daf4a90f 100644
--- a/lib/efi_loader/dtbdump.c
+++ b/lib/efi_loader/dtbdump.c
@@ -16,7 +16,6 @@
 
 #define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
 
-static struct efi_simple_text_input_protocol *cin;
 static struct efi_boot_services *bs;
 static const efi_guid_t fdt_guid = EFI_FDT_GUID;
 static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
@@ -50,113 +49,6 @@ static void print_char(unsigned char c)
 	print(out);
 }
 
-/**
- * efi_drain_input() - drain console input
- */
-static void efi_drain_input(void)
-{
-	cin->reset(cin, true);
-}
-
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_status_t ret;
-
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		/* Convert to lower case */
-		switch (key.unicode_char | 0x20) {
-		case 'y':
-			return EFI_SUCCESS;
-		case 'n':
-			return EFI_ACCESS_DENIED;
-		default:
-			break;
-		}
-	}
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:		input buffer
- * @buffer_size:	buffer size
- * Return:		status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_uintn_t pos = 0;
-	u16 outbuf[2] = u" ";
-	efi_status_t ret;
-
-	*buffer = 0;
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			print(u"\r\nAborted\r\n");
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		switch (key.unicode_char) {
-		case 0x08: /* Backspace */
-			if (pos) {
-				buffer[pos--] = 0;
-				print(u"\b \b");
-			}
-			break;
-		case 0x0a: /* Linefeed */
-		case 0x0d: /* Carriage return */
-			print(u"\r\n");
-			return EFI_SUCCESS;
-		default:
-			break;
-		}
-		/* Ignore surrogate codes */
-		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-			continue;
-		if (key.unicode_char >= 0x20 &&
-		    pos < buffer_size - 1) {
-			*outbuf = key.unicode_char;
-			buffer[pos++] = key.unicode_char;
-			buffer[pos] = 0;
-			print(outbuf);
-		}
-	}
-}
-
 /*
  * Convert FDT value to host endianness.
  *
@@ -702,7 +594,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
 	handle = image_handle;
 	systable = systab;
-	cin = systable->con_in;
 	bs = systable->boottime;
 
 	color(EFI_LIGHTBLUE);
diff --git a/lib/efi_loader/efi_app_common.c b/lib/efi_loader/efi_app_common.c
index e9e9334acc7..406cd236f6f 100644
--- a/lib/efi_loader/efi_app_common.c
+++ b/lib/efi_loader/efi_app_common.c
@@ -9,6 +9,7 @@
 #include "efi_app_common.h"
 
 static efi_handle_t app_handle;
+static struct efi_simple_text_input_protocol *cin;
 static struct efi_simple_text_output_protocol *cout;
 struct efi_boot_services *bs;
 static bool nocolor;
@@ -40,6 +41,7 @@ void efi_app_init(struct efi_system_table *sys_table, efi_handle_t image_handle)
 
 	app_handle = image_handle;
 	systable = sys_table;
+	cin = sys_table->con_in;
 	cout = sys_table->con_out;
 	bs = sys_table->boottime;
 
@@ -104,3 +106,89 @@ bool starts_with(u16 *string, u16 *keyword)
 	}
 	return true;
 }
+
+void efi_drain_input(void)
+{
+	cin->reset(cin, true);
+}
+
+efi_status_t efi_input_yn(void)
+{
+	struct efi_input_key key = { 0 };
+	efi_uintn_t index;
+	efi_status_t ret;
+
+	efi_drain_input();
+	for (;;) {
+		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+		if (ret != EFI_SUCCESS)
+			continue;
+		ret = cin->read_key_stroke(cin, &key);
+		if (ret != EFI_SUCCESS)
+			continue;
+		switch (key.scan_code) {
+		case 0x17: /* Escape */
+			return EFI_ABORTED;
+		default:
+			break;
+		}
+		/* Convert to lower case */
+		switch (key.unicode_char | 0x20) {
+		case 'y':
+			return EFI_SUCCESS;
+		case 'n':
+			return EFI_ACCESS_DENIED;
+		default:
+			break;
+		}
+	}
+}
+
+efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
+{
+	struct efi_input_key key = { 0 };
+	efi_uintn_t index;
+	efi_uintn_t pos = 0;
+	u16 outbuf[2] = u" ";
+	efi_status_t ret;
+
+	*buffer = 0;
+	for (;;) {
+		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+		if (ret != EFI_SUCCESS)
+			continue;
+		ret = cin->read_key_stroke(cin, &key);
+		if (ret != EFI_SUCCESS)
+			continue;
+		switch (key.scan_code) {
+		case 0x17: /* Escape */
+			print(u"\r\nAborted\r\n");
+			return EFI_ABORTED;
+		default:
+			break;
+		}
+		switch (key.unicode_char) {
+		case 0x08: /* Backspace */
+			if (pos) {
+				buffer[pos--] = 0;
+				print(u"\b \b");
+			}
+			break;
+		case 0x0a: /* Linefeed */
+		case 0x0d: /* Carriage return */
+			print(u"\r\n");
+			return EFI_SUCCESS;
+		default:
+			break;
+		}
+		/* Ignore surrogate codes */
+		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
+			continue;
+		if (key.unicode_char >= 0x20 && pos < buffer_size - 1) {
+			*outbuf = key.unicode_char;
+			buffer[pos++] = key.unicode_char;
+			buffer[pos] = 0;
+			print(outbuf);
+		}
+	}
+}
diff --git a/lib/efi_loader/efi_app_common.h b/lib/efi_loader/efi_app_common.h
index 45c17a8ed99..4498607ef07 100644
--- a/lib/efi_loader/efi_app_common.h
+++ b/lib/efi_loader/efi_app_common.h
@@ -64,4 +64,33 @@ void error(u16 *string);
  */
 bool starts_with(u16 *string, u16 *keyword);
 
+/**
+ * efi_drain_input() - drain console input
+ */
+void efi_drain_input(void);
+
+/**
+ * efi_input_yn() - get answer to yes/no question
+ *
+ * Drains the console input before reading.
+ *
+ * Return:
+ * y or Y
+ *     EFI_SUCCESS
+ * n or N
+ *     EFI_ACCESS_DENIED
+ * ESC
+ *     EFI_ABORTED
+ */
+efi_status_t efi_input_yn(void);
+
+/**
+ * efi_input() - read string from console
+ *
+ * @buffer:             input buffer
+ * @buffer_size:        buffer size
+ * Return:              status code
+ */
+efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size);
+
 #endif /* _EFI_APP_COMMON_H */
diff --git a/lib/efi_loader/initrddump.c b/lib/efi_loader/initrddump.c
index 60f8a020e8c..52562be048d 100644
--- a/lib/efi_loader/initrddump.c
+++ b/lib/efi_loader/initrddump.c
@@ -19,7 +19,6 @@
 
 static struct efi_system_table *systable;
 static struct efi_boot_services *bs;
-static struct efi_simple_text_input_protocol *cin;
 static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
 static const efi_guid_t guid_simple_file_system_protocol =
 					EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
@@ -46,113 +45,6 @@ static const struct efi_lo_dp_prefix initrd_dp = {
 	}
 };
 
-/**
- * efi_drain_input() - drain console input
- */
-static void efi_drain_input(void)
-{
-	cin->reset(cin, true);
-}
-
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_status_t ret;
-
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		/* Convert to lower case */
-		switch (key.unicode_char | 0x20) {
-		case 'y':
-			return EFI_SUCCESS;
-		case 'n':
-			return EFI_ACCESS_DENIED;
-		default:
-			break;
-		}
-	}
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:		input buffer
- * @buffer_size:	buffer size
- * Return:		status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_uintn_t pos = 0;
-	u16 outbuf[2] = u" ";
-	efi_status_t ret;
-
-	*buffer = 0;
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			print(u"\r\nAborted\r\n");
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		switch (key.unicode_char) {
-		case 0x08: /* Backspace */
-			if (pos) {
-				buffer[pos--] = 0;
-				print(u"\b \b");
-			}
-			break;
-		case 0x0a: /* Linefeed */
-		case 0x0d: /* Carriage return */
-			print(u"\r\n");
-			return EFI_SUCCESS;
-		default:
-			break;
-		}
-		/* Ignore surrogate codes */
-		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-			continue;
-		if (key.unicode_char >= 0x20 &&
-		    pos < buffer_size - 1) {
-			*outbuf = key.unicode_char;
-			buffer[pos++] = key.unicode_char;
-			buffer[pos] = 0;
-			print(outbuf);
-		}
-	}
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -356,7 +248,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
 	handle = image_handle;
 	systable = systab;
-	cin = systable->con_in;
 	bs = systable->boottime;
 
 	color(EFI_WHITE);
diff --git a/lib/efi_loader/smbiosdump.c b/lib/efi_loader/smbiosdump.c
index e19214d798f..100e03294e5 100644
--- a/lib/efi_loader/smbiosdump.c
+++ b/lib/efi_loader/smbiosdump.c
@@ -15,7 +15,6 @@
 
 #define BUFFER_SIZE 64
 
-static struct efi_simple_text_input_protocol *cin;
 static struct efi_boot_services *bs;
 static efi_handle_t handle;
 static struct efi_system_table *systable;
@@ -26,109 +25,6 @@ static const efi_guid_t guid_simple_file_system_protocol =
 					EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
 static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
 
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_status_t ret;
-
-	/* Drain the console input */
-	ret = cin->reset(cin, true);
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		/* Convert to lower case */
-		switch (key.unicode_char | 0x20) {
-		case 'y':
-			return EFI_SUCCESS;
-		case 'n':
-			return EFI_ACCESS_DENIED;
-		default:
-			break;
-		}
-	}
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:		input buffer
- * @buffer_size:	buffer size
- * Return:		status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-	struct efi_input_key key = {0};
-	efi_uintn_t index;
-	efi_uintn_t pos = 0;
-	u16 outbuf[2] = u" ";
-	efi_status_t ret;
-
-	/* Drain the console input */
-	ret = cin->reset(cin, true);
-	*buffer = 0;
-	for (;;) {
-		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-		if (ret != EFI_SUCCESS)
-			continue;
-		ret = cin->read_key_stroke(cin, &key);
-		if (ret != EFI_SUCCESS)
-			continue;
-		switch (key.scan_code) {
-		case 0x17: /* Escape */
-			print(u"\r\nAborted\r\n");
-			return EFI_ABORTED;
-		default:
-			break;
-		}
-		switch (key.unicode_char) {
-		case 0x08: /* Backspace */
-			if (pos) {
-				buffer[pos--] = 0;
-				print(u"\b \b");
-			}
-			break;
-		case 0x0a: /* Linefeed */
-		case 0x0d: /* Carriage return */
-			print(u"\r\n");
-			return EFI_SUCCESS;
-		default:
-			break;
-		}
-		/* Ignore surrogate codes */
-		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-			continue;
-		if (key.unicode_char >= 0x20 &&
-		    pos < buffer_size - 1) {
-			*outbuf = key.unicode_char;
-			buffer[pos++] = key.unicode_char;
-			buffer[pos] = 0;
-			print(outbuf);
-		}
-	}
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -467,7 +363,7 @@ static efi_status_t do_save(u16 *filename)
 }
 
 /**
- * command_loop - process user commands
+ * command_loop() - process user commands
  */
 static void command_loop(void)
 {
@@ -476,6 +372,7 @@ static void command_loop(void)
 		u16 *pos;
 		efi_uintn_t ret;
 
+		efi_drain_input();
 		print(u"=> ");
 		ret = efi_input(command, sizeof(command));
 		if (ret == EFI_ABORTED)
@@ -509,7 +406,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
 	handle = image_handle;
 	systable = systab;
-	cin = systable->con_in;
 	bs = systable->boottime;
 
 	color(EFI_WHITE);
-- 
2.53.0



More information about the U-Boot mailing list