From patchwork Fri Nov 16 01:18:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 151266 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp7715759ljp; Thu, 15 Nov 2018 17:17:56 -0800 (PST) X-Google-Smtp-Source: AJdET5fM9Xw69lDbmdWIK2VAXlZ/6xK8LaEFlxDGWy3qZ4tz8YxYlhkWd5YhqZIc1GdloQZV414R X-Received: by 2002:a50:880d:: with SMTP id b13mr7434421edb.68.1542331076006; Thu, 15 Nov 2018 17:17:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542331076; cv=none; d=google.com; s=arc-20160816; b=xVpndgN1e0/S3xdIibnzPJR9MWNup51eFNrE3RFL9BhocHHtgn1gJuAwPjvGqeB4BI zWe7RiSc9onRdyto6BBh3ih72sJXqakYmw+yxteVhfuCHH/B9vqVZ30Gv11bMlv5ldv3 vBwp0ErVpBcZCtMKpX9t8hsBOmU4oUEj/AfzH+natcnVlbONDB7vZ051urBFPwKxvc5T HUPZFKn2KmXifD5XOzvZuEApeEOLcanGuxVR4MixsABWZWH/ZaYOz32O295cIcuYBLAh ZxC0BYmEhhIUHKXqXfmCcmQY86MrGRwiPGJ9XaARpDe4LLrqn2TXwsovbu1tmkVWUDG2 CTug== 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=EagL5/AXVRWXWxNIEaAh9KzCzyx9in5D+jUGnZ4utZY=; b=fLNu4WCE7z4kCGMoWUKx+4LvnYXNJD0CtLpIjK9W72k0Sw8e7sQ2B/71D9Ttg6WslX 3qkXyRtUn89RKYGZCN5Wc2MKbaG1+9Q3kqRvnynH9e+XwpPzipqGXr0hzhh0akVpjAJI MAvw6u0MeURlzhUaqefke/4frsE7NjSO6qxCRn3pVXF3hRETi3ipQioDnhDVFNlP+iT/ 95e/MoXakGUODQmCNT8NK7hCJMegaMqkEyMaFP9lT0Ra15OYZ9QGv57lrS7kVfHqRlCq TBtV/cRI0gT9w+y3A/hTao+Krq2OLLst4045U2O4T7eLGyv9XJh36f7+h4VZkofRFfwd kN+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=P4CdYANv; 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 l22si2967988edj.93.2018.11.15.17.17.55; Thu, 15 Nov 2018 17:17:55 -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=P4CdYANv; 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 9AB9CC22108; Fri, 16 Nov 2018 01:17:12 +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 A66FEC22243; Fri, 16 Nov 2018 01:16:50 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 920C3C22247; Fri, 16 Nov 2018 01:16:44 +0000 (UTC) Received: from mail-yb1-f195.google.com (mail-yb1-f195.google.com [209.85.219.195]) by lists.denx.de (Postfix) with ESMTPS id 67F76C2225D for ; Fri, 16 Nov 2018 01:16:44 +0000 (UTC) Received: by mail-yb1-f195.google.com with SMTP id 131-v6so9144181ybe.12 for ; Thu, 15 Nov 2018 17:16:44 -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=sv8YISaPfzM5Os2V5bVVSpqTkXeECX6yFvKR+ztyPPM=; b=P4CdYANvImj1TknkNbAfnZrlvvogKfOl0+LpVSoarTF3qnsU+BaWzOsNFhRXC8f5pp E6R3/GypeGa8e2iTgiii/lsaqDE2j33Wfx9NH3xy8iAshcZO550WkCME22YZbn3JueNK /WKnc0ycdmBuuxM8+mCIo2mPKaZ+qEq1TzRrY= 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=sv8YISaPfzM5Os2V5bVVSpqTkXeECX6yFvKR+ztyPPM=; b=pD/lNaAVVDMoseltQ62pTenL3LjlCLHwb9kmguIFRhCeqpmLHNbv24hndgJdIQr72y 0t6gllOlxH4kTkcKX7NLeSN+E3Uyu+dyQuffRVpbBPuRtbyQOP+d0749r20Ax5Y1nOaU GTt8YqmdmqXC4yITVBwsluRKknTmxhOjHZzNq0zQ+fu0cWJt5hrevYAnVadtqEGvBkax GRuE5UErHdH2o2JrEc29Zo7KvCUXfJoQl9ZctI6ti1P8Be/vi4yRnW6WZzSEc4RT0Z8l 1Xopxim+Jj42T6/rL4ixjfZizi7OuR99biT2nW1xvARSdKb6bafd8WHf3zd7bXi+Tqlf DooA== X-Gm-Message-State: AGRZ1gK3J17HpKctY2hIYtvaJTcxANQOOw/7F/VLBmpca9mEw7aibP4V Uf367Lj1aoZrqHJJKUDjE9TAod/VUwo= X-Received: by 2002:a25:4644:: with SMTP id t65-v6mr8479145yba.43.1542331003201; Thu, 15 Nov 2018 17:16:43 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id w1sm400241ywd.49.2018.11.15.17.16.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Nov 2018 17:16:42 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Fri, 16 Nov 2018 10:18:35 +0900 Message-Id: <20181116011837.27542-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181116011837.27542-1-takahiro.akashi@linaro.org> References: <20181116011837.27542-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: xypron.glpk@gmx.de, u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 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 f3a0b4396b5a..76d7377bd2bb 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -844,6 +844,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