aboutsummaryrefslogtreecommitdiff
path: root/stand/efi/libefi
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2019-09-02 11:04:17 +0000
committerToomas Soome <tsoome@FreeBSD.org>2019-09-02 11:04:17 +0000
commit05b24e861745be347d0854468c38adef3b7b72c3 (patch)
treed0c25da935b4e647a55c773cbf6c0d22cd199d18 /stand/efi/libefi
parent591d5f0ef5a9a5f508435d0af743a1b68a6c46ed (diff)
downloadsrc-05b24e861745be347d0854468c38adef3b7b72c3.tar.gz
src-05b24e861745be347d0854468c38adef3b7b72c3.zip
loader.efi: use and prefer coninex interface
Add support for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
Notes
Notes: svn path=/head/; revision=351696
Diffstat (limited to 'stand/efi/libefi')
-rw-r--r--stand/efi/libefi/efi_console.c73
1 files changed, 66 insertions, 7 deletions
diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c
index 03f8532e1cf1..a8ed786f7867 100644
--- a/stand/efi/libefi/efi_console.c
+++ b/stand/efi/libefi/efi_console.c
@@ -32,8 +32,10 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h"
+static EFI_GUID simple_input_ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
static SIMPLE_INPUT_INTERFACE *conin;
+static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *coninex;
#ifdef TERM_EMU
#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
@@ -115,6 +117,8 @@ efi_cons_probe(struct console *cp)
static int
efi_cons_init(int arg)
{
+ EFI_STATUS status;
+
#ifdef TERM_EMU
conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
DEFAULT_BGCOLOR));
@@ -125,7 +129,11 @@ efi_cons_init(int arg)
bg_c = DEFAULT_BGCOLOR;
#endif
conout->EnableCursor(conout, TRUE);
- return 0;
+ status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid,
+ (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (status != EFI_SUCCESS)
+ coninex = NULL;
+ return (0);
}
static void
@@ -524,6 +532,40 @@ efi_readkey(void)
return (false);
}
+static bool
+efi_readkey_ex(void)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY *kp;
+ EFI_KEY_DATA key_data;
+ uint32_t kss;
+
+ status = coninex->ReadKeyStrokeEx(coninex, &key_data);
+ if (status == EFI_SUCCESS) {
+ kss = key_data.KeyState.KeyShiftState;
+ kp = &key_data.Key;
+ if (kss & EFI_SHIFT_STATE_VALID) {
+
+ /*
+ * quick mapping to control chars, replace with
+ * map lookup later.
+ */
+ if (kss & EFI_RIGHT_CONTROL_PRESSED ||
+ kss & EFI_LEFT_CONTROL_PRESSED) {
+ if (kp->UnicodeChar >= 'a' &&
+ kp->UnicodeChar <= 'z') {
+ kp->UnicodeChar -= 'a';
+ kp->UnicodeChar++;
+ }
+ }
+ }
+
+ keybuf_inschar(kp);
+ return (true);
+ }
+ return (false);
+}
+
int
efi_cons_getchar(void)
{
@@ -534,8 +576,13 @@ efi_cons_getchar(void)
key_pending = 0;
- if (efi_readkey())
- return (keybuf_getchar());
+ if (coninex == NULL) {
+ if (efi_readkey())
+ return (keybuf_getchar());
+ } else {
+ if (efi_readkey_ex())
+ return (keybuf_getchar());
+ }
return (-1);
}
@@ -543,6 +590,7 @@ efi_cons_getchar(void)
int
efi_cons_poll(void)
{
+ EFI_STATUS status;
if (keybuf_ischar() || key_pending)
return (1);
@@ -552,10 +600,21 @@ efi_cons_poll(void)
* WaitForKey().
* CheckEvent() can clear the signaled state.
*/
- if (conin->WaitForKey == NULL)
- key_pending = efi_readkey();
- else
- key_pending = BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS;
+ if (coninex != NULL) {
+ if (coninex->WaitForKeyEx == NULL) {
+ key_pending = efi_readkey_ex();
+ } else {
+ status = BS->CheckEvent(coninex->WaitForKeyEx);
+ key_pending = status == EFI_SUCCESS;
+ }
+ } else {
+ if (conin->WaitForKey == NULL) {
+ key_pending = efi_readkey();
+ } else {
+ status = BS->CheckEvent(conin->WaitForKey);
+ key_pending = status == EFI_SUCCESS;
+ }
+ }
return (key_pending);
}