From patchwork Wed Jan 19 18:55:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533272 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1130376imr; Wed, 19 Jan 2022 10:56:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJx0qXQWs1KmVsh7zggoJER+kxIiiqYDnRKpCrcb8znjizQxVDi5g47uVPNXgQyFM+2RktCJ X-Received: by 2002:a50:a6ce:: with SMTP id f14mr31416001edc.105.1642618610686; Wed, 19 Jan 2022 10:56:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618610; cv=none; d=google.com; s=arc-20160816; b=1ESpxRfThmUhyy+bXKN9IXzzDzzQDMtUsNI+/BYXbg8QhDiiGpyjBsqBNXqUKMEBQO wsyuQNqHUcll33lUf3+KmB407gZw+i79jWoknzy0u0SyKMa+hXRNgksBBcwPvY4BstlY YDskUicbI7s9svSOur59XlAm4nfAM9tmiZ0lPI4aMkABhmxBedYqxTEBziPyT0QTSmco lOxc+jZ2BoxGeUB7AL1qG8DFpXP53d4pqmVaJj7DaqwxprJKIgBkSmTyllq5GV1vpR6r P2a7Fr6pOrP4/Ye3WGbRkkJOSKgP9PZ/wjJRNHHK53NpTFvmffqSm4xPpsRGwZkVnrax +8iw== 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=i7h0eMxSxEpx7Dm78LOthMGUEUMFjavrXBTRDrhhwAg=; b=OP32uE5JT2LSfjWpAUZjkeWXgn+EgH3+gCVJWnSHHTawg7IAyxgNDALItiylD/YAXJ sUC5Y5tacvjT4P8HJfFYm2RLHkBWgO3pPFon9s9XtWB5r1w5sKjCaulwc8cXZBgxx45/ GarTKJlJXqSEOgj5A2sdSVcJ5g3rzB+StFe8VrqXWtU5VSoEa8QwFr4ZGP4wD+5devA3 C6nBIZmRsrPsaJjQ8II1gagO3W4rVAiA/ZrXzlg0RfTFD3rflkO4huch4GBWRZMeyfhK XyyQSEcEuGXwR/oca31SAdpAZsJ6P/pjt/h9kMSslRVaxkIvhx+J0VC9d3wuikoEA0OI YG6g== 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 hq3si305550ejc.417.2022.01.19.10.56.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:56:50 -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 9763B837FA; Wed, 19 Jan 2022 19:56:43 +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 148A88380A; Wed, 19 Jan 2022 19:56:43 +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 1E7EA837C4 for ; Wed, 19 Jan 2022 19:56:39 +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 5FCD61FB; Wed, 19 Jan 2022 10:56:38 -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 E0E163F73D; Wed, 19 Jan 2022 10:56:32 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 1/9] FWU: Add FWU metadata structure and functions for accessing metadata Date: Thu, 20 Jan 2022 00:25:40 +0530 Message-Id: <20220119185548.16730-2-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Use uint*_t types in fwu_mdata.h since the file is to be reused in other projects * Keep only the FWU metadata structures in fwu_mdata.h * Move all other function and macro declarations in fwu.h * Keep common implementations of fwu_update_active_index and fwu_revert_boot_index in fwu_mdata.c * Add a update_mdata function pointer in the fwu_mdata_ops structure include/fwu.h | 61 +++++++ include/fwu_mdata.h | 67 ++++++++ lib/fwu_updates/fwu_mdata.c | 329 ++++++++++++++++++++++++++++++++++++ 3 files changed, 457 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..acba725bc8 --- /dev/null +++ b/include/fwu.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#if !defined _FWU_H_ +#define _FWU_H_ + +#include +#include + +#include + +struct fwu_mdata; + +/** + * @get_active_index: get the current 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 + * @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 + * @update_mdata() - Update the FWU metadata copy + */ +struct fwu_mdata_ops { + int (*get_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 (*set_accept_image)(efi_guid_t *img_type_id, u32 bank); + + int (*clear_accept_image)(efi_guid_t *img_type_id, u32 bank); + + int (*get_mdata)(struct fwu_mdata **mdata); + + int (*update_mdata)(struct fwu_mdata *mdata); +}; + +struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void); + +#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_mdata(struct fwu_mdata **mdata); +int fwu_update_mdata(struct fwu_mdata *mdata); +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, u32 bank); +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..d788eb69e7 --- /dev/null +++ b/include/fwu_mdata.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#if !defined _FWU_MDATA_H_ +#define _FWU_MDATA_H_ + +#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; + uint32_t accepted; + uint32_t reserved; +} __attribute__((__packed__)); + +/** + * 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]; +} __attribute__((__packed__)); + +/** + * 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 { + uint32_t crc32; + uint32_t version; + uint32_t active_index; + uint32_t previous_active_index; + + struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +} __attribute__((__packed__)); + +#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..58e838fe28 --- /dev/null +++ b/lib/fwu_updates/fwu_mdata.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#include + +#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) +{ + int ret; + void *buf; + struct fwu_mdata *mdata = NULL; + + if (active_idx > CONFIG_FWU_NUM_BANKS) { + printf("Active index value to be updated is incorrect\n"); + return -1; + } + + ret = fwu_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 = fwu_update_mdata(mdata); + if (ret < 0) { + log_err("Failed to update FWU metadata partitions\n"); + ret = -EIO; + } + +out: + free(mdata); + + return ret; +} + +/** + * 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) +{ + int ret; + void *buf; + u32 cur_active_index; + struct fwu_mdata *mdata = NULL; + + ret = fwu_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 = fwu_update_mdata(mdata); + if (ret < 0) { + log_err("Failed to update FWU metadata partitions\n"); + ret = -EIO; + } + +out: + free(mdata); + + return ret; +} + +/** + * 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 + * @bank: Bank of which the image's Accept bit is to be set + * + * 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, u32 bank) +{ + 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, bank); +} + +/** + * 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 + * @bank: Bank of which the image's Accept 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); +} + +/** + * fwu_update_mdata() - Update the FWU metadata + * @mdata: Copy of the FWU metadata + * + * Update the FWU metadata structure by writing to the + * FWU metadata partitions. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_update_mdata(struct fwu_mdata *mdata) +{ + struct fwu_mdata_ops *ops; + + ops = get_fwu_mdata_ops(); + if (!ops) + return -EPROTONOSUPPORT; + + if (!ops->update_mdata) { + log_err("get_mdata() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->update_mdata(mdata); +} From patchwork Wed Jan 19 18:55:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533273 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1130493imr; Wed, 19 Jan 2022 10:57:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJzkps890+t/r1u2HCupjvXf2HEqXBPLFtlh9aAeX8w6Ho+ubtU3MxKW4kXPATbFEMjxiFEL X-Received: by 2002:aa7:c7cf:: with SMTP id o15mr32039778eds.176.1642618620583; Wed, 19 Jan 2022 10:57:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618620; cv=none; d=google.com; s=arc-20160816; b=N3NfRT71EXf/jbGkn8eBGdNoujPtqpgKgvGSK76/YAYrcEzPTx5S63B7xwRsDEs19O 0yerMoQ0uQYmuK9KH1OdGqAPXErJN/G2xdgi5UVKsOfjS/pkBpVFIcsyn9ppuTQIjEzQ Gzl+2NNg7IZ8+jShUEyibgivyjcTOMx2sMbIahcame7QZDaHKG1Jk8GlNyblm1Fs0OyS g8BHcZaKNXfKsL4u7BDT0m9SJj+lQtI4G6Q6DPbFcS2tvGelWQ7FEgVcdd9fpXVPklUL GYDS3Mr2urQ6n5IOB1D7AlgRsdEB+myMKSeEu7/JArc0VrT02K5EcpT4ZVaefYyZm+Hh rt3A== 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=qzjm7XHjNX6BdrWAJ2qA2pHuLA8OBswR8HCdY4zlLps=; b=bbcT+aBbPdg9RBxswXXEl0b4NU1StzDdzorVnW6waBOMB9G5/L9+0LxM8P3M74ODi9 mk54Oa/Bo0HJBeomx1Ke6zp1xSCK9m3bkj8Ws1u/eRxO4WGzIot0zYeGVb6NsmqaMrao IUKdfKG6NQsN/WCOpQTGPmqnDCo2CnRqMisPt2ygZXstvxuAlq7LamV1sA8SnwrFpfmL Uz5G0OF7gz+GrJROk1mPQl6e2I6UE6XL9L4SCTvr66MKDWXTEVZFdv0/DP62OCmWhYRP rVg+s8zbVR8ng5YkBa4gl/kAtuJc/o6rL8pdHO7XCG016qyGQzkaJx4JKXInnVpPTadE Xcog== 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 hw17si223896ejc.184.2022.01.19.10.57.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:00 -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 E6D668383D; Wed, 19 Jan 2022 19:56:52 +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 3C54783835; Wed, 19 Jan 2022 19:56:51 +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 78CC983845 for ; Wed, 19 Jan 2022 19:56:45 +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 7773B1FB; Wed, 19 Jan 2022 10:56: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 F24C13F73D; Wed, 19 Jan 2022 10:56:38 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 2/9] FWU: Add FWU metadata access functions for GPT partitioned block devices Date: Thu, 20 Jan 2022 00:25:41 +0530 Message-Id: <20220119185548.16730-3-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Move the function definition of fwu_verify_mdata to fwu_mdata.c to facilitate reuse * Remove the block device specific desc->devnum parameter for the fwu_plat_get_alt_num function call include/fwu.h | 1 + include/fwu_mdata.h | 2 + lib/fwu_updates/fwu_mdata.c | 29 ++ lib/fwu_updates/fwu_mdata_gpt_blk.c | 520 ++++++++++++++++++++++++++++ 4 files changed, 552 insertions(+) create mode 100644 lib/fwu_updates/fwu_mdata_gpt_blk.c diff --git a/include/fwu.h b/include/fwu.h index acba725bc8..12f7eecdb0 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -53,6 +53,7 @@ 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_verify_mdata(struct fwu_mdata *mdata, bool pri_part); int fwu_mdata_check(void); int fwu_revert_boot_index(void); int fwu_accept_image(efi_guid_t *img_type_id, u32 bank); diff --git a/include/fwu_mdata.h b/include/fwu_mdata.h index d788eb69e7..53e39f9af6 100644 --- a/include/fwu_mdata.h +++ b/include/fwu_mdata.h @@ -64,4 +64,6 @@ struct fwu_mdata { struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; } __attribute__((__packed__)); +extern struct fwu_mdata_ops fwu_gpt_blk_ops; + #endif /* _FWU_MDATA_H_ */ diff --git a/lib/fwu_updates/fwu_mdata.c b/lib/fwu_updates/fwu_mdata.c index 58e838fe28..252fcf50f6 100644 --- a/lib/fwu_updates/fwu_mdata.c +++ b/lib/fwu_updates/fwu_mdata.c @@ -25,6 +25,35 @@ static struct fwu_mdata_ops *get_fwu_mdata_ops(void) return ops; } +/** + * fwu_verify_mdata() - Verify the FWU metadata + * @mdata: FWU metadata structure + * @pri_part: FWU metadata partition is primary or secondary + * + * Verify the FWU metadata by computing the CRC32 for the metadata + * structure and comparing it against the CRC32 value stored as part + * of the structure. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_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; +} + /** * fwu_get_active_index() - Get active_index from the FWU metadata * @active_idx: active_index value to be read 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..cb47ddf4a7 --- /dev/null +++ b/lib/fwu_updates/fwu_mdata_gpt_blk.c @@ -0,0 +1,520 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#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_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 fwu_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 = fwu_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 = fwu_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 = fwu_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 = fwu_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(&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_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); +} + +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; + } + + 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 = fwu_gpt_update_mdata(mdata); + goto out; + } + } + + /* Image not found */ + ret = -EINVAL; + +out: + free(mdata); + + return ret; +} + +static int fwu_gpt_accept_image(efi_guid_t *img_type_id, u32 bank) +{ + return fwu_gpt_set_clear_image_accept(img_type_id, bank, + IMAGE_ACCEPT_SET); +} + +static 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, + .get_image_alt_num = fwu_gpt_get_image_alt_num, + .mdata_check = fwu_gpt_mdata_check, + .set_accept_image = fwu_gpt_accept_image, + .clear_accept_image = fwu_gpt_clear_accept_image, + .get_mdata = fwu_gpt_get_mdata, + .update_mdata = fwu_gpt_update_mdata, +}; From patchwork Wed Jan 19 18:55:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533274 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1130626imr; Wed, 19 Jan 2022 10:57:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJw5anar7afbvBoor5Nu/WmBEtLyAsLNvI9X44NLPQCDl7K3iLZs8UMRHY6L/auruXcGEj3N X-Received: by 2002:a17:906:c2da:: with SMTP id ch26mr5633221ejb.372.1642618630496; Wed, 19 Jan 2022 10:57:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618630; cv=none; d=google.com; s=arc-20160816; b=F2kdNSgh8WBQ/814fR6Svl0jRVd9pNOHs60eFfT0c4E2vjzLFvHPelIeks3+qSxLRD ldtEX8Aej2QwCbDZxPM6VXJGSCWlBtmMqbv4eAJNvXMUbOauaP20MZwYV6wq9zW7UX7t aJ1EIuuwDZmS1HgOdHtvA1z2O35u5vluWGhesYU5A51mlyvcsoDX3D9iiAlXmB758XMx WKI4r9z5PYlrnuRu7CyUtfsJSg0mFeryxXtHexy6KGIB9AZbiSTdUDpV1kNvu/N7zObe lq/w0YX/ZqkgqexiCqM9lGgchLL3tWHdydjx0uMaPgsiLQ+d3jkCc3NHQgiBIVVpbR1U qTfQ== 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=o6MtYcF90KHF0YvUhtTx1yCwnFI4WHJ/7Eg3FksByEc=; b=VzF1WugpBquvOElbm3DJDc7jE0xkeLmgZhn/52NSkOloD4JXBihHC/Ycue1GTSa/QY bK1LjMQNDKmz6HIVFJe+0N6sYp+yQBIeH3wvbfdi05CIecfpepsCMI25bTezGRal7084 /MZc4Umy1QSrnJ3P+lmTwlwRN5u2LtvLX1vrSITUOXY5DZlxqnPP8Vwom8oZI++AY1O8 ohJR/HWTtNZEhnuA2s37IS06SMQZqb/70Kc+40lON5MU5S4FRPiPSERqKCyGcg+olwAd j7bQ814XXGuiE9RdtO0+wCb+N1vnSZ8G5+k8WlvHguhiYmNdNsr35oyaW3zJYiwz6xKQ mfHg== 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 z13si435960edd.410.2022.01.19.10.57.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:10 -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 64FCD83852; Wed, 19 Jan 2022 19:56:57 +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 1124C83845; Wed, 19 Jan 2022 19:56:54 +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 DF4ED83325 for ; Wed, 19 Jan 2022 19:56:50 +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 3BC991FB; Wed, 19 Jan 2022 10:56:50 -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 14BB03F73D; Wed, 19 Jan 2022 10:56:44 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 3/9] FWU: stm32mp1: Add helper functions for accessing FWU metadata Date: Thu, 20 Jan 2022 00:25:42 +0530 Message-Id: <20220119185548.16730-4-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Change the implementation of fwu_plat_get_alt_num to get the devnum in the function before calling gpt_plat_get_alt_num board/st/stm32mp1/stm32mp1.c | 176 ++++++++++++++++++++++++++++ include/fwu.h | 5 + lib/fwu_updates/fwu_mdata_gpt_blk.c | 7 +- 3 files changed, 185 insertions(+), 3 deletions(-) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 84592677e4..66cbe3f798 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,174 @@ 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 + +static int gpt_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; +} + +int fwu_plat_get_alt_num(void *identifier) +{ + 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_plat_get_alt_num(desc->devnum, identifier); +} + +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 12f7eecdb0..b23a93ac40 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -59,4 +59,9 @@ int fwu_revert_boot_index(void); int fwu_accept_image(efi_guid_t *img_type_id, u32 bank); 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(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 cb47ddf4a7..796b08e76f 100644 --- a/lib/fwu_updates/fwu_mdata_gpt_blk.c +++ b/lib/fwu_updates/fwu_mdata_gpt_blk.c @@ -37,6 +37,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; @@ -324,7 +325,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) { @@ -355,7 +356,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; @@ -459,7 +460,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 Wed Jan 19 18:55:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533275 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1130735imr; Wed, 19 Jan 2022 10:57:19 -0800 (PST) X-Google-Smtp-Source: ABdhPJx1vzUJmKbKokctgjEFlHktPiaNiGhJOR5fLOt37tI2n4tGxH90tjGNBuDj5Rw+jXimz2kz X-Received: by 2002:aa7:de82:: with SMTP id j2mr31411024edv.389.1642618639569; Wed, 19 Jan 2022 10:57:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618639; cv=none; d=google.com; s=arc-20160816; b=t3jARyawAzm36hXFbzJzHmJfjTSMW4+vKmcte5oWQsUD+Fe2BQu1XJNTl4XGU/YSin Uh+QApoD2J+71+GTPTldw59QVKQwyQjdwr54IkHnqeOiHh6gdjsMivqgnD3WNh1VOWLs n2p1ucoaR/nWCKcX67zFWfTdz3EVOrl8xnde8CBNSRJAZDA4qMaN+cWPkXuqIi1w7Sje v923f21Nn5yH0oErtUgT1p3x60j07wn52P+KUEpuS80bEnjhQYaXv0J0g1goa/PjF3Oe M7s35jyu46Ow1WtUJ7JF8ziOM51QiEa/P0Jymh0nxUnETTijGm+8GU/pTLtjcoAShfSh BGXA== 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=r1ebGMGRMUC/qYMBc29oJhzXMSExK2NlBkFBpX0GhhI=; b=ekQptjYi7Khqi1IPbbYa4jeLiVZktbHBiGuj7gtw29RpxEJLQEEqdIp0YVUI7/VJcs dUeC7cI18W8TIQvRW74EQT7fUERCNM/wWpcsPf2L+zj0GUcJbCuZqTWIr/94MgaeoFcS 6HsVhxTcmMk2wnC6wOTBRrSm9DIkXmrSDhm9duQkKmahbsm66FJpmKYptqgcgvC678h1 nP5rPhKi/Cram2xOiJN5pTY1t5AriRKKsE9EomZAXLC1N16XNylRRnYqeVTRv+QIskpR Oybmb+Ps5+64Y525Gq7BNmdFdOWqziCKaxJlMqfQQiX77K3j/BoiE63FikTcO8aju0bQ zhFw== 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 hs27si369469ejc.46.2022.01.19.10.57.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:19 -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 E845D83857; Wed, 19 Jan 2022 19:57:01 +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 E835083855; Wed, 19 Jan 2022 19:56:59 +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 85DAA83857 for ; Wed, 19 Jan 2022 19:56:56 +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 078611FB; Wed, 19 Jan 2022 10:56:56 -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 D44523F73D; Wed, 19 Jan 2022 10:56:50 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 4/9] FWU: STM32MP1: Add support to read boot index from backup register Date: Thu, 20 Jan 2022 00:25:43 +0530 Message-Id: <20220119185548.16730-5-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: None 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 66cbe3f798..6e7aaaa8a4 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -1104,6 +1104,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 b23a93ac40..6393a1dbb5 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -63,5 +63,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(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 Wed Jan 19 18:55:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533276 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1130901imr; Wed, 19 Jan 2022 10:57:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJxeTnAItL094uQP6WiCNuo6VDngDEgT+6c7HmcKOYCLyJBNPhsSMpp7JwaN8aAHFbQnd0Hk X-Received: by 2002:a05:6402:2294:: with SMTP id cw20mr7365315edb.178.1642618648863; Wed, 19 Jan 2022 10:57:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618648; cv=none; d=google.com; s=arc-20160816; b=RO0L0HJ/B6t2/YP+4vtPupbETL5jxot1bGiQ5T/bS4K62POcgPC43DQz8F2YayiVqb Jd1j+GbrkpS33XWJwcD+NQOiKG412aUxwlRCxyDa/44mwZMc9Xu07fMyHx4LcuY4u969 OvtkKgs3mC/sd61IhHo+woAG/jxJSdna7c5cgz3+pvx6t5Oi1FxgG4lq/8LCAAbCyF61 PPLjuuV1Cj8CKLhRIUim8WAMF8wWvx8xeaTI5Wak3jTmowhITPfRCqzaRf5jpCsl6g47 WaJAhl+aVhn4gm89Bf6g0uy5HkWsV+RCbE/wfYhQJMKgyhz1/hpxiIkur5NdfO7OoaN6 U0xw== 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=ZwVeJTGt6HYPOQqQ4RwIYeFdairbAdVeLg30LzTYdVs=; b=IwHcfMrsBfaGd0jYbit76x4L/NRrExY+fKoW9xYe3ug0rahBvBAy7IygpyVMlOuT4Y lqLMMqhDGPFa0oxs98cGZcxRHmSy2kAIY2AaxHXCcPzEy3Gx/3LfUcqd/7Vo689YD6SP SX+cobpnmjqSBW85NidDr+NK/p14KZLfhdVAu3lv3n938apCQHo27xJiqhRWfFE5zJIJ 7mrsL//gOuUQvibDgtNXUPCecTl4JFZ5Gd8rtaHDTUAVsFb3f+xKo0BloGBUCBOxXChD 5KUFhx8srj2D/wA/9WJ0Uhbf5hR6YYOH38ZivxuzDG0hmirQm44jPm90EcnMbHHWuc10 +5/Q== 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 y12si336176edl.290.2022.01.19.10.57.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:28 -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 560E28386D; Wed, 19 Jan 2022 19:57: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 014A483868; Wed, 19 Jan 2022 19:57:06 +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 5EC2083858 for ; Wed, 19 Jan 2022 19:57: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 C18191FB; Wed, 19 Jan 2022 10:57:01 -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 98F203F73D; Wed, 19 Jan 2022 10:56:56 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 5/9] EFI: FMP: Add provision to update image's ImageTypeId in image descriptor Date: Thu, 20 Jan 2022 00:25:44 +0530 Message-Id: <20220119185548.16730-6-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: None 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 Wed Jan 19 18:55:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533277 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1131011imr; Wed, 19 Jan 2022 10:57:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJz3pwbINct3xplZ/N8nFGqtQcffmikL80HQ5swE3o+6R8jnpHc8Gekqqe09hehS/Fn1MbUn X-Received: by 2002:a17:906:3485:: with SMTP id g5mr14982586ejb.293.1642618658832; Wed, 19 Jan 2022 10:57:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618658; cv=none; d=google.com; s=arc-20160816; b=cOGcp3LLMC/3X16q7m6dKavwoihxXG0iy61kEJ31E9zbZ8USOwzGuFCCLH8h2lJKEl 5/hGED7La2ES9UwPrA+zSKOJJqDfn2SD4C/iUxXF0hVzDBAl5lmTAVjuPQv9yCUST1gu sWo+6YvHssZKRIy0xsjPR5BCe/9+q4R8Uig48o0V8sJq3GJ9NBL8oJkkj1OLpQbdnk6q jmNyAGwuCRxETMIsc1y9ZssCyA4xtJYd9quQUpBONnRc2yzYQX2Qw1qWhdq1Beyx5dDx 9ZxnVo1iX4z2ztwutI/ftvwwHTdzByWWcWsmDmaQb6kvtkUeTVBr7P5b9TQa84encAiC D0rQ== 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=PDU1THH+B9pA8K/Nbw+2nmi62kmcSdC8uGNarrFCzPo=; b=L2+ZPmHE7SYIXDQN5bgGI/p3z01IF9DnMlD7D1+9pJB7hIIaOw9zE9AtKTllXvhEZq +L1HjwfxGPrt+A5WXMn6/6iugjl/oLeJFkC8kybopwyNZ/tu5s3m1LiolQ3XMXdur6Ef Rxjopr5IYqUEMonybhjl5gHjJdAubMSVaBFur1+t22oWrAwJfzF1tDnG/WUx0tnytJIt GjxhluLMOKAUdd8ufEuw4g+JTpEv+6kO8t3H7WeGM2vJmsNptBRLmkIpzQ8vdo63trBK ph0a2Wl909wVHp3WvBS7dHFz31J2maUpW6CsxmajEMPeBGY6htJj1KwW2939b7GADXKo rlIQ== 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 qa44si391969ejc.6.2022.01.19.10.57.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:38 -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 A81E58383F; Wed, 19 Jan 2022 19:57:13 +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 A1E83832CD; Wed, 19 Jan 2022 19:57:11 +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 27EEF8385A for ; Wed, 19 Jan 2022 19:57:08 +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 8B9F01FB; Wed, 19 Jan 2022 10:57:07 -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 5F0E13F73D; Wed, 19 Jan 2022 10:57:02 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 6/9] FWU: Add boot time checks as highlighted by the FWU specification Date: Thu, 20 Jan 2022 00:25:45 +0530 Message-Id: <20220119185548.16730-7-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Add logic to delete the TrialStateCtr variable if system is not in Trial State common/board_r.c | 6 ++ include/fwu.h | 3 + lib/fwu_updates/fwu.c | 171 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 180 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 6393a1dbb5..950a816dbd 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -47,6 +47,9 @@ struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void); 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_mdata(struct fwu_mdata **mdata); int fwu_update_mdata(struct fwu_mdata *mdata); int fwu_get_active_index(u32 *active_idx); diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c new file mode 100644 index 0000000000..906b5e622a --- /dev/null +++ b/lib/fwu_updates/fwu.c @@ -0,0 +1,171 @@ +// 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; + } + } + } else { + trial_state_ctr = 0; + ret = 0; + status = efi_set_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + 0, + 0, &trial_state_ctr, + NULL); + } + +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 Wed Jan 19 18:55:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533278 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1131135imr; Wed, 19 Jan 2022 10:57:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJxmzfu3eNbTBgVqDlnyQwyI1PEQYA7LzcGppCdJrpYo3zqh+nD4axEqL+oMrLtYGF9w38AC X-Received: by 2002:a05:6402:51cd:: with SMTP id r13mr19181827edd.139.1642618670348; Wed, 19 Jan 2022 10:57:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618670; cv=none; d=google.com; s=arc-20160816; b=Vl4vHGMBV7Fm4Bi4XoKCt+YuywtHP+o7PMqrE1fJ4//HP+LfluZDPXn6wmf++1PWf3 3fNe4mFRkOjm09rez8dfPggwJFWK+ERnHe3oan5b9fjZkWZwxU/U2FNNHRkIUHMPnIyC eJdUjg0RulVTYogMJYvGMAB8qSoMb9IAOVfb6BWs2dvgDkkTnrb4KnnTSyMxRzMBIm50 nIRn310HW380O60WljZdHUcyRYWyF82k4QZ3uUvfgEXLHlslvlFnJshI8wjsET5eoRTj vZDTqqK4QQiAnThki7t63VMWknQuUdtw/Hf7rkiVAJLqO27jX08B056QEM066Tq++xya AD2Q== 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=eVlrEEf8zb9QFOmmUwL81djHTUwjf1shXV6iIh+e1HQ=; b=bhLiQp4BOY+rTPFULdZK4C4pQcoJowKYn3qOqWKuoRBa4NpSppDuWZxoc8CfiU+gY5 xr52cnYUIl0/DPNwwugEIuDj9PjTpZdNhRw0qAdKLA6YAryh963XndIkxwboj/MaG1VJ l9NZMiuvCoNZjWeoXNohvCBiR6VGeZvjqdouWwesfuM229DKL/kVpntK4rkT5bDimttf Z9YjLv7ey+eN4Ir8SzrhwOgKsXBrorYf9ZfEwzgHfXcFeI2zY3ln9thTRjobZi9YMkSz 6J2VXrlz3TF8LWJz4x5UpP+HxHXtNWV4Zjo1I4oujebtxL+MBz1L8sY4TdP8tv7QP/KO xwEQ== 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 e11si259857ejl.859.2022.01.19.10.57.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:57:50 -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 862F683867; Wed, 19 Jan 2022 19:57:21 +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 4B06D83325; Wed, 19 Jan 2022 19:57:20 +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 7A92183875 for ; Wed, 19 Jan 2022 19:57:14 +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 D07B71FB; Wed, 19 Jan 2022 10:57:13 -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 2ABA93F73D; Wed, 19 Jan 2022 10:57:07 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 7/9] FWU: Add support for FWU Multi Bank Update feature Date: Thu, 20 Jan 2022 00:25:46 +0530 Message-Id: <20220119185548.16730-8-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Add logic to check if bit 15(OS Acceptance) of the Flags member in the capsule header is set * Add logic to set the accept bit of all images from a capsule if the OS Acceptance bit in the capsule header is not set include/fwu.h | 12 +- lib/Kconfig | 6 + lib/Makefile | 1 + lib/efi_loader/efi_capsule.c | 233 ++++++++++++++++++++++++++++++++++- lib/efi_loader/efi_setup.c | 3 +- lib/fwu_updates/Kconfig | 31 +++++ lib/fwu_updates/Makefile | 11 ++ lib/fwu_updates/fwu.c | 27 ++++ 8 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 lib/fwu_updates/Kconfig create mode 100644 lib/fwu_updates/Makefile diff --git a/include/fwu.h b/include/fwu.h index 950a816dbd..6c9b64a9f1 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -42,13 +42,23 @@ struct fwu_mdata_ops { struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void); #define FWU_MDATA_VERSION 0x1 +#define FWU_IMAGE_ACCEPTED 0x1 #define FWU_MDATA_GUID \ EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) -int fwu_boottime_checks(void); +#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) + u8 fwu_update_checks_pass(void); +int fwu_boottime_checks(void); +int fwu_trial_state_ctr_start(void); int fwu_get_mdata(struct fwu_mdata **mdata); int fwu_update_mdata(struct fwu_mdata *mdata); diff --git a/lib/Kconfig b/lib/Kconfig index 807a4c6ade..d8ff672354 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -835,3 +835,9 @@ 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. + +menu "FWU Multi Bank Updates" + +source lib/fwu_updates/Kconfig + +endmenu 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..83c89a0cbb 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,16 @@ 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; + +#define FW_ACCEPT_OS (u32)0x8000 + +__maybe_unused static u32 update_index; +__maybe_unused static bool capsule_update; +__maybe_unused static bool fw_accept_os; #ifdef CONFIG_EFI_CAPSULE_ON_DISK /* for file system access */ @@ -403,10 +414,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 +495,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 +535,38 @@ static efi_status_t efi_capsule_update_firmware( efi_free_pool(abort_reason); goto out; } + + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + if (!fw_accept_os) { + /* + * The OS will not be accepting the firmware + * images. Set the accept bit of all the + * images contained in this capsule. + */ + status = fwu_accept_image(&image_type_id, + update_index); + } else { + status = fwu_clear_accept_image(&image_type_id, + update_index); + } + + if (status < 0) { + log_err("Unable to %s the accept bit for the image %pUl\n", + fw_accept_os ? "clear" : "set", + &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("%s the accepted bit for Image %pUl\n", + fw_accept_os ? "Cleared" : "Set", + &image_type_id); + } + } out: @@ -527,6 +601,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 +615,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 +639,82 @@ 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; + } + if (capsule->flags & FW_ACCEPT_OS) + fw_accept_os = 0x1; + } + 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. Recommend rebooting the system\n"); + } + } 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_get_active_index(&active_idx); + if (status < 0) { + log_err("Unable to get the active_index from the FWU metadata\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; + goto out; + } + + status = fwu_accept_image(image_guid, active_idx); + if (status < 0) { + log_err("Unable to set the Accept bit for the image %pUl\n", + image_guid); + 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 +725,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 +1282,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 +1313,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 +1325,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 +1333,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 49172e3579..df41510340 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -302,7 +302,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/Kconfig b/lib/fwu_updates/Kconfig new file mode 100644 index 0000000000..6de28e0c9c --- /dev/null +++ b/lib/fwu_updates/Kconfig @@ -0,0 +1,31 @@ +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/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 906b5e622a..fd0eccd5c6 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -115,6 +115,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 Wed Jan 19 18:55:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533279 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1131236imr; Wed, 19 Jan 2022 10:58:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJybum72nrPNH2P/tA+l4QVRb01hGVwsKa9jMi3UyJkCfGLodCWOpTriTPWkeGbiRU0sLgBj X-Received: by 2002:aa7:dc15:: with SMTP id b21mr31498900edu.237.1642618680539; Wed, 19 Jan 2022 10:58:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618680; cv=none; d=google.com; s=arc-20160816; b=iEkzQF5iZelExJtSv6a3rI+1ZDmcnsUberTbswta15u5hHO678Jd5vLu6JKidtmjla 38isk8OBYLVMRuHCV/2IRu2f93Mb4jufwf0Y6b5WhQaoRIY2hFvQwVfhqL1No/gV0M4A TDmvpIXjSZlVE0CDU1nVY5M8UUaiLqfKyvKN/lpmwOJe59NTICvTMP/CNvrYjuqON5t4 8SDOqX3NLZgfPVoDXeMl7mWi2VPtPMLnE4jjonUzWJ29JkbGSbQ2GffUHoJZKrhQgiLt mL4HP+DGY0LQbrRntg6KLDKrt0sDY0ObwA4TG4Bns1uSHXenJgPKEsrOlPrD1KjWsxOs rlJg== 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=cOiFW9GwQxPvULBjeLtNWMHgBIy9cbEOmyMzrHDzbWU=; b=AyZDThtTUdKy19Un3aZY4HIwy5cGiUhmVdSvSsP5/+vgNwTCDsLsAfsKgxWVolCB1N RrGgy7KA/uCof9FNChszwCDu0tnXuayloN9+B/Thxjr5qeotS9QI/Yi9EX27WztTOWK2 12A+B/7PI7qE/nzVG7sqFOe580FYWBSQD86JzTDlyFUwg5MFx3ESd8ajk0Icujd9oAXA mRRTt9Drdbbxh5kO1Icvbb9yOJmDYs6Rzs9rfxWDTmsRp9N50OxHK/H7Y9uUwLxudXDh 8uD3XKfoB+giSJMLoguTrsOaA8Fbc1oPOCQ22TK+HoY+/CRmoInmOLATfiy4Bh54tex/ cawA== 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 o1si316943edf.363.2022.01.19.10.58.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:58:00 -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 35F8B83876; Wed, 19 Jan 2022 19:57: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 EAC3283858; Wed, 19 Jan 2022 19:57:22 +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 4EEBA83858 for ; Wed, 19 Jan 2022 19:57:20 +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 A0A2B1FB; Wed, 19 Jan 2022 10:57:19 -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 73C363F73D; Wed, 19 Jan 2022 10:57:14 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 8/9] FWU: cmd: Add a command to read FWU metadata Date: Thu, 20 Jan 2022 00:25:47 +0530 Message-Id: <20220119185548.16730-9-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 V2: * Include the log.h and stdio.h header files cmd/Kconfig | 7 ++++++ cmd/Makefile | 1 + cmd/fwu_mdata.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 cmd/fwu_mdata.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 02c298fdbe..c8eb12e00f 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 e31ac15ef7..b917527965 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..81e4850442 --- /dev/null +++ b/cmd/fwu_mdata.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#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", + "" +); From patchwork Wed Jan 19 18:55:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533280 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1131337imr; Wed, 19 Jan 2022 10:58:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJzbvJv/w4w7rTmdP1F849YQ/rm9DtRI0xZXoXZ9KWxToEFv40gDzB8+cOgHmlaDpgUS1y3e X-Received: by 2002:a05:6402:1d54:: with SMTP id dz20mr31874664edb.395.1642618690159; Wed, 19 Jan 2022 10:58:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618690; cv=none; d=google.com; s=arc-20160816; b=ckTaj4qun9lrttam1Y+SK+13qXCZHWMzRrW5048DP0vXM65YShrDPcORCepeNNuLK/ 5P3xv+LbIDqBqzhgIksPiFiX7fl4zAoKdzf+4VNSVde8aiutgDukDZRtlUUFrm7iM6NH jwnK/OFNqIJSOt/GkYFvz9lHNDGBUvstcfbNdsdNlVUn6CsQHCEJUoO0s2tpe4y8Y5kU +7vCxLAPzpQ9zuqqUR4+kb6O06jEiWiZar5ZT166iW5bOCXtpLu6w+HM0WoWAALklGii LHReNEeUhbSOXLCiTv46vA8nVCUWW4HpbVahEKRRUNmQXevLlF5+UsVnda3j+vOpaC9s ifuA== 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=t+8iHypcaZPC93Tffk6MLq1+z71wkKnlzrcNbILF4es=; b=XAmzKiHtpdN3UGjqJCsIzZRMm2CrjgkNjR3m03kgIUm7EY3KT1+/BEqhGDQt7J7HsO 2cr/Rqco5uc4LemIQcIwV9/Oo6bis46lIYNh1u89cu6S8tSfK888SV7G1hAiMxZEYXka /WDerXtlT477IeRutRM8AXIsrGr8Of6d8KLUwdopnkaXL0tYCHoIwVh/s8c94SIRuS2P GUzGGudHe081JMVKTmABKxhAdD63tr3Wkgl9yIPieu6OIoa9lTnqZO5iLsD9rDfa0ptX UZjhJoF3m/4pa+nTeyD2yoPNLzwQUXJJAM7lYRagQUPqu320YEd+sWWI3DJXqiGTJJ2N xwlg== 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 bl4si329903ejb.462.2022.01.19.10.58.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:58:10 -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 19C958383D; Wed, 19 Jan 2022 19:57:32 +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 D7B5A8384B; Wed, 19 Jan 2022 19:57:29 +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 0726D8388D for ; Wed, 19 Jan 2022 19:57:26 +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 69D611FB; Wed, 19 Jan 2022 10:57:25 -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 3DB113F73D; Wed, 19 Jan 2022 10:57:19 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 9/9] mkeficapsule: Add support for generating empty capsules Date: Thu, 20 Jan 2022 00:25:48 +0530 Message-Id: <20220119185548.16730-10-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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 Dependable Boot specification describes the structure of the firmware accept and revert capsules. These are empty capsules which are used for signalling the acceptance or rejection of the updated firmware by the OS. Add support for generating these empty capsules. Signed-off-by: Sughosh Ganu --- Changes since V2: * New patch for generating empty capsules tools/eficapsule.h | 8 ++++ tools/mkeficapsule.c | 102 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 8c1560bb06..6001952bdc 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -50,6 +50,14 @@ typedef struct { EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) +#define FW_ACCEPT_OS_GUID \ + EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \ + 0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8) + +#define FW_REVERT_OS_GUID \ + EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \ + 0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0) + /* flags */ #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index 161affdd15..643da3849d 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -29,6 +29,7 @@ #include "eficapsule.h" static const char *tool_name = "mkeficapsule"; +static unsigned char empty_capsule; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_image_type_uboot_fit = @@ -38,9 +39,9 @@ efi_guid_t efi_guid_image_type_uboot_raw = efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; #ifdef CONFIG_TOOLS_LIBCRYPTO -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "frg:i:I:v:p:c:m:dhAR"; #else -static const char *opts_short = "frg:i:I:v:h"; +static const char *opts_short = "frg:i:I:v:hAR"; #endif static struct option options[] = { @@ -55,15 +56,23 @@ static struct option options[] = { {"monotonic-count", required_argument, NULL, 'm'}, {"dump-sig", no_argument, NULL, 'd'}, #endif + {"fw-accept", no_argument, NULL, 'A'}, + {"fw-revert", no_argument, NULL, 'R'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; static void print_usage(void) { - fprintf(stderr, "Usage: %s [options] \n" - "Options:\n" + if (empty_capsule) { + fprintf(stderr, "Usage: %s [options] \n", + tool_name); + } else { + fprintf(stderr, "Usage: %s [options] \n", + tool_name); + } + fprintf(stderr, "Options:\n" "\t-f, --fit FIT image type\n" "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" @@ -75,8 +84,9 @@ static void print_usage(void) "\t-m, --monotonic-count monotonic count\n" "\t-d, --dump_sig dump signature (*.p7)\n" #endif - "\t-h, --help print a help message\n", - tool_name); + "\t-A, --fw-accept firmware accept capsule\n" + "\t-R, --fw-revert firmware revert capsule\n" + "\t-h, --help print a help message\n"); } /** @@ -598,6 +608,59 @@ void convert_uuid_to_guid(unsigned char *buf) buf[7] = c; } +static int create_empty_capsule(char *path, efi_guid_t *guid, bool fw_accept) +{ + struct efi_capsule_header header; + FILE *f; + int ret; + efi_guid_t fw_accept_guid = FW_ACCEPT_OS_GUID; + efi_guid_t fw_revert_guid = FW_REVERT_OS_GUID; + efi_guid_t payload, capsule_guid; + + f = NULL; + ret = -1; + + f = fopen(path, "w"); + if (!f) { + printf("cannot open %s\n", path); + goto err; + } + + if (fw_accept) + capsule_guid = fw_accept_guid; + else + capsule_guid = fw_revert_guid; + + memcpy(&header.capsule_guid, &capsule_guid, sizeof(efi_guid_t)); + header.header_size = sizeof(header); + header.flags = 0; + + if (fw_accept) { + header.capsule_image_size = sizeof(header) + sizeof(efi_guid_t); + } else { + header.capsule_image_size = sizeof(header); + } + + if (write_capsule_file(f, &header, sizeof(header), + "Capsule header")) + goto err; + + if (fw_accept) { + memcpy(&payload, guid, sizeof(efi_guid_t)); + if (write_capsule_file(f, &payload, sizeof(payload), + "FW Accept Capsule Payload")) + goto err; + } + + ret = 0; + +err: + if (f) + fclose(f); + + return ret; +} + /** * main - main entry function of mkeficapsule * @argc: Number of arguments @@ -616,6 +679,7 @@ int main(int argc, char **argv) unsigned char uuid_buf[16]; unsigned long index, instance; uint64_t mcount; + unsigned char accept_fw_capsule, revert_fw_capsule; char *privkey_file, *cert_file; int c, idx; @@ -625,6 +689,8 @@ int main(int argc, char **argv) mcount = 0; privkey_file = NULL; cert_file = NULL; + accept_fw_capsule = 0; + revert_fw_capsule = 0; dump_sig = 0; for (;;) { c = getopt_long(argc, argv, opts_short, options, &idx); @@ -691,22 +757,38 @@ int main(int argc, char **argv) dump_sig = 1; break; #endif /* CONFIG_TOOLS_LIBCRYPTO */ + case 'A': + accept_fw_capsule = 1; + break; + case 'R': + revert_fw_capsule = 1; + break; case 'h': print_usage(); exit(EXIT_SUCCESS); } } + empty_capsule = (accept_fw_capsule || revert_fw_capsule); + /* check necessary parameters */ - if ((argc != optind + 2) || !guid || - ((privkey_file && !cert_file) || + if ((!empty_capsule && argc != optind + 2) || + (empty_capsule && argc != optind + 1) || + (!revert_fw_capsule && !guid) || ((privkey_file && !cert_file) || (!privkey_file && cert_file))) { print_usage(); exit(EXIT_FAILURE); } - if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, index, instance, - mcount, privkey_file, cert_file) < 0) { + if (empty_capsule) { + if (create_empty_capsule(argv[argc - 1], guid, + accept_fw_capsule ? 1 : 0) < 0) { + printf("Creating empty capsule failed\n"); + exit(EXIT_FAILURE); + } + } else if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, + index, instance, mcount, privkey_file, + cert_file) < 0) { fprintf(stderr, "Creating firmware capsule failed\n"); exit(EXIT_FAILURE); }