From patchwork Tue Oct 10 12:22:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 115400 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp3690623qgn; Tue, 10 Oct 2017 05:24:42 -0700 (PDT) X-Received: by 10.80.163.140 with SMTP id s12mr7573369edb.22.1507638282572; Tue, 10 Oct 2017 05:24:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507638282; cv=none; d=google.com; s=arc-20160816; b=T/eXk8uKvjudh6hnobw0zyGKByZtx57heyAGytb0KxBV3znY0ikh6w666nagXYVYWP AiNXlWko83UZzs3B2tLeRZFdZVuNvgCmKHwMw8Gb49Zvqrae5m8v2cKioj1ZAN1DVmtA s84yMVps7/kVqyp0WmCNCZuWlctW/XpBGP1m4uTHR9oly41Rh/qOFAsXLFKFXP2Sl6pE svRsdrebKZ2WgHaDDI9XGJfKN7UMYz8s0FUbLmjT9CkMWRG9Jkgv9x7drCOiRNkODq+M yboFmwnM05QH0u8PJUNLXOeHMJDC3OUWt34tJliQQWhpPdNeq8yRS8bzQo3o8vbI00FG KRUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:arc-authentication-results; bh=ixy5ox/j5pubVourDilENkCbEIoGwgmLZXPMb9vbHx4=; b=DFYD8lyxYYteFHI0/VC0Sls0/lcBc8fmR9cv8iPED/F8JJZppuP198PbEgYK62DwL7 wPDFKMf3xcdrM/2YBuWwj2/2rgBFIsUUz8BfYY8OwYA09uTPBC4MSjUSEVCGyuIpIOC1 yMFTxI3FTg56JEPO+dXyAEGdSOuKZwVhIUjJ3iznYYWO4aLckM/W5s3Ir6fc8NPwXA71 Wc/78MUUeJW7A7O9WCMtDIb8k/6aKTT2OPtSZFNJkNsGGDP9sA/v1hucQHx/DooAQKty QDbXbymxvZmeoZ/6PVInu9kPi8x2uSbqVdsSswWmDoVzWxib6b41KW8eTmyl9VGPlcTo RGYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=ndBKiVbh; 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=gmail.com Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id j4si537409edd.462.2017.10.10.05.24.42; Tue, 10 Oct 2017 05:24:42 -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=@gmail.com header.s=20161025 header.b=ndBKiVbh; 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=gmail.com Received: by lists.denx.de (Postfix, from userid 105) id 0C9BFC21E0C; Tue, 10 Oct 2017 12:23:37 +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_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 90FE3C21D90; Tue, 10 Oct 2017 12:23:29 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8F2ECC21D5F; Tue, 10 Oct 2017 12:23:26 +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 62131C21D80 for ; Tue, 10 Oct 2017 12:23:22 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id 32so15984674qtp.4 for ; Tue, 10 Oct 2017 05:23:22 -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=BtvilWVDYXj9Vw8it6dRHeAawXAdfsv7YYF77N/nQLQ=; b=ndBKiVbhkU/A1cSOqyr47k0O7hQVd0lNpNrXYlqWyoADPxOYE3G3NJtBIoeuusBrPJ fefriAWcO6Nd1fCfDjGhmaAm4RksykalaxWGTNahtytPR9aGU/P7zCjrIKTmAq0Dlvhr KqNzWItFxbV+BypqAdoslTMJOdCFeFsWhMRmsRQYLcLsv4zjByyc3z+v6s3VpWgLUkTP CzqC8QgCpmuzzrnMA8jFNr+npb/J2VyS06ElcsLbTG1b/AK4YeOL2N0HZ0FPXE6y2HI9 u6EYE5DNAn8BieOdxfU6qOD54EvTpCa9Jf5XoK1HjfuvahLwfJaqDht/seXMNb7wYs3R FtOQ== 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=BtvilWVDYXj9Vw8it6dRHeAawXAdfsv7YYF77N/nQLQ=; b=CpKrnljhqEcNbX6AOBZCec7S++nauBrf9PCcngiZTH7869fk6wROfv04rgVtpo3MQJ U2IgYjK6KhB5MV4aJnjp+XukVjhtIDyhRW8+3Dbga4JfFp2wYdrMmot0J1TrhJnJyXaE ZW+jZhcxKloIsPRZbXJSCXt2w4oGC1WRjM2D94iuwp4Y7me0vQYDdu/N7MBbG9g2ryrv R4w2eY+gYfdW7lRCwsY43SssDZ98510moF30/JM0vdqqtf0+yT1eT6zOr/JHxGeuoPwL 6FEeBx/GiyGiCqGgrOcfx2bQbieBv2jhlh95P2lE5br2aQzaU0WHSYkutxh7V5y1fHjb KRtw== X-Gm-Message-State: AMCzsaXH1mvCy1vTpKKe6LlYkHtPdfpWHDKKFHlCYSeZW3UiouQK2/CO ILHxm02WMTXq3K7ILHMZ3FkMjkCX X-Google-Smtp-Source: AOwi7QCDVl2QKK1MMAptTIaZxiwV/MyDDpo+CSvKr382Vnpp4INaNCXd4KFwWrD4qLlvA0V7pQT2QA== X-Received: by 10.55.59.131 with SMTP id i125mr13274321qka.93.1507638200984; Tue, 10 Oct 2017 05:23:20 -0700 (PDT) Received: from localhost ([144.121.20.162]) by smtp.gmail.com with ESMTPSA id m65sm6283535qkl.87.2017.10.10.05.23.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 10 Oct 2017 05:23:19 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Tue, 10 Oct 2017 08:22:57 -0400 Message-Id: <20171010122309.25313-2-robdclark@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171010122309.25313-1-robdclark@gmail.com> References: <20171010122309.25313-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Leif Lindholm Subject: [U-Boot] [PATCH 01/11] efi_loader: Initial EFI_DEVICE_PATH_UTILITIES_PROTOCOL 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" From: Leif Lindholm Not complete, but enough for Shell.efi and SCT.efi. We'll implement the rest as needed or once we have SCT running properly so there is a way to validate the interface against the conformance test suite. Initial skeleton written by Leif, and then implementation by myself. Cc: Leif Lindholm Signed-off-by: Rob Clark --- include/efi_api.h | 34 +++++++++++- include/efi_loader.h | 2 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_boottime.c | 4 ++ lib/efi_loader/efi_device_path_utilities.c | 88 ++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 lib/efi_loader/efi_device_path_utilities.c diff --git a/include/efi_api.h b/include/efi_api.h index a9a6494afe..ffdba7fe1a 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -28,8 +28,9 @@ enum efi_timer_delay { EFI_TIMER_RELATIVE = 2 }; -#define UINTN size_t -typedef long INTN; +#define UINTN size_t /* TODO this should be removed in a future patch */ +typedef size_t efi_uintn_t; +typedef ssize_t efi_intn_t; typedef uint16_t *efi_string_t; #define EVT_TIMER 0x80000000 @@ -506,6 +507,35 @@ struct efi_device_path_to_text_protocol bool allow_shortcuts); }; +#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ + EFI_GUID(0x0379be4e, 0xd706, 0x437d, \ + 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4) + +struct efi_device_path_utilities_protocol { + efi_uintn_t (EFIAPI *get_device_path_size)( + const struct efi_device_path *device_path); + struct efi_device_path *(EFIAPI *duplicate_device_path)( + const struct efi_device_path *device_path); + struct efi_device_path *(EFIAPI *append_device_path)( + const struct efi_device_path *src1, + const struct efi_device_path *src2); + struct efi_device_path *(EFIAPI *append_device_node)( + const struct efi_device_path *device_path, + const struct efi_device_path *device_node); + struct efi_device_path *(EFIAPI *append_device_path_instance)( + const struct efi_device_path *device_path, + const struct efi_device_path *device_path_instance); + struct efi_device_path *(EFIAPI *get_next_device_path_instance)( + struct efi_device_path **device_path_instance, + efi_uintn_t *device_path_instance_size); + bool (EFIAPI *is_device_path_multi_instance)( + const struct efi_device_path *device_path); + struct efi_device_path *(EFIAPI *create_device_node)( + uint8_t node_type, + uint8_t node_sub_type, + uint16_t node_length); +}; + #define EFI_GOP_GUID \ EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \ 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a) diff --git a/include/efi_loader.h b/include/efi_loader.h index e1179b7dcd..5d37c1d75f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -79,6 +79,7 @@ extern const struct efi_simple_text_output_protocol efi_con_out; 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; +extern const struct efi_device_path_utilities_protocol efi_device_path_utilities; uint16_t *efi_dp_str(struct efi_device_path *dp); @@ -89,6 +90,7 @@ extern const efi_guid_t efi_guid_loaded_image; extern const efi_guid_t efi_guid_device_path_to_text_protocol; extern const efi_guid_t efi_simple_file_system_protocol_guid; extern const efi_guid_t efi_file_info_guid; +extern const efi_guid_t efi_guid_device_path_utilities_protocol; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index ddb978f650..b6927b3b84 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -17,6 +17,7 @@ endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o +obj-y += efi_device_path_utilities.o obj-y += efi_file.o efi_variable.o efi_bootmgr.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 976d5822f7..92c778fcca 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1153,6 +1153,10 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob obj->protocols[3].protocol_interface = (void *)&efi_device_path_to_text; + obj->protocols[4].guid = &efi_guid_device_path_utilities_protocol; + obj->protocols[4].protocol_interface = + (void *)&efi_device_path_utilities; + info->file_path = file_path; info->device_handle = efi_dp_find_obj(device_path, NULL); diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c new file mode 100644 index 0000000000..9d90f14ee4 --- /dev/null +++ b/lib/efi_loader/efi_device_path_utilities.c @@ -0,0 +1,88 @@ +/* + * EFI device path interface + * + * Copyright (c) 2017 Leif Lindholm + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +const efi_guid_t efi_guid_device_path_utilities_protocol = + EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID; + +static efi_uintn_t EFIAPI get_device_path_size( + const struct efi_device_path *device_path) +{ + efi_uintn_t sz = 0; + EFI_ENTRY("%p", device_path); + /* size includes the END node: */ + if (device_path) + sz = efi_dp_size(device_path) + sizeof(struct efi_device_path); + return EFI_EXIT(sz); +} + +static struct efi_device_path * EFIAPI duplicate_device_path( + const struct efi_device_path *device_path) +{ + EFI_ENTRY("%p", device_path); + return EFI_EXIT(efi_dp_dup(device_path)); +} + +static struct efi_device_path * EFIAPI append_device_path( + const struct efi_device_path *src1, + const struct efi_device_path *src2) +{ + EFI_ENTRY("%p, %p", src1, src2); + return EFI_EXIT(efi_dp_append(src1, src2)); +} + +static struct efi_device_path * EFIAPI append_device_node( + const struct efi_device_path *device_path, + const struct efi_device_path *device_node) +{ + EFI_ENTRY("%p, %p", device_path, device_node); + return EFI_EXIT(efi_dp_append_node(device_path, device_node)); +} + +static struct efi_device_path * EFIAPI append_device_path_instance( + const struct efi_device_path *device_path, + const struct efi_device_path *device_path_instance) +{ + EFI_ENTRY("%p, %p", device_path, device_path_instance); + return EFI_EXIT(NULL); +} + +static struct efi_device_path * EFIAPI get_next_device_path_instance( + struct efi_device_path **device_path_instance, + efi_uintn_t *device_path_instance_size) +{ + EFI_ENTRY("%p, %p", device_path_instance, device_path_instance_size); + return EFI_EXIT(NULL); +} + +static bool EFIAPI is_device_path_multi_instance( + const struct efi_device_path *device_path) +{ + EFI_ENTRY("%p", device_path); + return EFI_EXIT(false); +} + +static struct efi_device_path * EFIAPI create_device_node( + uint8_t node_type, uint8_t node_sub_type, uint16_t node_length) +{ + EFI_ENTRY("%u, %u, %u", node_type, node_sub_type, node_length); + return EFI_EXIT(NULL); +} + +const struct efi_device_path_utilities_protocol efi_device_path_utilities = { + .get_device_path_size = get_device_path_size, + .duplicate_device_path = duplicate_device_path, + .append_device_path = append_device_path, + .append_device_node = append_device_node, + .append_device_path_instance = append_device_path_instance, + .get_next_device_path_instance = get_next_device_path_instance, + .is_device_path_multi_instance = is_device_path_multi_instance, + .create_device_node = create_device_node, +}; From patchwork Tue Oct 10 12:22:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 115402 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp3691596qgn; Tue, 10 Oct 2017 05:25:45 -0700 (PDT) X-Received: by 10.80.160.231 with SMTP id 94mr17764909edo.242.1507638345165; Tue, 10 Oct 2017 05:25:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507638345; cv=none; d=google.com; s=arc-20160816; b=Ka6mKCmTDS658KWrVMLWmiu8iZrp/nBlSyaejWiofs2+qi8J4yLncYazD+4iJSAPpY ehL4bEJLC0XFUsbIAFdO79o9wZS0gU6UBHkc04qWtP6aGgJrKdxSQr8Ydt201zPMPb5l 9jSLTNVI1wXFShGoYGQ7Jt0lXC5At+NrZJez/slVSRkrIAOsX/164LL957sEryPXqpAN T4V60ZzKCwsjEQREC8JJYcDgdrmCw5q2QbySatFUjXeqjXXUhQBRBHfr/kc0ZXLz1cht yPe8VMh5x/3lbjVNfUIsEiy3N48tSDl5WKe/YvaaMMC+QPk/xmIVwforX5NmH3rEB/sq c7DA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:arc-authentication-results; bh=XjaTVqHKr6QBSCzon/Bwubrwh8fihAybe5SGV00XshM=; b=aA7FxI5EKupLHUAUqtFO8j/PugkZsjYrlltN7lae/8WQX4AHPQBn0jAVeIdKlzeHn6 Mjq1vaKuLj+01wbx/oOG8YyUqmCg0Cy5wTRmyevnWpm8cVwEUyzGAxbYRrAw+GhSksae SNRbtoWALIP/WS8CD9CsiUbSVWOn8gxFkT3+ir8DtsjOS/3gzx5ZDXfc4brZ2VIW4Zrl hPuSCCF4O3YFHXVtMaXv/okvtWrS8GlNHdWhSDoFqf8q/l3qTD/gucaCkw4r57rs3z3B RHVIEK8XwlRbpfvlL8dCfhVePsR4kaDs1d9xUXUp6Kvj9bIRj3xkjsQ2piJq4bL1hC29 t/ug== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=HGB9ZaEV; 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=gmail.com Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id o6si4248951eda.375.2017.10.10.05.25.44; Tue, 10 Oct 2017 05:25:45 -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=@gmail.com header.s=20161025 header.b=HGB9ZaEV; 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=gmail.com Received: by lists.denx.de (Postfix, from userid 105) id AD681C21E08; Tue, 10 Oct 2017 12:24:28 +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_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 777CFC21DA5; Tue, 10 Oct 2017 12:23:54 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4B32FC21D64; Tue, 10 Oct 2017 12:23:30 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 86116C21DA5 for ; Tue, 10 Oct 2017 12:23:26 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id 24so4847422qts.3 for ; Tue, 10 Oct 2017 05:23:26 -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=Byvn6XqnjhIdxQDg5PB3cSqd0O1gNLwfiwcBcmeH0O8=; b=HGB9ZaEVZac7+eaEMqzOQ1FDtM0nvIcOpLQYMXUWj5GzI8bUrKcOSBPzZ73yYTbZcZ kciPfc+/x6neCKSprPz+u3uanunwwRu/ci/qTg74R09PqnxyhqQN1pCp81i7u1aPI6of bJDXie6YdnOt2SUWl9Kw8N8WsTfb916kX3Mn34mo6Bcjqg5+GONgMPfUcejBQqhCjrNw yroFnhqVp/6hm08cEAp7acXjs96iitxb227We5SQOIvBL2dvL684Z9pnt3ORcKLglqmG mVSGBIcLvKVR136cobcEQszsfb+pI1Nr0hgB+nvIkTD22xpeZ1TP171I/hIDGF19P/Qj Xf6g== 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=Byvn6XqnjhIdxQDg5PB3cSqd0O1gNLwfiwcBcmeH0O8=; b=mgg99Du+C7LOJ6RyQnd3W2MFqyOy8Z+Ntop/XhmzhHikDanau2U40ZYL3oc5bPTg/C DblwLzlst8puOl/KC9o1Bs+F35Bxh6sJ1H4zcEF2T/BgPoVSjq3mrkYJc+cxlpogT01m VEJMjPqEDlm3kxZoaPEXcIXxWax+kKdDKlEjAyjRCe2QIOhxBTuRXtm8sVeeLKgmxky+ UKTt/8E5rlAeQh1MXNXpOAY+CfCOalkOrwh6PJBALWL40QRkYllvwMCqDQxOxknd/OXr 9pfqZZ5eGud9k6FDgAx55mSDf1EPwwC8wZuz60/Apl45WInA7iDLWvyerIlzBc0b6h7j MZZQ== X-Gm-Message-State: AMCzsaUi73KgIuTdl+82exN0fqMG/UlseovDbwX8ccl5/hUVkuX2sson OZYbIVUd+ClVgUFJ6yoCVgbTAVHe X-Google-Smtp-Source: AOwi7QAqkRgQ82lblWBBxrGuDSHhi9t6ljkZdNv355uspIdz+G8xjvGAkmJLiNIeCz7HJAXsyeA01Q== X-Received: by 10.55.40.81 with SMTP id o78mr12569261qkh.343.1507638204942; Tue, 10 Oct 2017 05:23:24 -0700 (PDT) Received: from localhost ([144.121.20.162]) by smtp.gmail.com with ESMTPSA id z192sm6171694qka.91.2017.10.10.05.23.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 10 Oct 2017 05:23:23 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Tue, 10 Oct 2017 08:22:58 -0400 Message-Id: <20171010122309.25313-3-robdclark@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171010122309.25313-1-robdclark@gmail.com> References: <20171010122309.25313-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Leif Lindholm Subject: [U-Boot] [PATCH 02/11] efi_loader: Initial HII protocols 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" From: Leif Lindholm Enough implementation of the following protocols to run Shell.efi and SCT.efi: EfiHiiConfigRoutingProtocolGuid EfiHiiDatabaseProtocol EfiHiiStringProtocol We'll fill in the rest once SCT is running properly so we can validate the implementation against the conformance test suite. Initial skeleton written by Leif, and then implementation by myself. Cc: Leif Lindholm Signed-off-by: Rob Clark --- include/efi_api.h | 261 ++++++++++++++++++++++ include/efi_loader.h | 6 + lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_boottime.c | 9 + lib/efi_loader/efi_hii.c | 507 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 784 insertions(+), 1 deletion(-) create mode 100644 lib/efi_loader/efi_hii.c diff --git a/include/efi_api.h b/include/efi_api.h index ffdba7fe1a..164147dc87 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -16,6 +16,7 @@ #define _EFI_API_H #include +#include #ifdef CONFIG_EFI_LOADER #include @@ -536,6 +537,266 @@ struct efi_device_path_utilities_protocol { uint16_t node_length); }; +#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + EFI_GUID(0x587e72d7, 0xcc50, 0x4f79, \ + 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f) + +typedef uint16_t efi_string_id_t; + +struct efi_hii_config_routing_protocol { + efi_status_t(EFIAPI *extract_config)( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t request, + efi_string_t *progress, + efi_string_t *results); + efi_status_t(EFIAPI *export_config)( + const struct efi_hii_config_routing_protocol *this, + efi_string_t *results); + efi_status_t(EFIAPI *route_config)( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t configuration, + efi_string_t *progress); + efi_status_t(EFIAPI *block_to_config)( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_request, + const uint8_t *block, + const efi_uintn_t block_size, + efi_string_t *config, + efi_string_t *progress); + efi_status_t(EFIAPI *config_to_block)( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_resp, + const uint8_t *block, + const efi_uintn_t *block_size, + efi_string_t *progress); + efi_status_t(EFIAPI *get_alt_config)( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_resp, + const efi_guid_t *guid, + const efi_string_t name, + const struct efi_device_path *device_path, + const efi_string_t alt_cfg_id, + efi_string_t *alt_cfg_resp); +}; + +#define EFI_HII_DATABASE_PROTOCOL_GUID \ + EFI_GUID(0xef9fc172, 0xa1b2, 0x4693, \ + 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42) + +typedef enum { + EFI_KEY_LCTRL, EFI_KEY_A0, EFI_KEY_LALT, EFI_KEY_SPACE_BAR, + EFI_KEY_A2, EFI_KEY_A3, EFI_KEY_A4, EFI_KEY_RCTRL, EFI_KEY_LEFT_ARROW, + EFI_KEY_DOWN_ARROW, EFI_KEY_RIGHT_ARROW, EFI_KEY_ZERO, + EFI_KEY_PERIOD, EFI_KEY_ENTER, EFI_KEY_LSHIFT, EFI_KEY_B0, + EFI_KEY_B1, EFI_KEY_B2, EFI_KEY_B3, EFI_KEY_B4, EFI_KEY_B5, EFI_KEY_B6, + EFI_KEY_B7, EFI_KEY_B8, EFI_KEY_B9, EFI_KEY_B10, EFI_KEY_RSHIFT, + EFI_KEY_UP_ARROW, EFI_KEY_ONE, EFI_KEY_TWO, EFI_KEY_THREE, + EFI_KEY_CAPS_LOCK, EFI_KEY_C1, EFI_KEY_C2, EFI_KEY_C3, EFI_KEY_C4, + EFI_KEY_C5, EFI_KEY_C6, EFI_KEY_C7, EFI_KEY_C8, EFI_KEY_C9, + EFI_KEY_C10, EFI_KEY_C11, EFI_KEY_C12, EFI_KEY_FOUR, EFI_KEY_FIVE, + EFI_KEY_SIX, EFI_KEY_PLUS, EFI_KEY_TAB, EFI_KEY_D1, EFI_KEY_D2, + EFI_KEY_D3, EFI_KEY_D4, EFI_KEY_D5, EFI_KEY_D6, EFI_KEY_D7, EFI_KEY_D8, + EFI_KEY_D9, EFI_KEY_D10, EFI_KEY_D11, EFI_KEY_D12, EFI_KEY_D13, + EFI_KEY_DEL, EFI_KEY_END, EFI_KEY_PG_DN, EFI_KEY_SEVEN, EFI_KEY_EIGHT, + EFI_KEY_NINE, EFI_KEY_E0, EFI_KEY_E1, EFI_KEY_E2, EFI_KEY_E3, + EFI_KEY_E4, EFI_KEY_E5, EFI_KEY_E6, EFI_KEY_E7, EFI_KEY_E8, EFI_KEY_E9, + EFI_KEY_E10, EFI_KEY_E11, EFI_KEY_E12, EFI_KEY_BACK_SPACE, + EFI_KEY_INS, EFI_KEY_HOME, EFI_KEY_PG_UP, EFI_KEY_NLCK, EFI_KEY_SLASH, + EFI_KEY_ASTERISK, EFI_KEY_MINUS, EFI_KEY_ESC, EFI_KEY_F1, EFI_KEY_F2, + EFI_KEY_F3, EFI_KEY_F4, EFI_KEY_F5, EFI_KEY_F6, EFI_KEY_F7, EFI_KEY_F8, + EFI_KEY_F9, EFI_KEY_F10, EFI_KEY_F11, EFI_KEY_F12, EFI_KEY_PRINT, + EFI_KEY_SLCK, EFI_KEY_PAUSE, +} efi_key; + +struct efi_key_descriptor { + efi_key key; + uint16_t unicode; + uint16_t shifted_unicode; + uint16_t alt_gr_unicode; + uint16_t shifted_alt_gr_unicode; + uint16_t modifier; + uint16_t affected_attribute; +}; + +struct efi_hii_keyboard_layout { + uint16_t layout_length; + efi_guid_t guid; + uint32_t layout_descriptor_string_offset; + uint8_t descriptor_count; + struct efi_key_descriptor descriptors[]; +}; + +struct efi_hii_package_list_header { + efi_guid_t package_list_guid; + uint32_t package_length; +} __packed; + +struct efi_hii_package_header { + uint32_t length : 24; + uint32_t type : 8; +} __packed; + +#define EFI_HII_PACKAGE_TYPE_ALL 0x00 +#define EFI_HII_PACKAGE_TYPE_GUID 0x01 +#define EFI_HII_PACKAGE_FORMS 0x02 +#define EFI_HII_PACKAGE_STRINGS 0x04 +#define EFI_HII_PACKAGE_FONTS 0x05 +#define EFI_HII_PACKAGE_IMAGES 0x06 +#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07 +#define EFI_HII_PACKAGE_DEVICE_PATH 0x08 +#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x09 +#define EFI_HII_PACKAGE_ANIMATIONS 0x0A +#define EFI_HII_PACKAGE_END 0xDF +#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0 +#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF + +struct efi_hii_strings_package { + struct efi_hii_package_header header; + uint32_t header_size; + uint32_t string_info_offset; + uint16_t language_window[16]; + efi_string_id_t language_name; + uint8_t language[]; +} __packed; + +struct efi_hii_string_block { + uint8_t block_type; + /*uint8_t block_body[];*/ +} __packed; + +#define EFI_HII_SIBT_END 0x00 // The end of the string information. +#define EFI_HII_SIBT_STRING_SCSU 0x10 // Single string using default font information. +#define EFI_HII_SIBT_STRING_SCSU_FONT 0x11 // Single string with font information. +#define EFI_HII_SIBT_STRINGS_SCSU 0x12 // Multiple strings using default font information. +#define EFI_HII_SIBT_STRINGS_SCSU_FONT 0x13 // Multiple strings with font information. +#define EFI_HII_SIBT_STRING_UCS2 0x14 // Single UCS-2 string using default font information. +#define EFI_HII_SIBT_STRING_UCS2_FONT 0x15 // Single UCS-2 string with font information +#define EFI_HII_SIBT_STRINGS_UCS2 0x16 // Multiple UCS-2 strings using default font information. +#define EFI_HII_SIBT_STRINGS_UCS2_FONT 0x17 // Multiple UCS-2 strings with font information. +#define EFI_HII_SIBT_DUPLICATE 0x20 // Create a duplicate of an existing string. +#define EFI_HII_SIBT_SKIP2 0x21 // Skip a certain number of string identifiers. +#define EFI_HII_SIBT_SKIP1 0x22 // Skip a certain number of string identifiers. +#define EFI_HII_SIBT_EXT1 0x30 // For future expansion (one byte length field) +#define EFI_HII_SIBT_EXT2 0x31 // For future expansion (two byte length field) +#define EFI_HII_SIBT_EXT4 0x32 // For future expansion (four byte length field) +#define EFI_HII_SIBT_FONT 0x40 // Font information. + +struct efi_hii_sibt_string_ucs2_block { + struct efi_hii_string_block header; + uint16_t string_text[]; +} __packed; + +static inline struct efi_hii_string_block *efi_hii_sibt_string_ucs2_block_next( + struct efi_hii_sibt_string_ucs2_block *blk) +{ + return ((void *)blk) + sizeof(*blk) + + (utf16_strlen(blk->string_text) + 1) * 2; +} + +typedef void *efi_hii_handle_t; + +struct efi_hii_database_protocol { + efi_status_t(EFIAPI *new_package_list)( + const struct efi_hii_database_protocol *this, + const struct efi_hii_package_list_header *package_list, + const efi_handle_t driver_handle, + efi_hii_handle_t *handle); + efi_status_t(EFIAPI *remove_package_list)( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle); + efi_status_t(EFIAPI *update_package_list)( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle, + const struct efi_hii_package_list_header *package_list); + efi_status_t(EFIAPI *list_package_lists)( + const struct efi_hii_database_protocol *this, + uint8_t package_type, + const efi_guid_t *package_guid, + efi_uintn_t *handle_buffer_length, + efi_hii_handle_t *handle); + efi_status_t(EFIAPI *export_package_lists)( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle, + efi_uintn_t *buffer_size, + struct efi_hii_package_list_header *buffer); + efi_status_t(EFIAPI *register_package_notify)( + const struct efi_hii_database_protocol *this, + uint8_t package_type, + const efi_guid_t *package_guid, + const void *package_notify_fn, + efi_uintn_t notify_type, + efi_handle_t *notify_handle); + efi_status_t(EFIAPI *unregister_package_notify)( + const struct efi_hii_database_protocol *this, + efi_handle_t notification_handle + ); + efi_status_t(EFIAPI *find_keyboard_layouts)( + const struct efi_hii_database_protocol *this, + uint16_t *key_guid_buffer_length, + efi_guid_t *key_guid_buffer); + efi_status_t(EFIAPI *get_keyboard_layout)( + const struct efi_hii_database_protocol *this, + efi_guid_t *key_guid, + uint16_t *keyboard_layout_length, + struct efi_hii_keyboard_layout *keyboard_layout); + efi_status_t(EFIAPI *set_keyboard_layout)( + const struct efi_hii_database_protocol *this, + efi_guid_t *key_guid); + efi_status_t(EFIAPI *get_package_list_handle)( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t package_list_handle, + efi_handle_t *driver_handle); +}; + +#define EFI_HII_STRING_PROTOCOL_GUID \ + EFI_GUID(0x0fd96974, 0x23aa, 0x4cdc, \ + 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a) + +typedef uint32_t efi_hii_font_style_t; + +struct efi_font_info { + efi_hii_font_style_t font_style; + uint16_t font_size; + uint16_t font_name[1]; +}; + +struct efi_hii_string_protocol { + efi_status_t(EFIAPI *new_string)( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + efi_string_id_t *string_id, + const uint8_t *language, + const uint16_t *language_name, + const efi_string_t string, + const struct efi_font_info *string_font_info); + efi_status_t(EFIAPI *get_string)( + const struct efi_hii_string_protocol *this, + const uint8_t *language, + efi_hii_handle_t package_list, + efi_string_id_t string_id, + efi_string_t string, + efi_uintn_t *string_size, + struct efi_font_info **string_font_info); + efi_status_t(EFIAPI *set_string)( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + efi_string_id_t string_id, + const uint8_t *language, + const efi_string_t string, + const struct efi_font_info *string_font_info); + efi_status_t(EFIAPI *get_languages)( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + uint8_t *languages, + efi_uintn_t *languages_size); + efi_status_t(EFIAPI *get_secondary_languages)( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + const uint8_t *primary_language, + uint8_t *secondary_languages, + efi_uintn_t *secondary_languages_size); +}; + #define EFI_GOP_GUID \ EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \ 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a) diff --git a/include/efi_loader.h b/include/efi_loader.h index 5d37c1d75f..591bf07e7a 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -80,6 +80,9 @@ 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; extern const struct efi_device_path_utilities_protocol efi_device_path_utilities; +extern const struct efi_hii_config_routing_protocol efi_hii_config_routing; +extern const struct efi_hii_database_protocol efi_hii_database; +extern const struct efi_hii_string_protocol efi_hii_string; uint16_t *efi_dp_str(struct efi_device_path *dp); @@ -91,6 +94,9 @@ extern const efi_guid_t efi_guid_device_path_to_text_protocol; extern const efi_guid_t efi_simple_file_system_protocol_guid; extern const efi_guid_t efi_file_info_guid; extern const efi_guid_t efi_guid_device_path_utilities_protocol; +extern const efi_guid_t efi_guid_hii_config_routing_protocol; +extern const efi_guid_t efi_guid_hii_database_protocol; +extern const efi_guid_t efi_guid_hii_string_protocol; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index b6927b3b84..725e0cba85 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -17,7 +17,7 @@ endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -obj-y += efi_device_path_utilities.o +obj-y += efi_device_path_utilities.o efi_hii.o obj-y += efi_file.o efi_variable.o efi_bootmgr.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 92c778fcca..c179afc25a 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1157,6 +1157,15 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob obj->protocols[4].protocol_interface = (void *)&efi_device_path_utilities; + obj->protocols[5].guid = &efi_guid_hii_string_protocol; + obj->protocols[5].protocol_interface = (void *)&efi_hii_string; + + obj->protocols[6].guid = &efi_guid_hii_database_protocol; + obj->protocols[6].protocol_interface = (void *)&efi_hii_database; + + obj->protocols[7].guid = &efi_guid_hii_config_routing_protocol; + obj->protocols[7].protocol_interface = (void *)&efi_hii_config_routing; + info->file_path = file_path; info->device_handle = efi_dp_find_obj(device_path, NULL); diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c new file mode 100644 index 0000000000..25c8e88a60 --- /dev/null +++ b/lib/efi_loader/efi_hii.c @@ -0,0 +1,507 @@ +/* + * EFI Human Interface Infrastructure ... interface + * + * Copyright (c) 2017 Leif Lindholm + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +const efi_guid_t efi_guid_hii_config_routing_protocol = + EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID; +const efi_guid_t efi_guid_hii_database_protocol = EFI_HII_DATABASE_PROTOCOL_GUID; +const efi_guid_t efi_guid_hii_string_protocol = EFI_HII_STRING_PROTOCOL_GUID; + +struct hii_package { + // TODO should there be an associated efi_object? + struct list_head string_tables; /* list of string_table */ + /* we could also track fonts, images, etc */ +}; + +struct string_table { + struct list_head link; + efi_string_id_t language_name; + char *language; + uint32_t nstrings; + /* NOTE: string id starts at 1 so value is stbl->strings[id-1] */ + struct { + efi_string_t string; + /* we could also track font info, etc */ + } strings[]; +}; + +static void free_strings_table(struct string_table *stbl) +{ + int i; + + for (i = 0; i < stbl->nstrings; i++) + free(stbl->strings[i].string); + free(stbl->language); + free(stbl); +} + +static struct hii_package *new_package(void) +{ + struct hii_package *hii = malloc(sizeof(*hii)); + INIT_LIST_HEAD(&hii->string_tables); + return hii; +} + +static void free_package(struct hii_package *hii) +{ + + while (!list_empty(&hii->string_tables)) { + struct string_table *stbl; + + stbl = list_first_entry(&hii->string_tables, + struct string_table, link); + list_del(&stbl->link); + free_strings_table(stbl); + } + + free(hii); +} + +static efi_status_t add_strings_package(struct hii_package *hii, + struct efi_hii_strings_package *strings_package) +{ + struct efi_hii_string_block *block; + void *end = ((void *)strings_package) + strings_package->header.length; + uint32_t nstrings = 0; + unsigned id = 0; + + debug("header_size: %08x\n", strings_package->header_size); + debug("string_info_offset: %08x\n", strings_package->string_info_offset); + debug("language_name: %u\n", strings_package->language_name); + debug("language: %s\n", strings_package->language); + + /* count # of string entries: */ + block = ((void *)strings_package) + strings_package->string_info_offset; + while ((void *)block < end) { + switch (block->block_type) { + case EFI_HII_SIBT_STRING_UCS2: { + struct efi_hii_sibt_string_ucs2_block *ucs2 = + (void *)block; + nstrings++; + block = efi_hii_sibt_string_ucs2_block_next(ucs2); + break; + } + case EFI_HII_SIBT_END: + block = end; + break; + default: + debug("unknown HII string block type: %02x\n", + block->block_type); + return EFI_INVALID_PARAMETER; + } + } + + struct string_table *stbl = malloc(sizeof(*stbl) + + (nstrings * sizeof(stbl->strings[0]))); + stbl->language_name = strings_package->language_name; + stbl->language = strdup((char *)strings_package->language); + stbl->nstrings = nstrings; + + list_add(&stbl->link, &hii->string_tables); + + /* and now parse string entries and populate string_table */ + block = ((void *)strings_package) + strings_package->string_info_offset; + + while ((void *)block < end) { + switch (block->block_type) { + case EFI_HII_SIBT_STRING_UCS2: { + struct efi_hii_sibt_string_ucs2_block *ucs2 = + (void *)block; + id++; + debug("%4u: \"%ls\"\n", id, ucs2->string_text); + stbl->strings[id-1].string = + utf16_strdup(ucs2->string_text); + block = efi_hii_sibt_string_ucs2_block_next(ucs2); + break; + } + case EFI_HII_SIBT_END: + return EFI_SUCCESS; + default: + debug("unknown HII string block type: %02x\n", + block->block_type); + return EFI_INVALID_PARAMETER; + } + } + + return EFI_SUCCESS; +} + +/* + * EFI_HII_CONFIG_ROUTING_PROTOCOL + */ + +static efi_status_t EFIAPI extract_config( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t request, + efi_string_t *progress, + efi_string_t *results) +{ + EFI_ENTRY("%p, \"%ls\", %p, %p", this, request, progress, results); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI export_config( + const struct efi_hii_config_routing_protocol *this, + efi_string_t *results) +{ + EFI_ENTRY("%p, %p", this, results); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI route_config( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t configuration, + efi_string_t *progress) +{ + EFI_ENTRY("%p, \"%ls\", %p", this, configuration, progress); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI block_to_config( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_request, + const uint8_t *block, + const efi_uintn_t block_size, + efi_string_t *config, + efi_string_t *progress) +{ + EFI_ENTRY("%p, \"%ls\", %p, %zu, %p, %p", this, config_request, block, + block_size, config, progress); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI config_to_block( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_resp, + const uint8_t *block, + const efi_uintn_t *block_size, + efi_string_t *progress) +{ + EFI_ENTRY("%p, \"%ls\", %p, %p, %p", this, config_resp, block, + block_size, progress); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI get_alt_config( + const struct efi_hii_config_routing_protocol *this, + const efi_string_t config_resp, + const efi_guid_t *guid, + const efi_string_t name, + const struct efi_device_path *device_path, + const efi_string_t alt_cfg_id, + efi_string_t *alt_cfg_resp) +{ + EFI_ENTRY("%p, \"%ls\", %pUl, \"%ls\", %p, \"%ls\", %p", this, + config_resp, guid, name, device_path, alt_cfg_id, + alt_cfg_resp); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + + +/* + * EFI_HII_DATABASE_PROTOCOL + */ + +static efi_status_t EFIAPI new_package_list( + const struct efi_hii_database_protocol *this, + const struct efi_hii_package_list_header *package_list, + const efi_handle_t driver_handle, + efi_hii_handle_t *handle) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %p, %p, %p", this, package_list, driver_handle, handle); + + if (!package_list || !driver_handle) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + struct hii_package *hii = new_package(); + struct efi_hii_package_header *package; + void *end = ((void *)package_list) + package_list->package_length; + + debug("package_list: %pUl (%u)\n", &package_list->package_list_guid, + package_list->package_length); + + package = ((void *)package_list) + sizeof(*package_list); + while ((void *)package < end) { + debug("package=%p, package type=%x, length=%u\n", package, + package->type, package->length); + switch (package->type) { + case EFI_HII_PACKAGE_STRINGS: + ret = add_strings_package(hii, + (struct efi_hii_strings_package *)package); + break; + default: + break; + } + + if (ret != EFI_SUCCESS) + goto error; + + package = ((void *)package) + package->length; + } + + // TODO in theory there is some notifications that should be sent.. + + *handle = hii; + + return EFI_EXIT(EFI_SUCCESS); + +error: + free_package(hii); + return EFI_EXIT(ret); +} + +static efi_status_t EFIAPI remove_package_list( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle) +{ + struct hii_package *hii = handle; + EFI_ENTRY("%p, %p", this, handle); + free_package(hii); + return EFI_EXIT(EFI_SUCCESS); +} + +static efi_status_t EFIAPI update_package_list( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle, + const struct efi_hii_package_list_header *package_list) +{ + EFI_ENTRY("%p, %p, %p", this, handle, package_list); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI list_package_lists( + const struct efi_hii_database_protocol *this, + uint8_t package_type, + const efi_guid_t *package_guid, + efi_uintn_t *handle_buffer_length, + efi_hii_handle_t *handle) +{ + EFI_ENTRY("%p, %u, %pUl, %p, %p", this, package_type, package_guid, + handle_buffer_length, handle); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI export_package_lists( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t handle, + efi_uintn_t *buffer_size, + struct efi_hii_package_list_header *buffer) +{ + EFI_ENTRY("%p, %p, %p, %p", this, handle, buffer_size, buffer); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI register_package_notify( + const struct efi_hii_database_protocol *this, + uint8_t package_type, + const efi_guid_t *package_guid, + const void *package_notify_fn, + efi_uintn_t notify_type, + efi_handle_t *notify_handle) +{ + EFI_ENTRY("%p, %u, %pUl, %p, %zu, %p", this, package_type, + package_guid, package_notify_fn, notify_type, + notify_handle); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); +} + +static efi_status_t EFIAPI unregister_package_notify( + const struct efi_hii_database_protocol *this, + efi_handle_t notification_handle) +{ + EFI_ENTRY("%p, %p", this, notification_handle); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI find_keyboard_layouts( + const struct efi_hii_database_protocol *this, + uint16_t *key_guid_buffer_length, + efi_guid_t *key_guid_buffer) +{ + EFI_ENTRY("%p, %p, %p", this, key_guid_buffer_length, key_guid_buffer); + return EFI_EXIT(EFI_NOT_FOUND); /* Invalid */ +} + +static efi_status_t EFIAPI get_keyboard_layout( + const struct efi_hii_database_protocol *this, + efi_guid_t *key_guid, + uint16_t *keyboard_layout_length, + struct efi_hii_keyboard_layout *keyboard_layout) +{ + EFI_ENTRY("%p, %pUl, %p, %p", this, key_guid, keyboard_layout_length, + keyboard_layout); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI set_keyboard_layout( + const struct efi_hii_database_protocol *this, + efi_guid_t *key_guid) +{ + EFI_ENTRY("%p, %pUl", this, key_guid); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI get_package_list_handle( + const struct efi_hii_database_protocol *this, + efi_hii_handle_t package_list_handle, + efi_handle_t *driver_handle) +{ + EFI_ENTRY("%p, %p, %p", this, package_list_handle, driver_handle); + return EFI_EXIT(EFI_INVALID_PARAMETER); +} + + +/* + * EFI_HII_STRING_PROTOCOL + */ + +static efi_status_t EFIAPI new_string( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + efi_string_id_t *string_id, + const uint8_t *language, + const uint16_t *language_name, + const efi_string_t string, + const struct efi_font_info *string_font_info) +{ + EFI_ENTRY("%p, %p, %p, \"%s\", %p, \"%ls\", %p", this, package_list, + string_id, language, language_name, string, + string_font_info); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI get_string( + const struct efi_hii_string_protocol *this, + const uint8_t *language, + efi_hii_handle_t package_list, + efi_string_id_t string_id, + efi_string_t string, + efi_uintn_t *string_size, + struct efi_font_info **string_font_info) +{ + struct hii_package *hii = package_list; + struct string_table *stbl; + + EFI_ENTRY("%p, \"%s\", %p, %u, %p, %p, %p", this, language, + package_list, string_id, string, string_size, + string_font_info); + + list_for_each_entry(stbl, &hii->string_tables, link) { + if (!strcmp((char *)language, (char *)stbl->language)) { + unsigned idx = string_id - 1; + if (idx > stbl->nstrings) + return EFI_EXIT(EFI_NOT_FOUND); + efi_string_t str = stbl->strings[idx].string; + size_t len = utf16_strlen(str) + 1; + if (*string_size < len * 2) { + *string_size = len * 2; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + memcpy(string, str, len * 2); + *string_size = len * 2; + return EFI_EXIT(EFI_SUCCESS); + } + } + + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI set_string( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + efi_string_id_t string_id, + const uint8_t *language, + const efi_string_t string, + const struct efi_font_info *string_font_info) +{ + EFI_ENTRY("%p, %p, %u, \"%s\", \"%ls\", %p", this, package_list, + string_id, language, string, string_font_info); + return EFI_EXIT(EFI_NOT_FOUND); +} + +static efi_status_t EFIAPI get_languages( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + uint8_t *languages, + efi_uintn_t *languages_size) +{ + struct hii_package *hii = package_list; + struct string_table *stbl; + size_t len = 0; + + EFI_ENTRY("%p, %p, %p, %p", this, package_list, languages, + languages_size); + + /* figure out required size: */ + list_for_each_entry(stbl, &hii->string_tables, link) { + len += strlen((char *)stbl->language) + 1; + } + + if (*languages_size < len) { + *languages_size = len; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + char *p = (char *)languages; + list_for_each_entry(stbl, &hii->string_tables, link) { + if (p != (char *)languages) + p += sprintf(p, ";"); + p += sprintf(p, "%s", stbl->language); + } + + debug("languages: %s\n", languages); + + return EFI_EXIT(EFI_SUCCESS); +} + +static efi_status_t EFIAPI get_secondary_languages( + const struct efi_hii_string_protocol *this, + efi_hii_handle_t package_list, + const uint8_t *primary_language, + uint8_t *secondary_languages, + efi_uintn_t *secondary_languages_size) +{ + EFI_ENTRY("%p, %p, \"%s\", %p, %p", this, package_list, + primary_language, secondary_languages, + secondary_languages_size); + return EFI_EXIT(EFI_NOT_FOUND); +} + +const struct efi_hii_config_routing_protocol efi_hii_config_routing = { + .extract_config = extract_config, + .export_config = export_config, + .route_config = route_config, + .block_to_config = block_to_config, + .config_to_block = config_to_block, + .get_alt_config = get_alt_config +}; +const struct efi_hii_database_protocol efi_hii_database = { + .new_package_list = new_package_list, + .remove_package_list = remove_package_list, + .update_package_list = update_package_list, + .list_package_lists = list_package_lists, + .export_package_lists = export_package_lists, + .register_package_notify = register_package_notify, + .unregister_package_notify = unregister_package_notify, + .find_keyboard_layouts = find_keyboard_layouts, + .get_keyboard_layout = get_keyboard_layout, + .set_keyboard_layout = set_keyboard_layout, + .get_package_list_handle = get_package_list_handle +}; +const struct efi_hii_string_protocol efi_hii_string = { + .new_string = new_string, + .get_string = get_string, + .set_string = set_string, + .get_languages = get_languages, + .get_secondary_languages = get_secondary_languages +}; From patchwork Tue Oct 10 12:22:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 115401 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp3690755qgn; Tue, 10 Oct 2017 05:24:51 -0700 (PDT) X-Received: by 10.80.149.169 with SMTP id w38mr5718728eda.191.1507638290931; Tue, 10 Oct 2017 05:24:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507638290; cv=none; d=google.com; s=arc-20160816; b=g1vqn0N/I7o6ZPCxq5FPGzwRq4LjPew2nPzNw3zhzcc6QpWZItXusnEjf9QhLO7NQM Km+j8EJryx4t+3vrhzE4CF8HBQkxG2ACLD21jhXqf+D5KodTFuFjSJUPGfSyUuUGJyuL mMhe9PIZREzqvwT2MjPZ551sOSG8luWVFyguyjAZI3OFJ/27iSkWm+T10nBNhURTvZcN GTiBwzWy6GW3kt1eMVKDmhWUKadED6PNXGcChTYZpufJi4uxSEIrzzqS5D56YoM9BOM4 mBYuTd/CCzDIgZabaLw+hWA2M0xu1sj8Pin0Zz9hl+aspELhzObVm7Ib3dHSOwI1EaT+ /bUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:arc-authentication-results; bh=Yns3fRu5Qm/Dr/pttzwd1pbsYe2/471Svwz9fWrdO1A=; b=EvP/TIdAhdp3Z5l1LbFARhCbJKxIEYO3xUW4NMulAPUTmU/d2IwRKpviuOzk8KaulU LvTwnMZCdNyaZGwQ022xR5iY3xym6e7uoXjoMKjCLP8nVs9FC2sEWqC5z9PZo3oFjkW2 O2PwfAAoM/RwjbS8L9UpdjKeeEnuy133uFGLnsKObloAv8cc4Ga2ewaiqHNr8rgmRDcT Y99KguHpoRiTIGt3rilizVCS9MdxQZMwe+0WObDQuI8BPLwNOJtgwfZsuMSbvDYCMh6e IGpJTfgjhmWjH5uHGPw7gU45JJPVZEhodJBv160sHrnKzu7UZYRlRkZKug3J8FrC4IX5 ybDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=Ebp9VAsb; 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=gmail.com Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id x5si2645775edj.433.2017.10.10.05.24.50; Tue, 10 Oct 2017 05:24:50 -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=@gmail.com header.s=20161025 header.b=Ebp9VAsb; 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=gmail.com Received: by lists.denx.de (Postfix, from userid 105) id 7E657C21C93; Tue, 10 Oct 2017 12:24:00 +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_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 78989C21DBA; Tue, 10 Oct 2017 12:23:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6CE9AC21D84; Tue, 10 Oct 2017 12:23:33 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 473ABC21DA3 for ; Tue, 10 Oct 2017 12:23:30 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id z50so45456252qtj.4 for ; Tue, 10 Oct 2017 05:23:30 -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=xTIxuatjBe6vhbNlTtMaBmoRDpN/KRWlVMVixz5FDN0=; b=Ebp9VAsbn92g46Cngx7valPogx4gqT7pUmZ8Fr+BckpsQOlvUDchrNzsb1qTJLP9eL SpEKOO/8+48Mjo5pb8MVy7mAZUsxwaIn2IeLuJomeqvJUIOurHjvXW9uCwUTstikGBdj dpQm0Ha6MoKzfCyOn13MDc0tX/yxRe85rxaHI3RPXgsuc8tA/CtoTm6Ss1lFXiMqZEde VHPug9Fs2p+3v/7FFk8ha5OzCtDoIOunNRD79T2Fog2PfY+6soUaNrBCZYNsW/7m5kRT o9oXu+qHba2PE66NGVwh4GJ+kFi1RbtE2MhDQV03NqO7jfA0UkzrWrMarZsV1VKWV8bl hwig== 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=xTIxuatjBe6vhbNlTtMaBmoRDpN/KRWlVMVixz5FDN0=; b=UyKq6MGIUXFChogzG0fTpRKhF0AqffZXxpZAukqX4FvMn+fAQyKkHwXd1l4mVNsokj XU6S+mdC0VucZE/54i83DMEKlHQDJN24ju8iyO1cfgTsEbgOJs+ipjRlRE+QSwttsfNj ferY5h9K+rhTyLwTE7ZhKhacCvcpJMUODVwQ/NSBDuvClPJUGHKL28w4P4tMeXyNLjf7 u0IrejvpqNq6YqbgUHH8QkNERrcXmXNq3OONgRs0st/f4FgKJXOMC9qPvanlYeEngwgn fHlp3B2G/NJfMXsRATn3C5xVZs/7noqrv2rn6Xdts2OxE5oIozconf5umDONmvBokU5f 5yLQ== X-Gm-Message-State: AMCzsaVe6vh2d58VbPZY4xvx/DkUUAX4FdSNcg6rcEDkol5MTrvS0rYl a43V3zc+V6hnByBrfim7bZ8hk9zT X-Google-Smtp-Source: AOwi7QCu3VGqRbpapBcwCI1EfTBZgNREWptBtcISEorTyV3+aJZk6/LAc9QgfD2pbqJmEZOWnFOyWg== X-Received: by 10.237.37.76 with SMTP id w12mr13648889qtc.201.1507638208910; Tue, 10 Oct 2017 05:23:28 -0700 (PDT) Received: from localhost ([144.121.20.162]) by smtp.gmail.com with ESMTPSA id v185sm6201878qkd.44.2017.10.10.05.23.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 10 Oct 2017 05:23:27 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Tue, 10 Oct 2017 08:22:59 -0400 Message-Id: <20171010122309.25313-4-robdclark@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171010122309.25313-1-robdclark@gmail.com> References: <20171010122309.25313-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Leif Lindholm Subject: [U-Boot] [PATCH 03/11] efi_loader: Initial EFI_UNICODE_COLLATION_PROTOCOL 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" From: Leif Lindholm Not complete, but enough for Shell.efi and SCT.efi. Initial skeleton written by Leif, and then implementation by myself. Cc: Leif Lindholm Signed-off-by: Rob Clark --- include/efi_api.h | 41 ++++++++++ include/efi_loader.h | 3 + lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_boottime.c | 6 ++ lib/efi_loader/efi_unicode.c | 170 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 lib/efi_loader/efi_unicode.c diff --git a/include/efi_api.h b/include/efi_api.h index 164147dc87..38dd1240c1 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -797,6 +797,47 @@ struct efi_hii_string_protocol { efi_uintn_t *secondary_languages_size); }; +/* + * Both UNICODE_COLLATION protocols seem to be the same thing, but + * advertised with two different GUID's because, why not? + */ + +#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + EFI_GUID(0x1d85cd7f, 0xf43d, 0x11d2, \ + 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) + +#define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ + EFI_GUID(0xa4c751fc, 0x23ae, 0x4c3e, \ + 0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49) + +struct efi_unicode_collation_protocol { + efi_intn_t (EFIAPI *stri_coll)( + struct efi_unicode_collation_protocol *this, + efi_string_t s1, + efi_string_t s2); + bool (EFIAPI *metai_match)( + struct efi_unicode_collation_protocol *this, + efi_string_t string, + efi_string_t pattern); + void (EFIAPI *str_lwr)( + struct efi_unicode_collation_protocol *this, + efi_string_t string); + void (EFIAPI *str_upr)( + struct efi_unicode_collation_protocol *this, + efi_string_t string); + void (EFIAPI *fat_to_str)( + struct efi_unicode_collation_protocol *this, + efi_uintn_t fat_size, + uint8_t *fat, + efi_string_t string); + bool (EFIAPI *str_to_fat)( + struct efi_unicode_collation_protocol *this, + efi_string_t string, + efi_uintn_t fat_size, + uint8_t *fat); + uint8_t *supported_languages; +}; + #define EFI_GOP_GUID \ EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \ 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a) diff --git a/include/efi_loader.h b/include/efi_loader.h index 591bf07e7a..af6812b2b4 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -83,6 +83,7 @@ extern const struct efi_device_path_utilities_protocol efi_device_path_utilities extern const struct efi_hii_config_routing_protocol efi_hii_config_routing; extern const struct efi_hii_database_protocol efi_hii_database; extern const struct efi_hii_string_protocol efi_hii_string; +extern const struct efi_unicode_collation_protocol efi_unicode_collation; uint16_t *efi_dp_str(struct efi_device_path *dp); @@ -97,6 +98,8 @@ extern const efi_guid_t efi_guid_device_path_utilities_protocol; extern const efi_guid_t efi_guid_hii_config_routing_protocol; extern const efi_guid_t efi_guid_hii_database_protocol; extern const efi_guid_t efi_guid_hii_string_protocol; +extern const efi_guid_t efi_guid_unicode_collation_protocol; +extern const efi_guid_t efi_guid_unicode_collation_protocol2; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 725e0cba85..7ea96a4f1c 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -17,7 +17,7 @@ endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -obj-y += efi_device_path_utilities.o efi_hii.o +obj-y += efi_device_path_utilities.o efi_hii.o efi_unicode.o obj-y += efi_file.o efi_variable.o efi_bootmgr.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index c179afc25a..b568f3f162 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1166,6 +1166,12 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob obj->protocols[7].guid = &efi_guid_hii_config_routing_protocol; obj->protocols[7].protocol_interface = (void *)&efi_hii_config_routing; + obj->protocols[8].guid = &efi_guid_unicode_collation_protocol; + obj->protocols[8].protocol_interface = (void *)&efi_unicode_collation; + + obj->protocols[9].guid = &efi_guid_unicode_collation_protocol2; + obj->protocols[9].protocol_interface = (void *)&efi_unicode_collation; + info->file_path = file_path; info->device_handle = efi_dp_find_obj(device_path, NULL); diff --git a/lib/efi_loader/efi_unicode.c b/lib/efi_loader/efi_unicode.c new file mode 100644 index 0000000000..2c6302df25 --- /dev/null +++ b/lib/efi_loader/efi_unicode.c @@ -0,0 +1,170 @@ +/* +* EFI Unicode interface + * + * Copyright (c) 2017 Leif Lindholm + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +const efi_guid_t efi_guid_unicode_collation_protocol = + EFI_UNICODE_COLLATION_PROTOCOL_GUID; + +const efi_guid_t efi_guid_unicode_collation_protocol2 = + EFI_UNICODE_COLLATION_PROTOCOL2_GUID; + +static int matchn(efi_string_t s1, unsigned n1, efi_string_t s2, unsigned n2) +{ + char u1[MAX_UTF8_PER_UTF16 * n1 + 1]; + char u2[MAX_UTF8_PER_UTF16 * n2 + 1]; + + *utf16_to_utf8((u8 *)u1, s1, n1) = '\0'; + *utf16_to_utf8((u8 *)u2, s2, n2) = '\0'; + + return strcasecmp(u1, u2); +} + +static efi_intn_t EFIAPI stri_coll(struct efi_unicode_collation_protocol *this, + efi_string_t s1, + efi_string_t s2) +{ + EFI_ENTRY("%p, \"%ls\", \"%ls\"", this, s1, s2); + + unsigned n1 = utf16_strlen(s1); + unsigned n2 = utf16_strlen(s2); + + return EFI_EXIT(matchn(s1, n1, s2, n2)); +} + +static bool match(efi_string_t string, efi_string_t pattern) +{ + while (true) { + uint16_t p = *pattern++; + bool matches = false; + + if (p == '\0' || *string == '\0') { + /* + * End of pattern or string, succeed if + * end of both: + */ + return *string == p; + } + + switch (p) { + case '*': + /* Match zero or more chars: */ + while (*string != '\0') { + if (match(string, pattern)) + return true; + string++; + } + return match(string, pattern); + case '?': + /* Match any one char: */ + string++; + break; + case '[': + /* Match char set, either [abc] or [a-c]: */ + + if (pattern[0] == '\0' || pattern[0] == ']') { + /* invalid pattern */ + return false; + } + + if (pattern[1] == '-') { + uint16_t lo, hi, c; + + /* range: [a-c] */ + lo = pattern[0]; + hi = pattern[2]; + + if (hi == '\0' || hi == ']' || pattern[3] != ']') { + /* invalid pattern */ + return false; + } + + c = tolower(*string); + lo = tolower(lo); + hi = tolower(hi); + + if (lo <= c && c <= hi) + matches = true; + + pattern += 4; + } else { + /* set: [abc] */ + while ((p = *pattern++) && p != ']') + if (matchn(string, 1, &p, 1)) + matches = true; + } + + if (!matches) + return false; + + string++; + break; + default: + if (matchn(string, 1, &p, 1)) + return false; + string++; + break; + } + } +} + +static bool EFIAPI metai_match(struct efi_unicode_collation_protocol *this, + efi_string_t string, + efi_string_t pattern) +{ + EFI_ENTRY("%p, \"%ls\", \"%ls\"", this, string, pattern); + return EFI_EXIT(match(string, pattern)); +} + +static void EFIAPI str_lwr(struct efi_unicode_collation_protocol *this, + efi_string_t string) +{ + EFI_ENTRY("%p, \"%ls\"", this, string); + EFI_EXIT(EFI_SUCCESS); + return; +} + +static void EFIAPI str_upr(struct efi_unicode_collation_protocol *this, + efi_string_t string) +{ + EFI_ENTRY("%p, \"%ls\"", this, string); + EFI_EXIT(EFI_SUCCESS); + return; +} + +static void EFIAPI fat_to_str(struct efi_unicode_collation_protocol *this, + efi_uintn_t fat_size, + uint8_t *fat, + efi_string_t string) +{ + EFI_ENTRY("%p, %zu, \"%s\", %p", this, fat_size, fat, string); + EFI_EXIT(EFI_SUCCESS); + return; +} + +static bool EFIAPI str_to_fat(struct efi_unicode_collation_protocol *this, + efi_string_t string, + efi_uintn_t fat_size, + uint8_t *fat) +{ + EFI_ENTRY("%p, \"%ls\", %zu, %p", this, string, fat_size, fat); + return EFI_EXIT(false); +} + +const struct efi_unicode_collation_protocol efi_unicode_collation = { + .stri_coll = stri_coll, + .metai_match = metai_match, + .str_lwr = str_lwr, + .str_upr = str_upr, + .fat_to_str = fat_to_str, + .str_to_fat = str_to_fat, + .supported_languages = (uint8_t *)"eng", +};