From patchwork Sat Mar 13 21:47:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 399600 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2272505jai; Sat, 13 Mar 2021 13:48:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJxWnsdGWde4JKxZLPvLPWgT0l7BTWcy0x9qF2sCncS/IdymofMDG02jcrit8QrSNxExkBTm X-Received: by 2002:a17:906:4f10:: with SMTP id t16mr15821567eju.531.1615672108855; Sat, 13 Mar 2021 13:48:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615672108; cv=none; d=google.com; s=arc-20160816; b=tQIOSYriYt0kFJi/Ut9QGN75kITSUm8BTzz+g9jgwodMFFSTWvM4LPSTp7hvtOvGM6 SLMlWTLPzVEF/oOkmOh8XJL3jCfiVg8DvUafL7uBl6hBDP1mJIeB9ZvYYeTFNKcCStCq Tr2jQFPd7vQEQzYQRCJci6NybDhuT3zfWHT24c5K8J61TXO5UvtmQCpooTy0ZTrGTglF S0b+P+6H9aQX0uzfFeMHB5GShbC+WdeUGxWBmkUZawMtgWFS/7odgw6CWD22+GIGWFGo JyNsSFBui0f3aacmmlfRvnR3Si1cUKhHRMrPXuvalC2fJWCwWQSINk0zWcnPq7CYr5Ip 7l2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ZnqTmLPK2tec982rpzAZD1Q5kUsUf1yvvxEDvurPSUs=; b=eWezrC/KjdRlLEFlrV2PjpyDG/nEU25+h3APu8IPp4CW11KGVsBNqUOGvNjHpHIedR GjKIMaWYEKRebG94wsjSBurb5I6u+aRe7+Y2dqLD+WFwMnrg5AB0FhZeHY/XGWFtNaeZ DBDoB7EAxbZCFX0gkLuWTJC5omZs4sLBS01/R7XAlISVPJfg3FzvA4al8xMlSzanXfeY A4Di+i4FryXYs6arxNm4aHNnMS5nk59bTpcZb/zZm05bh5iumLYPDSPWvT1UCVeQigyT HgFp7scg+olXZH1gb7boIxGigtuxU0TxvYBQKecNkidZni8PgIs2n9sF7GRhWRBalh9U YqeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ilhYmPnq; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id h15si7567969edv.182.2021.03.13.13.48.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Mar 2021 13:48:28 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ilhYmPnq; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 42E908284D; Sat, 13 Mar 2021 22:47:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ilhYmPnq"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 665EE82858; Sat, 13 Mar 2021 22:47:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BFB4782806 for ; Sat, 13 Mar 2021 22:47:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-ed1-x52b.google.com with SMTP id j3so12936184edp.11 for ; Sat, 13 Mar 2021 13:47:49 -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=ZnqTmLPK2tec982rpzAZD1Q5kUsUf1yvvxEDvurPSUs=; b=ilhYmPnqC0QirMIjbcz+ploMkFbv2F0lgTrCojI7P5xQ3NzzK/2Nh/+L0Ukyi6OJ3l Eg/loIMejYW6g1daDp+56Ye0kosgde9UmJYHaFObIjHYnOI4uL8ANcFAIwKv+4tIElWc zGoeD54bP4JVxcDRJ1a+LfhYn7tuoYTJRiqfRpECot7bxY6Tq7LAQJlucxlTSaTZF5zH 0ocNv7bvsGJf/cjR7H4w0NpDF5R2/fWWY2oCQxjpSNSE8jUdQKjJt9MvL5tr6cDfbTRv cWGMLdZ2BhndYDVO14eoPF+Y/T1jutocuTQP4DVfItkcK+sTkhkEzeUry3dk/H8cF7Sf SoAw== 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=ZnqTmLPK2tec982rpzAZD1Q5kUsUf1yvvxEDvurPSUs=; b=AcQUtKrnJH5rmVz+TNIVNnlWohZST+kkqmrvzLcpHdnI+hlaky2pt/yo7KxC3Fl2H4 Is1zFylKkC7BIz6V7n+5kZPOIuFVUnymPt7QySZLpTxjar6CHY33bWtqwSNwK8aJLdQM JntkuyK6UzM2WfVYUsk4yYXEJn0DmPrF9E2AIskLHcmv15Z1Jp1XMZfSEZYceAB0Cmko 9DpKSNWLxPt3PXuvfdDrUEcat3WeC3aCZ5YI+ebFey8WKWtyeG3/NhGj5J8zEp9r8BXe nu6DnVmNodUq4jQNPu6BAV8RItUHD1rDu2Oz2R4WuPrOLZYW3yDRO2VOKg2yWSikVIIC m/Og== X-Gm-Message-State: AOAM532bOz/4yRgp0F7kc8VxAvhSwdfTmR5g+ATWDAUz0hDp2ZFBWJEz K0omkMcBmvj16bt//AUbfnNRDg== X-Received: by 2002:a05:6402:1853:: with SMTP id v19mr21726712edy.179.1615672069422; Sat, 13 Mar 2021 13:47:49 -0800 (PST) Received: from apalos.home ([2a02:587:4647:e6c6:2e56:dcff:fe9a:8f06]) by smtp.gmail.com with ESMTPSA id a9sm1571144eds.33.2021.03.13.13.47.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Mar 2021 13:47:49 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de Cc: takahiro.akashi@linaro.org, Ilias Apalodimas , Alexander Graf , Sughosh Ganu , u-boot@lists.denx.de Subject: [PATCH 3/6 v2] efi_loader: Introduce helper functions for EFI Date: Sat, 13 Mar 2021 23:47:34 +0200 Message-Id: <20210313214738.3257922-4-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210313214738.3257922-1-ilias.apalodimas@linaro.org> References: <20210313214738.3257922-1-ilias.apalodimas@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean A following patch introduces a different logic for loading initrd's based on the EFI_LOAD_FILE2_PROTOCOL. Since similar logic can be applied in the future for other system files (i.e DTBs), let's add some helper functions which will retrieve and parse file paths stored in EFI variables. Signed-off-by: Ilias Apalodimas --- include/efi_helper.h | 15 ++++ include/efi_loader.h | 2 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_helper.c | 133 ++++++++++++++++++++++++++++++++ lib/efi_loader/efi_var_common.c | 33 ++++++++ 5 files changed, 184 insertions(+) create mode 100644 include/efi_helper.h create mode 100644 lib/efi_loader/efi_helper.c -- 2.30.1 diff --git a/include/efi_helper.h b/include/efi_helper.h new file mode 100644 index 000000000000..97492c65b6d2 --- /dev/null +++ b/include/efi_helper.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#if !defined _EFI_HELPER_H_ +#define _EFI_HELPER_H + +#include +#include + +efi_status_t efi_get_file_size(struct efi_file_handle *fh, efi_uintn_t *size); +struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid); + +#endif diff --git a/include/efi_loader.h b/include/efi_loader.h index eb11a8c7d4b1..aa812a9a3052 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -717,6 +717,8 @@ efi_status_t EFIAPI efi_query_variable_info( u64 *remaining_variable_storage_size, u64 *maximum_variable_size); +void *efi_get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size); + /* * See section 3.1.3 in the v2.7 UEFI spec for more details on * the layout of EFI_LOAD_OPTION. In short it is: diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 10b42e8847bf..da2741adecfa 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -23,6 +23,7 @@ endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o obj-y += efi_boottime.o +obj-y += efi_helper.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o obj-y += efi_console.o diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c new file mode 100644 index 000000000000..df5bdc506dbe --- /dev/null +++ b/lib/efi_loader/efi_helper.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#define LOG_CATEGORY LOGC_EFI +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * efi_create_current_boot_var() - Return Boot#### name were #### is replaced by + * the value of BootCurrent + * + * @var_name: variable name + * @var_name_size: size of var_name + * + * Return: Status code + */ +static efi_status_t efi_create_current_boot_var(u16 var_name[], + size_t var_name_size) +{ + efi_uintn_t boot_current_size; + efi_status_t ret; + u16 boot_current; + u16 *pos; + + boot_current_size = sizeof(boot_current); + ret = efi_get_variable_int(L"BootCurrent", + &efi_global_variable_guid, NULL, + &boot_current_size, &boot_current, NULL); + if (ret != EFI_SUCCESS) + goto out; + + pos = efi_create_indexed_name(var_name, var_name_size, "Boot", + boot_current); + if (!pos) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + +out: + return ret; +} + +/** + * efi_get_dp_from_boot() - Retrieve and return a device path from an EFI + * Boot### variable + * + * @guid: Vendor guid of the VenMedia DP + * + * Return: device path or NULL. Caller must free the returned value + */ +struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid) +{ + struct efi_device_path *file_path = NULL; + struct efi_device_path *tmp; + struct efi_load_option lo; + void *var_value = NULL; + efi_uintn_t size; + efi_status_t ret; + u16 var_name[16]; + + ret = efi_create_current_boot_var(var_name, sizeof(var_name)); + if (ret != EFI_SUCCESS) + return NULL; + + var_value = efi_get_var(var_name, &efi_global_variable_guid, &size); + if (!var_value) + return NULL; + + ret = efi_deserialize_load_option(&lo, var_value, &size); + if (ret != EFI_SUCCESS) + goto out; + + tmp = efi_dp_from_lo(&lo, &size, guid); + if (!tmp) + goto out; + + /* efi_dp_dup will just return NULL if efi_dp_next is NULL */ + file_path = efi_dp_dup(efi_dp_next(tmp)); + +out: + efi_free_pool(tmp); + free(var_value); + + return file_path; +} + +/** + * efi_get_file_size() - Get the size of a file using an EFI file handle + * + * @handle: EFI file handle + * @size: buffer to fill in the discovered size + * + * Return: device path or NULL. Caller must free the returned value + */ +efi_status_t efi_get_file_size(struct efi_file_handle *fh, efi_uintn_t *size) +{ + struct efi_file_info *info = NULL; + efi_uintn_t bs = 0; + efi_status_t ret; + + *size = 0; + ret = EFI_CALL(fh->getinfo(fh, (efi_guid_t *)&efi_file_info_guid, &bs, + info)); + if (ret != EFI_BUFFER_TOO_SMALL) { + ret = EFI_DEVICE_ERROR; + goto out; + } + + info = malloc(bs); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + ret = EFI_CALL(fh->getinfo(fh, (efi_guid_t *)&efi_file_info_guid, &bs, + info)); + if (ret != EFI_SUCCESS) + goto out; + + *size = info->file_size; + +out: + free(info); + return ret; +} diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 1c7459266a38..b11ed91a74a4 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -9,6 +9,7 @@ #include #include #include +#include enum efi_secure_mode { EFI_MODE_SETUP, @@ -343,3 +344,35 @@ enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid) } return EFI_AUTH_VAR_NONE; } + +/** + * efi_get_var() - read value of an EFI variable + * + * @name: variable name + * @start: vendor GUID + * @size: size of allocated buffer + * + * Return: buffer with variable data or NULL + */ +void *efi_get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size) +{ + efi_status_t ret; + void *buf = NULL; + + *size = 0; + ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + buf = malloc(*size); + if (!buf) + return NULL; + ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL); + } + + if (ret != EFI_SUCCESS) { + free(buf); + *size = 0; + return NULL; + } + + return buf; +}