I think we need the _EX version for SCT.. and either way we need to wire up the corresponding objects in the systab properly.
This fixes some issues with SCT.efi. Signed-off-by: Rob Clark <robdcl...@gmail.com> --- include/efi_api.h | 60 +++++++++++++++++++- include/efi_loader.h | 10 +--- lib/efi_loader/efi_boottime.c | 3 + lib/efi_loader/efi_console.c | 129 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 177 insertions(+), 25 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 5612dfad49..87c8ffe68e 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -242,11 +242,11 @@ struct efi_system_table { struct efi_table_hdr hdr; unsigned long fw_vendor; /* physical addr of wchar_t vendor string */ u32 fw_revision; - unsigned long con_in_handle; + efi_handle_t con_in_handle; struct efi_simple_input_interface *con_in; - unsigned long con_out_handle; + efi_handle_t con_out_handle; struct efi_simple_text_output_protocol *con_out; - unsigned long stderr_handle; + efi_handle_t stderr_handle; struct efi_simple_text_output_protocol *std_err; struct efi_runtime_services *runtime; struct efi_boot_services *boottime; @@ -473,6 +473,60 @@ struct efi_simple_input_interface { struct efi_event *wait_for_key; }; + +#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + EFI_GUID(0xdd9e7534, 0x7762, 0x4698, \ + 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa) + +/* key-shift state: */ +#define EFI_SHIFT_STATE_VALID 0x80000000 +#define EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define EFI_RIGHT_ALT_PRESSED 0x00000010 +#define EFI_EFI_LEFT_ALT_PRESSED 0x00000020 +#define EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define EFI_LEFT_LOGO_PRESSED 0x00000080 +#define EFI_MENU_KEY_PRESSED 0x00000100 +#define EFI_SYS_REQ_PRESSED 0x00000200 + +/* key-toggle state: */ +#define EFI_TOGGLE_STATE_VALID 0x80 +#define EFI_SCROLL_LOCK_ACTIVE 0x01 +#define EFI_NUM_LOCK_ACTIVE 0x02 +#define EFI_CAPS_LOCK_ACTIVE 0x04 + +struct efi_key_state { + uint32_t key_shift_state; + uint8_t key_toggle_state; +}; + +struct efi_key_data { + struct efi_input_key key; + struct efi_key_state key_state; +}; + +struct efi_simple_text_input_ex_interface { + efi_status_t (EFIAPI *reset)( + struct efi_simple_text_input_ex_interface *this, + bool ExtendedVerification); + efi_status_t (EFIAPI *read_key_stroke)( + struct efi_simple_text_input_ex_interface *this, + struct efi_key_data *key_data); + struct efi_event *wait_for_key; + efi_status_t (EFIAPI *set_state)( + struct efi_simple_text_input_ex_interface *this, + uint8_t key_toggle_state); + efi_status_t (EFIAPI *register_key_notify)( + struct efi_simple_text_input_ex_interface *this, + efi_status_t (EFIAPI *notify_fn)(struct efi_key_data *key_data), + efi_handle_t *notify_handle); + efi_status_t (EFIAPI *unregister_key_notify)( + struct efi_simple_text_input_ex_interface *this, + efi_handle_t notify_handle); +}; + #define CONSOLE_CONTROL_GUID \ EFI_GUID(0xf42f7782, 0x12e, 0x4c12, \ 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21) diff --git a/include/efi_loader.h b/include/efi_loader.h index 4864b3ac77..72734b3a44 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -54,7 +54,9 @@ const char *__efi_nesting_dec(void); extern struct efi_runtime_services efi_runtime_services; extern struct efi_system_table systab; +extern struct efi_object efi_console_output_obj; extern const struct efi_simple_text_output_protocol efi_con_out; +extern struct efi_object efi_console_input_obj; 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; @@ -108,14 +110,6 @@ struct efi_object { void *handle; }; -#define EFI_PROTOCOL_OBJECT(_guid, _protocol) (struct efi_object){ \ - .protocols = {{ \ - .guid = &(_guid), \ - .protocol_interface = (void *)(_protocol), \ - }}, \ - .handle = (void *)(_protocol), \ -} - /** * struct efi_event * diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 7b53570354..9628bef474 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1394,8 +1394,11 @@ struct efi_system_table __efi_runtime_data systab = { .headersize = sizeof(struct efi_table_hdr), }, .fw_vendor = (long)firmware_vendor, + .con_in_handle = &efi_console_input_obj, .con_in = (void*)&efi_con_in, + .con_out_handle = &efi_console_output_obj, .con_out = (void*)&efi_con_out, + .stderr_handle = &efi_console_output_obj, .std_err = (void*)&efi_con_out, .runtime = (void*)&efi_runtime_services, .boottime = (void*)&efi_boot_services, diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index afc725a2c7..2e13fdc096 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -50,6 +50,10 @@ const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID; #define cESC '\x1b' #define ESC "\x1b" +/* + * EFI_CONSOLE_CONTROL: + */ + static efi_status_t EFIAPI efi_cin_get_mode( struct efi_console_control_protocol *this, int *mode, char *uga_exists, char *std_in_locked) @@ -97,6 +101,11 @@ static struct simple_text_output_mode efi_con_mode = { .cursor_visible = 1, }; + +/* + * EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL: + */ + static int term_read_reply(int *n, int maxnum, char end_char) { char c; @@ -364,6 +373,11 @@ const struct efi_simple_text_output_protocol efi_con_out = { .mode = (void*)&efi_con_mode, }; + +/* + * EFI_SIMPLE_TEXT_INPUT_PROTOCOL: + */ + static efi_status_t EFIAPI efi_cin_reset( struct efi_simple_input_interface *this, bool extended_verification) @@ -372,9 +386,7 @@ static efi_status_t EFIAPI efi_cin_reset( return EFI_EXIT(EFI_UNSUPPORTED); } -static efi_status_t EFIAPI efi_cin_read_key_stroke( - struct efi_simple_input_interface *this, - struct efi_input_key *key) +static efi_status_t read_key_stroke(struct efi_key_data *key_data) { struct efi_input_key pressed_key = { .scan_code = 0, @@ -382,14 +394,12 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke( }; char ch; - EFI_ENTRY("%p, %p", this, key); - /* We don't do interrupts, so check for timers cooperatively */ efi_timer_check(); if (!tstc()) { /* No key pressed */ - return EFI_EXIT(EFI_NOT_READY); + return EFI_NOT_READY; } ch = getc(); @@ -438,9 +448,31 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke( ch = 0x08; } pressed_key.unicode_char = ch; - *key = pressed_key; + key_data->key = pressed_key; - return EFI_EXIT(EFI_SUCCESS); + /* TODO not sure if we have a way to get this from stdin? + * We might need to use keyboard driver directly for _ex + * stuff? + */ + memset(&key_data->key_state, 0, sizeof(key_data->key_state)); + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI efi_cin_read_key_stroke( + struct efi_simple_input_interface *this, + struct efi_input_key *key) +{ + struct efi_key_data key_data; + efi_status_t ret; + + EFI_ENTRY("%p, %p", this, key); + + ret = read_key_stroke(&key_data); + if (ret == EFI_SUCCESS) + *key = key_data.key; + + return EFI_EXIT(ret); } struct efi_simple_input_interface efi_con_in = { @@ -465,12 +497,81 @@ static void EFIAPI efi_console_timer_notify(struct efi_event *event, } -static struct efi_object efi_console_control_obj = - EFI_PROTOCOL_OBJECT(efi_guid_console_control, &efi_console_control); -static struct efi_object efi_console_output_obj = - EFI_PROTOCOL_OBJECT(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, &efi_con_out); -static struct efi_object efi_console_input_obj = - EFI_PROTOCOL_OBJECT(EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, &efi_con_in); +/* + * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL + */ + +static efi_status_t EFIAPI efi_cin_ex_reset( + struct efi_simple_text_input_ex_interface *this, + bool extended_verification) +{ + EFI_ENTRY("%p, %d", this, extended_verification); + return EFI_EXIT(EFI_UNSUPPORTED); +} + +static efi_status_t EFIAPI efi_cin_ex_read_key_stroke( + struct efi_simple_text_input_ex_interface *this, + struct efi_key_data *key_data) +{ + EFI_ENTRY("%p, %p", this, key_data); + return EFI_EXIT(read_key_stroke(key_data)); +} + +static efi_status_t EFIAPI efi_cin_ex_set_state( + struct efi_simple_text_input_ex_interface *this, + uint8_t key_toggle_state) +{ + EFI_ENTRY("%p, %x", this, key_toggle_state); + return EFI_EXIT(EFI_SUCCESS); +} + +static efi_status_t EFIAPI efi_cin_ex_register_key_notify( + struct efi_simple_text_input_ex_interface *this, + efi_status_t (EFIAPI *notify_fn)(struct efi_key_data *key_data), + efi_handle_t *notify_handle) +{ + EFI_ENTRY("%p, %p, %p", this, notify_fn, notify_handle); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI efi_cin_ex_unregister_key_notify( + struct efi_simple_text_input_ex_interface *this, + efi_handle_t notify_handle) +{ + EFI_ENTRY("%p, %p", this, notify_handle); + return EFI_EXIT(EFI_INVALID_PARAMETER); +} + +static struct efi_simple_text_input_ex_interface efi_con_in_ex = { + .reset = efi_cin_ex_reset, + .read_key_stroke = efi_cin_ex_read_key_stroke, + .wait_for_key = NULL, + .set_state = efi_cin_ex_set_state, + .register_key_notify = efi_cin_ex_register_key_notify, + .unregister_key_notify = efi_cin_ex_unregister_key_notify, +}; + +static struct efi_object efi_console_control_obj = { + .protocols = { + { &efi_guid_console_control, (void *)&efi_console_control }, + }, + .handle = &efi_console_control_obj, +}; + +struct efi_object efi_console_output_obj = { + .protocols = { + {&EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, (void *)&efi_con_out}, + }, + .handle = &efi_console_output_obj, +}; + +struct efi_object efi_console_input_obj = { + .protocols = { + {&EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, (void *)&efi_con_in}, + {&EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID, (void *)&efi_con_in_ex}, + }, + .handle = &efi_console_input_obj, +}; /* This gets called from do_bootefi_exec(). */ int efi_console_register(void) -- 2.13.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot