From patchwork Sun Sep 10 13:22:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 812144 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="F7lczsdj"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqsLN5CCQz9s7g for ; Sun, 10 Sep 2017 23:27:40 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 79411C21F0D; Sun, 10 Sep 2017 13:26:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 237FCC21F74; Sun, 10 Sep 2017 13:24:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 939DFC21E40; Sun, 10 Sep 2017 13:23:16 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id 47904C21EE4 for ; Sun, 10 Sep 2017 13:23:07 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id u48so1297462qtc.4 for ; Sun, 10 Sep 2017 06:23:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=r5ZC6/3pNXKFsf7NlBcHZ0Vu14dwXZhcZy36GpjGa6Y=; b=F7lczsdjBeFxI7OPnOg5/c7Tub9mQC2wEosD5Qg1uUcpa5MS11Y8T3jCQOcAQdi0cE LgGB9fl2Ol0ChPWFl90pPc8yZ2QKXih/mYT/4nWLD6uXwWK50a83veHwWKCXdzmHAdKh gCCAn6cEtKtN+1cPN1He7hKanxXVwgF1JbFB98V1G+YNwIp6jSQP0CyyDDRkHYRRQBUp g/zOJtj9yG15ylt1m2Lt+RO5YKqp0ubO0Mwa370OMNIo3/ta70h9Zq2qV2nFKfBqCILd Xt1kwQt3fvw2aBGp74tewLjnTCs3mrWb/yrAERAFSmVlBoq7VFZAGAiz++dTti+HcAZU eHpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r5ZC6/3pNXKFsf7NlBcHZ0Vu14dwXZhcZy36GpjGa6Y=; b=GML14R1zaXhKc9FkBN7hBA9PM4hjPiVEfEF8Rc4kkI4Cq5rK3q5wwSkZHvHxdI+Gup jp+tkCNmOAxmnjWFe1fh/tYlZG0NEB/0EAwJSNAAM2uoNIU1AMn1mQSfn82bKKkA78QS n2opIzF5jT1GeEg8Uv1/P/WWjPCvrD+L3YgO292nIP4hSzGewqBE0j/AbpNjTKCyPRvR GIVdCbMCFCA9oy/azS40C6UbA+clnjfO+BcnMoakuIVBJyY5l7zKbVt24jVRXGDqpwEo EoLtjvOBHhGIp3Vl40VKr7tIS6y8ihzNSHDaTHhugggqin2XGtlL+/gO9g0I/Bt6Trsb qC7A== X-Gm-Message-State: AHPjjUhLoe0+6+hn49WcuXuF+NcXoqP1aTqPrErE7oIsoHyFqH3spjGA kAO7RErq1RRWlJOmJ9U= X-Google-Smtp-Source: AOwi7QBUJpCpsdvi8sOdpO41hnmfAgp/NTPyIomsJlLU4pG5h3N1WeKp5xffNoF/+rbyu4YicW2kJA== X-Received: by 10.200.36.78 with SMTP id d14mr7744473qtd.136.1505049785822; Sun, 10 Sep 2017 06:23:05 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id l19sm5248416qkl.31.2017.09.10.06.23.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 10 Sep 2017 06:23:04 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sun, 10 Sep 2017 09:22:28 -0400 Message-Id: <20170910132236.14318-8-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170910132236.14318-1-robdclark@gmail.com> References: <20170910132236.14318-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones , Leif Lindholm Subject: [U-Boot] [PATCH v1 07/12] efi_loader: SIMPLE_TEXT_INPUT_EX plus wire up objects properly X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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 --- 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)