From patchwork Thu Nov 25 07:12:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519368 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp367763imj; Wed, 24 Nov 2021 23:13:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJzRN1ipfxi5cjHTIFxzd//HmKwkeqDDc7FJaYoBOA/KVRVMH+4XLRY3emn4HjTmG2gGzH86 X-Received: by 2002:a05:6402:27cd:: with SMTP id c13mr36120713ede.57.1637824425937; Wed, 24 Nov 2021 23:13:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824425; cv=none; d=google.com; s=arc-20160816; b=gCp6g8IXAWdB7cofWlJrgFFwyAAS27+KRCBjBBCmtsakBiezqza0wEvvNosbWdgafd e5wMxeku34fMpDNbGaedFsCXJLOh1ON/od7bpcEeDa5RY0ERhvlRJA8+aAB11vHYdHNH jh0LEzmwhb7IXNQpJkHTw8gRqr5NgF9g9VThNfaITkpLj779AZEah/XXfe0bDYYatLUK N4vDmQSFilmHpq3/DXE+H+EpzTOGSYNmvPHeoxR8hQ5fKSAr3y3d1SiDJThWRwrZqi5L WE0Bq305xRSX25aNxigoO1Qc1NG9Bpxc2NzsOXXYusVATcAo5zyhNQaU9de/WApFmYOs QE+g== 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=jkx32brlUzX6lAGWc302486BdZdKR0CFUsJu+XUEpq0=; b=lySqkjbGY2PJvwXS7F94CQAmfptJFv9MV8hwczTDgnFY2LZh1VOXYmRp+oPo8tGPxQ /rXTw9lMTw4KUayk//Fg5tgCJXRKqmBXP8H2pT91P3jaWfNVdFbyUzPN13TnM/xPnm0C JidbAQo41xQ6TmztSipBsATN2PkHfnODHbl3BYnwHN+by37tCy/FW6hV9zD0c7xK8WvP 5UzrbOyhoPtlHcs1vjC9vuSxrpez0YbVzhYNdk0Ff7QB0Dhhf3mFTj+08tgcJj3+Kbnd CRBOWoTixU9UfFQuHEaCIr+PyLlLR2lM7r9g8dQGvH7KOOCQ6VCrnuDqB6Yv2IZ5XUhK zQLw== 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 a2si5028746edk.328.2021.11.24.23.13.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:13:45 -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 2C44283709; Thu, 25 Nov 2021 08:13: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 1E4638321B; Thu, 25 Nov 2021 08:13:36 +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 894B18128B for ; Thu, 25 Nov 2021 08:13:32 +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 F1D261042; Wed, 24 Nov 2021 23:13:31 -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 364F43F5A1; Wed, 24 Nov 2021 23:13:27 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 01/10] GPT: Add function to get gpt header and partition entries Date: Thu, 25 Nov 2021 12:42:53 +0530 Message-Id: <20211125071302.3644-2-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 function to get the gpt header and partition entries filled. These would be used subsequently for multi bank firmware update support on devices where the images reside on GPT partitions. Signed-off-by: Sughosh Ganu --- disk/part_efi.c | 10 ++++++++++ include/part.h | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/disk/part_efi.c b/disk/part_efi.c index 0ca7effc32..792b9218a9 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -216,6 +216,16 @@ int get_disk_guid(struct blk_desc * dev_desc, char *guid) return 0; } +int get_gpt_hdr_parts(struct blk_desc *desc, gpt_header *gpt_head, + gpt_entry **gpt_pte) +{ + /* This function validates and fills in the GPT header and PTE's */ + if (find_valid_gpt(desc, gpt_head, gpt_pte) != 1) + return -EINVAL; + + return 0; +} + void part_print_efi(struct blk_desc *dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); diff --git a/include/part.h b/include/part.h index b66b07a1f0..8e86485b97 100644 --- a/include/part.h +++ b/include/part.h @@ -345,6 +345,20 @@ struct part_driver { #if CONFIG_IS_ENABLED(EFI_PARTITION) /* disk/part_efi.c */ + +/** + * get_gpt_hdr_parts() - Get information on the GPT Header and + * Partition Table Entries + * + * @param desc - block device descriptor + * @param gpt_h - pointer to GPT header representation + * @param gpt_e - pointer to GPT partition table entries + * + * @return - zero on success, otherwise error + */ +int get_gpt_hdr_parts(struct blk_desc *desc, gpt_header *gpt_head, + gpt_entry **gpt_pte); + /** * write_gpt_table() - Write the GUID Partition Table to disk * From patchwork Thu Nov 25 07:12:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519369 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp368204imj; Wed, 24 Nov 2021 23:14:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJwuEyWmTErT1EP7YRFyitn3Asjf211+L1ejqlhI9gDDYMd7p81HLac11Dt9kNXTGEei9PdL X-Received: by 2002:a05:6402:2152:: with SMTP id bq18mr15986107edb.105.1637824444449; Wed, 24 Nov 2021 23:14:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824444; cv=none; d=google.com; s=arc-20160816; b=nuuTYxKfNBAwKxS7BrOq8mkOaoyKFb9/MwdUuqSr9G8dLoDisW/pPGiRu5MR9SlU9u ujLE9jmkI+MifLWbfdUuEOJpkLOpbwndebpecHJEwOOACtpK8nCQU+SgA4unQy8dpQWU V6hHgSPOsE/whUTX2sDODuOa3U0Zkmdc3bgIL3HXYcYBbyfevZBNKv35L6795Z1eQWOt o2biQ3ge+yMWLG6rMgvnp1a2ZSiBOb6Ih0euZBUHLUupViFncQ8o/Y9dJMgWFhz17xy7 3eplCHFT+lSMB4LwPRa7MnQvK5+/JLCCANVwukZvCqTV6Kg0KMk513TNh58qoqwss5Ui V1Kw== 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=UzVwHKqtbQSl/9CntY4NtBolQk9uQC0G/pcUmfMLLmI=; b=sD++ghYtvjYL6SxlK4wCBig28M8AeyGij9iOSGV/32o2XMZDye9F214tdF/jLZV1sr kGEi6cgRbM77PrhPdHg5gkyTqm0I/236LG4NQcF2wRNQ2bHhg8uXr2E+Z3wkYU43K51q w4PpjIUAWMs3UFbGtDqow5UIkDCW71bFJskfXDOZznhmdt2WeSRCu2Fse4DBU3gogKCl Hkcwbu9bMqkRZZdAYIsJag4FkWX8J/nkRpLIHjKMY3QSu+pSdOKMfAni+v0cavZY1kWb mC9SgPaHCCga1ddfeAQAnxJ7bWU+X+F1NUFYv+XIM1+SibqfUzrkzoe+dp+Zea5yySCx nJAw== 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 yc28si4379324ejb.200.2021.11.24.23.14.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:14:04 -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 B404883468; Thu, 25 Nov 2021 08:13:53 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id D1E13836C9; Thu, 25 Nov 2021 08:13:40 +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 B99D38128B for ; Thu, 25 Nov 2021 08:13:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3782511B3; Wed, 24 Nov 2021 23:13:36 -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 6FF883F5A1; Wed, 24 Nov 2021 23:13:32 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 02/10] stm32mp: dfu: Move the ram partitions to the end of the dfu_alt_info variable Date: Thu, 25 Nov 2021 12:42:54 +0530 Message-Id: <20211125071302.3644-3-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 With the FWU multi bank update feature enabled, the dfu alt no that is used to identify the partition to be updated is derived at runtime and should match the partition number on the storage media. Achieve this by moving the ram partitions to the end of the dfu_alt_info variable. Signed-off-by: Sughosh Ganu --- board/st/common/stm32mp_dfu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c index 00d1fb8f59..394a2704ee 100644 --- a/board/st/common/stm32mp_dfu.c +++ b/board/st/common/stm32mp_dfu.c @@ -102,6 +102,7 @@ static void board_get_alt_info_mtd(struct mtd_info *mtd, char *buf) void set_dfu_alt_info(char *interface, char *devstr) { + int len; struct udevice *dev; struct mtd_info *mtd; @@ -112,9 +113,6 @@ void set_dfu_alt_info(char *interface, char *devstr) memset(buf, 0, sizeof(buf)); - snprintf(buf, DFU_ALT_BUF_LEN, - "ram 0=%s", CONFIG_DFU_ALT_RAM0); - if (CONFIG_IS_ENABLED(MMC)) { if (!uclass_get_device(UCLASS_MMC, 0, &dev)) board_get_alt_info_mmc(dev, buf); @@ -151,6 +149,13 @@ void set_dfu_alt_info(char *interface, char *devstr) strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); } + len = strlen(buf); + if (buf[0] != '\0') + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&"); + + snprintf(buf + len, DFU_ALT_BUF_LEN, + "ram 0=%s", CONFIG_DFU_ALT_RAM0); + env_set("dfu_alt_info", buf); puts("DFU alt info setting: done\n"); } From patchwork Thu Nov 25 07:12:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519370 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp368441imj; Wed, 24 Nov 2021 23:14:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJz0jN99zaLD/A9o0tVz4rRgLGfyDHVxI32SKhAAuqmIYHYI+XTQfknBfPgOc+HOgMeT8++y X-Received: by 2002:a17:907:7210:: with SMTP id dr16mr28616542ejc.267.1637824458056; Wed, 24 Nov 2021 23:14:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824458; cv=none; d=google.com; s=arc-20160816; b=ebAR33caYN0ms1uahem5DTESIEJurDH4v1f2CJ9MOkwvRaINnYMPJrihSaUvjoodIW ftkMEjZ9a8hQ/jmietvTvRkOH0L3up304QKI+8UbSCh/87r6/xwm7O/9sn/IxFhbeNiA fQfr4GA4aebvrLgOBkOxRl1NbuxNquu+421gdkiCde/ZSLMj05JlJ+fvWfWD85EoUbI9 380lhzwMgjapcRAGvhTIm43MjSnLv/Mn+lwj6xM7T+wTcjUXdxWwqD0Y3DPYnRcENthk G0DAu9qfx6zFMbTFpTsjtNDky1O09jdt7XZCD8Hqzlp5imFxkl9MZrP1O7E/yiM1aM3o lp8w== 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=JIqyWQbDwwhrZENTfNmz/Fxv4anjVb810vu/1sq7Dps=; b=NbWY1munSZ/pT7b5uSizcUwLlQvGkP9NSSGitmCcQrzU3sJv280oNgP6hqgfBf5ZWp 3d/RW+626Y+OiHFsz4VE8OC9UmhEr2RVTTW/L9MmxQOXe7aBn5m1yE9W98Gq6xjS6DZR k4tjP/PNgVRE3y2OEmNvQTPFmxJ1w1QCZTkSeNGqAACIB/vnOPfrqEdRG5A7BAFcC1uL jHYqW6Qhql263urvxmpQTrgPGW8npTqUar6vSMzkeNAnmczouWSMfTUXcI0Q3TMlzAY5 2YSkOLCdCIhq/SL4eNhR0Wjx2UGmv1ZadkKv6t9zgzCaB5lplpre3XvUEmYWqoXFt6Iu 3TXw== 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 z19si4547166ejx.623.2021.11.24.23.14.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:14:18 -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 97C6E8374D; Thu, 25 Nov 2021 08:13:58 +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 E528A8128B; Thu, 25 Nov 2021 08:13:46 +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 41AF7836E2 for ; Thu, 25 Nov 2021 08:13:41 +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 AB18B150C; Wed, 24 Nov 2021 23:13:40 -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 A7F833F5A1; Wed, 24 Nov 2021 23:13:36 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 03/10] FWU: Add metadata structure and functions for accessing metadata Date: Thu, 25 Nov 2021 12:42:55 +0530 Message-Id: <20211125071302.3644-4-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- include/fwu_metadata.h | 125 +++++++++++++++ lib/fwu_updates/fwu_metadata.c | 275 +++++++++++++++++++++++++++++++++ 2 files changed, 400 insertions(+) create mode 100644 include/fwu_metadata.h create mode 100644 lib/fwu_updates/fwu_metadata.c diff --git a/include/fwu_metadata.h b/include/fwu_metadata.h new file mode 100644 index 0000000000..e692ef7506 --- /dev/null +++ b/include/fwu_metadata.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#if !defined _FWU_METADATA_H_ +#define _FWU_METADATA_H_ + +#include +#include +#include + +#include + +/** + * struct fwu_image_bank_info - firmware image information + * @image_uuid: Guid value of the image in this bank + * @accepted: Acceptance status of the image + * @reserved: Reserved + * + * The structure contains image specific fields which are + * used to identify the image and to specify the image's + * acceptance status + */ +struct fwu_image_bank_info { + efi_guid_t image_uuid; + u32 accepted; + u32 reserved; +}; + +/** + * struct fwu_image_entry - information for a particular type of image + * @image_type_uuid: Guid value for identifying the image type + * @location_uuid: Guid of the storage volume where the image is located + * @img_bank_info: Array containing properties of images + * + * This structure contains information on various types of updatable + * firmware images. Each image type then contains an array of image + * information per bank. + */ +struct fwu_image_entry { + efi_guid_t image_type_uuid; + efi_guid_t location_uuid; + struct fwu_image_bank_info img_bank_info[CONFIG_FWU_NUM_BANKS]; +}; + +/** + * struct fwu_metadata - Metadata structure for multi-bank updates + * @crc32: crc32 value for the metadata + * @version: 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_metadata { + u32 crc32; + u32 version; + u32 active_index; + u32 previous_active_index; + + struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +}; + +/** + * @get_active_index: get the current active_index value + * @update_active_index: update the active_index value + * @fill_partition_guid_array: fill the array with guid values of the + * partitions found on the storage media + * @get_image_alt_num: get the alt number to be used for the image + * @metadata_check: check the validity of the metadata partitions + * @revert_boot_index: set the active_index to previous_active_index + * @set_accept_image: set the accepted bit for the image + * @clear_accept_image: clear the accepted bit for the image + * @get_metadata() - Get a metadata copy + */ +struct fwu_metadata_ops { + int (*get_active_index)(u32 *active_idx); + + int (*update_active_index)(u32 active_idx); + + int (*fill_partition_guid_array)(efi_guid_t **part_guid_arr, + u32 *nparts); + + int (*get_image_alt_num)(efi_guid_t image_type_id, u32 update_bank, + int *alt_num); + + int (*metadata_check)(void); + + int (*revert_boot_index)(u32 *active_idx); + + int (*set_accept_image)(efi_guid_t *img_type_id); + + int (*clear_accept_image)(efi_guid_t *img_type_id, u32 bank); + + int (*get_metadata)(struct fwu_metadata **metadata); +}; + +#define FWU_METADATA_GUID \ + EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ + 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) + +#define FWU_METADATA_VERSION 0x1 + +extern struct fwu_metadata_ops fwu_gpt_blk_ops; + +struct fwu_metadata_ops *get_plat_fwu_metadata_ops(void); +int fwu_get_active_index(u32 *active_idx); +int fwu_update_active_index(u32 active_idx); +int fwu_fill_partition_guid_array(efi_guid_t **part_guid_arr, u32 *nparts); +int fwu_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, + int *alt_num); +int fwu_metadata_check(void); +int fwu_revert_boot_index(u32 *active_idx); +int fwu_accept_image(efi_guid_t *img_type_id); +int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank); +int fwu_get_metadata(struct fwu_metadata **metadata); + +#endif /* _FWU_METADATA_H_ */ diff --git a/lib/fwu_updates/fwu_metadata.c b/lib/fwu_updates/fwu_metadata.c new file mode 100644 index 0000000000..ebc3eaa04a --- /dev/null +++ b/lib/fwu_updates/fwu_metadata.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include + +#include +#include + +static inline struct fwu_metadata_ops *get_fwu_metadata_ops(void) +{ + return get_plat_fwu_metadata_ops(); +} + +/** + * fwu_get_active_index() - Get active_index from the metadata + * @active_idx: active_index value to be read + * + * Read the active_index field from the 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_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + 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 metadata + * @active_idx: active_index value to be updated + * + * Update the active_index field in the metadata + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_update_active_index(u32 active_idx) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->update_active_index) { + log_err("update_active_index() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->update_active_index(active_idx); +} + +/** + * fwu_fill_partition_guid_array() - Fill the part_guid_arr array with the guid's of + * the partitions + * @part_guid_arr: array of partition guid's + * @nparts: Number of gpt partitions on the device + * + * Get the information on the partition guid's, filling the array with the guid + * values and also the number of partitions. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_fill_partition_guid_array(efi_guid_t **part_guid_arr, u32 *nparts) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->fill_partition_guid_array) { + log_err("fill_partition_guid_array() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->fill_partition_guid_array(part_guid_arr, nparts); +} + +/** + * 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_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + 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_metadata_check() - Check if the metadata is valid + * + * Validate both copies of 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_metadata_check(void) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->metadata_check) { + log_err("metadata_check() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->metadata_check(); +} + +/** + * fwu_revert_boot_index() - Revert the active index in the metadata + * @active_idx: Value of the updated active_index + * + * Revert the active_index value in the metadata, by swapping the values + * of active_index and previous_active_index in both copies of the + * metadata. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_revert_boot_index(u32 *active_idx) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->revert_boot_index) { + log_err("revert_boot_index() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->revert_boot_index(active_idx); +} + +/** + * fwu_accept_image() - Set the Acceptance bit for the image + * @img_type_id: Guid of the image type for which the accepted bit is to be + * cleared + * + * Set the accepted bit for the image specified by the img_guid parameter. This + * indicates acceptance of image for subsequent boots by some governing component + * like OS(or firmware). + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_accept_image(efi_guid_t *img_type_id) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->set_accept_image) { + log_err("set_accept_image() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->set_accept_image(img_type_id); +} + +/** + * fwu_clear_accept_image() - Clear the Acceptance bit for the image + * @img_type_id: Guid of the image type for which the accepted bit is to be + * cleared + * + * Clear the accepted bit for the image type specified by the img_type_id parameter. + * This function is called after the image has been updated. The accepted bit is + * cleared to be set subsequently after passing the image acceptance criteria, by + * either the OS(or firmware) + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + 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_metadata() - Get a metadata copy + * @metadata: Copy of the metadata + * + * Get a valid copy of the metadata. + * + * Return: 0 if OK, -ve on error + * + */ +int fwu_get_metadata(struct fwu_metadata **metadata) +{ + struct fwu_metadata_ops *ops; + + ops = get_fwu_metadata_ops(); + if (!ops) { + log_err("Unable to get fwu ops\n"); + return -EPROTONOSUPPORT; + } + + if (!ops->get_metadata) { + log_err("get_metadata() method not defined for the platform\n"); + return -ENOSYS; + } + + return ops->get_metadata(metadata); +} From patchwork Thu Nov 25 07:12:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519374 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp368650imj; Wed, 24 Nov 2021 23:14:30 -0800 (PST) X-Google-Smtp-Source: ABdhPJwm7V1uEj27S459P/VvputRVDi8IH/3QRjiq+eiJF1U9GIa0FCq/hx5VeFM0CHo6XsIJK93 X-Received: by 2002:a17:907:7250:: with SMTP id ds16mr28713642ejc.54.1637824470195; Wed, 24 Nov 2021 23:14:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824470; cv=none; d=google.com; s=arc-20160816; b=PiKo3FpxlZ6ukjVBslp1p63/as29dOf9YmO9pFu/IlYDqvNIPcwLTi1WFtU66D79YV 8eypysg4PGAL0TLnI8mj5PyScYIiZTy/pa+c11Ca1p4nITZbAOWgjSoTVVh4UwSzaUB8 hszCEvExh7j226wxsQnm6k2oLMOoPvdIs0+aUuvvKEt2U2DtHDC0zzuiXK0peakOjRSe REmvHpuXGa+Knm1bgtQ2VpBrsPgm4HHzJawUgT+lTv00a3iH3Q9IpWlzWEwPhW8g8tEQ U3hK6awUkMv67gQm7pFtJi2Olivdj0GI4GS4pmFSyOJrcXX+z4de03X5Cc/7JAx19VPq VDRg== 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=TRRMigymu8SYg1x8C/oX2bw10o7otvsWQs6aNoDTHdE=; b=mgOIo+VzvqJlKZHfEpa8gql2CALLlsW9z9pHd1KYeTImncCt86UYXjh7UVhqcGJiL2 SGkScOK/Eqj66L/fEOEaA4Ecy1y24h532iOIrymNhSKPwivV296Ze18DK5IfKNzg1mS+ ddyVu+mr8CRr3qaeQdcoQuc/x+X0KB5W8uLCO1bic5SQQN88571biAG+1Btz1Y6ia1lR WUIxTOSWErObHHnJeBg0kEU7AzsE8uI8TSBP7XBK+QIySQ+AfZQ2GML//muKDdYGNUYm 6BCSg35xfv8K5NJ7VUiJKy3xb7SVe+2gX+7uPl7Nzej0wmGXqqYYA3Ao19p4Y072CCd5 INIw== 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 fp5si3890879ejc.517.2021.11.24.23.14.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:14:30 -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 E239983762; Thu, 25 Nov 2021 08:14:04 +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 7E7408373E; Thu, 25 Nov 2021 08:13:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-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 B9EB183468 for ; Thu, 25 Nov 2021 08:13: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 263C41515; Wed, 24 Nov 2021 23:13:45 -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 25AB73F5A1; Wed, 24 Nov 2021 23:13:40 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 04/10] FWU: Add metadata access functions for GPT partitioned block devices Date: Thu, 25 Nov 2021 12:42:56 +0530 Message-Id: <20211125071302.3644-5-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- lib/fwu_updates/fwu_metadata_gpt_blk.c | 716 +++++++++++++++++++++++++ 1 file changed, 716 insertions(+) create mode 100644 lib/fwu_updates/fwu_metadata_gpt_blk.c diff --git a/lib/fwu_updates/fwu_metadata_gpt_blk.c b/lib/fwu_updates/fwu_metadata_gpt_blk.c new file mode 100644 index 0000000000..98cc53f706 --- /dev/null +++ b/lib/fwu_updates/fwu_metadata_gpt_blk.c @@ -0,0 +1,716 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PRIMARY_VALID 0x1 +#define SECONDARY_VALID 0x2 + +#define MDATA_READ (u8)0x1 +#define MDATA_WRITE (u8)0x2 + +#define IMAGE_ACCEPT_SET (u8)0x1 +#define IMAGE_ACCEPT_CLEAR (u8)0x2 + +static int gpt_verify_metadata(struct fwu_metadata *metadata, bool pri_part) +{ + u32 calc_crc32; + void *buf; + + buf = &metadata->version; + calc_crc32 = crc32(0, buf, sizeof(*metadata) - sizeof(u32)); + + if (calc_crc32 != metadata->crc32) { + log_err("crc32 check failed for %s metadata partition\n", + pri_part ? "primary" : "secondary"); + return -1; + } + + return 0; +} + +static int gpt_get_metadata_partitions(struct blk_desc *desc, + u32 *primary_mpart, + u32 *secondary_mpart) +{ + int i, ret; + u32 nparts, mparts; + gpt_entry *gpt_pte = NULL; + const efi_guid_t fwu_metadata_guid = FWU_METADATA_GUID; + + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, + desc->blksz); + + ret = get_gpt_hdr_parts(desc, gpt_head, &gpt_pte); + if (ret < 0) { + log_err("Error getting GPT header and partitions\n"); + ret = -EIO; + goto out; + } + + nparts = gpt_head->num_partition_entries; + for (i = 0, mparts = 0; i < nparts; i++) { + if (!guidcmp(&fwu_metadata_guid, + &gpt_pte[i].partition_type_guid)) { + ++mparts; + if (!*primary_mpart) + *primary_mpart = i + 1; + else + *secondary_mpart = i + 1; + } + } + + if (mparts != 2) { + log_err("Expect two copies of the metadata instead of %d\n", + mparts); + ret = -EINVAL; + } else { + ret = 0; + } +out: + free(gpt_pte); + + return ret; +} + +static int gpt_get_metadata_disk_part(struct blk_desc *desc, + struct disk_partition *info, + u32 part_num) +{ + int ret; + char *metadata_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 metadata part %d", + part_num); + return -1; + } + + /* Check that it is indeed the metadata partition */ + if (!strncmp(info->type_guid, metadata_guid_str, UUID_STR_LEN)) { + /* Found the metadata partition */ + return 0; + } + + return -1; +} + +static int gpt_read_write_metadata(struct blk_desc *desc, + struct fwu_metadata *metadata, + u8 access, u32 part_num) +{ + int ret; + u32 len, blk_start, blkcnt; + struct disk_partition info; + + ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_metadata, mdata, 1, desc->blksz); + + ret = gpt_get_metadata_disk_part(desc, &info, part_num); + if (ret < 0) { + printf("Unable to get the metadata partition\n"); + return -ENODEV; + } + + len = sizeof(*metadata); + blkcnt = BLOCK_CNT(len, desc); + if (blkcnt > info.size) { + log_err("Block count exceeds metadata partition size\n"); + return -ERANGE; + } + + blk_start = info.start; + if (access == MDATA_READ) { + if (blk_dread(desc, blk_start, blkcnt, mdata) != blkcnt) { + log_err("Error reading metadata from the device\n"); + return -EIO; + } + memcpy(metadata, mdata, sizeof(struct fwu_metadata)); + } else { + if (blk_dwrite(desc, blk_start, blkcnt, metadata) != blkcnt) { + log_err("Error writing metadata to the device\n"); + return -EIO; + } + } + + return 0; +} + +static int gpt_read_metadata(struct blk_desc *desc, + struct fwu_metadata *metadata, u32 part_num) +{ + return gpt_read_write_metadata(desc, metadata, MDATA_READ, part_num); +} + +static int gpt_write_metadata_partition(struct blk_desc *desc, + struct fwu_metadata *metadata, + u32 part_num) +{ + return gpt_read_write_metadata(desc, metadata, MDATA_WRITE, part_num); +} + +static int gpt_update_metadata(struct fwu_metadata *metadata) +{ + int ret; + struct blk_desc *desc; + u32 primary_mpart, secondary_mpart; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + primary_mpart = secondary_mpart = 0; + ret = gpt_get_metadata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the metadata partitions\n"); + return -ENODEV; + } + + /* First write the primary partition*/ + ret = gpt_write_metadata_partition(desc, metadata, primary_mpart); + if (ret < 0) { + log_err("Updating primary metadata partition failed\n"); + return ret; + } + + /* And now the replica */ + ret = gpt_write_metadata_partition(desc, metadata, secondary_mpart); + if (ret < 0) { + log_err("Updating secondary metadata partition failed\n"); + return ret; + } + + return 0; +} + +static int gpt_get_valid_metadata(struct fwu_metadata **metadata) +{ + int ret; + struct blk_desc *desc; + u32 primary_mpart, secondary_mpart; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + primary_mpart = secondary_mpart = 0; + ret = gpt_get_metadata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the metadata partitions\n"); + return -ENODEV; + } + + *metadata = malloc(sizeof(struct fwu_metadata)); + if (!*metadata) { + log_err("Unable to allocate memory for reading metadata\n"); + return -ENOMEM; + } + + ret = gpt_read_metadata(desc, *metadata, primary_mpart); + if (ret < 0) { + log_err("Failed to read the metadata from the device\n"); + return -EIO; + } + + ret = gpt_verify_metadata(*metadata, 1); + if (!ret) + return 0; + + /* + * Verification of the primary metadata copy failed. + * Try to read the replica. + */ + memset(*metadata, 0, sizeof(struct fwu_metadata)); + ret = gpt_read_metadata(desc, *metadata, secondary_mpart); + if (ret < 0) { + log_err("Failed to read the metadata from the device\n"); + return -EIO; + } + + ret = gpt_verify_metadata(*metadata, 0); + if (!ret) + return 0; + + /* Both the metadata copies are corrupted. */ + return -1; +} + +static int gpt_check_metadata_validity(void) +{ + int ret; + struct blk_desc *desc; + struct fwu_metadata *pri_metadata; + struct fwu_metadata *secondary_metadata; + u32 primary_mpart, secondary_mpart; + u32 valid_partitions; + + ret = fwu_plat_get_blk_desc(&desc); + if (ret < 0) { + log_err("Block device not found\n"); + return -ENODEV; + } + + /* + * Two metadata partitions are expected. + * If we don't have two, user needs to create + * them first + */ + primary_mpart = secondary_mpart = 0; + valid_partitions = 0; + ret = gpt_get_metadata_partitions(desc, &primary_mpart, + &secondary_mpart); + + if (ret < 0) { + log_err("Error getting the metadata partitions\n"); + return -ENODEV; + } + + pri_metadata = malloc(sizeof(*pri_metadata)); + if (!pri_metadata) { + log_err("Unable to allocate memory for reading metadata\n"); + return -ENOMEM; + } + + secondary_metadata = malloc(sizeof(*secondary_metadata)); + if (!secondary_metadata) { + log_err("Unable to allocate memory for reading metadata\n"); + return -ENOMEM; + } + + ret = gpt_read_metadata(desc, pri_metadata, primary_mpart); + if (ret < 0) { + log_err("Failed to read the metadata from the device\n"); + ret = -EIO; + goto out; + } + + ret = gpt_verify_metadata(pri_metadata, 1); + if (!ret) + valid_partitions |= PRIMARY_VALID; + + /* Now check the secondary partition */ + ret = gpt_read_metadata(desc, secondary_metadata, secondary_mpart); + if (ret < 0) { + log_err("Failed to read the metadata from the device\n"); + ret = -EIO; + goto out; + } + + ret = gpt_verify_metadata(secondary_metadata, 0); + if (!ret) + valid_partitions |= SECONDARY_VALID; + + if (valid_partitions == (PRIMARY_VALID | SECONDARY_VALID)) { + ret = -1; + /* + * Before returning, check that both the + * metadata copies are the same. If not, + * the metadata copies need to be + * re-populated. + */ + if (!memcmp(pri_metadata, secondary_metadata, + sizeof(*pri_metadata))) + ret = 0; + goto out; + } else if (valid_partitions == SECONDARY_VALID) { + ret = gpt_write_metadata_partition(desc, secondary_metadata, + primary_mpart); + if (ret < 0) { + log_err("Restoring primary metadata partition failed\n"); + goto out; + } + } else if (valid_partitions == PRIMARY_VALID) { + ret = gpt_write_metadata_partition(desc, pri_metadata, + secondary_mpart); + if (ret < 0) { + log_err("Restoring secondary metadata partition failed\n"); + goto out; + } + } else { + ret = -1; + } + +out: + free(pri_metadata); + + return ret; +} + +static int gpt_fill_partition_guid_array(struct blk_desc *desc, + efi_guid_t **part_guid_arr, + u32 *nparts) +{ + int ret, i; + u32 parts; + gpt_entry *gpt_pte = NULL; + const efi_guid_t null_guid = NULL_GUID; + + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, + desc->blksz); + + ret = get_gpt_hdr_parts(desc, gpt_head, &gpt_pte); + if (ret < 0) { + log_err("Error getting GPT header and partitions\n"); + ret = -EIO; + goto out; + } + + *nparts = gpt_head->num_partition_entries; + + /* + * There could be a scenario where the number of partition entries + * configured in the GPT header is the default value of 128. Find + * the actual number of populated partitioned entries + */ + for (i = 0, parts = 0; i < *nparts; i++) { + if (!guidcmp(&gpt_pte[i].partition_type_guid, &null_guid)) + continue; + ++parts; + } + + *nparts = parts; + *part_guid_arr = malloc(sizeof(efi_guid_t) * *nparts); + if (!part_guid_arr) { + log_err("Unable to allocate memory for guid array\n"); + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < *nparts; i++) { + guidcpy((*part_guid_arr + i), + &gpt_pte[i].partition_type_guid); + } + +out: + free(gpt_pte); + return ret; +} + +int fwu_gpt_get_active_index(u32 *active_idx) +{ + int ret; + struct fwu_metadata *metadata; + + ret = gpt_get_valid_metadata(&metadata); + if (ret < 0) { + log_err("Unable to get valid metadata\n"); + goto out; + } + + /* + * Found the metadata partition, now read the active_index + * value + */ + *active_idx = metadata->active_index; + if (*active_idx > CONFIG_FWU_NUM_BANKS - 1) { + printf("Active index value read is incorrect\n"); + ret = -EINVAL; + goto out; + } + +out: + free(metadata); + + 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 nparts; + gpt_entry *gpt_pte = NULL; + struct fwu_metadata *metadata; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + efi_guid_t unique_part_guid; + efi_guid_t image_guid = NULL_GUID; + + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, + desc->blksz); + + ret = gpt_get_valid_metadata(&metadata); + if (ret < 0) { + log_err("Unable to read valid metadata\n"); + goto out; + } + + /* + * The 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, + &metadata->img_entry[i].image_type_uuid)) { + img_entry = &metadata->img_entry[i]; + img_bank_info = &img_entry->img_bank_info[update_bank]; + guidcpy(&image_guid, &img_bank_info->image_uuid); + } + } + + /* + * 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 + */ + ret = get_gpt_hdr_parts(desc, gpt_head, &gpt_pte); + if (ret < 0) { + log_err("Error getting GPT header and partitions\n"); + ret = -EIO; + goto out; + } + + nparts = gpt_head->num_partition_entries; + + for (i = 0; i < nparts; i++) { + unique_part_guid = gpt_pte[i].unique_partition_guid; + if (!guidcmp(&unique_part_guid, &image_guid)) { + /* Found the partition */ + *alt_no = i + 1; + break; + } + } + + if (i == nparts) { + log_err("Partition with the image guid not found\n"); + ret = -EINVAL; + } + +out: + free(metadata); + free(gpt_pte); + return ret; +} + +int fwu_gpt_update_active_index(u32 active_idx) +{ + int ret; + void *buf; + u32 cur_active_index; + struct fwu_metadata *metadata; + + if (active_idx > CONFIG_FWU_NUM_BANKS) { + printf("Active index value to be updated is incorrect\n"); + return -1; + } + + ret = gpt_get_valid_metadata(&metadata); + if (ret < 0) { + log_err("Unable to get valid metadata\n"); + goto out; + } + + /* + * Update the active index and previous_active_index fields + * in the metadata + */ + cur_active_index = metadata->active_index; + metadata->active_index = active_idx; + metadata->previous_active_index = cur_active_index; + + /* + * Calculate the crc32 for the updated metadata + * and put the updated value in the metadata crc32 + * field + */ + buf = &metadata->version; + metadata->crc32 = crc32(0, buf, sizeof(*metadata) - sizeof(u32)); + + /* + * Now write this updated metadata to both the + * metadata partitions + */ + ret = gpt_update_metadata(metadata); + if (ret < 0) { + log_err("Failed to update metadata partitions\n"); + ret = -EIO; + } + +out: + free(metadata); + + return ret; +} + +int fwu_gpt_fill_partition_guid_array(efi_guid_t **part_guid_arr, u32 *nparts) +{ + 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_fill_partition_guid_array(desc, part_guid_arr, nparts); +} + +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_metadata_check(void) +{ + /* + * Check if both the copies of the metadata are valid. + * If one has gone bad, restore it from the other good + * copy. + */ + return gpt_check_metadata_validity(); +} + +int fwu_gpt_get_metadata(struct fwu_metadata **metadata) +{ + return gpt_get_valid_metadata(metadata); +} + +int fwu_gpt_revert_boot_index(u32 *active_idx) +{ + int ret; + void *buf; + u32 cur_active_index; + struct fwu_metadata *metadata; + + ret = gpt_get_valid_metadata(&metadata); + if (ret < 0) { + log_err("Unable to get valid metadata\n"); + goto out; + } + + /* + * Swap the active index and previous_active_index fields + * in the metadata + */ + cur_active_index = metadata->active_index; + metadata->active_index = metadata->previous_active_index; + metadata->previous_active_index = cur_active_index; + *active_idx = metadata->active_index; + + /* + * Calculate the crc32 for the updated metadata + * and put the updated value in the metadata crc32 + * field + */ + buf = &metadata->version; + metadata->crc32 = crc32(0, buf, sizeof(*metadata) - sizeof(u32)); + + /* + * Now write this updated metadata to both the + * metadata partitions + */ + ret = gpt_update_metadata(metadata); + if (ret < 0) { + log_err("Failed to update metadata partitions\n"); + ret = -EIO; + } + +out: + free(metadata); + + return ret; +} + +static int fwu_gpt_set_clear_image_accept(efi_guid_t *img_type_id, + u32 bank, u8 action) +{ + void *buf; + int ret, i; + u32 nimages; + struct fwu_metadata *metadata; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + ret = gpt_get_valid_metadata(&metadata); + if (ret < 0) { + log_err("Unable to get valid metadata\n"); + goto out; + } + + if (action == IMAGE_ACCEPT_SET) + bank = metadata->active_index; + + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + img_entry = &metadata->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 = &metadata->version; + metadata->crc32 = crc32(0, buf, sizeof(*metadata) - + sizeof(u32)); + + ret = gpt_update_metadata(metadata); + goto out; + } + } + + /* Image not found */ + ret = -EINVAL; + +out: + free(metadata); + + return ret; +} + +int fwu_gpt_accept_image(efi_guid_t *img_type_id) +{ + return fwu_gpt_set_clear_image_accept(img_type_id, 0, + IMAGE_ACCEPT_SET); +} + +int fwu_gpt_clear_accept_image(efi_guid_t *img_type_id, u32 bank) +{ + return fwu_gpt_set_clear_image_accept(img_type_id, bank, + IMAGE_ACCEPT_CLEAR); +} + +struct fwu_metadata_ops fwu_gpt_blk_ops = { + .get_active_index = fwu_gpt_get_active_index, + .update_active_index = fwu_gpt_update_active_index, + .fill_partition_guid_array = fwu_gpt_fill_partition_guid_array, + .get_image_alt_num = fwu_gpt_get_image_alt_num, + .metadata_check = fwu_gpt_metadata_check, + .revert_boot_index = fwu_gpt_revert_boot_index, + .set_accept_image = fwu_gpt_accept_image, + .clear_accept_image = fwu_gpt_clear_accept_image, + .get_metadata = fwu_gpt_get_metadata, +}; From patchwork Thu Nov 25 07:12:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519375 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp368845imj; Wed, 24 Nov 2021 23:14:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJyR+NW4i9qnXz9NxEmw5xB3XM831Rl0PZndTE6Pbqoo7XdZqs4n4cn+zXkgyHy7CzDHHvBs X-Received: by 2002:a05:6402:5193:: with SMTP id q19mr35543002edd.86.1637824483691; Wed, 24 Nov 2021 23:14:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824483; cv=none; d=google.com; s=arc-20160816; b=jfF9Vk0vowIH63sh/ok/xfGPSAuULKt8bJW8U1Mfj2slHOttgclQamxuGNm7KqafsX rceyeRlUnR/TW7ATBEjyWCYeqN6FFAR7FhgrI8iJxZ8a5vLO1FXS7XE5x8+hvf+ykalr mkvsXcRpawKcJOKcKOwa8kOc/A/x3DwkDEDklH3m6QP/figOdJFeQ1zLDZ0FYsvEwcvH dVtIcMOHgKw2sb41tjLYKSnjOUR/QoEcx6JIoxtCSsCQwNDlfU3DWzQEYZmEVbILjsBi jhcpwofXWo7p61Zdk1mxvpEQziaD0yYPD8K6AgQd/dgbg9r+hDKo3iGBZH0iDLl8ANDQ /PoQ== 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=CpYdJ/o66UcWZlpqK2guk60h9LAoE+a95Rei7NIKwKQ=; b=VNB8qoL5DSGMfNq1tTXvDNaR5/RG+dmZlWIHURo8gskoRf0t6HxvbniyvVn/brQdrR 208y31PmYxYOO0uIib1x2uwDRHa4pTZUw3ndb88LK8ZqeAvd3ha2ZS/EcrcwNBKxbELT CUfFl5b558k5tIQ7GeXSzoqY6GLjI6rDp4Sh8+cZbTG25rrFtznr77v9uIMMtRn+e8Uy sNUFGmtcPKHaHESQb9DK5jz05vJEylsJT/qVVspf3kBzODgq12UZDqz7zFwMDxixsL4/ nFFz3Qi8KhCYc0XhOolM8QBYagbnLETP82uSizwRxErDvcLPueDtLCTZNEl2iRMU4/ip GVrA== 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 nd29si6714163ejc.75.2021.11.24.23.14.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:14:43 -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 4764A83775; Thu, 25 Nov 2021 08:14:14 +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 9CCD48373E; Thu, 25 Nov 2021 08:13:57 +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 2506E8373F for ; Thu, 25 Nov 2021 08:13: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 613A7152B; Wed, 24 Nov 2021 23:13:49 -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 968023F5A1; Wed, 24 Nov 2021 23:13:45 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 05/10] FWU: stm32mp1: Add helper functions for accessing metadata Date: Thu, 25 Nov 2021 12:42:57 +0530 Message-Id: <20211125071302.3644-6-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 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 --- board/st/stm32mp1/stm32mp1.c | 63 ++++++++++++++++++++++++++++++++++++ include/fwu_metadata.h | 3 ++ 2 files changed, 66 insertions(+) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 84592677e4..a6884d2772 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -938,3 +941,63 @@ 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); + +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE + +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_metadata_ops *get_plat_fwu_metadata_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_metadata.h b/include/fwu_metadata.h index e692ef7506..6a5e814ab6 100644 --- a/include/fwu_metadata.h +++ b/include/fwu_metadata.h @@ -122,4 +122,7 @@ int fwu_accept_image(efi_guid_t *img_type_id); int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank); int fwu_get_metadata(struct fwu_metadata **metadata); +int fwu_plat_get_update_index(u32 *update_idx); +int fwu_plat_get_blk_desc(struct blk_desc **desc); + #endif /* _FWU_METADATA_H_ */ From patchwork Thu Nov 25 07:12:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519376 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp369045imj; Wed, 24 Nov 2021 23:14:55 -0800 (PST) X-Google-Smtp-Source: ABdhPJzOPEslg5xsk6DosniB97RDgzXx/FVnE6SiY+6UP9Noq382LO7BKV8SBysV/6FHWN5iM4KH X-Received: by 2002:a05:6402:1395:: with SMTP id b21mr36516601edv.299.1637824495581; Wed, 24 Nov 2021 23:14:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824495; cv=none; d=google.com; s=arc-20160816; b=fWRBXEwVIYf/VzAp5MULqmjU/dWTK7uedwg4tKKdQ57aQ1epMsjli/kOKYcnspLdJJ rxPgb8+U8jlvI/+I+sjiJG478BSRllMR+5vpU1bBwuLpGV9VLB/Qjv+XUNzNYfrnju0w 4hMiD4c3FexMg+JRYuKhPtJYZk+mFqtxLYmgi9aHd8OgUkkQQrJ4XgJfqAeKotsupksE tE2nbifjIFXdz6R9QpQmNzOWMbW3xHZTXGseV/s99zOu/1KAFFHP2UJ0KmgT8M3Nhik8 GqIIWZCPiiyNcK1xzmZnqIzo+nBipazvLUBMoG4jiZl5u8eTrv3tZNDxg1sVGYsXffuI KIqQ== 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=dJQkVusInXO/bkq83d8w3EB9nli2pD26qGSYfZ0iJ1M=; b=D8BDMiNh/wO1zu8opMJhRnSHLzCqlkEUZKq+gLUCjr/p3sguauLtoAG+ejL4bJITYo fWFlo7G0NIQVB0H4Z3pzsLvp+mC2uzIeYjQkjQKFmH2WQus+xzCPx/UeznGMCLnOgMP6 TA42UODinUpi8x6rmeBwziQMFUodm3F/02Yq7jPAPkD/Css0FoOYYishx/59IctS8tjV PNqzUMxcu01cOgJiq30rJMKYS0CWngE3LNShkkhviWJQ+XsmnUbKRB+RwifOz7CNt46a 5WLAlM85ygZ2cOOt8X8jfG4EbSIQTAmT8mMQSVGYDHlE+ZZ5yMrw9ZVNo1DKwgUi1ajr rPwA== 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 dd7si6582093ejc.344.2021.11.24.23.14.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:14:55 -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 E92BB82F89; Thu, 25 Nov 2021 08:14: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 12BA18373E; Thu, 25 Nov 2021 08:13: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 31C6683679 for ; Thu, 25 Nov 2021 08:13:54 +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 98AA3152F; Wed, 24 Nov 2021 23:13:53 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D1AC33F5A1; Wed, 24 Nov 2021 23:13:49 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 06/10] FWU: STM32MP1: Add support to read boot index from backup register Date: Thu, 25 Nov 2021 12:42:58 +0530 Message-Id: <20211125071302.3644-7-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- arch/arm/mach-stm32mp/include/mach/stm32.h | 1 + board/st/stm32mp1/stm32mp1.c | 7 +++++++ include/fwu_metadata.h | 1 + 3 files changed, 9 insertions(+) diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index c11a9903f2..21ed9f12e4 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -97,6 +97,7 @@ enum boot_device { #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x) #define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4) #define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5) +#define TAMP_FWU_BOOT_IDX TAMP_BACKUP_REGISTER(10) #define TAMP_COPRO_RSC_TBL_ADDRESS TAMP_BACKUP_REGISTER(17) #define TAMP_COPRO_STATE TAMP_BACKUP_REGISTER(18) #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index a6884d2772..32bba71289 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -990,6 +990,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_FWU_BOOT_IDX); +} + struct fwu_metadata_ops *get_plat_fwu_metadata_ops(void) { if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && diff --git a/include/fwu_metadata.h b/include/fwu_metadata.h index 6a5e814ab6..44f06f4c6a 100644 --- a/include/fwu_metadata.h +++ b/include/fwu_metadata.h @@ -124,5 +124,6 @@ int fwu_get_metadata(struct fwu_metadata **metadata); int fwu_plat_get_update_index(u32 *update_idx); int fwu_plat_get_blk_desc(struct blk_desc **desc); +void fwu_plat_get_bootidx(void *boot_idx); #endif /* _FWU_METADATA_H_ */ From patchwork Thu Nov 25 07:12:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519377 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp369260imj; Wed, 24 Nov 2021 23:15:08 -0800 (PST) X-Google-Smtp-Source: ABdhPJyu+FOptuE8ZuMX5hJcW45zR9i1F+Noyj9gaziFw6e7ejTv+tzwIhevds5uCMsw1YAX95DE X-Received: by 2002:a17:906:3e83:: with SMTP id a3mr29246938ejj.383.1637824508650; Wed, 24 Nov 2021 23:15:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824508; cv=none; d=google.com; s=arc-20160816; b=HMmeo9Kd9IN70hx/NY3EdlSRY4sjMqON14epH7T1Kj1szn5hwV95Ka8pVATpeJZdQt NcwgifOWNtrMCQ962QILHQecHsR4qZMVaoRWDyUFGNhtHmfc8M4aeYzdTE5b/QaHuCtW dBOhhlPfIz81SNkfwCO5xu9Mjn5HP2irAdDzRoQCPEOrc9yK6eFf5HNosKarsdsMCryG EWY8nY8aRyfoR6CceybgNnml2FnhrSk1UcMwQmtYRylDZtP0Ek+psv8J50ekAaPmYQxo UeDcewGvjEjtzMIx5aATsKdPR5vtUemJKwVEKR6vow+/Cm/pWIlS65XcPcOPEd/1GrLM LbOw== 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=abU56v1pjQ/E2CNhri4oruoVyOH0Mjlpt/eWEKG1xJI=; b=QUXXvSkPvr7EJa8zn+cwTcOlzosG7l5Y0qO4L/MS5Nv4Gb0rIztBouleWgQ0DuKoSR IC3yQHnoUUrNyeiTA5Ir2W8xkIsI39R8Sk9aAQvQRIYYAw8gr/IvMVprNzFpmc5PoHRK MP13WyPkvwROoV3i0AS2+uGMrewflZYkR9WFx2mtP/uDkpk2l9zxFy2zeOX29Ywb4KZ+ ub2BmmDYOIR8nDY0xNhrhqk+P4U4XcyYd+knWXKEJqQD5+PuBKWZe/XGaCsaWcNZ1EsH 3iwctHavcnH/697bl34k58FyVZGvPZEzdmLc536ZEH2aO1LqMojKDQvMYyF3hmfWxce7 NjzA== 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 hh12si4719769ejb.335.2021.11.24.23.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:15:08 -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 8353C83742; Thu, 25 Nov 2021 08:14:26 +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 E9ABF83767; Thu, 25 Nov 2021 08:14:05 +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 6C2448373F for ; Thu, 25 Nov 2021 08:13:58 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D3118153B; Wed, 24 Nov 2021 23:13:57 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 14A353F5A1; Wed, 24 Nov 2021 23:13:53 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 07/10] EFI: FMP: Add provision to update image's ImageTypeId in image descriptor Date: Thu, 25 Nov 2021 12:42:59 +0530 Message-Id: <20211125071302.3644-8-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- lib/efi_loader/efi_firmware.c | 76 ++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a1b88dbfc2..a2b639b448 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 @@ -106,7 +107,8 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( * @descriptor_size: Pointer to descriptor size * package_version: Package version * package_version_name: Package version's name - * image_type: Image type GUID + * guid_array: Image type GUID array + * nparts: Number of partions on the storage device * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. @@ -122,7 +124,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, u32 nparts) { struct dfu_entity *dfu; size_t names_len, total_size; @@ -145,6 +147,19 @@ static efi_status_t efi_get_dfu_info( return EFI_SUCCESS; } + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + /* + * For FWU multi bank updates, the number of partitions + * should at least be same as dfu partitions or less + */ + if (nparts > dfu_num) { + log_err("Number of dfu alt no's less than partitions\n"); + dfu_free_entities(); + + return EFI_INVALID_PARAMETER; + } + } + total_size = sizeof(*image_info) * dfu_num + names_len; /* * we will assume that sizeof(*image_info) * dfu_name @@ -172,7 +187,11 @@ 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; + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) + image_info[i].image_type_id = guid_array[i]; + else + image_info[i].image_type_id = *guid_array; + image_info[i].image_id = dfu->alt; /* copy the DFU entity name */ @@ -249,7 +268,9 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( u32 *package_version, u16 **package_version_name) { + u32 nparts; efi_status_t ret; + efi_guid_t *part_guid_arr; EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size, image_info, @@ -264,12 +285,24 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( !descriptor_size || !package_version || !package_version_name)) return EFI_EXIT(EFI_INVALID_PARAMETER); + part_guid_arr = malloc(sizeof(efi_guid_t)); + if (!part_guid_arr) { + log_err("Unable to allocate memory for guid array\n"); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + guidcpy(part_guid_arr, &efi_firmware_image_type_uboot_fit); + nparts = 1; + 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, nparts); +out: + free(part_guid_arr); return EFI_EXIT(ret); } @@ -358,7 +391,10 @@ efi_status_t EFIAPI efi_firmware_raw_get_image_info( u32 *package_version, u16 **package_version_name) { + u32 nparts; + int status; efi_status_t ret = EFI_SUCCESS; + efi_guid_t *part_guid_arr; EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size, image_info, @@ -373,12 +409,42 @@ 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)) { + /* + * Read the ImageType GUID values. Populate the guid array + * with thesevalues. These are the values to be used in the + * capsule for ImageTypeId. + */ + status = fwu_fill_partition_guid_array(&part_guid_arr, + &nparts); + if (status < 0) { + log_err("Unable to get partiion guid's\n"); + if (status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + } else { + part_guid_arr = malloc(sizeof(efi_guid_t)); + if (!part_guid_arr) { + log_err("Unable to allocate memory for guid array\n"); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + guidcpy(part_guid_arr, &efi_firmware_image_type_uboot_raw); + nparts = 1; + } + 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, nparts); +out: + free(part_guid_arr); return EFI_EXIT(ret); } From patchwork Thu Nov 25 07:13:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519378 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp369393imj; Wed, 24 Nov 2021 23:15:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJw9y21FfgwcfogxnabhKNditqWVH9jBydKLPMwURi3MtSQW741Q2F5xDJkaiPtgTc65gMGc X-Received: by 2002:a17:906:fb17:: with SMTP id lz23mr28397278ejb.149.1637824518788; Wed, 24 Nov 2021 23:15:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824518; cv=none; d=google.com; s=arc-20160816; b=fg8b4J+hXxxK5L+Zt158NIWjnfQFc4rCjQnOb2RocevUwUgKEr+C0fBXpzqldLYGB+ /CUa2JKDeNZTzpmhsXU/jI5+rhu3JFpr6ic/ZDY2jQ4/MECyordcJKhBk76jZGssBSXn s69szfiLxFU35qxsL+3c7vKW2LifWZmrhE/jxwOT0pc4iyqFetyAPpAWumxHUlSGDoKJ Ios0KW5YgHGMgGU183BaxbPDgAM0RLfR+evwHTdPmG78/FqesDoB6upuDWODPgogUMv6 AMRljcm2vlVLYWZ8Qiw7WQEYQ/fKrHcSphUHuXL8zfv3y7RxYAnkv9rpqa3XLAhXOIgb p0dg== 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=swvIVnvNdBrih5Q6pN4DnU9FHMRBqy9fPLoQAt/aHYQ=; b=qAI+ESElSxood0VCp0BiGrklOlu/YJR8h1CG0u4JRZqIVmmicy7PzTqhIH356E5HtC qkwXU4sXZC7CUHxGkBE/UbLNP+TgT5nhnBTcO1Szn55gbT4JHcRT3vdImbVZHUtdlMlU HEYX8DFVBdQg7kz8zNsVrn5FgQbFHI9NlQzrzLEnujRK5H8ZPr+XYASdyWQqjJm4xA9p SPkP6ZPGnCUfWwID0uTlP5LGfHVhKrVeNygtsxYMn7UI/+1RDyZlxIcwnxbcidHhYyYy 2B0w4Qg4/f3lVb+3GO3gUQk1bPZUmMLwvl42VbHATWjx3YxK6JjbZLFwdQc6HVi7il9P NzgA== 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 js16si6858174ejc.242.2021.11.24.23.15.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:15:18 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 18923836DC; Thu, 25 Nov 2021 08:14:31 +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 2D5A583773; Thu, 25 Nov 2021 08:14:10 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id BD6D88373E for ; Thu, 25 Nov 2021 08:14: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 161B21570; Wed, 24 Nov 2021 23:14:02 -0800 (PST) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4F3543F5A1; Wed, 24 Nov 2021 23:13:58 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 08/10] FWU: Add boot time checks as highlighted by the FWU specification Date: Thu, 25 Nov 2021 12:43:00 +0530 Message-Id: <20211125071302.3644-9-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- common/board_r.c | 6 ++ include/fwu_metadata.h | 1 + lib/fwu_updates/fwu.c | 143 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 lib/fwu_updates/fwu.c diff --git a/common/board_r.c b/common/board_r.c index 31a59c585a..01ccce2cca 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_metadata.h b/include/fwu_metadata.h index 44f06f4c6a..02897f33a8 100644 --- a/include/fwu_metadata.h +++ b/include/fwu_metadata.h @@ -125,5 +125,6 @@ int fwu_get_metadata(struct fwu_metadata **metadata); int fwu_plat_get_update_index(u32 *update_idx); int fwu_plat_get_blk_desc(struct blk_desc **desc); void fwu_plat_get_bootidx(void *boot_idx); +int fwu_boottime_checks(void); #endif /* _FWU_METADATA_H_ */ diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c new file mode 100644 index 0000000000..2e1904b912 --- /dev/null +++ b/lib/fwu_updates/fwu.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include +#include +#include + +#include +#include + +static int fwu_trial_state_check(void) +{ + int ret, i; + u8 trial_state; + efi_status_t status; + efi_uintn_t var_size; + u16 trial_state_ctr; + u32 nimages, active_bank, var_attributes, active_idx; + struct fwu_metadata *metadata; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + ret = fwu_get_metadata(&metadata); + if (ret < 0) + return ret; + + trial_state = ret = 0; + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + active_bank = metadata->active_index; + img_entry = &metadata->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"); + trial_state_ctr = 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 clear TrialStateCtr variable\n"); + ret = -1; + goto out; + } + + active_idx = metadata->active_index; + ret = fwu_revert_boot_index(&active_idx); + if (ret < 0) { + log_err("Unable to revert active_index\n"); + goto out; + } + } else { + status = efi_set_variable_int(L"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + var_size, + &trial_state_ctr, false); + if (status != EFI_SUCCESS) { + log_err("Unable to increment TrialStateCtr variable\n"); + ret = -1; + goto out; + } else { + ret = 0; + } + } + } + +out: + free(metadata); + return ret; +} + +int fwu_boottime_checks(void) +{ + int ret; + u32 boot_idx, active_idx; + + ret = fwu_metadata_check(); + if (ret < 0) + return ret; + + /* + * 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 metadata, + * update the active_index. + */ + fwu_plat_get_bootidx(&boot_idx); + if (boot_idx >= CONFIG_FWU_NUM_BANKS) + return -EINVAL; + + ret = fwu_get_active_index(&active_idx); + if (ret < 0) + return ret; + + 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) + return ret; + else + return 0; + } + + ret = fwu_trial_state_check(); + if (ret < 0) + return ret; + + return 0; +} From patchwork Thu Nov 25 07:13:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519379 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp369528imj; Wed, 24 Nov 2021 23:15:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJxJfoxPlC9hO7SxfK8LK6SgVSbkevIrGfAJ312ayg7lOXRIEMSJb8HyGGtOF/fnaShXU29n X-Received: by 2002:a17:906:c301:: with SMTP id s1mr28579072ejz.56.1637824529581; Wed, 24 Nov 2021 23:15:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824529; cv=none; d=google.com; s=arc-20160816; b=ZZCehrYeShwF5gqIPNSF+JzsElD1dfLKhzCMGwcno+LiB+05SYdF2ALyOxdIsK/QSL ZzU6AK63UO893S90epKdVmB1QiSGFY6abV/qzYTVoPFhVIrZtk8lwW51K8u3ayh9owtY tzPtMt1M4jsEBI+grzjQHhc6EAurbixYshKVmL4ugGtfbIbbD0PEG20oKBDh58fa4p8W nykWFREQk77vZyctx5mYaP7y/lgg+5kM6qAv/YCflAq81Osifg++SE9a7usLq4VTTwom dhRFf7qmfevNmX7cTr59SeX5EhlH3UV2dhozYudglkQ62cwnmeD5bOepJZnkI5eq7nJe jkZg== 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=lFHsWVHHWEOGgDY5wJCa6CxfC6Nix80AtBA6Z2Cnv8Q=; b=D2bnbD7PG4WnjX48JX1440S3gliXklnDE2KyKPntCqnL1H/mgGMgfI6N4CTSn+Hc2S 0/9S6mu14XsG7Wiou5MMAm6wVY7rd1PY4wojdvf3ud5bQyfEsbnTZsGKsx48XHbP1IJU euVm23W1sMQ/+f4llP3UPlUYf2tpGgDGNq4KRxUI0LtBZLAYCzu4uiNJabuS3tcDGSrq ndcd0x/fVLJhCR6PdlGq9AG2wKnFRcGDSSHd+z6J23M3N+KL90XZ6+ag2gRTPfUtvIGj Jsn+zAeAqHNBZWAL7uTJbPqbgb6kuneqnFhv/lBOJNw28P3K5h9UM4xhj+/O8Khxi7Zx G/yQ== 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 ho44si5717210ejc.445.2021.11.24.23.15.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:15:29 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EDFC583759; Thu, 25 Nov 2021 08:14:33 +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 129D783774; Thu, 25 Nov 2021 08:14:13 +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 D2D3F8373F for ; Thu, 25 Nov 2021 08:14:06 +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 53FEC1576; Wed, 24 Nov 2021 23:14:06 -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 88AB33F5A1; Wed, 24 Nov 2021 23:14:02 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 09/10] FWU: Add support for FWU Multi Bank Update feature Date: Thu, 25 Nov 2021 12:43:01 +0530 Message-Id: <20211125071302.3644-10-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- include/fwu_metadata.h | 10 ++ lib/Kconfig | 32 ++++++ lib/Makefile | 1 + lib/efi_loader/efi_capsule.c | 190 ++++++++++++++++++++++++++++++++++- lib/fwu_updates/Makefile | 11 ++ lib/fwu_updates/fwu.c | 29 +++++- 6 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 lib/fwu_updates/Makefile diff --git a/include/fwu_metadata.h b/include/fwu_metadata.h index 02897f33a8..2d276a019a 100644 --- a/include/fwu_metadata.h +++ b/include/fwu_metadata.h @@ -106,7 +106,16 @@ struct fwu_metadata_ops { EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) +#define FWU_OS_REQUEST_FW_REVERT_GUID \ + EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \ + 0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0) + +#define FWU_OS_REQUEST_FW_ACCEPT_GUID \ + EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \ + 0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8) + #define FWU_METADATA_VERSION 0x1 +#define FWU_IMAGE_ACCEPTED 0x1 extern struct fwu_metadata_ops fwu_gpt_blk_ops; @@ -126,5 +135,6 @@ int fwu_plat_get_update_index(u32 *update_idx); int fwu_plat_get_blk_desc(struct blk_desc **desc); void fwu_plat_get_bootidx(void *boot_idx); int fwu_boottime_checks(void); +int fwu_trial_state_ctr_start(void); #endif /* _FWU_METADATA_H_ */ diff --git a/lib/Kconfig b/lib/Kconfig index 807a4c6ade..7cb306317c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -835,3 +835,35 @@ config PHANDLE_CHECK_SEQ When there are multiple device tree nodes with same name, enable this config option to distinguish them using phandles in fdtdec_get_alias_seq() function. + +config FWU_MULTI_BANK_UPDATE + bool "Enable FWU Multi Bank Update Feature" + depends on EFI_HAVE_CAPSULE_SUPPORT + select PARTITION_TYPE_GUID + select EFI_SETUP_EARLY + help + Feature for updating firmware images on platforms having + multiple banks(copies) of the firmware images. One of the + bank is selected for updating all the firmware components + +config FWU_NUM_BANKS + int "Number of Banks defined by the platform" + depends on FWU_MULTI_BANK_UPDATE + help + Define the number of banks of firmware images on a platform + +config FWU_NUM_IMAGES_PER_BANK + int "Number of firmware images per bank" + depends on FWU_MULTI_BANK_UPDATE + help + Define the number of firmware images per bank. This value + should be the same for all the banks. + +config FWU_TRIAL_STATE_CNT + int "Number of times system boots in Trial State" + depends on FWU_MULTI_BANK_UPDATE + default 3 + help + With FWU Multi Bank Update feature enabled, number of times + the platform is allowed to boot in Trial State after an + update. diff --git a/lib/Makefile b/lib/Makefile index 5ddbc77ed6..bc5c1e22fc 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_driver/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest/ +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_updates/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_BZIP2) += bzip2/ obj-$(CONFIG_TIZEN) += tizen/ diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 502bcfca6e..40b9e87e92 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,13 @@ static const efi_guid_t efi_guid_firmware_management_capsule_id = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; const efi_guid_t efi_guid_firmware_management_protocol = EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID; +const efi_guid_t fwu_guid_os_request_fw_revert = + FWU_OS_REQUEST_FW_REVERT_GUID; +const efi_guid_t fwu_guid_os_request_fw_accept = + FWU_OS_REQUEST_FW_ACCEPT_GUID; + +__maybe_unused static u32 update_index; +__maybe_unused static bool capsule_update; #ifdef CONFIG_EFI_CAPSULE_ON_DISK /* for file system access */ @@ -403,10 +411,13 @@ static efi_status_t efi_capsule_update_firmware( void *image_binary, *vendor_code; efi_handle_t *handles; efi_uintn_t no_handles; - int item; + int item, alt_no; struct efi_firmware_management_protocol *fmp; u16 *abort_reason; + efi_guid_t image_type_id; efi_status_t ret = EFI_SUCCESS; + int status; + u8 image_index; /* sanity check */ if (capsule_data->header_size < sizeof(*capsule) || @@ -481,8 +492,36 @@ static efi_status_t efi_capsule_update_firmware( goto out; } + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + /* + * Based on the value of update_image_type_id, + * derive the alt number value. This will be + * passed as update_image_index to the + * set_image function. + */ + image_type_id = image->update_image_type_id; + status = fwu_get_image_alt_num(image_type_id, + update_index, + &alt_no); + if (status < 0) { + log_err("Unable to get the alt no for the image type %pUl\n", + &image_type_id); + if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + else if (status == -ERANGE || status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + goto out; + } + log_debug("alt_no %u for Image Type Id %pUl\n", + alt_no, &image_type_id); + image_index = alt_no; + } else { + image_index = image->update_image_index; + } abort_reason = NULL; - ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index, + ret = EFI_CALL(fmp->set_image(fmp, image_index, image_binary, image_binary_size, vendor_code, NULL, @@ -493,6 +532,24 @@ static efi_status_t efi_capsule_update_firmware( efi_free_pool(abort_reason); goto out; } + + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + status = fwu_clear_accept_image(&image_type_id, + update_index); + if (status < 0) { + log_err("Unable to clear the accept bit for the image %pUl\n", + &image_type_id); + if (status == -ENODEV || status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + else if (status == -ERANGE || status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + goto out; + } + log_debug("Cleared out accepted bit for Image %pUl\n", &image_type_id); + } + } out: @@ -527,6 +584,9 @@ efi_status_t EFIAPI efi_update_capsule( u64 scatter_gather_list) { struct efi_capsule_header *capsule; + efi_guid_t *image_guid; + u32 active_idx; + int status; unsigned int i; efi_status_t ret; @@ -538,6 +598,16 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { + /* First 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)) { @@ -553,6 +623,55 @@ efi_status_t EFIAPI efi_update_capsule( if (!guidcmp(&capsule->capsule_guid, &efi_guid_firmware_management_capsule_id)) { 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(&active_idx); + if (status < 0) { + log_err("Failed to revert the FWU boot index\n"); + if (status == -ENODEV || + status == -ERANGE || + status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + ret = EFI_SUCCESS; + log_err("Reverted the FWU active_index to %u. Recommend rebooting the system\n", + active_idx); + } + } else if (!guidcmp(&capsule->capsule_guid, + &fwu_guid_os_request_fw_accept)) { + /* + * Image accepted by the OS. Set the acceptance + * status for the image. + */ + image_guid = (void *)(char *)capsule + + capsule->header_size; + status = fwu_accept_image(image_guid); + if (status < 0) { + if (status == -ENODEV || + status == -ERANGE || + status == -EIO) + ret = EFI_DEVICE_ERROR; + else if (status == -EINVAL) + ret = EFI_INVALID_PARAMETER; + else if (status == -ENOMEM) + ret = EFI_OUT_OF_RESOURCES; + } else { + ret = EFI_SUCCESS; + } + } } else { log_err("Unsupported capsule type: %pUl\n", &capsule->capsule_guid); @@ -563,6 +682,36 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } + /* + * Update the 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 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(); @@ -1075,8 +1224,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()) return EFI_SUCCESS; @@ -1104,9 +1255,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); @@ -1114,6 +1267,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]); @@ -1121,7 +1275,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 metadata\n"); + } + } for (i = 0; i < nfiles; i++) free(files[i]); diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile new file mode 100644 index 0000000000..f6fa8290c1 --- /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_metadata.o +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o + +ifdef CONFIG_EFI_PARTITION +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_metadata_gpt_blk.o +endif diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c index 2e1904b912..bbd3dc249f 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -45,7 +45,7 @@ static int fwu_trial_state_check(void) log_info("System booting in Trial State\n"); var_attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, + EFI_VARIABLE_RUNTIME_ACCESS; status = efi_get_variable_int(L"TrialStateCtr", &efi_global_variable_guid, &var_attributes, @@ -99,6 +99,33 @@ out: return ret; } +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 Thu Nov 25 07:13:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 519380 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp369665imj; Wed, 24 Nov 2021 23:15:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJyXAH/WvSLA6h4d6nljYBLiGiOJ3L5pBeSUZ1wehymdLlWYVvPEhuXES4470lM2gY5FHrDJ X-Received: by 2002:a17:906:24ca:: with SMTP id f10mr28598571ejb.144.1637824540787; Wed, 24 Nov 2021 23:15:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637824540; cv=none; d=google.com; s=arc-20160816; b=uxhcP/QnJlINqY9UoEH3iLRP1K3NKLajJaSfMYzs/JNQFHxEHjruSltesD8zO+EXDz D9Yhn+TTNra3efYdY2CTG1jRAy+EIi7PjQ9LX2J5GQ7fIP5MnVJM7Cg89XISW3VWMM73 mJ7Z2Dz9QfmP5kSAUHQXUV5nM0/UwelFef1iQKshyn6cb3p+l4Y33PeVEs80UFAikVcX mMP5EGZVk0lr6vLHlUAPHwKTSedfqy/tlEHb01I+aq5d0ZVIGDrF3YFdPlkNyWeLaSgQ c4shptFgHRWe0TQwEse2TqzUPaBQa3VC9uR2bRnlmml0dlx3VnXKeY5JrW4wnzUBgDNv jDrQ== 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=PbHQ/60R6UQvWZgFqO/N3oqhLZzikbEmE7bSNVmEkr4=; b=hy48MRkjixEGYa+EZOaOuA/7vvRpcv971itKA2Hs+S9u9G4c3izLZfIRl2m7Z/hFez b5utXvs05Tai+H7k4KD6GLzRJ7v3CC5zlVT6eXfrWAXnibJlst58X2l0DU2Ez98skdhK b3IkZj8coQt7xrH36oIwSlbwjZjqGuaP8uP2tDpdX/3eyXYoFqr0F0FM7eiszELv7Obu RE6mJKFB5Mvjc7EqoO3xphwJEd5kFHScMCpKBWD58Y3aLp9+AZCxD6618hfFVSXPBYx6 KCxUG2E6WKEYYPDsaGgcQPUhE/u+O68K4C5nLMhYQohBU2ZHJclCCiBsDOf4I037WEK8 6O7Q== 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 gk1si6741841ejc.48.2021.11.24.23.15.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 23:15:40 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E435A8377A; Thu, 25 Nov 2021 08:14:37 +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 B3F2C83767; Thu, 25 Nov 2021 08:14:14 +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 19B4683759 for ; Thu, 25 Nov 2021 08:14:11 +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 8B29E1595; Wed, 24 Nov 2021 23:14:10 -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 C452C3F5A1; Wed, 24 Nov 2021 23:14:06 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Peng Fan , AKASHI Takahiro , Ilias Apalodimas , Jose Marinho , Grant Likely , Jason Liu , Sughosh Ganu Subject: [RESEND RFC PATCH 10/10] FWU: cmd: Add a command to read metadata Date: Thu, 25 Nov 2021 12:43:02 +0530 Message-Id: <20211125071302.3644-11-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211125071302.3644-1-sughosh.ganu@linaro.org> References: <20211125071302.3644-1-sughosh.ganu@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 --- cmd/Kconfig | 6 +++++ cmd/Makefile | 1 + cmd/fwu_metadata.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 cmd/fwu_metadata.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 5b30b13e43..1bf590caf0 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -137,6 +137,12 @@ 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" + default y if FWU_MULTI_BANK_UPDATE + help + Command to read the metadata and dump it's contents + config CMD_LICENSE bool "license" select BUILD_BIN2C diff --git a/cmd/Makefile b/cmd/Makefile index 891819ae0f..9dc05dd719 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_metadata.o obj-$(CONFIG_CMD_GETTIME) += gettime.o obj-$(CONFIG_CMD_GPIO) += gpio.o obj-$(CONFIG_CMD_HVC) += smccc.o diff --git a/cmd/fwu_metadata.c b/cmd/fwu_metadata.c new file mode 100644 index 0000000000..3908b60dea --- /dev/null +++ b/cmd/fwu_metadata.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021, Linaro Limited + */ + +#include +#include +#include + +#include + +static void print_metadata(struct fwu_metadata *metadata) +{ + int i, j; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_info; + u32 nimages, nbanks; + + printf("\tMetadata Read\n"); + printf("crc32: %#x\n", metadata->crc32); + printf("version: %#x\n", metadata->version); + printf("active_index: %#x\n", metadata->active_index); + printf("previous_active_index: %#x\n", metadata->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 = &metadata->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_metadata_read(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + int ret = CMD_RET_SUCCESS; + struct fwu_metadata *metadata; + + printf("Trying to get the metadata\n"); + ret = fwu_get_metadata(&metadata); + if (ret < 0) { + log_err("Unable to get valid metadata\n"); + ret = CMD_RET_FAILURE; + goto out; + } + + print_metadata(metadata); + +out: + free(metadata); + return ret; +} + +U_BOOT_CMD( + metadata_read, 1, 1, do_metadata_read, + "Read and print FWU metadata", + "" +);