From patchwork Thu Nov 1 04:47:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 149926 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp349567ljp; Wed, 31 Oct 2018 21:47:34 -0700 (PDT) X-Google-Smtp-Source: AJdET5fTwVEXbhGjN25xhEHE9bEnstUyIns7UbVN3uDiBPxUGJWL/nXf9ve5EPFD/MTst+Xu03X/ X-Received: by 2002:a50:8664:: with SMTP id 33-v6mr4170985edt.40.1541047654583; Wed, 31 Oct 2018 21:47:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1541047654; cv=none; d=google.com; s=arc-20160816; b=R+Q2eUFELFJNLcIQzYNvxI1mTgzMmeImUC8i0r8meKLEfH8iO1m6VS4Q03gtUaDTP3 bO6Uo3fAXW+xlw3DUlbuMDE0YVCxd6EpP5GCmeM0zHygKdqXIPs7sqD/VgDPxnjzhu9Q 402mqcEIvY40beFmKhyWx0GkX8Yu4N6rRlLjIQvamP6E4xuknwXFwORhY0NXeG++jaLN yGRjpUQrqDBjhxNiwbyv08VFMCF7SELZ3V5AfDskCAG56wNnMsHwnzuFjnhh4mfcghl2 AyftEzsN/v2LYMfD5JrfmUhRRCJP13A2EBQrGA59P3e5ZoWbXh9f5Xn1xTfmc2aY2e5q 3twQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :cc:mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature; bh=a0z45yz7x0hm1tMClBmjHKMVuD3b74VHY29oGRQV8oc=; b=aTzOYlfua1lvdDTiHOEDJkAWwzab+JmPa6MnOoFVW0o1psKPP/IZYkHULd28UOCI8A XMXPPyFXmF0MtCOpSVdV2PXeh+T+E2zvzxf3mX2OypkoLlF3/CL3aWRQd5L9yUiR+wAW hOrwV1u2lV8b17PeG80hgTzU5PFVQ5iMfOdLcBL1rmRzHj6RohUhUsPnsVB7Tfy/Nj2y d+lj6g2eGEOA8FO4TZFYu84hxLrlMUgi2StHJx+Uvn5qdp0HGDVwR6tkYe4Z3N1q/Siz PGNFUu7pso4iUYPeCysXdrFT43TF+3gqRxycaEPi7ik3zEGelko1L8XTfUom7q6Vy8Ag L36A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QaeYCWV4; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id s3-v6si1881274eds.341.2018.10.31.21.47.34; Wed, 31 Oct 2018 21:47:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QaeYCWV4; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.denx.de (Postfix, from userid 105) id 3A1F5C222D9; Thu, 1 Nov 2018 04:46:56 +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=RCVD_IN_MSPIKE_H2, 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 AE7CBC222E8; Thu, 1 Nov 2018 04:45:42 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7B8EEC22341; Thu, 1 Nov 2018 04:45:41 +0000 (UTC) Received: from mail-yb1-f193.google.com (mail-yb1-f193.google.com [209.85.219.193]) by lists.denx.de (Postfix) with ESMTPS id 01727C2232E for ; Thu, 1 Nov 2018 04:45:28 +0000 (UTC) Received: by mail-yb1-f193.google.com with SMTP id o204-v6so7617316yba.9 for ; Wed, 31 Oct 2018 21:45:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OJA7R5l9U2oJYohFWTC05WFXnXYhArM9Jll3eS+gdi4=; b=QaeYCWV4/suSrVB9GJ6LKrkqUSejLkcc+mWtfYrcERJzAJsBp98hkBQqV0YYtnDDjw joLYZXiuo50K51jQYVn/HZ8ZNudmBSNLTe0Ku81Llk2TAXOOYOT5t9ntvTdEnG11eYUR DIpE8LRf/GAg+Zwwpe1DJwIddKr2uC8MYCATo= 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:mime-version:content-transfer-encoding; bh=OJA7R5l9U2oJYohFWTC05WFXnXYhArM9Jll3eS+gdi4=; b=Jnhst+1+vjehBjnx48NtneGXouc9Kmwqva6E9WLsktzOXgcNPcLLq7JEUoklI16zSF ryyQ7SerMhrDALiIjv53+aSz5bHLlQryAUj9vWtFNnoS41LQUN9eekXg5oRtzxG7OVwA ZLNFqVi3JYcgd7/mKhKF0cOa03rgNZlC4w3rrATFH9Pp5+MN6tf6NeOmdsqDITmb4s0A j6rTLsACeMPesm3K5D96dmr8mgQovmSjzagjLDBFSCe+HAWmntozDUrdRJEQQp2FogTP TL4H9+P+KEwezH2/gnGr7vTI7l5bAyox+UVF+j7njbxhFqXJTFkuJFB1RPf7JD2ODXgd sXUA== X-Gm-Message-State: AGRZ1gKuCkQuwi8IN09SXlDcElN5KmJeQ4R2qr5BBccSntpjHoYJwJLR +2jih6uyM4uFp4bx1k35G6pEitQQoUo= X-Received: by 2002:a25:2386:: with SMTP id j128-v6mr6056204ybj.137.1541047526822; Wed, 31 Oct 2018 21:45:26 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id j2-v6sm7471491ywe.92.2018.10.31.21.45.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Oct 2018 21:45:26 -0700 (PDT) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Thu, 1 Nov 2018 13:47:44 +0900 Message-Id: <20181101044746.19977-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181101044746.19977-1-takahiro.akashi@linaro.org> References: <20181101044039.19755-1-takahiro.akashi@linaro.org> <20181101044746.19977-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: xypron.glpk@gmx.de, u-boot@lists.denx.de Subject: [U-Boot] [PATCH 4/6] efi: hii: add keyboard layout package support 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Allow for handling keyboard layout package in HII database protocol. A package can be added or deleted in HII database protocol, but we don't set 'current' keyboard layout as there is no driver that requests a keyboard layout. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 11 +++ lib/efi_loader/efi_hii.c | 141 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index c51b83ca4ec7..36764a5c6bbb 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -835,6 +835,17 @@ struct efi_hii_guid_package { char data[]; } __packed; +/* + * Keyboard layout package + */ + +struct efi_hii_keyboard_layout_package { + struct efi_hii_package_header header; + u8 layout_count; + u8 __pad; + struct efi_hii_keyboard_layout layout[]; +} __packed; + typedef void *efi_hii_handle_t; struct efi_hii_database_protocol { diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c index 036aa8eac956..fefe3a861387 100644 --- a/lib/efi_loader/efi_hii.c +++ b/lib/efi_loader/efi_hii.c @@ -17,6 +17,7 @@ const efi_guid_t efi_guid_hii_string_protocol = EFI_HII_STRING_PROTOCOL_GUID; const u32 hii_package_signature = 0x68696770; /* "higp" */ static LIST_HEAD(efi_package_lists); +static LIST_HEAD(efi_kb_layout_list); struct efi_hii_packagelist { struct list_head link; @@ -26,6 +27,7 @@ struct efi_hii_packagelist { u32 max_string_id; struct list_head string_tables; /* list of efi_string_table */ struct list_head guid_list; + struct list_head kb_layout_packages; /* we could also track fonts, images, etc */ }; @@ -53,6 +55,17 @@ struct efi_guid_data { struct efi_hii_guid_package package; }; +struct efi_kb_layout_data { + struct list_head link; /* in package */ + struct list_head link_sys; /* in global list */ + struct efi_hii_keyboard_layout kb_layout; +}; + +struct efi_kb_layout_package_data { + struct list_head link; /* in package_list */ + struct list_head kb_layout_list; +}; + static void free_strings_table(struct efi_string_table *stbl) { int i; @@ -213,6 +226,74 @@ add_guid_package(struct efi_hii_packagelist *hii, return EFI_SUCCESS; } +static void free_keyboard_layouts(struct efi_kb_layout_package_data *package) +{ + struct efi_kb_layout_data *data; + + while (!list_empty(&package->kb_layout_list)) { + data = list_first_entry(&package->kb_layout_list, + struct efi_kb_layout_data, + link); + list_del(&data->link); + list_del(&data->link_sys); + free(data); + } +} + +static void remove_keyboard_layout_package(struct efi_hii_packagelist *hii) +{ + struct efi_kb_layout_package_data *package; + + while (!list_empty(&hii->kb_layout_packages)) { + package = list_first_entry(&hii->kb_layout_packages, + struct efi_kb_layout_package_data, + link); + free_keyboard_layouts(package); + list_del(&package->link); + free(package); + } +} + +static efi_status_t +add_keyboard_layout_package(struct efi_hii_packagelist *hii, + struct efi_hii_keyboard_layout_package + *kb_layout_package) +{ + struct efi_kb_layout_package_data *package; + struct efi_hii_keyboard_layout *layout; + struct efi_kb_layout_data *data; + int i; + + package = malloc(sizeof(*package)); + if (!package) + return EFI_OUT_OF_RESOURCES; + INIT_LIST_HEAD(&package->link); + INIT_LIST_HEAD(&package->kb_layout_list); + + layout = &kb_layout_package->layout[0]; + for (i = 0; i < kb_layout_package->layout_count; i++) { + data = malloc(sizeof(*data) + layout->layout_length); + if (!data) + goto out; + + memcpy(&data->kb_layout, layout, layout->layout_length); + list_add_tail(&data->link, &package->kb_layout_list); + list_add_tail(&data->link_sys, &efi_kb_layout_list); + + layout += layout->layout_length; + } + + list_add_tail(&package->link, &hii->kb_layout_packages); + + return EFI_SUCCESS; + +out: + free_keyboard_layouts(package); + free(package); + + return EFI_OUT_OF_RESOURCES; +} + static struct efi_hii_packagelist *new_packagelist(void) { struct efi_hii_packagelist *hii; @@ -222,6 +303,7 @@ static struct efi_hii_packagelist *new_packagelist(void) hii->max_string_id = 0; INIT_LIST_HEAD(&hii->string_tables); INIT_LIST_HEAD(&hii->guid_list); + INIT_LIST_HEAD(&hii->kb_layout_packages); return hii; } @@ -230,6 +312,7 @@ static void free_packagelist(struct efi_hii_packagelist *hii) { remove_strings_package(hii); remove_guid_package(hii); + remove_keyboard_layout_package(hii); list_del(&hii->link); free(hii); @@ -284,8 +367,9 @@ add_packages(struct efi_hii_packagelist *hii, ret = EFI_INVALID_PARAMETER; break; case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: - printf("\tKeyboard layout package not supported\n"); - ret = EFI_INVALID_PARAMETER; + ret = add_keyboard_layout_package(hii, + (struct efi_hii_keyboard_layout_package *) + package); break; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -418,7 +502,7 @@ update_package_list(const struct efi_hii_database_protocol *this, ret = EFI_INVALID_PARAMETER; break; case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: - printf("\tKeyboard layout package not supported\n"); + remove_keyboard_layout_package(hii); break; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -506,7 +590,8 @@ list_package_lists(const struct efi_hii_database_protocol *this, ret = EFI_INVALID_PARAMETER; continue; case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: - printf("\tKeyboard layout package not supported\n"); + if (!list_empty(&hii->kb_layout_packages)) + break; continue; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -580,9 +665,29 @@ find_keyboard_layouts(const struct efi_hii_database_protocol *this, u16 *key_guid_buffer_length, efi_guid_t *key_guid_buffer) { + struct efi_kb_layout_data *data; + int package_cnt, package_max; + efi_status_t ret = EFI_SUCCESS; + EFI_ENTRY("%p, %p, %p", this, key_guid_buffer_length, key_guid_buffer); - return EFI_EXIT(EFI_NOT_FOUND); + if (!key_guid_buffer_length || + (*key_guid_buffer_length && !key_guid_buffer)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + package_cnt = 0; + package_max = *key_guid_buffer_length / sizeof(*key_guid_buffer); + list_for_each_entry(data, &efi_kb_layout_list, link_sys) { + package_cnt++; + if (package_cnt <= package_max) + memcpy(key_guid_buffer++, &data->kb_layout.guid, + sizeof(*key_guid_buffer)); + else + ret = EFI_BUFFER_TOO_SMALL; + } + *key_guid_buffer_length = package_cnt * sizeof(*key_guid_buffer); + + return EFI_EXIT(ret); } static efi_status_t EFIAPI @@ -591,10 +696,36 @@ get_keyboard_layout(const struct efi_hii_database_protocol *this, u16 *keyboard_layout_length, struct efi_hii_keyboard_layout *keyboard_layout) { + struct efi_kb_layout_data *data; + EFI_ENTRY("%p, %pUl, %p, %p", this, key_guid, keyboard_layout_length, keyboard_layout); + if (!keyboard_layout_length || + (*keyboard_layout_length && !keyboard_layout)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + /* TODO: no notion of current keyboard layout */ + if (!key_guid) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + list_for_each_entry(data, &efi_kb_layout_list, link_sys) { + if (!guidcmp(&data->kb_layout.guid, key_guid)) + goto found; + } + return EFI_EXIT(EFI_NOT_FOUND); + +found: + if (*keyboard_layout_length < data->kb_layout.layout_length) { + *keyboard_layout_length = data->kb_layout.layout_length; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + memcpy(keyboard_layout, &data->kb_layout, + sizeof(data->kb_layout.layout_length)); + + return EFI_EXIT(EFI_SUCCESS); } static efi_status_t EFIAPI