summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_console.c
diff options
context:
space:
mode:
authorMasahisa Kojima <masahisa.kojima@linaro.org>2022-09-12 17:33:50 +0900
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2022-09-14 08:43:31 +0200
commit87d791423ac69affec43dfb834965adcb0aa02e6 (patch)
tree82576a5bf3f39e7963c7931407542342deaeb9a7 /lib/efi_loader/efi_console.c
parentc2238fcf0c4567bbd581882e5952047e71406f58 (diff)
eficonfig: menu-driven addition of UEFI boot option
This commit add the "eficonfig" command. The "eficonfig" command implements the menu-driven UEFI boot option maintenance feature. This commit implements the addition of new boot option. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot#### variable. User can also enter the description and optional_data of the BOOT#### variable in utf8. This commit adds "include/efi_config.h", it contains the common definition to be used from other menus such as UEFI Secure Boot key management. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Diffstat (limited to 'lib/efi_loader/efi_console.c')
-rw-r--r--lib/efi_loader/efi_console.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 3164fd484e2..5be509f0d6e 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -7,6 +7,7 @@
#define LOG_CATEGORY LOGC_EFI
+#include <ansi.h>
#include <common.h>
#include <charset.h>
#include <malloc.h>
@@ -1318,3 +1319,72 @@ out_of_memory:
printf("ERROR: Out of memory\n");
return r;
}
+
+/**
+ * efi_console_get_u16_string() - get user input string
+ *
+ * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ * @buf: buffer to store user input string in UTF16
+ * @count: number of u16 string including NULL terminator that buf has
+ * @filter_func: callback to filter user input
+ * @row: row number to locate user input form
+ * @col: column number to locate user input form
+ * Return: status code
+ */
+efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin,
+ u16 *buf, efi_uintn_t count,
+ efi_console_filter_func filter_func,
+ int row, int col)
+{
+ efi_status_t ret;
+ efi_uintn_t len = 0;
+ struct efi_input_key key;
+
+ printf(ANSI_CURSOR_POSITION
+ ANSI_CLEAR_LINE_TO_END
+ ANSI_CURSOR_SHOW, row, col);
+
+ ret = EFI_CALL(cin->reset(cin, false));
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ for (;;) {
+ do {
+ ret = EFI_CALL(cin->read_key_stroke(cin, &key));
+ mdelay(10);
+ } while (ret == EFI_NOT_READY);
+
+ if (key.unicode_char == u'\b') {
+ if (len > 0)
+ buf[--len] = u'\0';
+
+ printf(ANSI_CURSOR_POSITION
+ "%ls"
+ ANSI_CLEAR_LINE_TO_END, row, col, buf);
+ continue;
+ } else if (key.unicode_char == u'\r') {
+ buf[len] = u'\0';
+ return EFI_SUCCESS;
+ } else if (key.unicode_char == 0x3 || key.scan_code == 23) {
+ return EFI_ABORTED;
+ } else if (key.unicode_char < 0x20) {
+ /* ignore control codes other than Ctrl+C, '\r' and '\b' */
+ continue;
+ } else if (key.scan_code != 0) {
+ /* only accept single ESC press for cancel */
+ continue;
+ }
+
+ if (filter_func) {
+ if (filter_func(&key) != EFI_SUCCESS)
+ continue;
+ }
+
+ if (len >= (count - 1))
+ continue;
+
+ buf[len] = key.unicode_char;
+ len++;
+ printf(ANSI_CURSOR_POSITION "%ls", row, col, buf);
+ }
+}