All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 04/13] efi_loader: rework event handling for console
Date: Tue, 11 Sep 2018 22:38:05 +0200	[thread overview]
Message-ID: <20180911203814.16960-5-xypron.glpk@gmx.de> (raw)
In-Reply-To: <20180911203814.16960-1-xypron.glpk@gmx.de>

Preread the next key in the console timer event.

The EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL requires to trigger registered key
notification functions based on the prefetched key.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
	rebase patch
v2
	rebase patch
---
 lib/efi_loader/efi_console.c | 175 +++++++++++++++++++++++++++--------
 1 file changed, 137 insertions(+), 38 deletions(-)

diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 6af083984c..e191e027a8 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -390,21 +390,12 @@ struct efi_simple_text_output_protocol efi_con_out = {
 	.mode = (void*)&efi_con_mode,
 };
 
-static efi_status_t EFIAPI efi_cin_reset(
-			struct efi_simple_text_input_protocol *this,
-			bool extended_verification)
-{
-	EFI_ENTRY("%p, %d", this, extended_verification);
-
-	/* Empty input buffer */
-	while (tstc())
-		getc();
+static bool key_available;
+static struct efi_input_key next_key;
 
-	return EFI_EXIT(EFI_SUCCESS);
-}
-
-/*
- * Analyze modifiers (shift, alt, ctrl) for function keys.
+/**
+ * skip_modifiers() - analyze modifiers (shift, alt, ctrl) for function keys
+ *
  * This gets called when we have already parsed CSI.
  *
  * @modifiers:  bitmask (shift, alt, ctrl)
@@ -445,9 +436,13 @@ out:
 	return ret;
 }
 
-static efi_status_t EFIAPI efi_cin_read_key_stroke(
-			struct efi_simple_text_input_protocol *this,
-			struct efi_input_key *key)
+/**
+ * efi_cin_read_key() - read a key from the console input
+ *
+ * @key:	- key received
+ * Return:	- status code
+ */
+static efi_status_t efi_cin_read_key(struct efi_input_key *key)
 {
 	efi_status_t ret;
 	struct efi_input_key pressed_key = {
@@ -456,14 +451,9 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke(
 	};
 	s32 ch;
 
-	EFI_ENTRY("%p, %p", this, key);
-
-	/* We don't do interrupts, so check for timers cooperatively */
-	efi_timer_check();
-
 	ret = console_read_unicode(&ch);
 	if (ret)
-		return EFI_EXIT(EFI_NOT_READY);
+		return EFI_NOT_READY;
 	/* We do not support multi-word codes */
 	if (ch >= 0x10000)
 		ch = '?';
@@ -556,7 +546,109 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke(
 		pressed_key.unicode_char = ch;
 	*key = pressed_key;
 
-	return EFI_EXIT(EFI_SUCCESS);
+	return EFI_SUCCESS;
+}
+
+/**
+ * efi_cin_check() - check if keyboard input is available
+ */
+static void efi_cin_check(void)
+{
+	efi_status_t ret;
+
+	if (key_available) {
+		efi_signal_event(efi_con_in.wait_for_key, true);
+		return;
+	}
+
+	if (tstc()) {
+		ret = efi_cin_read_key(&next_key);
+		if (ret == EFI_SUCCESS) {
+			key_available = true;
+
+			/* Queue the wait for key event */
+			efi_signal_event(efi_con_in.wait_for_key, true);
+		}
+	}
+}
+
+/**
+ * efi_cin_reset() - drain the input buffer
+ *
+ * @this:			instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ * @extended_verification:	allow for exhaustive verification
+ * Return:			status code
+ *
+ * This function implements the Reset service of the
+ * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ */
+static efi_status_t EFIAPI efi_cin_reset
+			(struct efi_simple_text_input_protocol *this,
+			 bool extended_verification)
+{
+	efi_status_t ret = EFI_SUCCESS;
+
+	EFI_ENTRY("%p, %d", this, extended_verification);
+
+	/* Check parameters */
+	if (!this) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	/* Empty input buffer */
+	while (tstc())
+		getc();
+	key_available = false;
+out:
+	return EFI_EXIT(ret);
+}
+
+/**
+ * efi_cin_reset() - drain the input buffer
+ *
+ * @this:	instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ * @key:	key read from console
+ * Return:	status code
+ *
+ * This function implements the ReadKeyStroke service of the
+ * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ */
+static efi_status_t EFIAPI efi_cin_read_key_stroke
+			(struct efi_simple_text_input_protocol *this,
+			 struct efi_input_key *key)
+{
+	efi_status_t ret = EFI_SUCCESS;
+
+	EFI_ENTRY("%p, %p", this, key);
+
+	/* Check parameters */
+	if (!this || !key) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	/* We don't do interrupts, so check for timers cooperatively */
+	efi_timer_check();
+
+	/* Enable console input after ExitBootServices */
+	efi_cin_check();
+
+	if (!key_available) {
+		ret = EFI_NOT_READY;
+		goto out;
+	}
+	*key = next_key;
+	key_available = false;
+	efi_con_in.wait_for_key->is_signaled = false;
+out:
+	return EFI_EXIT(ret);
 }
 
 struct efi_simple_text_input_protocol efi_con_in = {
@@ -567,31 +659,38 @@ struct efi_simple_text_input_protocol efi_con_in = {
 
 static struct efi_event *console_timer_event;
 
-static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
-{
-}
-
 /*
- * Notification function of the console timer event.
+ * efi_console_timer_notify() - notify the console timer event
  *
- * event:	console timer event
- * context:	not used
+ * @event:	console timer event
+ * @context:	not used
  */
 static void EFIAPI efi_console_timer_notify(struct efi_event *event,
 					    void *context)
 {
 	EFI_ENTRY("%p, %p", event, context);
+	efi_cin_check();
+	EFI_EXIT(EFI_SUCCESS);
+}
 
-	/* Check if input is available */
-	if (tstc()) {
-		/* Queue the wait for key event */
-		efi_con_in.wait_for_key->is_signaled = true;
-		efi_signal_event(efi_con_in.wait_for_key, true);
-	}
+/**
+ * efi_key_notify() - notify the wait for key event
+ *
+ * @event:	wait for key event
+ * @context:	not used
+ */
+static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
+{
+	EFI_ENTRY("%p, %p", event, context);
+	efi_cin_check();
 	EFI_EXIT(EFI_SUCCESS);
 }
 
-/* This gets called from do_bootefi_exec(). */
+/**
+ * efi_console_register() - install the console protocols
+ *
+ * This function is called from do_bootefi_exec().
+ */
 int efi_console_register(void)
 {
 	efi_status_t r;
-- 
2.18.0

  parent reply	other threads:[~2018-09-11 20:38 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-11 20:38 [U-Boot] [PATCH v3 0/13] efi_loader: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 01/13] efi_loader: support Unicode text input Heinrich Schuchardt
2018-09-11 21:37   ` Alexander Graf
2018-09-11 21:51     ` [U-Boot] [PATCH v4 " Heinrich Schuchardt
2018-09-11 22:05     ` [U-Boot] [PATCH v5 1/13] " Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 02/13] test/py: Unicode w/ EFI_SIMPLE_TEXT_INPUT_PROTOCOL Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 03/13] efi_selftest: refactor text input test Heinrich Schuchardt
2018-09-11 20:38 ` Heinrich Schuchardt [this message]
2018-09-11 20:38 ` [U-Boot] [PATCH v3 05/13] efi_selftest: use WaitForKey to test text input Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 06/13] test/py: rework test_efi_selftest_text_input() Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 07/13] efi_loader: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 08/13] efi_loader: support modifiers for F1 - F4 Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 09/13] efi_selftest: test EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 10/13] test/py: " Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 11/13] efi_loader: implement key notify functions Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 12/13] efi_selftest: test key notification functions Heinrich Schuchardt
2018-09-11 20:38 ` [U-Boot] [PATCH v3 13/13] efi_loader: unset CONFIG_EFI_UNICODE_CAPITALIZATION Heinrich Schuchardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180911203814.16960-5-xypron.glpk@gmx.de \
    --to=xypron.glpk@gmx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.