[PATCH v2 06/11] efi_loader: move console-input helpers to efi_app_common
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Sun Jun 21 10:19:10 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.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
v2:
new patch
---
lib/efi_loader/dbginfodump.c | 61 ------------------
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, 119 insertions(+), 385 deletions(-)
diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c
index 2dcff2a11fe..8fa60a7f48e 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);
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