From patchwork Sun Dec 19 07:05:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525850 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3052983imb; Sat, 18 Dec 2021 23:06:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJyho2QG1CV5Gsl6CaPUp8TkpDO5d/uBWLm4wndrkjmlnKR4JagQlbKVmF7H4hOTp/5PM80f X-Received: by 2002:a05:6402:84f:: with SMTP id b15mr10183456edz.377.1639897608937; Sat, 18 Dec 2021 23:06:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897608; cv=none; d=google.com; s=arc-20160816; b=b+5D04UpEYr9WDGD7qBWWqmDDIA6zZ7XbQc5s/Gmkvx0uyJfYN13skvfXoKaPO15Q4 Jjhjc/gVLavwotos2fgU1tsn1BG2daDlHuUQHheUQ1JCWN4TTANEz1pPbjixh9Jn2Wup R8nnjqIcnZ+dl8MUxPvZu/9LIerX8tmHtMWIZXxe3/8yr43csnE2UtrwEuR2TWWNvmkm dq7cLsunIpBRzkf7vCAjxlZSdw1ayoVCg+80Np1/UYjyXC/t88nUHf16+kDW508HbP2d /AcSjQRazGmaV06cQKquIb0x/DnjFJxwMPvIap54KkZL+lG5QWKrBn3GYS9ekUuFo1YY LIuA== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=L2CUw0Posqat0FAaz7EnoGO7/GDVM+Un+mHldT8OKeM=; b=sqdbJUoPJMrHqCqfgmXLDe4vEA5UgyZ9WsG+gOQeSrluJnkhx9jKwuc1oOXn8+RxHg W3jVTeL/5lTJeTxfww/l5O3qoahPQ/dchsm/+c3muOFvw/p7OnZnUwydksPrvRkvVxds OC58m6Lm81ndlsg1qyWUTv7DLiR1l99tVKYJe7rUOUwD1R+jQvpb6EWiJiL9+iDzM2v/ ieaGX7AZGM6weabO46JJ3sI59zhUHh6JlHGUXaSq0uvvxYtrbe7cjYg/wyio8u2q1cYh ZdI40YUbyWGVqh5yrRAOD1E0H5M/IeC6k1hFZIxhIYEKE7B7HjwwUcrg3uH2a3dbGSf6 nPuA== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 n9si6069967eds.447.2021.12.18.23.06.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:06:48 -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; 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=fail (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 13ED782FBC; Sun, 19 Dec 2021 08:06:40 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id A60C28307B; Sun, 19 Dec 2021 08:06:37 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 9364782F95 for ; Sun, 19 Dec 2021 08:06:31 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 96A9F12FC; Sat, 18 Dec 2021 23:06:30 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5C10D3F5A1; Sat, 18 Dec 2021 23:06:26 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 1/8] FWU: Add FWU metadata structure and functions for accessing metadata Date: Sun, 19 Dec 2021 12:35:58 +0530 Message-Id: <20211219070605.14894-2-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean In the FWU Multi Bank Update feature, the information about the updatable images is stored as part of the metadata, which is stored on a dedicated partition. Add the metadata structure, and functions to access the metadata. These are generic API's, and implementations can be added based on parameters like how the metadata partition is accessed and what type of storage device houses the metadata. Signed-off-by: Sughosh Ganu --- Changes since V1: * Move all function declarations to a separate header fwu.h * Rename metadata with mdata for all symbols * Drop the parameter in the function fwu_revert_boot_index as suggested by Etienne include/fwu.h | 28 +++++ include/fwu_mdata.h | 102 ++++++++++++++++ lib/fwu_updates/fwu_mdata.c | 236 ++++++++++++++++++++++++++++++++++++ 3 files changed, 366 insertions(+) create mode 100644 include/fwu.h create mode 100644 include/fwu_mdata.h create mode 100644 lib/fwu_updates/fwu_mdata.c diff --git a/include/fwu.h b/include/fwu.h new file mode 100644 index 0000000000..e6bc3e6b73 --- /dev/null +++ b/include/fwu.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#if !defined _FWU_H_ +#define _FWU_H_ + +#include + +#include + +#define FWU_MDATA_VERSION 0x1 + +#define FWU_MDATA_GUID \ + EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ + 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) + +int fwu_get_active_index(u32 *active_idx); +int fwu_update_active_index(u32 active_idx); +int fwu_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, + int *alt_num); +int fwu_mdata_check(void); +int fwu_revert_boot_index(void); +int fwu_accept_image(efi_guid_t *img_type_id); +int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank); + +#endif /* _FWU_H_ */ diff --git a/include/fwu_mdata.h b/include/fwu_mdata.h new file mode 100644 index 0000000000..11eb570012 --- /dev/null +++ b/include/fwu_mdata.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#if !defined _FWU_MDATA_H_ +#define _FWU_MDATA_H_ + +#include +#include + +#include + +/** + * struct fwu_image_bank_info - firmware image information + * @image_uuid: Guid value of the image in this bank + * @accepted: Acceptance status of the image + * @reserved: Reserved + * + * The structure contains image specific fields which are + * used to identify the image and to specify the image's + * acceptance status + */ +struct fwu_image_bank_info { + efi_guid_t image_uuid; + u32 accepted; + u32 reserved; +}; + +/** + * struct fwu_image_entry - information for a particular type of image + * @image_type_uuid: Guid value for identifying the image type + * @location_uuid: Guid of the storage volume where the image is located + * @img_bank_info: Array containing properties of images + * + * This structure contains information on various types of updatable + * firmware images. Each image type then contains an array of image + * information per bank. + */ +struct fwu_image_entry { + efi_guid_t image_type_uuid; + efi_guid_t location_uuid; + struct fwu_image_bank_info img_bank_info[CONFIG_FWU_NUM_BANKS]; +}; + +/** + * struct fwu_mdata - FWU metadata structure for multi-bank updates + * @crc32: crc32 value for the FWU metadata + * @version: FWU metadata version + * @active_index: Index of the bank currently used for booting images + * @previous_active_inde: Index of the bank used before the current bank + * being used for booting + * @img_entry: Array of information on various firmware images that can + * be updated + * + * This structure is used to store all the needed information for performing + * multi bank updates on the platform. This contains info on the bank being + * used to boot along with the information needed for identification of + * individual images + */ +struct fwu_mdata { + u32 crc32; + u32 version; + u32 active_index; + u32 previous_active_index; + + struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +}; + +/** + * @get_active_index: get the current active_index value + * @update_active_index: update the active_index value + * @get_image_alt_num: get the alt number to be used for the image + * @mdata_check: check the validity of the FWU metadata partitions + * @revert_boot_index: set the active_index to previous_active_index + * @set_accept_image: set the accepted bit for the image + * @clear_accept_image: clear the accepted bit for the image + * @get_mdata() - Get a FWU metadata copy + */ +struct fwu_mdata_ops { + int (*get_active_index)(u32 *active_idx); + + int (*update_active_index)(u32 active_idx); + + int (*get_image_alt_num)(efi_guid_t image_type_id, u32 update_bank, + int *alt_num); + + int (*mdata_check)(void); + + int (*revert_boot_index)(void); + + int (*set_accept_image)(efi_guid_t *img_type_id); + + int (*clear_accept_image)(efi_guid_t *img_type_id, u32 bank); + + int (*get_mdata)(struct fwu_mdata **mdata); +}; + +int fwu_get_mdata(struct fwu_mdata **mdata); +struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void); + +#endif /* _FWU_MDATA_H_ */ diff --git a/lib/fwu_updates/fwu_mdata.c b/lib/fwu_updates/fwu_mdata.c new file mode 100644 index 0000000000..348e9c85f7 --- /dev/null +++ b/lib/fwu_updates/fwu_mdata.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include + +#include +#include + +static struct fwu_mdata_ops *get_fwu_mdata_ops(void) +{ + struct fwu_mdata_ops *ops; + + ops = get_plat_fwu_mdata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return NULL; + } + + return ops; +} + +/** + * fwu_get_active_index() - Get active_index from the FWU metadata + * @active_idx: active_index value to be read + * + * Read the active_index field from the FWU metadata and place it in + * the variable pointed to be the function argument. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_get_active_index(u32 *active_idx) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->get_active_index) { + log_err("get_active_index() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->get_active_index(active_idx); +} + +/** + * fwu_update_active_index() - Update active_index from the FWU metadata + * @active_idx: active_index value to be updated + * + * Update the active_index field in the FWU metadata + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_update_active_index(u32 active_idx) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->update_active_index) { + log_err("update_active_index() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->update_active_index(active_idx); +} + +/** + * fwu_get_image_alt_num() - Get the dfu alt number to be used for capsule update + * @image_type_id: image guid as passed in the capsule + * @update_bank: Bank to which the update is to be made + * @alt_num: The alt_num for the image + * + * Based on the guid value passed in the capsule, along with the bank to which the + * image needs to be updated, get the dfu alt number which will be used for the + * capsule update + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, + int *alt_num) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->get_image_alt_num) { + log_err("get_image_alt_num() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->get_image_alt_num(image_type_id, update_bank, alt_num); +} + +/** + * fwu_mdata_check() - Check if the FWU metadata is valid + * + * Validate both copies of the FWU metadata. If one of the copies + * has gone bad, restore it from the other bad copy. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_mdata_check(void) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->mdata_check) { + log_err("mdata_check() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->mdata_check(); +} + +/** + * fwu_revert_boot_index() - Revert the active index in the FWU metadata + * + * Revert the active_index value in the FWU metadata, by swapping the values + * of active_index and previous_active_index in both copies of the + * FWU metadata. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_revert_boot_index(void) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->revert_boot_index) { + log_err("revert_boot_index() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->revert_boot_index(); +} + +/** + * fwu_accept_image() - Set the Acceptance bit for the image + * @img_type_id: Guid of the image type for which the accepted bit is to be + * cleared + * + * Set the accepted bit for the image specified by the img_guid parameter. This + * indicates acceptance of image for subsequent boots by some governing component + * like OS(or firmware). + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_accept_image(efi_guid_t *img_type_id) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->set_accept_image) { + log_err("set_accept_image() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->set_accept_image(img_type_id); +} + +/** + * fwu_clear_accept_image() - Clear the Acceptance bit for the image + * @img_type_id: Guid of the image type for which the accepted bit is to be + * cleared + * + * Clear the accepted bit for the image type specified by the img_type_id parameter. + * This function is called after the image has been updated. The accepted bit is + * cleared to be set subsequently after passing the image acceptance criteria, by + * either the OS(or firmware) + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->clear_accept_image) { + log_err("clear_accept_image() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->clear_accept_image(img_type_id, bank); +} + +/** + * fwu_get_mdata() - Get a FWU metadata copy + * @mdata: Copy of the FWU metadata + * + * Get a valid copy of the FWU metadata. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_get_mdata(struct fwu_mdata **mdata) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->get_mdata) { + log_err("get_mdata() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->get_mdata(mdata); +} From patchwork Sun Dec 19 07:05:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525851 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053076imb; Sat, 18 Dec 2021 23:06:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJxanx7EZsApZWTx9hs0QyrrsEV3Trnq0qHwVpwwGatLMsbxz6Xz2TCZoytoA2PezEQd+oy9 X-Received: by 2002:a17:907:86aa:: with SMTP id qa42mr8720949ejc.690.1639897619334; Sat, 18 Dec 2021 23:06:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897619; cv=none; d=google.com; s=arc-20160816; b=0SM0hWY7Kw6lwWHdPgYbcMtLhEq3b/Ubg5gpgrqQROLpLnYSBNNtZcOoSUKmGkBT32 SqlBEoUZl9cgofmI5LkAjMQ3oz9ulQAf/uHAfmVzy9C3UVfFd3Th/UrOe+23Hvc1oAUj K6vdLSVi/zSLITf86fPxshNslfSv+TI1IJ6QH2H+FZhFWq9ajuet8PLp3SOrWhWFwWHJ Q/KfK+AUe1/hqENpuk1x1otsIXAq64L3gfVoh5thacsrwnhEKLtGXsw5aRlUocfc32Gt vVAODBs6kBfQ2Xxh4+rZndP1EyV4IgIq3aML/i8O55GivIZhDVmhGgJg6DMkLBJlKHQP qnqg== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=1+azW6JYtm4maya9V5vkgVc+RmMQ1MrQtp2C+349fI8=; b=PTDDUv6pxFQFxY/X+pIv2pc46JPPBJBMLOvbctyEP6wM3nZhC7aZGzxZ3e5L9RAOUu q3/q2+TC5WKW6KrMog1Wdk6Oj04oJ7iz1QuOfRoGnv9a908TDte86S77/5b+nww/HIHM Bx1QPSRd8KaenE0By/8t8HFjgEtO8Z0GOqQpidsPI8onydnLvrnfHSubMRRF2WhDQtcc FJBmT464zj0+b1YT8EcFEs4eD+luY2kxdiUrfJCp6Uj/Au8nAS3uOenbf9XQnVD6kSF8 HED5XSHnBC19OHt8/wMzBJevJ7aKluUcrpwzplgZ6ksuNaFwnm3rB/pM7HeCmSWenH8/ EVGg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id s19si9342315edd.16.2021.12.18.23.06.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:06:59 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (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 B48B3830CA; Sun, 19 Dec 2021 08:06:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 1ED93830BE; Sun, 19 Dec 2021 08:06:44 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 0E5B083076 for ; Sun, 19 Dec 2021 08:06:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 49FDC11B3; Sat, 18 Dec 2021 23:06:35 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 12C103F5A1; Sat, 18 Dec 2021 23:06:30 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 2/8] FWU: Add FWU metadata access functions for GPT partitioned block devices Date: Sun, 19 Dec 2021 12:35:59 +0530 Message-Id: <20211219070605.14894-3-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean In the FWU Multi Bank Update feature, the information about the updatable images is stored as part of the metadata, on a separate partition. Add functions for reading from and writing to the metadata when the updatable images and the metadata are stored on a block device which is formated with GPT based partition scheme. Signed-off-by: Sughosh Ganu --- Changes since V1: * Rename metadata with mdata for all symbols * Use BIT for all macros * Use the logic suggested by Patrick to get the partition type guids and partition guid's instead of defining a new api * Call the platform function fwu_plat_get_alt_num for getting the alt_num for the image partition, instead of the earlier hard-coded approach. * Change the logic in gpt_check_mdata_validity as suggested by Ilias. * Other smaller code style changes suggested by Ilias include/fwu_mdata.h | 2 + lib/fwu_updates/fwu_mdata_gpt_blk.c | 634 ++++++++++++++++++++++++++++ 2 files changed, 636 insertions(+) create mode 100644 lib/fwu_updates/fwu_mdata_gpt_blk.c diff --git a/include/fwu_mdata.h b/include/fwu_mdata.h index 11eb570012..9e24ab4047 100644 --- a/include/fwu_mdata.h +++ b/include/fwu_mdata.h @@ -99,4 +99,6 @@ struct fwu_mdata_ops { int fwu_get_mdata(struct fwu_mdata **mdata); struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void); +extern struct fwu_mdata_ops fwu_gpt_blk_ops; + #endif /* _FWU_MDATA_H_ */ diff --git a/lib/fwu_updates/fwu_mdata_gpt_blk.c b/lib/fwu_updates/fwu_mdata_gpt_blk.c new file mode 100644 index 0000000000..2dcac0c3d4 --- /dev/null +++ b/lib/fwu_updates/fwu_mdata_gpt_blk.c @@ -0,0 +1,634 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PRIMARY_PART BIT(0) +#define SECONDARY_PART BIT(1) +#define BOTH_PARTS (PRIMARY_PART | SECONDARY_PART) + +#define MDATA_READ BIT(0) +#define MDATA_WRITE BIT(1) + +#define IMAGE_ACCEPT_SET BIT(0) +#define IMAGE_ACCEPT_CLEAR BIT(1) + +static int gpt_verify_mdata(struct fwu_mdata *mdata, bool pri_part) +{ + u32 calc_crc32; + void *buf; + + buf = &mdata->version; + calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + + if (calc_crc32 != mdata->crc32) { + log_err("crc32 check failed for %s FWU metadata partition\n", + pri_part ? "primary" : "secondary"); + return -1; + } + + return 0; +} + +static int gpt_get_mdata_partitions(struct blk_desc *desc, + u16 *primary_mpart, + u16 *secondary_mpart) +{ + int i, ret; + u32 mdata_parts; + efi_guid_t part_type_guid; + struct disk_partition info; + const efi_guid_t fwu_mdata_guid = FWU_MDATA_GUID; + + for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) { + if (part_get_info(desc, i, &info)) + continue; + uuid_str_to_bin(info.type_guid, part_type_guid.b, + UUID_STR_FORMAT_GUID); + + if (!guidcmp(&fwu_mdata_guid, &part_type_guid)) { + ++mdata_parts; + if (!*primary_mpart) + *primary_mpart = i; + else + *secondary_mpart = i; + } + } + + if (mdata_parts != 2) { + log_err("Expect two copies of the FWU metadata instead of %d\n", + mdata_parts); + ret = -EINVAL; + } else { + ret = 0; + } + + return ret; +} + +static int gpt_get_mdata_disk_part(struct blk_desc *desc, + struct disk_partition *info, + u32 part_num) +{ + int ret; + char *mdata_guid_str = "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23"; + + ret = part_get_info(desc, part_num, info); + if (ret < 0) { + log_err("Unable to get the partition info for the FWU metadata part %d", + part_num); + return -1; + } + + /* Check that it is indeed the FWU metadata partition */ + if (!strncmp(info->type_guid, mdata_guid_str, UUID_STR_LEN)) { + /* Found the FWU metadata partition */ + return 0; + } + + return -1; +} + +static int gpt_read_write_mdata(struct blk_desc *desc, + struct fwu_mdata *mdata, + u8 access, u32 part_num) +{ + int ret; + u32 len, blk_start, blkcnt; + struct disk_partition info; + + ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_mdata, mdata_aligned, 1, + desc->blksz); + + ret = gpt_get_mdata_disk_part(desc, &info, part_num); + if (ret < 0) { + printf("Unable to get the FWU metadata partition\n"); + return -ENODEV; + } + + len = sizeof(*mdata); + blkcnt = BLOCK_CNT(len, desc); + if (blkcnt > info.size) { + log_err("Block count exceeds FWU metadata partition size\n"); + return -ERANGE; + } + + blk_start = info.start; + if (access == MDATA_READ) { + if (blk_dread(desc, blk_start, blkcnt, mdata_aligned) != blkcnt) { + log_err("Error reading FWU metadata from the device\n"); + return -EIO; + } + memcpy(mdata, mdata_aligned, sizeof(struct fwu_mdata)); + } else { + if (blk_dwrite(desc, blk_start, blkcnt, mdata) != blkcnt) { + log_err("Error writing FWU metadata to the device\n"); + return -EIO; + } + } + + return 0; +} + +static int gpt_read_mdata(struct blk_desc *desc, + struct fwu_mdata *mdata, u32 part_num) +{ + return gpt_read_write_mdata(desc, mdata, MDATA_READ, part_num); +} + +static int gpt_write_mdata_partition(struct blk_desc *desc, + struct fwu_mdata *mdata, + u32 part_num) +{ + return gpt_read_write_mdata(desc, mdata, MDATA_WRITE, part_num); +} + +static int gpt_update_mdata(struct fwu_mdata *mdata) +{ + int ret; + struct blk_desc *desc; + u16 primary_mpart = 0, secondary_mpart = 0; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + ret = gpt_get_mdata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the FWU metadata partitions\n"); + return -ENODEV; + } + + /* First write the primary partition*/ + ret = gpt_write_mdata_partition(desc, mdata, primary_mpart); + if (ret < 0) { + log_err("Updating primary FWU metadata partition failed\n"); + return ret; + } + + /* And now the replica */ + ret = gpt_write_mdata_partition(desc, mdata, secondary_mpart); + if (ret < 0) { + log_err("Updating secondary FWU metadata partition failed\n"); + return ret; + } + + return 0; +} + +static int gpt_get_mdata(struct fwu_mdata **mdata) +{ + int ret; + struct blk_desc *desc; + u16 primary_mpart = 0, secondary_mpart = 0; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + ret = gpt_get_mdata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the FWU metadata partitions\n"); + return -ENODEV; + } + + *mdata = malloc(sizeof(struct fwu_mdata)); + if (!*mdata) { + log_err("Unable to allocate memory for reading FWU metadata\n"); + return -ENOMEM; + } + + ret = gpt_read_mdata(desc, *mdata, primary_mpart); + if (ret < 0) { + log_err("Failed to read the FWU metadata from the device\n"); + return -EIO; + } + + ret = gpt_verify_mdata(*mdata, 1); + if (!ret) + return 0; + + /* + * Verification of the primary FWU metadata copy failed. + * Try to read the replica. + */ + memset(*mdata, 0, sizeof(struct fwu_mdata)); + ret = gpt_read_mdata(desc, *mdata, secondary_mpart); + if (ret < 0) { + log_err("Failed to read the FWU metadata from the device\n"); + return -EIO; + } + + ret = gpt_verify_mdata(*mdata, 0); + if (!ret) + return 0; + + /* Both the FWU metadata copies are corrupted. */ + return -1; +} + +static int gpt_check_mdata_validity(void) +{ + int ret; + struct blk_desc *desc; + struct fwu_mdata pri_mdata; + struct fwu_mdata secondary_mdata; + u16 primary_mpart = 0, secondary_mpart = 0; + u16 valid_partitions, invalid_partitions; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + /* + * Two FWU metadata partitions are expected. + * If we don't have two, user needs to create + * them first + */ + valid_partitions = 0; + ret = gpt_get_mdata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the FWU metadata partitions\n"); + return -ENODEV; + } + + ret = gpt_read_mdata(desc, &pri_mdata, primary_mpart); + if (ret < 0) { + log_err("Failed to read the FWU metadata from the device\n"); + goto secondary_read; + } + + ret = gpt_verify_mdata(&pri_mdata, 1); + if (!ret) + valid_partitions |= PRIMARY_PART; + +secondary_read: + /* Now check the secondary partition */ + ret = gpt_read_mdata(desc, &secondary_mdata, secondary_mpart); + if (ret < 0) { + log_err("Failed to read the FWU metadata from the device\n"); + goto mdata_restore; + } + + ret = gpt_verify_mdata(&secondary_mdata, 0); + if (!ret) + valid_partitions |= SECONDARY_PART; + +mdata_restore: + if (valid_partitions == (PRIMARY_PART | SECONDARY_PART)) { + ret = -1; + /* + * Before returning, check that both the + * FWU metadata copies are the same. If not, + * the FWU metadata copies need to be + * re-populated. + */ + if (!memcmp(&pri_mdata, &secondary_mdata, + sizeof(struct fwu_mdata))) { + ret = 0; + } else { + log_err("Both FWU metadata copies are valid but do not match. Please check!\n"); + } + goto out; + } + + ret = -1; + if (!(valid_partitions & BOTH_PARTS)) + goto out; + + invalid_partitions = valid_partitions ^ BOTH_PARTS; + ret = gpt_write_mdata_partition(desc, + (invalid_partitions == PRIMARY_PART) ? + &secondary_mdata : &pri_mdata, + (invalid_partitions == PRIMARY_PART) ? + primary_mpart : secondary_mpart); + + if (ret < 0) + log_err("Restoring %s FWU metadata partition failed\n", + (invalid_partitions == PRIMARY_PART) ? + "primary" : "secondary"); + +out: + return ret; +} + +int fwu_gpt_get_active_index(u32 *active_idx) +{ + int ret; + struct fwu_mdata *mdata; + + ret = gpt_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to get valid FWU metadata\n"); + goto out; + } + + /* + * Found the FWU metadata partition, now read the active_index + * value + */ + *active_idx = mdata->active_index; + if (*active_idx > CONFIG_FWU_NUM_BANKS - 1) { + printf("Active index value read is incorrect\n"); + ret = -EINVAL; + goto out; + } + +out: + free(mdata); + + return ret; +} + +static int gpt_get_image_alt_num(struct blk_desc *desc, + efi_guid_t image_type_id, + u32 update_bank, int *alt_no) +{ + int ret, i; + u32 part; + struct fwu_mdata *mdata; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + struct disk_partition info; + efi_guid_t unique_part_guid; + efi_guid_t image_guid = NULL_GUID; + + ret = gpt_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to read valid FWU metadata\n"); + goto out; + } + + /* + * The FWU metadata has been read. Now get the image_uuid for the + * image with the update_bank. + */ + for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { + if (!guidcmp(&image_type_id, + &mdata->img_entry[i].image_type_uuid)) { + img_entry = &mdata->img_entry[i]; + img_bank_info = &img_entry->img_bank_info[update_bank]; + guidcpy(&image_guid, &img_bank_info->image_uuid); + break; + } + } + + /* + * Now read the GPT Partition Table Entries to find a matching + * partition with UniquePartitionGuid value. We need to iterate + * through all the GPT partitions since they might be in any + * order + */ + for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) { + if (part_get_info(desc, i, &info)) + continue; + uuid_str_to_bin(info.uuid, unique_part_guid.b, + UUID_STR_FORMAT_GUID); + + if (!guidcmp(&unique_part_guid, &image_guid)) { + /* Found the partition */ + part = i; + *alt_no = fwu_plat_get_alt_num(desc->devnum, &part); + if (*alt_no != -1) + log_info("alt_num %d for partition %pUl\n", + *alt_no, &image_guid); + ret = 0; + break; + } + } + + if (*alt_no == -1) { + log_err("alt_num not found for partition with GUID %pUl\n", + &image_guid); + ret = -EINVAL; + } + + if (i == MAX_SEARCH_PARTITIONS) { + log_err("Partition with the image guid not found\n"); + ret = -EINVAL; + } + +out: + free(mdata); + + return ret; +} + +int fwu_gpt_update_active_index(u32 active_idx) +{ + int ret; + void *buf; + struct fwu_mdata *mdata; + + if (active_idx > CONFIG_FWU_NUM_BANKS) { + printf("Active index value to be updated is incorrect\n"); + return -1; + } + + ret = gpt_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to get valid FWU metadata\n"); + goto out; + } + + /* + * Update the active index and previous_active_index fields + * in the FWU metadata + */ + mdata->previous_active_index = mdata->active_index; + mdata->active_index = active_idx; + + + /* + * Calculate the crc32 for the updated FWU metadata + * and put the updated value in the FWU metadata crc32 + * field + */ + buf = &mdata->version; + mdata->crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + + /* + * Now write this updated FWU metadata to both the + * FWU metadata partitions + */ + ret = gpt_update_mdata(mdata); + if (ret < 0) { + log_err("Failed to update FWU metadata partitions\n"); + ret = -EIO; + } + +out: + free(mdata); + + return ret; +} + +int fwu_gpt_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, + int *alt_no) +{ + int ret; + struct blk_desc *desc; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + return gpt_get_image_alt_num(desc, image_type_id, update_bank, alt_no); +} + +int fwu_gpt_mdata_check(void) +{ + /* + * Check if both the copies of the FWU metadata are + * valid. If one has gone bad, restore it from the + * other good copy. + */ + return gpt_check_mdata_validity(); +} + +int fwu_gpt_get_mdata(struct fwu_mdata **mdata) +{ + return gpt_get_mdata(mdata); +} + +int fwu_gpt_revert_boot_index(void) +{ + int ret; + void *buf; + u32 cur_active_index; + struct fwu_mdata *mdata; + + ret = gpt_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to get valid FWU metadata\n"); + goto out; + } + + /* + * Swap the active index and previous_active_index fields + * in the FWU metadata + */ + cur_active_index = mdata->active_index; + mdata->active_index = mdata->previous_active_index; + mdata->previous_active_index = cur_active_index; + + /* + * Calculate the crc32 for the updated FWU metadata + * and put the updated value in the FWU metadata crc32 + * field + */ + buf = &mdata->version; + mdata->crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + + /* + * Now write this updated FWU metadata to both the + * FWU metadata partitions + */ + ret = gpt_update_mdata(mdata); + if (ret < 0) { + log_err("Failed to update FWU metadata partitions\n"); + ret = -EIO; + } + +out: + free(mdata); + + return ret; +} + +static int fwu_gpt_set_clear_image_accept(efi_guid_t *img_type_id, + u32 bank, u8 action) +{ + void *buf; + int ret, i; + u32 nimages; + struct fwu_mdata *mdata; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + ret = gpt_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to get valid FWU metadata\n"); + goto out; + } + + if (action == IMAGE_ACCEPT_SET) + bank = mdata->active_index; + + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + img_entry = &mdata->img_entry[0]; + for (i = 0; i < nimages; i++) { + if (!guidcmp(&img_entry[i].image_type_uuid, img_type_id)) { + img_bank_info = &img_entry[i].img_bank_info[bank]; + if (action == IMAGE_ACCEPT_SET) + img_bank_info->accepted |= FWU_IMAGE_ACCEPTED; + else + img_bank_info->accepted = 0; + + buf = &mdata->version; + mdata->crc32 = crc32(0, buf, sizeof(*mdata) - + sizeof(u32)); + + ret = gpt_update_mdata(mdata); + goto out; + } + } + + /* Image not found */ + ret = -EINVAL; + +out: + free(mdata); + + return ret; +} + +int fwu_gpt_accept_image(efi_guid_t *img_type_id) +{ + return fwu_gpt_set_clear_image_accept(img_type_id, 0, + IMAGE_ACCEPT_SET); +} + +int fwu_gpt_clear_accept_image(efi_guid_t *img_type_id, u32 bank) +{ + return fwu_gpt_set_clear_image_accept(img_type_id, bank, + IMAGE_ACCEPT_CLEAR); +} + +struct fwu_mdata_ops fwu_gpt_blk_ops = { + .get_active_index = fwu_gpt_get_active_index, + .update_active_index = fwu_gpt_update_active_index, + .get_image_alt_num = fwu_gpt_get_image_alt_num, + .mdata_check = fwu_gpt_mdata_check, + .revert_boot_index = fwu_gpt_revert_boot_index, + .set_accept_image = fwu_gpt_accept_image, + .clear_accept_image = fwu_gpt_clear_accept_image, + .get_mdata = fwu_gpt_get_mdata, +}; From patchwork Sun Dec 19 07:06:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525852 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053162imb; Sat, 18 Dec 2021 23:07:09 -0800 (PST) X-Google-Smtp-Source: ABdhPJzhG7CGxs/L0IVJVe7G+XFYJBUf8xt6IrbXXdgKZ19vow2n7ylwtn9s0Vb9ieAyIvEGRMsc X-Received: by 2002:a17:906:b758:: with SMTP id fx24mr8393834ejb.640.1639897629574; Sat, 18 Dec 2021 23:07:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897629; cv=none; d=google.com; s=arc-20160816; b=qpXfcG7NmTx14buacMIbGB6r9B5IXnhLDub/WFSwjiIj1wVZmTzuHJMcxG8sk9uzw2 hku2ZJHsyOygkoP7OgMMCgPD628b0uIYpBtRK5p80M8ABJomkzWNz1lxd0QRv3Wdygxt 97PaFfsBUq/8ISs8j7+0UPPbG5co99V2QQK7RZ65oBaynMXJeDIUimp2vJ27hpUw+x2U zLw8ppp0+inV1PD0wO6xSM+HrxRf1UWvF3SKQgS5tddPwfJM2i3Xa48aUjGM9rtUY2Xr ElV239f4+yvjYnAPV0NifSOzBZ1ISGTU/kXbK//4QA/UthCiyoVzYHDXicgaPu5Onb7p UFuQ== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=b3AhdexrjX4u9MeI97iXLWbsvjt3i4pvogiaTqj/Swg=; b=TEPpzsBfFP3sUdtyRv4aA/c9mlgcW9DA0dvIzTggWFZmgP3Gf49pgOe0R3O/i1u7xo IGn60oQN5Yp8uH/qbO9enASkJGQmhMdRj/cGaVDO/+yrHbXX0ReAR1E90KGG+pAd+JoX 3jOh9EI2z8c0x3voeOzP8RUV5e4hz2zAkF1Z9tmSLeeLyi+kh6uMgOeI0o5ofmA9T+ko 5mlOr4csMzMNxDEbefvSaw5j29FbFLcXQjWqZZKgiyw955Hlr3dPD6ZpDcjvz7qSJiqR xkQ1xCs7SYjD+7KamM3MEDwg7U1hfDH/iGGPPGLBLRE0MQ4LL6Z9hVnsyqqZoktnQLBC 8Rzg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 r24si8348736ejy.396.2021.12.18.23.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:09 -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; 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=fail (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 ABE7183176; Sun, 19 Dec 2021 08:06:53 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 86D768304A; Sun, 19 Dec 2021 08:06:47 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 6A9988307B for ; Sun, 19 Dec 2021 08:06:40 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B80CD11B3; Sat, 18 Dec 2021 23:06:39 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B9AC03F5A1; Sat, 18 Dec 2021 23:06:35 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 3/8] FWU: stm32mp1: Add helper functions for accessing FWU metadata Date: Sun, 19 Dec 2021 12:36:00 +0530 Message-Id: <20211219070605.14894-4-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add helper functions needed for accessing the FWU metadata which contains information on the updatable images. These functions have been added for the STM32MP157C-DK2 board which has the updatable images on the uSD card, formatted as GPT partitions. Signed-off-by: Sughosh Ganu --- Changes since V1: * Define a new function fwu_plat_get_alt_num using logic suggested by Patrick for returning the alt_num for the partition * Define a new function plat_fill_gpt_partition_guids to fill the guid array with Partition Type guids board/st/stm32mp1/stm32mp1.c | 162 ++++++++++++++++++++++++++++ include/fwu.h | 5 + lib/fwu_updates/fwu_mdata_gpt_blk.c | 11 +- 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 84592677e4..28402fd127 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -7,10 +7,13 @@ #include #include +#include #include #include #include +#include #include +#include #include #include #include @@ -23,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -938,3 +943,160 @@ static void board_copro_image_process(ulong fw_image, size_t fw_size) } U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process); + +#if defined(CONFIG_FWU_MULTI_BANK_UPDATE) +#include +#include + +int fwu_plat_get_alt_num(int dev_num, void *identifier) +{ + int i; + int ret = -1; + u32 part; + int alt_num = dfu_get_alt_number(); + struct dfu_entity *dfu; + + part = *(u32 *)identifier; + dfu_init_env_entities(NULL, NULL); + + for (i = 0; i < alt_num; i++) { + dfu = dfu_get_entity(i); + + if (!dfu) + continue; + + /* + * Currently, Multi Bank update + * feature is being supported + * only on GPT partitioned + * MMC/SD devices. + */ + if (dfu->dev_type != DFU_DEV_MMC) + continue; + + if (dfu->layout == DFU_RAW_ADDR && + dfu->data.mmc.dev_num == dev_num && + dfu->data.mmc.part == part) { + ret = dfu->alt; + break; + } + } + + dfu_free_entities(); + + return ret; +} + +static int plat_fill_gpt_partition_guids(struct blk_desc *desc, + efi_guid_t **part_guid_arr) +{ + int i, ret = 0; + u32 part; + struct dfu_entity *dfu; + struct disk_partition info; + efi_guid_t part_type_guid; + int alt_num = dfu_get_alt_number(); + + dfu_init_env_entities(NULL, NULL); + + for (i = 0, part = 1; i < alt_num; i++) { + dfu = dfu_get_entity(i); + + if (!dfu) + continue; + + /* + * Currently, Multi Bank update + * feature is being supported + * only on GPT partitioned + * MMC/SD devices. + */ + if (dfu->dev_type != DFU_DEV_MMC) + continue; + + if (part_get_info(desc, part, &info)) { + part++; + continue; + } + + uuid_str_to_bin(info.type_guid, part_type_guid.b, + UUID_STR_FORMAT_GUID); + guidcpy((*part_guid_arr + i), &part_type_guid); + part++; + } + + dfu_free_entities(); + + return ret; +} + +int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr) +{ + int ret; + struct blk_desc *desc; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + return plat_fill_gpt_partition_guids(desc, part_guid_arr); +} + +int fwu_plat_get_update_index(u32 *update_idx) +{ + int ret; + u32 active_idx; + + ret = fwu_get_active_index(&active_idx); + + if (ret < 0) + return -1; + + *update_idx = active_idx ^= 0x1; + + return ret; +} + +int fwu_plat_get_blk_desc(struct blk_desc **desc) +{ + int ret; + struct mmc *mmc; + struct udevice *dev; + + /* + * Initial support is being added for the DK2 + * platform + */ + if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && + (of_machine_is_compatible("st,stm32mp157c-dk2"))) { + ret = uclass_get_device(UCLASS_MMC, 0, &dev); + if (ret) + return -1; + + mmc = mmc_get_mmc_dev(dev); + if (!mmc) + return -1; + + if (mmc_init(mmc)) + return -1; + + *desc = mmc_get_blk_desc(mmc); + if (!*desc) + return -1; + } + + return 0; +} + +struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void) +{ + if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && + (of_machine_is_compatible("st,stm32mp157c-dk2"))) { + return &fwu_gpt_blk_ops; + } + + return NULL; +} +#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */ diff --git a/include/fwu.h b/include/fwu.h index e6bc3e6b73..1e7a1eabff 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -25,4 +25,9 @@ int fwu_revert_boot_index(void); int fwu_accept_image(efi_guid_t *img_type_id); int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank); +int fwu_plat_get_update_index(u32 *update_idx); +int fwu_plat_get_blk_desc(struct blk_desc **desc); +int fwu_plat_get_alt_num(int dev_num, void *identifier); +int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr); + #endif /* _FWU_H_ */ diff --git a/lib/fwu_updates/fwu_mdata_gpt_blk.c b/lib/fwu_updates/fwu_mdata_gpt_blk.c index 2dcac0c3d4..6a2fa176f9 100644 --- a/lib/fwu_updates/fwu_mdata_gpt_blk.c +++ b/lib/fwu_updates/fwu_mdata_gpt_blk.c @@ -53,6 +53,7 @@ static int gpt_get_mdata_partitions(struct blk_desc *desc, struct disk_partition info; const efi_guid_t fwu_mdata_guid = FWU_MDATA_GUID; + mdata_parts = 0; for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) { if (part_get_info(desc, i, &info)) continue; @@ -340,7 +341,7 @@ out: int fwu_gpt_get_active_index(u32 *active_idx) { int ret; - struct fwu_mdata *mdata; + struct fwu_mdata *mdata = NULL; ret = gpt_get_mdata(&mdata); if (ret < 0) { @@ -371,7 +372,7 @@ static int gpt_get_image_alt_num(struct blk_desc *desc, { int ret, i; u32 part; - struct fwu_mdata *mdata; + struct fwu_mdata *mdata = NULL; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info; struct disk_partition info; @@ -443,7 +444,7 @@ int fwu_gpt_update_active_index(u32 active_idx) { int ret; void *buf; - struct fwu_mdata *mdata; + struct fwu_mdata *mdata = NULL; if (active_idx > CONFIG_FWU_NUM_BANKS) { printf("Active index value to be updated is incorrect\n"); @@ -523,7 +524,7 @@ int fwu_gpt_revert_boot_index(void) int ret; void *buf; u32 cur_active_index; - struct fwu_mdata *mdata; + struct fwu_mdata *mdata = NULL; ret = gpt_get_mdata(&mdata); if (ret < 0) { @@ -569,7 +570,7 @@ static int fwu_gpt_set_clear_image_accept(efi_guid_t *img_type_id, void *buf; int ret, i; u32 nimages; - struct fwu_mdata *mdata; + struct fwu_mdata *mdata = NULL; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info; From patchwork Sun Dec 19 07:06:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525853 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053233imb; Sat, 18 Dec 2021 23:07:19 -0800 (PST) X-Google-Smtp-Source: ABdhPJzy/DBYAqAm2aACOrKvSeLcjw+ZCFY+4wt4KM21cXuscpo74CC6ziMXpVztscdOI0rk7yoI X-Received: by 2002:a05:6402:445:: with SMTP id p5mr10334219edw.110.1639897638971; Sat, 18 Dec 2021 23:07:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897638; cv=none; d=google.com; s=arc-20160816; b=eUTFhIh9PVFWJR1Y4ezyJhsDePprxIZzxW6TYTCu4dKsPjrqe8u3xaIRQnIlL0ygtP O9PFYPDP0zjXWWPemQJhG75ksqhSa1/uYAn0Hh8ixwX1q5RDS6TJ0pmzXUtzAu5/MPzm 35viCFj+hyDGhSLD2eCMi1p41cEqjZaIFkMyVx4VeDqw2Tzeh6SL0nebnIvroYC2OvA8 asj39ERcSD/mlYqc6hUKfFmbLl6AlQz5DrEQAD/G0DuHOO7iGq8aHCnVwtypG+QObwUt /v+MSZFrP2yGxSeDJOawpx9bLATHV18BufsUsxYK2uI7FVT0lt3sAtZuA2JwCVAfIdvi 28VQ== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=7IbFXfSx1vOLnKoUhMhl50fEHsFg2Yqf0/a9SP6w4VU=; b=rlwTpYhz0KmJzgl2Yw4RhuUblIVbKaz/M4UM4qOUqQPynV+FUX3rRYZC0+LJpKMovq W7RzrJ+z9XCCRvwFBAMtwbzbX+owGsriSXMJMpoxjwcBMQUkctAjuEMgwcztP97FP64w YL2UtZ3kpMsM3pWWuSBz3015uaiMXcKTlSl8H/lGT8a8kCQXqcTRqobuoIXvQ+bkEvFp UVeewTcCKp0NOXnqGHEZACCeIskoNA1F1HVTrk/JV8fYWlYJBIMttdFqr5KgZhN9HuwD aHcecxnPRhQOUwSKebW+97q2kMDrvkEZe77v7v8Ma6twIcad341rgWM/pClguLhHLEfS SpNw== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 g18si1045862edb.144.2021.12.18.23.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:18 -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; 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=fail (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 38E1A830C4; Sun, 19 Dec 2021 08:07:00 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id A76E88307B; Sun, 19 Dec 2021 08:06:49 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id E15E983076 for ; Sun, 19 Dec 2021 08:06:44 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 33D5F11B3; Sat, 18 Dec 2021 23:06:44 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 33EC03F5A1; Sat, 18 Dec 2021 23:06:39 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 4/8] FWU: STM32MP1: Add support to read boot index from backup register Date: Sun, 19 Dec 2021 12:36:01 +0530 Message-Id: <20211219070605.14894-5-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean The FWU Multi Bank Update feature allows the platform to boot the firmware images from one of the partitions(banks). The first stage bootloader(fsbl) passes the value of the boot index, i.e. the bank from which the firmware images were booted from to U-Boot. On the STM32MP157C-DK2 board, this value is passed through one of the SoC's backup register. Add a function to read the boot index value from the backup register. Signed-off-by: Sughosh Ganu --- Changes since V1: * Use the TAMP_BOOTCOUNT register as suggested by Yann Gautier instead of the earlier unused register 10 board/st/stm32mp1/stm32mp1.c | 7 +++++++ include/fwu.h | 1 + 2 files changed, 8 insertions(+) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 28402fd127..a8543c6410 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -1090,6 +1090,13 @@ int fwu_plat_get_blk_desc(struct blk_desc **desc) return 0; } +void fwu_plat_get_bootidx(void *boot_idx) +{ + u32 *bootidx = boot_idx; + + *bootidx = readl(TAMP_BOOTCOUNT); +} + struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void) { if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && diff --git a/include/fwu.h b/include/fwu.h index 1e7a1eabff..5ba437798d 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -29,5 +29,6 @@ int fwu_plat_get_update_index(u32 *update_idx); int fwu_plat_get_blk_desc(struct blk_desc **desc); int fwu_plat_get_alt_num(int dev_num, void *identifier); int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr); +void fwu_plat_get_bootidx(void *boot_idx); #endif /* _FWU_H_ */ From patchwork Sun Dec 19 07:06:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525854 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053315imb; Sat, 18 Dec 2021 23:07:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJznR/Kw1dJu4sDfNDglY/Bx43LrxDYn5SS3dmBDOGnhogqmvezRNuHgMecFlqFB6LQBqFwb X-Received: by 2002:a17:906:3cd:: with SMTP id c13mr8531560eja.285.1639897649629; Sat, 18 Dec 2021 23:07:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897649; cv=none; d=google.com; s=arc-20160816; b=QMAsO2KnmQI3Y/tXB1rxMU9fI0NKJJd1Vv1VgoolTTos+uXEJy33C029V3dbLs/E5W 0ePn653dPJvHffSpJA7eWcLtPQC1fXfyvUUdb46baYj/ZAUWSMR7029NzX/aT/s3k92N xxyOTRkOn5UGUTxvmZZXz4YGrxb2QTi1iYYtyOPkgDECLqux2EpS2hCMf82KVJLZFjYJ Unmo8kIP51nydQRbmlI/ASjXvxI065Gf1NFBpIYXuQSAYQMFkzQ95guPxEvR0Cl4drzQ 4UI7GW8XaApmqv3CiKRk8i6S7jcKj+iYjyF0DE312pOK0otEbRtBRkoh3Tbr7dMFS7YT zTiA== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=MZ8LqkjyxqR4c4Y8kIqjRM2qIvVyUW6Rfvr65r4qNz4=; b=cLzwOHxjQGG2yifNQOKyNklMMJFGvMw1dKZjXIoIrWArlLxPQ0WnR7Hmwd7MLFElWp dNmZmYuHWkfufxx5sSr0XeSS2TQuAY78rDvlc561ZhXWyH1kM4nETdmn4H+APia+iMD5 N4mMMeJijvWHt8Wy9Gt9MlXQetllQ06MULfeqIpRrv7t/Jcx29ZikR4HyZmGJT5YXyJU 8EeIeUdgpLfprIIbi51LX42TbimQOUjsJRmn2WtwRN9VlWaZ9CZHOvmnZMdgPcUpQwvl ShlPBZMBezG4DYMTRKkM92icR18p/a4AS7HAnM7OeCgOavQO5lxElYnMSO0H4zL0Oy6r +61A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id b20si5912652ejz.420.2021.12.18.23.07.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:29 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (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 4C5D9830AF; Sun, 19 Dec 2021 08:07:07 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 108B6831D7; Sun, 19 Dec 2021 08:06:55 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 37211830A0 for ; Sun, 19 Dec 2021 08:06:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A5E6711B3; Sat, 18 Dec 2021 23:06:48 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A5DAE3F5A1; Sat, 18 Dec 2021 23:06:44 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 5/8] EFI: FMP: Add provision to update image's ImageTypeId in image descriptor Date: Sun, 19 Dec 2021 12:36:02 +0530 Message-Id: <20211219070605.14894-6-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean The FWU Multi Banks Update feature allows updating different types of updatable firmware images on the platform. These image types are identified using the ImageTypeId GUID value. Add support in the GetImageInfo function of the FMP protocol to get the GUID values for the individual images and populate these in the image descriptor for the corresponding images. Signed-off-by: Sughosh Ganu --- Changes since V1: * Define a new function fwu_plat_get_alt_num for filling up all the dfu partitions with a preset ImageTypeId guid * Remove the distinction made in the earlier version for setting image_type_id as suggested by Heinrich lib/efi_loader/efi_firmware.c | 90 ++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a1b88dbfc2..648342ae72 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,46 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( return EFI_EXIT(EFI_UNSUPPORTED); } +static efi_status_t fill_part_guid_array(const efi_guid_t *guid, + efi_guid_t **part_guid_arr) +{ + int i; + int dfu_num = 0; + efi_guid_t *guid_arr; + struct dfu_entity *dfu; + efi_status_t ret = EFI_SUCCESS; + + dfu_init_env_entities(NULL, NULL); + + dfu_num = 0; + list_for_each_entry(dfu, &dfu_list, list) { + dfu_num++; + } + + if (!dfu_num) { + log_warning("Probably dfu_alt_info not defined\n"); + ret = EFI_NOT_READY; + goto out; + } + + *part_guid_arr = malloc(sizeof(efi_guid_t) * dfu_num); + if (!*part_guid_arr) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + guid_arr = *part_guid_arr; + for (i = 0; i < dfu_num; i++) { + guidcpy(guid_arr, guid); + ++guid_arr; + } + +out: + dfu_free_entities(); + + return ret; +} + /** * efi_get_dfu_info - return information about the current firmware image * @this: Protocol instance @@ -104,9 +145,9 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( * @descriptor_version: Pointer to version number * @descriptor_count: Pointer to number of descriptors * @descriptor_size: Pointer to descriptor size - * package_version: Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name + * @guid_array: Image type GUID array * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. @@ -122,7 +163,7 @@ static efi_status_t efi_get_dfu_info( efi_uintn_t *descriptor_size, u32 *package_version, u16 **package_version_name, - const efi_guid_t *image_type) + const efi_guid_t *guid_array) { struct dfu_entity *dfu; size_t names_len, total_size; @@ -172,7 +213,7 @@ static efi_status_t efi_get_dfu_info( next = name; list_for_each_entry(dfu, &dfu_list, list) { image_info[i].image_index = dfu->alt + 1; - image_info[i].image_type_id = *image_type; + image_info[i].image_type_id = guid_array[i]; image_info[i].image_id = dfu->alt; /* copy the DFU entity name */ @@ -250,6 +291,7 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( u16 **package_version_name) { efi_status_t ret; + efi_guid_t *part_guid_arr = NULL; EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size, image_info, @@ -264,12 +306,19 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( !descriptor_size || !package_version || !package_version_name)) return EFI_EXIT(EFI_INVALID_PARAMETER); + ret = fill_part_guid_array(&efi_firmware_image_type_uboot_fit, + &part_guid_arr); + if (ret != EFI_SUCCESS) + goto out; + ret = efi_get_dfu_info(image_info_size, image_info, descriptor_version, descriptor_count, descriptor_size, package_version, package_version_name, - &efi_firmware_image_type_uboot_fit); + part_guid_arr); +out: + free(part_guid_arr); return EFI_EXIT(ret); } @@ -358,7 +407,10 @@ efi_status_t EFIAPI efi_firmware_raw_get_image_info( u32 *package_version, u16 **package_version_name) { + int status; efi_status_t ret = EFI_SUCCESS; + const efi_guid_t null_guid = NULL_GUID; + efi_guid_t *part_guid_arr = NULL; EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size, image_info, @@ -373,12 +425,36 @@ efi_status_t EFIAPI efi_firmware_raw_get_image_info( !descriptor_size || !package_version || !package_version_name)) return EFI_EXIT(EFI_INVALID_PARAMETER); + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + ret = fill_part_guid_array(&null_guid, &part_guid_arr); + if (ret != EFI_SUCCESS) + goto out; + + /* + * Call the platform function to fill the GUID array + * with the corresponding partition GUID values + */ + status = fwu_plat_fill_partition_guids(&part_guid_arr); + if (status < 0) { + log_err("Unable to get partiion guid's\n"); + ret = EFI_DEVICE_ERROR; + goto out; + } + } else { + ret = fill_part_guid_array(&efi_firmware_image_type_uboot_raw, + &part_guid_arr); + if (ret != EFI_SUCCESS) + goto out; + } + ret = efi_get_dfu_info(image_info_size, image_info, descriptor_version, descriptor_count, descriptor_size, package_version, package_version_name, - &efi_firmware_image_type_uboot_raw); + part_guid_arr); +out: + free(part_guid_arr); return EFI_EXIT(ret); } From patchwork Sun Dec 19 07:06:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525855 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053399imb; Sat, 18 Dec 2021 23:07:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJwWJgRSdVFT3IJQjaQDO9QWaxWINAWmXfQZEuuO9C0u+369ilYTKhSWZRs8HJmWtxFaJBlJ X-Received: by 2002:a17:907:d90:: with SMTP id go16mr8642701ejc.137.1639897660202; Sat, 18 Dec 2021 23:07:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897660; cv=none; d=google.com; s=arc-20160816; b=TpPbrS0DgVjtkJ1XRUyNWdK4o5w/r6ob3hZDdlnxFqywqDjQhSCiiQjyNLtnSs05jH ZJWsX/0QywKAMs1Hq9/YZZ5R5Q8JHX6gkzdePE3Bfxad+jQTwmH4WRHi3kzBNENC1WkU 1OEHg0M6hBaiT6WKRsJ8K/bMLsi4aw7zwNu8Afis+NHIksFQ6tz9KnO/DrR+pDryKV0P WiCd2Tm8sNOSE2SyviM+cKksL1zdeKQfeaUfQk1rUb5RvZ+1ndu1R7Kv/wUJdmqFUyg5 QU52LgEKVNy47LDC5swg4m9Qyi3Ee9/lF2Es+QxvvgwiBtkgtuE+bGza+ysP/R+UGzYr 8ecw== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=zs02rvwq42UH3V5YUI26wVL8bR/zCc/KDgGvSPynidQ=; b=nf1wkbCKaGI3hN5YFJu3VSTw6uJsQInNHfJeBif0w2GhibYyAs/fsiX7YX4JpWmPWd 47VI63EOM/7ahsijSdU5/rnncyrVq/xcG8NuMVG4A4R0ILXTSEj3sdVhr8upAeGzjQ86 a4MduEAO8XmGmJI+izBUdiAQw9llHuNn88QeOXDdF8GWM0pMjXuIS2W6beIKZX71xwp1 Mqv04ebFGzH+YgQ1lCA2U+df7WEA9zUBQkeceXqqfkzFm2DPJWIAA8zuCgPLNemM9oko iqAnlCL5R/RVU1eOvLCPZB2TRqqgIi2FbttGccLEkAXy+U7ZaYWXJSn9rR/6x1Fc39hA D3Bg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 w13si9279788edx.102.2021.12.18.23.07.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:40 -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; 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=fail (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 E6BD083046; Sun, 19 Dec 2021 08:07:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id B6557830AF; Sun, 19 Dec 2021 08:07:00 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id C491F831FF for ; Sun, 19 Dec 2021 08:06:53 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1F9F511B3; Sat, 18 Dec 2021 23:06:53 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 21E553F5A1; Sat, 18 Dec 2021 23:06:48 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 6/8] FWU: Add boot time checks as highlighted by the FWU specification Date: Sun, 19 Dec 2021 12:36:03 +0530 Message-Id: <20211219070605.14894-7-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean The FWU Multi Bank Update specification requires the Update Agent to carry out certain checks at the time of platform boot. The Update Agent is the component which is responsible for updating the firmware components and maintaining and keeping the metadata in sync. The spec requires that the Update Agent perform the following checks at the time of boot * Sanity check of both the metadata copies maintained by the platform. * Get the boot index passed to U-Boot by the prior stage bootloader and use this value for metadata bookkeeping. * Check if the system is booting in Trial State. If the system boots in the Trial State for more than a specified number of boot counts, change the Active Bank to be booting the platform from. Add these checks in the board initialisation sequence, invoked after relocation. Signed-off-by: Sughosh Ganu --- Changes since V1: * Define a funtion fwu_update_checks_pass to do the checks before initiating the update * Log the status of the boottime checks using boottime_check variable and allow system to boot instead of hanging the platform(fwu_boottime_checks) common/board_r.c | 6 ++ include/fwu.h | 3 + lib/fwu_updates/fwu.c | 163 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 lib/fwu_updates/fwu.c diff --git a/common/board_r.c b/common/board_r.c index 31a59c585a..81678870b9 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -78,6 +78,9 @@ #ifdef CONFIG_EFI_SETUP_EARLY #include #endif +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -805,6 +808,9 @@ static init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_EFI_SETUP_EARLY (init_fnc_t)efi_init_obj_list, +#endif +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE + fwu_boottime_checks, #endif run_main_loop, }; diff --git a/include/fwu.h b/include/fwu.h index 5ba437798d..2d2e674d6a 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -16,6 +16,9 @@ EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) +int fwu_boottime_checks(void); +u8 fwu_update_checks_pass(void); + int fwu_get_active_index(u32 *active_idx); int fwu_update_active_index(u32 active_idx); int fwu_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c new file mode 100644 index 0000000000..e964f9b0b1 --- /dev/null +++ b/lib/fwu_updates/fwu.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static u8 trial_state = 0; +static u8 boottime_check = 0; + +static int fwu_trial_state_check(void) +{ + int ret, i; + efi_status_t status; + efi_uintn_t var_size; + u16 trial_state_ctr; + u32 nimages, active_bank, var_attributes, active_idx; + struct fwu_mdata *mdata = NULL; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + ret = fwu_get_mdata(&mdata); + if (ret < 0) + return ret; + + ret = 0; + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + active_bank = mdata->active_index; + img_entry = &mdata->img_entry[0]; + for (i = 0; i < nimages; i++) { + img_bank_info = &img_entry[i].img_bank_info[active_bank]; + if (!img_bank_info->accepted) { + trial_state = 1; + break; + } + } + + if (trial_state) { + var_size = (efi_uintn_t)sizeof(trial_state_ctr); + log_info("System booting in Trial State\n"); + var_attributes = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + status = efi_get_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + &var_attributes, + &var_size, &trial_state_ctr, + NULL); + if (status != EFI_SUCCESS) { + log_err("Unable to read TrialStateCtr variable\n"); + ret = -1; + goto out; + } + + ++trial_state_ctr; + if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) { + log_info("Trial State count exceeded. Revert back to previous_active_index\n"); + active_idx = mdata->active_index; + ret = fwu_revert_boot_index(); + if (ret < 0) { + log_err("Unable to revert active_index\n"); + goto out; + } + + trial_state_ctr = 0; + status = efi_set_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + 0, + &trial_state_ctr, false); + if (status != EFI_SUCCESS) { + log_err("Unable to clear TrialStateCtr variable\n"); + ret = -1; + goto out; + } + } else { + status = efi_set_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + var_size, + &trial_state_ctr, false); + if (status != EFI_SUCCESS) { + log_err("Unable to increment TrialStateCtr variable\n"); + ret = -1; + goto out; + } else { + ret = 0; + } + } + } + +out: + free(mdata); + return ret; +} + +u8 fwu_update_checks_pass(void) +{ + return !trial_state && boottime_check; +} + +int fwu_boottime_checks(void) +{ + int ret; + u32 boot_idx, active_idx; + + ret = fwu_mdata_check(); + if (ret < 0) { + boottime_check = 0; + return 0; + } + + /* + * Get the Boot Index, i.e. the bank from + * which the platform has booted. This value + * gets passed from the ealier stage bootloader + * which booted u-boot, e.g. tf-a. If the + * boot index is not the same as the + * active_index read from the FWU metadata, + * update the active_index. + */ + fwu_plat_get_bootidx(&boot_idx); + if (boot_idx >= CONFIG_FWU_NUM_BANKS) { + log_err("Received incorrect value of boot_index\n"); + boottime_check = 0; + return 0; + } + + ret = fwu_get_active_index(&active_idx); + if (ret < 0) { + log_err("Unable to read active_index\n"); + boottime_check = 0; + return 0; + } + + if (boot_idx != active_idx) { + log_info("Boot idx %u is not matching active idx %u, changing active_idx\n", + boot_idx, active_idx); + ret = fwu_update_active_index(boot_idx); + if (ret < 0) + boottime_check = 0; + else + boottime_check = 1; + + return 0; + } + + ret = fwu_trial_state_check(); + if (ret < 0) + boottime_check = 0; + else + boottime_check = 1; + + return 0; +} From patchwork Sun Dec 19 07:06:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525857 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053544imb; Sat, 18 Dec 2021 23:07:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJzJibNxUdRJRIS2Rjgztk9VGQi0+UlfmvwknZMw1vL/nMhR/p1aPlAoHVNOLXIOBxB0kEmO X-Received: by 2002:a17:906:c1c2:: with SMTP id bw2mr8904592ejb.499.1639897677520; Sat, 18 Dec 2021 23:07:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897677; cv=none; d=google.com; s=arc-20160816; b=Y+gM1UkUd1OfMydBhb6E5qOmqPqyNE2PJUIWaKowPJJQbAJNLQtX0AUWBYBedyi5GK yX7li0b5IMQOa3X5b2pTaUtOD8VMevHBIqf1JNHo3ZjX4IoeRYn9dWmB6GAWYNNhlyxw o4htgSDUQ7DkDOX5U8TVJb87vbA1Af8PVPGQj+95jyMiQuFGP83B6d27+oA3jwQgXX52 zmA6SjIXIw08S6yoN+v4Z7pks2j94pMAms57ruhKXyDsLq1c73F02cIYfdbvjzdLvnhV zEzxgMAE78n8eS77AztFsUOoCfES18Ip7AqfAUV3cPjZ2UMxtD27K8I/cKk7a/hPcEE2 s0ZA== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=uyKbH5thE+TgzcHGEjsRA3/9KZrJYSyyJdthYYVA/Vk=; b=voq+kfX/JxyYiQ6BgpwRv0VnAY26kGZi5+RBjElGnjTSE0CorHdpQgHGsU4yhs22XE S2Ihes9Ab045QclPfrkIld9VdMLAKZbYextKnLuNJe2EOsehGG5qtKJBCgvaM5bCrVB3 r/f133uNLfJtcVJOJDzqlXe61GBo3ZFdz3kFTBN3QzoM653fdFWzJQIWeMPMi9AI9xoT wE6npDKiTdySDvRfxTo791qNl4wTpTf7rJIBxqA2XDIiZE/b/Z+qHGT8xDBe2HG56PgS RNwT5Ek+3gkzX0qxjUeJR0EIllW7aXBopsmFhzT4ruYVGD16ZUoh/k+3vKjjjKBU7xv/ FW3g== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 r11si7784898ejr.881.2021.12.18.23.07.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:57 -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; 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=fail (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 C5ECF83458; Sun, 19 Dec 2021 08:07:28 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 53BDF830F5; Sun, 19 Dec 2021 08:07:10 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 44C17830D9 for ; Sun, 19 Dec 2021 08:06:58 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8DEC811B3; Sat, 18 Dec 2021 23:06:57 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8FC423F5A1; Sat, 18 Dec 2021 23:06:53 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 7/8] FWU: Add support for FWU Multi Bank Update feature Date: Sun, 19 Dec 2021 12:36:04 +0530 Message-Id: <20211219070605.14894-8-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean The FWU Multi Bank Update feature supports updation of firmware images to one of multiple sets(also called banks) of images. The firmware images are clubbed together in banks, with the system booting images from the active bank. Information on the images such as which bank they belong to is stored as part of the metadata structure, which is stored on the same storage media as the firmware images on a dedicated partition. At the time of update, the metadata is read to identify the bank to which the images need to be flashed(update bank). On a successful update, the metadata is modified to set the updated bank as active bank to subsequently boot from. Signed-off-by: Sughosh Ganu --- Changes since V1: * Call function fwu_update_checks_pass to check if the update can be initiated * Do not allow firmware update from efi_init_obj_list as the fwu boot-time checks need to be run include/fwu.h | 18 +++- lib/Kconfig | 32 ++++++ lib/Makefile | 1 + lib/efi_loader/efi_capsule.c | 198 ++++++++++++++++++++++++++++++++++- lib/efi_loader/efi_setup.c | 3 +- lib/fwu_updates/Makefile | 11 ++ lib/fwu_updates/fwu.c | 27 +++++ 7 files changed, 284 insertions(+), 6 deletions(-) create mode 100644 lib/fwu_updates/Makefile diff --git a/include/fwu.h b/include/fwu.h index 2d2e674d6a..bf50fe9277 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -10,14 +10,28 @@ #include -#define FWU_MDATA_VERSION 0x1 +#define FWU_MDATA_GUID \ + EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ + 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) + +#define FWU_OS_REQUEST_FW_REVERT_GUID \ + EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \ + 0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0) + +#define FWU_OS_REQUEST_FW_ACCEPT_GUID \ + EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \ + 0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8) #define FWU_MDATA_GUID \ EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) -int fwu_boottime_checks(void); +#define FWU_MDATA_VERSION 0x1 +#define FWU_IMAGE_ACCEPTED 0x1 + u8 fwu_update_checks_pass(void); +int fwu_boottime_checks(void); +int fwu_trial_state_ctr_start(void); int fwu_get_active_index(u32 *active_idx); int fwu_update_active_index(u32 active_idx); diff --git a/lib/Kconfig b/lib/Kconfig index 807a4c6ade..7cb306317c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -835,3 +835,35 @@ config PHANDLE_CHECK_SEQ When there are multiple device tree nodes with same name, enable this config option to distinguish them using phandles in fdtdec_get_alias_seq() function. + +config FWU_MULTI_BANK_UPDATE + bool "Enable FWU Multi Bank Update Feature" + depends on EFI_HAVE_CAPSULE_SUPPORT + select PARTITION_TYPE_GUID + select EFI_SETUP_EARLY + help + Feature for updating firmware images on platforms having + multiple banks(copies) of the firmware images. One of the + bank is selected for updating all the firmware components + +config FWU_NUM_BANKS + int "Number of Banks defined by the platform" + depends on FWU_MULTI_BANK_UPDATE + help + Define the number of banks of firmware images on a platform + +config FWU_NUM_IMAGES_PER_BANK + int "Number of firmware images per bank" + depends on FWU_MULTI_BANK_UPDATE + help + Define the number of firmware images per bank. This value + should be the same for all the banks. + +config FWU_TRIAL_STATE_CNT + int "Number of times system boots in Trial State" + depends on FWU_MULTI_BANK_UPDATE + default 3 + help + With FWU Multi Bank Update feature enabled, number of times + the platform is allowed to boot in Trial State after an + update. diff --git a/lib/Makefile b/lib/Makefile index 5ddbc77ed6..bc5c1e22fc 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_driver/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest/ +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_updates/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_BZIP2) += bzip2/ obj-$(CONFIG_TIZEN) += tizen/ diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 8301eed631..6dfe56bb0f 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,13 @@ static const efi_guid_t efi_guid_firmware_management_capsule_id = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; const efi_guid_t efi_guid_firmware_management_protocol = EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID; +const efi_guid_t fwu_guid_os_request_fw_revert = + FWU_OS_REQUEST_FW_REVERT_GUID; +const efi_guid_t fwu_guid_os_request_fw_accept = + FWU_OS_REQUEST_FW_ACCEPT_GUID; + +__maybe_unused static u32 update_index; +__maybe_unused static bool capsule_update; #ifdef CONFIG_EFI_CAPSULE_ON_DISK /* for file system access */ @@ -403,10 +411,13 @@ static efi_status_t efi_capsule_update_firmware( void *image_binary, *vendor_code; efi_handle_t *handles; efi_uintn_t no_handles; - int item; + int item, alt_no; struct efi_firmware_management_protocol *fmp; u16 *abort_reason; + efi_guid_t image_type_id; efi_status_t ret = EFI_SUCCESS; + int status; + u8 image_index; /* sanity check */ if (capsule_data->header_size < sizeof(*capsule) || @@ -481,8 +492,36 @@ static efi_status_t efi_capsule_update_firmware( goto out; } + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + /* + * Based on the value of update_image_type_id, + * derive the alt number value. This will be + * passed as update_image_index to the + * set_image function. + */ + image_type_id = image->update_image_type_id; + status = fwu_get_image_alt_num(image_type_id, + update_index, + &alt_no); + if (status < 0) { + log_err("Unable to get the alt no for the image type %pUl\n", + &image_type_id); + if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + else if (status == -ERANGE || status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + goto out; + } + log_debug("alt_no %u for Image Type Id %pUl\n", + alt_no, &image_type_id); + image_index = alt_no + 1; + } else { + image_index = image->update_image_index; + } abort_reason = NULL; - ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index, + ret = EFI_CALL(fmp->set_image(fmp, image_index, image_binary, image_binary_size, vendor_code, NULL, @@ -493,6 +532,24 @@ static efi_status_t efi_capsule_update_firmware( efi_free_pool(abort_reason); goto out; } + + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + status = fwu_clear_accept_image(&image_type_id, + update_index); + if (status < 0) { + log_err("Unable to clear the accept bit for the image %pUl\n", + &image_type_id); + if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + else if (status == -ERANGE || status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + goto out; + } + log_debug("Cleared out accepted bit for Image %pUl\n", &image_type_id); + } + } out: @@ -527,6 +584,9 @@ efi_status_t EFIAPI efi_update_capsule( u64 scatter_gather_list) { struct efi_capsule_header *capsule; + efi_guid_t *image_guid; + u32 active_idx; + int status; unsigned int i; efi_status_t ret; @@ -538,6 +598,16 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + /* Obtain the update_index from the platform */ + status = fwu_plat_get_update_index(&update_index); + if (status < 0) { + log_err("Failed to get the FWU update_index value\n"); + ret = EFI_DEVICE_ERROR; + goto out; + } + } + ret = EFI_SUCCESS; for (i = 0, capsule = *capsule_header_array; i < capsule_count; i++, capsule = *(++capsule_header_array)) { @@ -552,7 +622,64 @@ efi_status_t EFIAPI efi_update_capsule( i, &capsule->capsule_guid); if (!guidcmp(&capsule->capsule_guid, &efi_guid_firmware_management_capsule_id)) { + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + if (!fwu_update_checks_pass()) { + log_err("FWU checks failed. Cannot start update\n"); + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + ret = efi_capsule_update_firmware(capsule); + capsule_update = true; + } else if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + capsule_update = false; + if (!guidcmp(&capsule->capsule_guid, + &fwu_guid_os_request_fw_revert)) { + /* + * One of the previously updated image has + * failed the OS acceptance test. OS has + * requested to revert back to the earlier + * boot index + */ + status = fwu_revert_boot_index(); + if (status < 0) { + log_err("Failed to revert the FWU boot index\n"); + if (status == -ENODEV || + status == -ERANGE || + status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + ret = EFI_SUCCESS; + log_err("Reverted the FWU active_index to %u. Recommend rebooting the system\n", + active_idx); + } + } else if (!guidcmp(&capsule->capsule_guid, + &fwu_guid_os_request_fw_accept)) { + /* + * Image accepted by the OS. Set the acceptance + * status for the image. + */ + image_guid = (void *)(char *)capsule + + capsule->header_size; + status = fwu_accept_image(image_guid); + if (status < 0) { + if (status == -ENODEV || + status == -ERANGE || + status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + ret = EFI_SUCCESS; + } + } } else { log_err("Unsupported capsule type: %pUl\n", &capsule->capsule_guid); @@ -563,6 +690,36 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } + /* + * Update the FWU metadata once all the capsules have + * been updated. This is done only for the Runtime + * capsule update service. + * The update_index value now gets written to the + * active_index and the update_index value also + * gets updated. + * For the capsule-on-disk feature, the updation + * of the FWU metadata happens in efi_launch_capsules + */ + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE) && + !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK)) { + status = fwu_update_active_index(update_index); + if (status < 0) { + log_err("Failed to update FWU metadata index values\n"); + if (status == -EINVAL || status == -ERANGE) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + status = fwu_trial_state_ctr_start(); + if (status < 0) + ret = EFI_DEVICE_ERROR; + else + ret = EFI_SUCCESS; + } + } + if (IS_ENABLED(CONFIG_EFI_ESRT)) { /* Rebuild the ESRT to reflect any updated FW images. */ ret = efi_esrt_populate(); @@ -1090,8 +1247,10 @@ efi_status_t efi_launch_capsules(void) { struct efi_capsule_header *capsule = NULL; u16 **files; + int status; unsigned int nfiles, index, i; efi_status_t ret; + bool update_status = true; if (check_run_capsules() != EFI_SUCCESS) return EFI_SUCCESS; @@ -1119,9 +1278,11 @@ efi_status_t efi_launch_capsules(void) ret = efi_capsule_read_file(files[i], &capsule); if (ret == EFI_SUCCESS) { ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0)); - if (ret != EFI_SUCCESS) + if (ret != EFI_SUCCESS) { log_err("Applying capsule %ls failed\n", files[i]); + update_status = false; + } /* create CapsuleXXXX */ set_capsule_result(index, capsule, ret); @@ -1129,6 +1290,7 @@ efi_status_t efi_launch_capsules(void) free(capsule); } else { log_err("Reading capsule %ls failed\n", files[i]); + update_status = false; } /* delete a capsule either in case of success or failure */ ret = efi_capsule_delete_file(files[i]); @@ -1136,7 +1298,37 @@ efi_status_t efi_launch_capsules(void) log_err("Deleting capsule %ls failed\n", files[i]); } + efi_capsule_scan_done(); + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + if (update_status == true && capsule_update == true) { + /* + * All the capsules have been updated successfully, + * update the FWU metadata. + */ + log_debug("Update Complete. Now updating active_index to %u\n", + update_index); + status = fwu_update_active_index(update_index); + if (status < 0) { + log_err("Failed to update FWU metadata index values\n"); + if (status == -EINVAL || status == -ERANGE) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + log_debug("Successfully updated the active_index\n"); + status = fwu_trial_state_ctr_start(); + if (status < 0) + ret = EFI_DEVICE_ERROR; + else + ret = EFI_SUCCESS; + } + } else if (capsule_update == true && update_status == false) { + log_err("All capsules were not updated. Not updating FWU metadata\n"); + } + } for (i = 0; i < nfiles; i++) free(files[i]); diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 1aba71cd96..6601176a2d 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -298,7 +298,8 @@ efi_status_t efi_init_obj_list(void) goto out; /* Execute capsules after reboot */ - if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && + if (!IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE) && + IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) ret = efi_launch_capsules(); out: diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile new file mode 100644 index 0000000000..73099a30cb --- /dev/null +++ b/lib/fwu_updates/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2021, Linaro Limited +# + +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata.o +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o + +ifdef CONFIG_EFI_PARTITION +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata_gpt_blk.o +endif diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c index e964f9b0b1..bb0e1961be 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -107,6 +107,33 @@ u8 fwu_update_checks_pass(void) return !trial_state && boottime_check; } +int fwu_trial_state_ctr_start(void) +{ + int ret; + u32 var_attributes; + efi_status_t status; + efi_uintn_t var_size; + u16 trial_state_ctr; + + var_size = (efi_uintn_t)sizeof(trial_state_ctr); + var_attributes = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + + trial_state_ctr = ret = 0; + status = efi_set_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + var_size, + &trial_state_ctr, false); + if (status != EFI_SUCCESS) { + log_err("Unable to increment TrialStateCtr variable\n"); + ret = -1; + } + + return ret; +} + int fwu_boottime_checks(void) { int ret; From patchwork Sun Dec 19 07:06:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 525856 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp3053491imb; Sat, 18 Dec 2021 23:07:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJxlr/IxfeRA4RocvBE0994b2dVvSE7EE28zdHrDita3JqvRNw/Na0sOJ9H1Ah3AtkMZl827 X-Received: by 2002:a50:9556:: with SMTP id v22mr9971719eda.69.1639897669894; Sat, 18 Dec 2021 23:07:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639897669; cv=none; d=google.com; s=arc-20160816; b=ugBvKBgcuCywT4CF7u5tjyxJV+1qe0067sZ54t1fNsXEUQuzv1WSbRBE5iULdibnit jPKivko8AXksmMEH0NRyxhpyFePwBTCyD7OJc/17fRJHx5U0IHaw7XokzYFvAjQkbq0m qqndmuskVGaI/zElFZgPYbyhSQQIEb8j+OxPOhpv8XffEw43MhrAyBDCQsTbA264RWrR 1KVjoz4vC0XxFM29XWvIEbEZ7pU7KQmhTgFRS2U0QkjGKs5nPyNBE2xWXOrrRIIYww05 O95zusE6Pg9nL7cMaX4RF38Jhbx2x8K3FuIvnAlzkNMjuTR/hd14AKFvPtRHmBAIaFsy VKfw== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=AnKEEn+JZBE5yvKlokZiW8gYTA03YCn/4URmM5AxH7o=; b=Q8rygVGZYUi3ylMz+lea0W98f6OizA7iXkgI0Q5Ls0Y19mOH5QXuG/bqmHymaOh8ui Bb5pNs2g1d00QsPeyZlBGAXdDDJjz/x1AJRrL1LP75rEcUWM9IXYkiptkZWH5Up9gGqH 54WqsPTsnBX0ehFTnM8t/CZSp9ghIwcrCQGmNH4o/Tb8KJW+E+R1ncsOijFWlhK9/kpq pFuGMN4hXIa6BsMwRXik96TBVExrZEDXh81ZtopO5oMXWXHq++MxmjfmKk/ZgqurG7Aq vRSOeu4yQCGn1Kpdv9wfD2sF+i43Po71VdpFWLSHI33ubgaJNXk48btV8COraNpJENGl JBOA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id k16si4017812ejb.476.2021.12.18.23.07.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Dec 2021 23:07:49 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (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 902738344C; Sun, 19 Dec 2021 08:07:24 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 9256983104; Sun, 19 Dec 2021 08:07:09 +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=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id E48B3830F5 for ; Sun, 19 Dec 2021 08:07:02 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 07D3A11B3; Sat, 18 Dec 2021 23:07:02 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0A0403F5A1; Sat, 18 Dec 2021 23:06:57 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v2 8/8] FWU: cmd: Add a command to read FWU metadata Date: Sun, 19 Dec 2021 12:36:05 +0530 Message-Id: <20211219070605.14894-9-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211219070605.14894-1-sughosh.ganu@linaro.org> References: <20211219070605.14894-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.38 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add a command to read the metadata as specified in the FWU specification and print the fields of the metadata. Signed-off-by: Sughosh Ganu --- Changes since V1: * None cmd/Kconfig | 7 ++++++ cmd/Makefile | 1 + cmd/fwu_mdata.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 cmd/fwu_mdata.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 5b30b13e43..ee8a976b46 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -137,6 +137,13 @@ config CMD_CPU internal name) and clock frequency. Other information may be available depending on the CPU driver. +config CMD_FWU_METADATA + bool "fwu metadata read" + depends on FWU_MULTI_BANK_UPDATE + default y if FWU_MULTI_BANK_UPDATE + help + Command to read the metadata and dump it's contents + config CMD_LICENSE bool "license" select BUILD_BIN2C diff --git a/cmd/Makefile b/cmd/Makefile index 891819ae0f..32958cba43 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o obj-$(CONFIG_CMD_FPGAD) += fpgad.o obj-$(CONFIG_CMD_FS_GENERIC) += fs.o obj-$(CONFIG_CMD_FUSE) += fuse.o +obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o obj-$(CONFIG_CMD_GETTIME) += gettime.o obj-$(CONFIG_CMD_GPIO) += gpio.o obj-$(CONFIG_CMD_HVC) += smccc.o diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c new file mode 100644 index 0000000000..4049fb186d --- /dev/null +++ b/cmd/fwu_mdata.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include + +#include + +static void print_mdata(struct fwu_mdata *mdata) +{ + int i, j; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_info; + u32 nimages, nbanks; + + printf("\tFWU Metadata Read\n"); + printf("crc32: %#x\n", mdata->crc32); + printf("version: %#x\n", mdata->version); + printf("active_index: %#x\n", mdata->active_index); + printf("previous_active_index: %#x\n", mdata->previous_active_index); + + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + nbanks = CONFIG_FWU_NUM_BANKS; + printf("\tImage Info\n"); + for (i = 0; i < nimages; i++) { + img_entry = &mdata->img_entry[i]; + printf("\nImage Type Guid: %pUL\n", &img_entry->image_type_uuid); + printf("Location Guid: %pUL\n", &img_entry->location_uuid); + for (j = 0; j < nbanks; j++) { + img_info = &img_entry->img_bank_info[j]; + printf("Image Guid: %pUL\n", &img_info->image_uuid); + printf("Image Acceptance: %#x\n", img_info->accepted); + } + } +} + +int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + int ret = CMD_RET_SUCCESS; + struct fwu_mdata *mdata = NULL; + + ret = fwu_get_mdata(&mdata); + if (ret < 0) { + log_err("Unable to get valid FWU metadata\n"); + ret = CMD_RET_FAILURE; + goto out; + } + + print_mdata(mdata); + +out: + free(mdata); + return ret; +} + +U_BOOT_CMD( + fwu_mdata_read, 1, 1, do_fwu_mdata_read, + "Read and print FWU metadata", + "" +);