efi_console: set up events

Set up a timer event and the WaitForKey event.
In the notify function of the timer event check for console input
and signal the WaitForKey event accordingly.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 8ef7326..dbe98ac 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -421,8 +421,46 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-const struct efi_simple_input_interface efi_con_in = {
+struct efi_simple_input_interface efi_con_in = {
 	.reset = efi_cin_reset,
 	.read_key_stroke = efi_cin_read_key_stroke,
 	.wait_for_key = NULL,
 };
+
+static struct efi_event *console_timer_event;
+
+static void efi_key_notify(struct efi_event *event, void *context)
+{
+}
+
+static void efi_console_timer_notify(struct efi_event *event, void *context)
+{
+	EFI_ENTRY("%p, %p", event, context);
+	if (tstc())
+		efi_signal_event(efi_con_in.wait_for_key);
+	EFI_EXIT(EFI_SUCCESS);
+}
+
+/* This gets called from do_bootefi_exec(). */
+int efi_console_register(void)
+{
+	efi_status_t r;
+	r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK,
+			     efi_key_notify, NULL, &efi_con_in.wait_for_key);
+	if (r != EFI_SUCCESS) {
+		printf("ERROR: Failed to register WaitForKey event\n");
+		return r;
+	}
+	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+			     efi_console_timer_notify, NULL,
+			     &console_timer_event);
+	if (r != EFI_SUCCESS) {
+		printf("ERROR: Failed to register console event\n");
+		return r;
+	}
+	/* 5000 ns cycle is sufficient for 2 MBaud */
+	r = efi_set_timer(console_timer_event, EFI_TIMER_PERIODIC, 50);
+	if (r != EFI_SUCCESS)
+		printf("ERROR: Failed to set console timer\n");
+	return r;
+}