From patchwork Fri Dec 14 10:10:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 153798 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp1875490ljp; Fri, 14 Dec 2018 02:08:29 -0800 (PST) X-Google-Smtp-Source: AFSGD/VKwo0qKGBOtpI0g45udafH7nhhKkWuTTLkI8mGQGbUonewKbNHG8KHw4/qWrCfj3qca1IL X-Received: by 2002:a17:906:d191:: with SMTP id c17-v6mr1980553ejz.27.1544782109273; Fri, 14 Dec 2018 02:08:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544782109; cv=none; d=google.com; s=arc-20160816; b=JP//o4U72TQa9PQoDsgaQ748kVxEc++P/F/aN5Jof56J9bLdrjciwkskIHizsaQEjx OusHurnvGblIXbvsr7l4vfZJFEG4ZaHuMT40yey/2zhIi4H2gYvqJcHgNXMOTp79S8rk zp6dC8DMV9VUo880GBacKe2PTsnR1sWSIXocs4LrKOUMVn0JMEk/iVZ4IE9coQdDLCao 0nmvnWh5LmCP5yJavMpYGuLgxj57N98Y8wVjfn7agdJ51hqomRVec/NFUxX9xRH6YyNz UiaAcRbuSVX5MfGEUfh7ojUgqwvH4rg1tEDKHaV+VGv+EmKMRWWp+lsmpYmRcRfG8QD3 7Yig== 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=a2ye10dXprH1CVarfbUIo0CLxpKb30F1DpUJXyU8LIc=; b=ti5fZ3QX0vOOKWIJ/Z+8ErJqwU1BqnGquGbZ6LA2S/YG757MuIUzuRdioxIwQ8RRUa izyD8evkeGpo7qZQrfcArJrJ8irLYyM23+pqy6XXulRVG5jJsUBUVwxuQKJ/8yxleXb6 /3y1f5IOJEHtuUd195gICX78urCqHlXtm35nsTq0tQGRzq7DMgHXk5e2bzR0l+csEi2o sOBsBmJHwA083P9UVGslOdtUzUlQyxnjFrKNiuiOo1EiH4zgIkKC0/B9ejRzglzKP+wP YzgS3AOFbqSSfGvyX+gbuJ6qgCwNiJCf6u5pHhN5DZs0HDVwW5biMKt7e3uM6zeDxwmz XlMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=jk9VCZLs; 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 gf7-v6si1630573ejb.92.2018.12.14.02.08.28; Fri, 14 Dec 2018 02:08:29 -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=jk9VCZLs; 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 CC61FC2274D; Fri, 14 Dec 2018 10:08:05 +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_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 1BCBBC227A5; Fri, 14 Dec 2018 10:07:48 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6EDE2C227BE; Fri, 14 Dec 2018 10:07:46 +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 B6E8BC227BE for ; Fri, 14 Dec 2018 10:07:41 +0000 (UTC) Received: by mail-yw1-f68.google.com with SMTP id v20so663113ywc.0 for ; Fri, 14 Dec 2018 02:07:41 -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=L4YN0shZiRy1ksmXlLgoj1tOtIAUj0RZJiIHfR12iDE=; b=jk9VCZLsN/TxwzbWEbSZHp6f8JXOQXEprKhojau+SJcTPIsFva4DRBwfLs52yIA0Da RcnR4JUKigO6ri+YLO+HS6sX+5JXVC+KJlsOWnLVDVc49Ig6+TP1aqQi2hG9uVx/yQfo jU7izfVyEAYnsfrRXF8AWWMhSsuahh4ete/EE= 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=L4YN0shZiRy1ksmXlLgoj1tOtIAUj0RZJiIHfR12iDE=; b=Ithwjg4YW9/91Lxna/XviCbEnM6G+NGAGulyEJXMLACvoE+N1BDBFbEeKrKyHOhNiS F93JbLkHNIvakm5QRQhMnLfjRz5utpU1xxo4JIVPdbSa3VXiQYhHvUEvlu1g/fQttnEP aPX4+cwXf7aH/VBJ7HV6eBoGbh7ZFXSusIUssJS3vipnfx4AK/w65i+r3nQfN5UOrPpv 2vhEaSjPZipV8pbIndOhYPsZBqfoqjKagNoF1kGv8Xu8VYFvIDcuvwHyLTPf7dpwEj1I weASxvS4Wj7OZ66fHr9F+hKBUi8FeOj8qUPfe04T1A/CskkkCiaBnavUXS7ZSJtiEqdR /EUg== X-Gm-Message-State: AA+aEWYKTp84B7gOZTTTx1lUaZFZVTRAn327vZZdHkZScuto23VM8aMo bp2vrbs9oGpQRua7C98XGRMa5t3S9X8= X-Received: by 2002:a81:6a04:: with SMTP id f4mr2207911ywc.485.1544782060581; Fri, 14 Dec 2018 02:07:40 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id c140sm2471889ywa.74.2018.12.14.02.07.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Dec 2018 02:07:40 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de, xypron.glpk@gmx.de Date: Fri, 14 Dec 2018 19:10:41 +0900 Message-Id: <20181214101043.14067-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181214101043.14067-1-takahiro.akashi@linaro.org> References: <20181214101043.14067-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [RESEND 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 7209f268c78f..954d2414c5c7 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