efi_console: set up events
authorxypron.glpk@gmx.de <xypron.glpk@gmx.de>
Tue, 18 Jul 2017 18:17:22 +0000 (20:17 +0200)
committerAlexander Graf <agraf@suse.de>
Wed, 19 Jul 2017 12:36:04 +0000 (14:36 +0200)
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>
cmd/bootefi.c
include/efi_loader.h
lib/efi_loader/efi_boottime.c
lib/efi_loader/efi_console.c

index 08c60e6fa9dea71a3ee8c01f4d3c47ccda77defa..e9f14d54af381fa3b9c33b8931090d11d3156bb7 100644 (file)
@@ -226,6 +226,7 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
        INIT_LIST_HEAD(&efi_obj_list);
        list_add_tail(&loaded_image_info_obj.link, &efi_obj_list);
        list_add_tail(&bootefi_device_obj.link, &efi_obj_list);
+       efi_console_register();
 #ifdef CONFIG_PARTITIONS
        efi_disk_register();
 #endif
index 342e960d145df8b1e1707779222e7187f5403f42..2abb6b87e17acbbfcc8449d41c00664182c5a838 100644 (file)
@@ -26,7 +26,7 @@ extern struct efi_runtime_services efi_runtime_services;
 extern struct efi_system_table systab;
 
 extern const struct efi_simple_text_output_protocol efi_con_out;
-extern const struct efi_simple_input_interface efi_con_in;
+extern struct efi_simple_input_interface efi_con_in;
 extern const struct efi_console_control_protocol efi_console_control;
 extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;
 
@@ -90,6 +90,8 @@ struct efi_event {
 /* This list contains all UEFI objects we know of */
 extern struct list_head efi_obj_list;
 
+/* Called by bootefi to make console interface available */
+int efi_console_register(void);
 /* Called by bootefi to make all disk storage accessible as EFI objects */
 int efi_disk_register(void);
 /* Called by bootefi to make GOP (graphical) interface available */
@@ -125,6 +127,8 @@ efi_status_t efi_create_event(enum efi_event_type type, UINTN notify_tpl,
 /* Call this to set a timer */
 efi_status_t efi_set_timer(struct efi_event *event, int type,
                           uint64_t trigger_time);
+/* Call this to signal an event */
+void efi_signal_event(struct efi_event *event);
 
 /* Generic EFI memory allocator, call this to get memory */
 void *efi_alloc(uint64_t len, int memory_type);
index 4cd06b3c4c22b219cc698fad69ac9977e354e87b..b8dfceae0c003b529c16e3449f3532d3def93a16 100644 (file)
@@ -81,7 +81,7 @@ efi_status_t efi_exit_func(efi_status_t ret)
        return ret;
 }
 
-static void efi_signal_event(struct efi_event *event)
+void efi_signal_event(struct efi_event *event)
 {
        if (event->signaled)
                return;
index 8ef7326fef2ec04df0da7866947cb047aca5d298..dbe98ac08b8c10cb2c597a54cbe61dee8a4fe489 100644 (file)
@@ -421,8 +421,46 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke(
        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;
+}