From patchwork Mon Jan 21 03:12:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 156141 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp5899947jaa; Sun, 20 Jan 2019 19:14:18 -0800 (PST) X-Google-Smtp-Source: ALg8bN4RHWtFqNizq9N7SQ1dhxi0wx0vAe85eJin/tk7oVL5ixWZuk+BmWnAI3IkS3ar7geDIpgY X-Received: by 2002:a50:8b41:: with SMTP id l59mr25073278edl.44.1548040458106; Sun, 20 Jan 2019 19:14:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548040458; cv=none; d=google.com; s=arc-20160816; b=hmmLevSj3gBXj7d9hkrWnLaNz2QmqswsZ/9UQRXTa+rEpdyoCdqkXk4yCB+SP1/cRW ZfjZYbw87qDu6BQSLbvoOa7Hbbfa/Qf93xwFTl3CW9IOyhNHclpzwJdy5vfgSY5qK+xn 7JhwZczCa1Qox4LIWSGZjQLRcdkBXanl10hKfm/eehJqNzIJV0u8oNmyxUOqBmLkoMmh 7jIcYM+y7Ob3oz7A3CkISPQrJXUQbimP/Czun4Agn9vVv1D9AeC58qDG6Wkv5vkS/QMk mhCFp3cF9Nc0Us6iMRJbJ5gCtpKvkoZ0Sy7xCZDW2ruGoOmkCsF6ch4BzjGkJTDA3JBz VNxg== 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=U2BiOdWqWo5Z0pSV8fiQj41gnMsixFRNLUmfRFI5c/w=; b=s6wPlUbHoR6oeAK0Qg5YwGmmHZUyS6+/3puE1vkgojGx5qBovWkBZOh5pvmvERh2uk Bw6vckqGKDAbRCHo7Qqxr+QsfHPIeb2QYXSuR4JSfOEdLxScSnCfnp38KnhkF7hFznlj v87XJoH2BCtBlt3Z0P091Iq+HD2byAF1kfs0lxxVEprXNNfhdC5fcIepHKCyK++dmwYu tcrFh51xH06RnWYASr3Ug7vEd7cM2V+2lJJJb18WWes64UasAnjeW/c1u1ctONCboGa5 MdkFJhgXBNCIJtJw51zpZX42CE0bQI8UHo7TXNw/0ZK9vgxg0P8OJdMewKDW5ETx4K26 BjrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=bg+ZXHlA; 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 r24si1784565edi.201.2019.01.20.19.14.17; Sun, 20 Jan 2019 19:14:18 -0800 (PST) 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=bg+ZXHlA; 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 96A85C21E60; Mon, 21 Jan 2019 03:14:17 +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_DNSWL_BLOCKED, 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 00492C21DFA; Mon, 21 Jan 2019 03:13:16 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 706CAC21E4E; Mon, 21 Jan 2019 03:13:02 +0000 (UTC) Received: from mail-yw1-f68.google.com (mail-yw1-f68.google.com [209.85.161.68]) by lists.denx.de (Postfix) with ESMTPS id F01B6C21DA6 for ; Mon, 21 Jan 2019 03:12:58 +0000 (UTC) Received: by mail-yw1-f68.google.com with SMTP id x2so7517026ywc.9 for ; Sun, 20 Jan 2019 19:12:58 -0800 (PST) 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=K9ePgqSZ/nEuzOZQl3r+uGUg2ZHLttC+u3EnL9bYcr8=; b=bg+ZXHlAborD+hbg3p7K1utiPmMmEdbdSWjF/lpzgXztm6KqrkCXoOgwco/tg/g1VI Wb6wh2rsosUljx+fYledl6zEoZUv1wVOXop8gB11TbVHvE91mJFPjvJ+eZIUC4hAImqT 13McFvH4nqrUXA8IAZ07snfB1XRlwhY269vSo= 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=K9ePgqSZ/nEuzOZQl3r+uGUg2ZHLttC+u3EnL9bYcr8=; b=btCcCJETYCFHqt/YhVTed8E+DkaU9xtWWrV8Kv1kLGxgsMWOXPzgsVkLngKuIqSbOg cdFm5OGq3rxHNejj33W5FKd3VMNRiUDWSQWaak5b+wtcy2+cuQclGNL15uHfgcdcA9pE lqh4TO2xM8rvtPqGXZ8t5AuXMmf/w/S6EBnC7KaUuu9X/ZFAActS7XYc6tzJFL6L6D4P BquYGS+vs7Rtj+7ZTI+jB9qeoa5TtmrqrI7VIbXDrjZ9Gp4k3GFTN21tRhH7vL8vpIkj 5lk5pt4y9owP04CJxPRxN56m+d+jmM6L12uszbFeLWB7p0VOPmjD3m8BokcXwVqLB9Y4 Pv+Q== X-Gm-Message-State: AJcUukdrHbev+Kv+yy9U2Lxzu1GbE7/dAuIqCiROd14Xl2iy2d9/gtIW Y2GstxrBOLRGFlIR592pLQje0wm5Z4M= X-Received: by 2002:a81:9ad5:: with SMTP id r204mr26580725ywg.215.1548040377872; Sun, 20 Jan 2019 19:12:57 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id x9sm4913433ywc.8.2019.01.20.19.12.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 19:12:57 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de, xypron.glpk@gmx.de Date: Mon, 21 Jan 2019 12:12:59 +0900 Message-Id: <20190121031301.1808-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190121031301.1808-1-takahiro.akashi@linaro.org> References: <20190121031301.1808-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v3 3/5] 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 | 6 ++ lib/efi_loader/efi_hii.c | 147 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 148 insertions(+), 5 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index b2e77832a756..46a86535a83d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -842,6 +842,12 @@ struct efi_hii_keyboard_layout { struct efi_key_descriptor descriptors[]; } __packed; +struct efi_hii_keyboard_package { + struct efi_hii_package_header header; + u16 layout_count; + struct efi_hii_keyboard_layout layout[]; +} __packed; + /* * HII protocols */ diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c index d7cd0c4f0fc6..89e1a6c2369c 100644 --- a/lib/efi_loader/efi_hii.c +++ b/lib/efi_loader/efi_hii.c @@ -16,6 +16,7 @@ const efi_guid_t efi_guid_hii_database_protocol const efi_guid_t efi_guid_hii_string_protocol = EFI_HII_STRING_PROTOCOL_GUID; static LIST_HEAD(efi_package_lists); +static LIST_HEAD(efi_keyboard_layout_list); struct efi_hii_packagelist { struct list_head link; @@ -24,6 +25,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 keyboard_packages; /* we could also track fonts, images, etc */ }; @@ -86,6 +88,17 @@ struct efi_guid_data { struct efi_hii_guid_package package; }; +struct efi_keyboard_layout_data { + struct list_head link; /* in package */ + struct list_head link_sys; /* in global list */ + struct efi_hii_keyboard_layout keyboard_layout; +}; + +struct efi_keyboard_package_data { + struct list_head link; /* in package_list */ + struct list_head keyboard_layout_list; +}; + static void free_strings_table(struct efi_string_table *stbl) { int i; @@ -253,6 +266,78 @@ add_guid_package(struct efi_hii_packagelist *hii, return EFI_SUCCESS; } +static void free_keyboard_layouts(struct efi_keyboard_package_data *package) +{ + struct efi_keyboard_layout_data *layout_data; + + while (!list_empty(&package->keyboard_layout_list)) { + layout_data = list_first_entry(&package->keyboard_layout_list, + struct efi_keyboard_layout_data, + link); + list_del(&layout_data->link); + list_del(&layout_data->link_sys); + free(layout_data); + } +} + +static void remove_keyboard_package(struct efi_hii_packagelist *hii) +{ + struct efi_keyboard_package_data *package; + + while (!list_empty(&hii->keyboard_packages)) { + package = list_first_entry(&hii->keyboard_packages, + struct efi_keyboard_package_data, + link); + free_keyboard_layouts(package); + list_del(&package->link); + free(package); + } +} + +static efi_status_t +add_keyboard_package(struct efi_hii_packagelist *hii, + struct efi_hii_keyboard_package *keyboard_package) +{ + struct efi_keyboard_package_data *package_data; + struct efi_hii_keyboard_layout *layout; + struct efi_keyboard_layout_data *layout_data; + u16 layout_count, layout_length; + int i; + + package_data = malloc(sizeof(*package_data)); + if (!package_data) + return EFI_OUT_OF_RESOURCES; + INIT_LIST_HEAD(&package_data->link); + INIT_LIST_HEAD(&package_data->keyboard_layout_list); + + layout = &keyboard_package->layout[0]; + layout_count = get_unaligned_le16(&keyboard_package->layout_count); + for (i = 0; i < layout_count; i++) { + layout_length = get_unaligned_le16(&layout->layout_length); + layout_data = malloc(sizeof(*layout_data) + layout_length); + if (!layout_data) + goto out; + + memcpy(&layout_data->keyboard_layout, layout, layout_length); + list_add_tail(&layout_data->link, + &package_data->keyboard_layout_list); + list_add_tail(&layout_data->link_sys, + &efi_keyboard_layout_list); + + layout += layout_length; + } + + list_add_tail(&package_data->link, &hii->keyboard_packages); + + return EFI_SUCCESS; + +out: + free_keyboard_layouts(package_data); + free(package_data); + + return EFI_OUT_OF_RESOURCES; +} + static struct efi_hii_packagelist *new_packagelist(void) { struct efi_hii_packagelist *hii; @@ -261,6 +346,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->keyboard_packages); return hii; } @@ -269,6 +355,7 @@ static void free_packagelist(struct efi_hii_packagelist *hii) { remove_strings_package(hii); remove_guid_package(hii); + remove_keyboard_package(hii); list_del(&hii->link); free(hii); @@ -324,8 +411,8 @@ 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_package(hii, + (struct efi_hii_keyboard_package *)package); break; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -458,7 +545,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_package(hii); break; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -546,7 +633,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->keyboard_packages)) + break; continue; case EFI_HII_PACKAGE_ANIMATIONS: printf("\tAnimation package not supported\n"); @@ -620,9 +708,30 @@ find_keyboard_layouts(const struct efi_hii_database_protocol *this, u16 *key_guid_buffer_length, efi_guid_t *key_guid_buffer) { + struct efi_keyboard_layout_data *layout_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(layout_data, &efi_keyboard_layout_list, link_sys) { + package_cnt++; + if (package_cnt <= package_max) + memcpy(key_guid_buffer++, + &layout_data->keyboard_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 @@ -631,10 +740,38 @@ get_keyboard_layout(const struct efi_hii_database_protocol *this, u16 *keyboard_layout_length, struct efi_hii_keyboard_layout *keyboard_layout) { + struct efi_keyboard_layout_data *layout_data; + u16 layout_length; + 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(layout_data, &efi_keyboard_layout_list, link_sys) { + if (!guidcmp(&layout_data->keyboard_layout.guid, key_guid)) + goto found; + } + return EFI_EXIT(EFI_NOT_FOUND); + +found: + layout_length = + get_unaligned_le16(&layout_data->keyboard_layout.layout_length); + if (*keyboard_layout_length < layout_length) { + *keyboard_layout_length = layout_length; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + memcpy(keyboard_layout, &layout_data->keyboard_layout, layout_length); + + return EFI_EXIT(EFI_SUCCESS); } static efi_status_t EFIAPI