From: Simon Glass <sjg@chromium.org>
Create a new file in lib/efi to handle conversion of keys from EFI
format to characters, so we can use it from multiple places. Update the
serial_efi driver accordingly.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
drivers/serial/serial_efi.c | 15 +-------------
include/efi.h | 32 +++++++++++++++++++++++++++++
lib/efi/Makefile | 1 +
lib/efi/input.c | 40 +++++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 14 deletions(-)
create mode 100644 lib/efi/input.c
@@ -73,7 +73,6 @@ static int serial_efi_get_key(struct serial_efi_priv *priv)
static int serial_efi_getc(struct udevice *dev)
{
struct serial_efi_priv *priv = dev_get_priv(dev);
- char conv_scan[10] = {0, 'p', 'n', 'f', 'b', 'a', 'e', 0, 8};
int ret, ch;
ret = serial_efi_get_key(priv);
@@ -81,19 +80,7 @@ static int serial_efi_getc(struct udevice *dev)
return ret;
priv->have_key = false;
- ch = priv->key.unicode_char;
-
- /*
- * Unicode char 8 (for backspace) is never returned. Instead we get a
- * key scan code of 8. Handle this so that backspace works correctly
- * in the U-Boot command line.
- */
- if (!ch && priv->key.scan_code < sizeof(conv_scan)) {
- ch = conv_scan[priv->key.scan_code];
- if (ch >= 'a')
- ch -= 'a' - 1;
- }
- debug(" [%x %x %x] ", ch, priv->key.unicode_char, priv->key.scan_code);
+ ch = efi_decode_key(&priv->key);
return ch;
}
@@ -24,6 +24,8 @@
#endif
struct abuf;
+struct efi_input_key;
+struct efi_key_data;
struct udevice;
/* Type INTN in UEFI specification */
@@ -912,4 +914,34 @@ int efi_read_var(const u16 *name, const efi_guid_t *guid, u32 *attrp,
uint16_t *efi_dp_str(struct efi_device_path *dp);
+/**
+ * efi_decode_key() - Convert EFI input key to character
+ *
+ * Converts an EFI input key structure to a character code, handling
+ * both unicode characters and scan codes for special keys like arrow keys
+ * and backspace.
+ *
+ * Unicode characters are returned as-is, with the exception that carriage
+ * return ('\r') is converted to newline ('\n') for consistency with U-Boot
+ * conventions.
+ *
+ * @key: Pointer to EFI input key structure
+ * Return: Character code (0-255), or 0 if no valid character
+ */
+int efi_decode_key(struct efi_input_key *key);
+
+/**
+ * efi_decode_key_ex() - Convert EFI extended input key to character
+ *
+ * Converts an EFI extended key data structure to a character code by
+ * extracting the basic input key and calling efi_decode_key().
+ *
+ * This function provides a convenient wrapper for handling EFI Simple Text
+ * Input EX Protocol key data, which includes modifier keys (currently ignored)
+ *
+ * @key_data: Pointer to EFI extended key data structure
+ * Return: Character code (0-255), or 0 if no valid character
+ */
+int efi_decode_key_ex(struct efi_key_data *key_data);
+
#endif /* _LINUX_EFI_H */
@@ -6,6 +6,7 @@
obj-y += basename.o
obj-y += device_path.o
obj-y += helper.o
+obj-y += input.o
obj-y += load_options.o
obj-y += memory.o
obj-y += run.o
new file mode 100644
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EFI input key decoding functions
+ *
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEGORY LOGC_EFI
+
+#include <efi.h>
+#include <efi_api.h>
+#include <cli.h>
+
+int efi_decode_key(struct efi_input_key *key)
+{
+ static const char conv_scan[] = {0, 'p', 'n', 'f', 'b', 'a', 'e', 0, 8};
+ int ch;
+
+ ch = key->unicode_char;
+
+ /*
+ * Unicode char 8 (for backspace) is never returned. Instead we get a
+ * key scan code of 8. Handle this so that backspace works correctly
+ * in the U-Boot command line.
+ */
+ if (!ch && key->scan_code < sizeof(conv_scan)) {
+ ch = conv_scan[key->scan_code];
+ if (ch >= 'a')
+ ch -= 'a' - 1;
+ }
+ log_debug(" [%x %x %x] ", ch, key->unicode_char, key->scan_code);
+
+ return ch;
+}
+
+int efi_decode_key_ex(struct efi_key_data *key_data)
+{
+ return efi_decode_key(&key_data->key);
+}