
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 diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c index b506bb18ffb..6645520e2ca 100644 --- a/drivers/serial/serial_efi.c +++ b/drivers/serial/serial_efi.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; } diff --git a/include/efi.h b/include/efi.h index 52f3a014f1d..3d983bd69a4 100644 --- a/include/efi.h +++ b/include/efi.h @@ -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 */ diff --git a/lib/efi/Makefile b/lib/efi/Makefile index 842067dcab3..c2e56df7144 100644 --- a/lib/efi/Makefile +++ b/lib/efi/Makefile @@ -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 diff --git a/lib/efi/input.c b/lib/efi/input.c new file mode 100644 index 00000000000..4d6b81bf183 --- /dev/null +++ b/lib/efi/input.c @@ -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); +} -- 2.43.0