From patchwork Wed Jan 13 11:11:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 362077 Delivered-To: patch@linaro.org Received: by 2002:a02:ccad:0:0:0:0:0 with SMTP id t13csp427854jap; Wed, 13 Jan 2021 03:12:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJxZSO+toS1Lpbp5a8fhAME0apfwyAgN/NlwYY+1CkFdrBqpTMcyN5ocqFUyANMzMIho9Qwc X-Received: by 2002:a17:906:29cd:: with SMTP id y13mr1214279eje.453.1610536343565; Wed, 13 Jan 2021 03:12:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610536343; cv=none; d=google.com; s=arc-20160816; b=GOa3vc2rpuKFRLljGtbKZgX5QJAuA4ZwnkuQRj9MzNqiGfc47GIwXEJDVst4lk36UV DK3BMpOuW0dQ5aHjMZ3oItjB/HPKkP0c8GuUXK6N5jo6NH45JKpLmFUOmoi+Y0GCqPEg jW4VPFgtESpX/2wclRLyxIIx+8339ANbbEPuXAgs5/Sx1zmRBU0SSaocU8KlOZZR2sVk XNN4UhSap1JqbYqU4tOhC2Ohw0eWyThDOmaVdsIEsky75vwHODFPMJRTT0kpW4YslRpt NE7umDfdZUglPy0CwFDwZJlSPFPZDpSUqixEqtHMKYhRRXuIPlxRrh11ntoDjErNLnzj pEjQ== 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=14TnePlIK7QrOjuO8nJc+ZP7/oA6x3UGx8t67WWo1WI=; b=NTkysrMlhrw9UaEPtqyh7sexjP/rRPb0mR0rNDbowcpX3/xN8idfz6Nwq1Rw3C+grm 2t9/5vqWvk8jOvC0K9Acpfii64uJKpsCN57XXM7wHIx+5CjcNJlw4n6hdjOBdcu0ocOr J0YiWhWmpTyiMGlHCkmdtF2Jr48dEpItRlFOIV1nibkMJoSsYW0fsQWKiDWT+LOLeh/A tADAWT5W7LmQhSrdOtR5n3NisTPE3PjJSbN5Drik75SWTuZaj6ya2bEzLu/ZlFucXdqf lu6CuvRcS/rQotmM+94HS5xZGihSnuOgW9NCP7fgO8yr5ZG+Uy2FsgRnwMySKz4CVG1f 3JIQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="nS3/w28s"; 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 w11si849052ejc.533.2021.01.13.03.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 03:12:23 -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="nS3/w28s"; 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 B685F82652; Wed, 13 Jan 2021 12:12:06 +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="nS3/w28s"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 78BAE8261E; Wed, 13 Jan 2021 12:11:58 +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,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) (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 2BA36825C4 for ; Wed, 13 Jan 2021 12:11:54 +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-wr1-x42f.google.com with SMTP id q18so1694289wrn.1 for ; Wed, 13 Jan 2021 03:11:54 -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=14TnePlIK7QrOjuO8nJc+ZP7/oA6x3UGx8t67WWo1WI=; b=nS3/w28sG0hKvuDQ6dQteqkfza1/7/abnc3OW1qAlA5+1SY8B/S8KWUszosDhIvXEk 5Eqcj168bnOrPvzdbEjVor2bmtweGV+qNGroyJVS3EK1cLTROc+SSWJ8bU/YqHMTzO65 sIIJ8RMO5OoYkA2J0kezeFox4RquVSZI24iyKFjRW3tMN28KDd5xg+MtvUI8k9ETlafN UEKnMXE2Me+Tr9Ey7oJJoim9XWAcSLuGPGcO+q+Ch3iqs43av+rlUYCtE9C2hIhK9R2U 1ts6n+lsszE6e8I2FmzfKP0xlYngxQSjxXVd+gBQOyWzJce873KXJpixAe/QIZ4L5FaL QGTA== 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=14TnePlIK7QrOjuO8nJc+ZP7/oA6x3UGx8t67WWo1WI=; b=Z4EfI1gdNJSOQsS8nbm7zB0zlHxS3qnW3BIJ0SId2kGjge7x8NOLTYknDxjkwZpZ6/ zb00+0pLIC2pVu5fqEvKNmvregYBUOhvxcUld7WlGjQcm9lwaZFOZ0vU87sfLBCD8RiD r6Al0qlKbcFgTE40CKJur4YLMpLvTGVgTz03RHYRSsORthpgCMb61E74b01nggWJwURL RtDF8jB0539JNKahfYaH0czIT0ZXZsKJOj41jUq3Ly/sqC49sIAgsvRK0Bwi7eb8uIX0 QJV26VGN36LZGaGyE5R9rUPfSTS8MkC+N3HBdMnpEZr3K5EcAOH63VJKbu0ULa0mZf0/ 4Mkw== X-Gm-Message-State: AOAM533ZwdgkziK+arTsEgAG2cfgAJZ2M7ywZfY2iEM6q1iHL0DDv4bz ZNTFl2PAFhWeVUtPAjW8HxD3oQ== X-Received: by 2002:adf:a551:: with SMTP id j17mr1984227wrb.217.1610536313720; Wed, 13 Jan 2021 03:11:53 -0800 (PST) Received: from apalos.home ([2a02:587:4667:3e9:2e56:dcff:fe9a:8f06]) by smtp.gmail.com with ESMTPSA id r2sm2589869wrn.83.2021.01.13.03.11.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 03:11:53 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de Cc: takahiro.akashi@linaro.org, Ilias Apalodimas , Alexander Graf , u-boot@lists.denx.de Subject: [RFC PATCH 1/3] efi_loader: Introduce helper functions for EFI Date: Wed, 13 Jan 2021 13:11:47 +0200 Message-Id: <20210113111149.64567-2-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.30.0.rc2 In-Reply-To: <20210113111149.64567-1-ilias.apalodimas@linaro.org> References: <20210113111149.64567-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.3 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 load options. Signed-off-by: Ilias Apalodimas --- include/efi_helper.h | 23 ++++++ lib/efi_loader/efi_helper.c | 146 ++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 include/efi_helper.h create mode 100644 lib/efi_loader/efi_helper.c -- 2.30.0.rc2 diff --git a/include/efi_helper.h b/include/efi_helper.h new file mode 100644 index 000000000000..4e6bd2f036df --- /dev/null +++ b/include/efi_helper.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#if !defined _EFI_HELPER_H_ +#define _EFI_HELPER_H + +#include +#include + +enum load_option_dp_type { + BOOT_IMAGE_DP, + INITRD_DP, + DTB_DP, +}; + +void *efi_get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size); +struct efi_device_path *efi_get_fp_from_boot(int idx); +struct efi_device_path *efi_dp_instance_by_idx(struct efi_device_path *dp, + efi_uintn_t *size, int idx); + +#endif diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c new file mode 100644 index 000000000000..e2437a4f698b --- /dev/null +++ b/lib/efi_loader/efi_helper.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * 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); + ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL); + } + + if (ret != EFI_SUCCESS) { + free(buf); + *size = 0; + return NULL; + } + + return buf; +} + +/** + * efi_dp_instance_by_idx() - Get a file path with a specific index + * + * @name: device path array + * @size: size of the discovered device path + * @idx: index of the device path + * + * Return: device path or NULL. Caller must free the returned value + */ + +struct +efi_device_path *efi_dp_instance_by_idx(struct efi_device_path *dp, + efi_uintn_t *size, int idx) +{ + struct efi_device_path *instance = NULL; + efi_uintn_t instance_size = 0; + + if (!efi_dp_is_multi_instance(dp)) + return NULL; + + while (idx >= 0 && dp) { + instance = efi_dp_get_next_instance(&dp, &instance_size); + if (idx && instance) { + efi_free_pool(instance); + instance_size = 0; + instance = NULL; + } + idx--; + } + *size = instance_size; + + return instance; +} + +/** + * create_boot_var_indexed() - 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 create_boot_var_indexed(u16 var_name[], size_t var_name_size) +{ + efi_uintn_t boot_order_size; + efi_status_t ret; + u16 boot_order; + u16 *pos; + + boot_order_size = sizeof(boot_order); + ret = efi_get_variable_int(L"BootCurrent", + &efi_global_variable_guid, NULL, + &boot_order_size, &boot_order, NULL); + if (ret != EFI_SUCCESS) + goto out; + + pos = efi_create_indexed_name(var_name, var_name_size, "Boot", + boot_order); + if (!pos) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + +out: + return ret; +} + +/** + * efi_get_fp_from_var() - Retrieve and return a device path from an EFI + * Boot### variable + * + * @idx: index of the instance to retrieve + * + * Return: device path of NULL. Caller must free the returned value + */ +struct efi_device_path *efi_get_fp_from_boot(int idx) +{ + struct efi_device_path *file_path; + struct efi_load_option lo; + void *var_value = NULL; + efi_uintn_t size; + efi_status_t ret; + u16 var_name[16]; + + ret = create_boot_var_indexed(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; + + efi_deserialize_load_option(&lo, var_value, &size); + file_path = efi_dp_instance_by_idx(lo.file_path, &size, idx); + if (!file_path) { + printf("Instance not found\n"); + return NULL; + } + + return file_path; +}