[PATCH v7 4/7] cmd: rng: Add support for selecting RNG device

2022-07-20 Thread Sughosh Ganu
The 'rng' u-boot command is used for printing a select number of
random bytes on the console. Currently, the RNG device from which the
random bytes are read is fixed. However, a platform can have multiple
RNG devices, one example being qemu, which has a virtio RNG device and
the RNG pseudo device through the TPM chip.

Extend the 'rng' command so that the user can provide the RNG device
number from which the random bytes are to be read. This will be the
device index under the RNG uclass.

Signed-off-by: Sughosh Ganu 
Tested-by: Heinrich Schuchardt 
Reviewed-by: Ilias Apalodimas 
---
Changes since V6: None

 cmd/rng.c | 31 +++
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/cmd/rng.c b/cmd/rng.c
index 1ad5a096c0..2ddf27545f 100644
--- a/cmd/rng.c
+++ b/cmd/rng.c
@@ -13,19 +13,34 @@
 
 static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const 
argv[])
 {
-   size_t n = 0x40;
+   size_t n;
struct udevice *dev;
void *buf;
+   int devnum;
int ret = CMD_RET_SUCCESS;
 
-   if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) {
+   switch (argc) {
+   case 1:
+   devnum = 0;
+   n = 0x40;
+   break;
+   case 2:
+   devnum = hextoul(argv[1], NULL);
+   n = 0x40;
+   break;
+   case 3:
+   devnum = hextoul(argv[1], NULL);
+   n = hextoul(argv[2], NULL);
+   break;
+   default:
+   return CMD_RET_USAGE;
+   }
+
+   if (uclass_get_device_by_seq(UCLASS_RNG, devnum, ) || !dev) {
printf("No RNG device\n");
return CMD_RET_FAILURE;
}
 
-   if (argc >= 2)
-   n = hextoul(argv[1], NULL);
-
buf = malloc(n);
if (!buf) {
printf("Out of memory\n");
@@ -46,12 +61,12 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
 
 #ifdef CONFIG_SYS_LONGHELP
 static char rng_help_text[] =
-   "[n]\n"
-   "  - print n random bytes\n";
+   "[dev [n]]\n"
+   "  - print n random bytes read from dev\n";
 #endif
 
 U_BOOT_CMD(
-   rng, 2, 0, do_rng,
+   rng, 3, 0, do_rng,
"print bytes from the hardware random number generator",
rng_help_text
 );
-- 
2.34.1



[PATCH v7 3/7] tpm: Add the RNG child device

2022-07-20 Thread Sughosh Ganu
The TPM device comes with the random number generator(RNG)
functionality which is built into the TPM device. Add logic to add the
RNG child device in the TPM uclass post probe callback.

The RNG device can then be used to pass a set of random bytes to the
linux kernel, need for address space randomisation through the
EFI_RNG_PROTOCOL interface.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 drivers/tpm/tpm-uclass.c | 37 +
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index f67fe1019b..e1f1ef01e1 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -11,10 +11,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "tpm_internal.h"
 
+#include 
+
+#define TPM_RNG_DRV_NAME   "tpm-rng"
+
 int tpm_open(struct udevice *dev)
 {
struct tpm_ops *ops = tpm_get_ops(dev);
@@ -136,12 +141,36 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, 
size_t send_size,
return 0;
 }
 
+static int tpm_uclass_post_probe(struct udevice *dev)
+{
+   int ret;
+   const char *drv = TPM_RNG_DRV_NAME;
+   struct udevice *child;
+
+   if (CONFIG_IS_ENABLED(TPM_RNG)) {
+   ret = device_find_first_child_by_uclass(dev, UCLASS_RNG,
+   );
+
+   if (ret != -ENODEV) {
+   log_debug("RNG child already added to the TPM 
device\n");
+   return ret;
+   }
+
+   ret = device_bind_driver(dev, drv, "tpm-rng0", );
+   if (ret)
+   return log_msg_ret("bind", ret);
+   }
+
+   return 0;
+}
+
 UCLASS_DRIVER(tpm) = {
-   .id = UCLASS_TPM,
-   .name   = "tpm",
-   .flags  = DM_UC_FLAG_SEQ_ALIAS,
+   .id = UCLASS_TPM,
+   .name   = "tpm",
+   .flags  = DM_UC_FLAG_SEQ_ALIAS,
 #if CONFIG_IS_ENABLED(OF_REAL)
-   .post_bind  = dm_scan_fdt_dev,
+   .post_bind  = dm_scan_fdt_dev,
 #endif
+   .post_probe = tpm_uclass_post_probe,
.per_device_auto= sizeof(struct tpm_chip_priv),
 };
-- 
2.34.1



[PATCH v7 2/7] tpm: rng: Add driver model interface for TPM RNG device

2022-07-20 Thread Sughosh Ganu
The TPM device has a builtin random number generator(RNG)
functionality. Expose the RNG functions of the TPM device to the
driver model so that they can be used by the EFI_RNG_PROTOCOL if the
protocol is installed.

Also change the function arguments and return type of the random
number functions to comply with the driver model api.

Signed-off-by: Sughosh Ganu 
---
Changes since V6:
* Remove the changes made in tpm-v[12].c to return -EIO instead of
  TPM_LIB_ERROR as suggested by Simon

 drivers/rng/Kconfig   |  9 +
 drivers/rng/Makefile  |  1 +
 drivers/rng/tpm_rng.c | 23 +++
 lib/Kconfig   |  1 +
 lib/tpm_api.c |  6 +++---
 5 files changed, 37 insertions(+), 3 deletions(-)
 create mode 100644 drivers/rng/tpm_rng.c

diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index 21a9ff0195..16143681da 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -74,4 +74,13 @@ config RNG_SMCCC_TRNG
  Enable random number generator for platforms that support Arm
  SMCCC TRNG interface.
 
+config TPM_RNG
+   bool "Enable random number generator on TPM device"
+   depends on TPM
+   default y
+   help
+ The TPM device has an inbuilt random number generator
+ functionality. Enable random number generator on TPM
+ devices.
+
 endif
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 2494717d7c..78f61051ac 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
 obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
 obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
 obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o
+obj-$(CONFIG_TPM_RNG) += tpm_rng.o
diff --git a/drivers/rng/tpm_rng.c b/drivers/rng/tpm_rng.c
new file mode 100644
index 00..1a5e9e2e4b
--- /dev/null
+++ b/drivers/rng/tpm_rng.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+
+static int rng_tpm_random_read(struct udevice *dev, void *data, size_t count)
+{
+   return tpm_get_random(dev_get_parent(dev), data, count);
+}
+
+static const struct dm_rng_ops tpm_rng_ops = {
+   .read = rng_tpm_random_read,
+};
+
+U_BOOT_DRIVER(tpm_rng) = {
+   .name   = "tpm-rng",
+   .id = UCLASS_RNG,
+   .ops= _rng_ops,
+};
diff --git a/lib/Kconfig b/lib/Kconfig
index 7dd777b56a..e888c29245 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -360,6 +360,7 @@ source lib/crypt/Kconfig
 config TPM
bool "Trusted Platform Module (TPM) Support"
depends on DM
+   imply DM_RNG
help
  This enables support for TPMs which can be used to provide security
  features for your board. The TPM can be connected via LPC or I2C
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 4ac4612c81..032f383ca0 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -269,7 +269,7 @@ u32 tpm_get_random(struct udevice *dev, void *data, u32 
count)
if (tpm_is_v1(dev))
return tpm1_get_random(dev, data, count);
else if (tpm_is_v2(dev))
-   return -ENOSYS; /* not implemented yet */
-   else
-   return -ENOSYS;
+   return tpm2_get_random(dev, data, count);
+
+   return -ENOSYS;
 }
-- 
2.34.1



[PATCH v7 1/7] tpm: Export the TPM-version functions

2022-07-20 Thread Sughosh Ganu
From: Simon Glass 

These functions should really be available outside the TPM code, so that
other callers can find out which version the TPM is. Rename them to have
a tpm_ prefix() and add them to the header file.

Signed-off-by: Simon Glass 
---
Changes since V6: None

 include/tpm_api.h | 10 ++
 lib/tpm_api.c | 92 +--
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/include/tpm_api.h b/include/tpm_api.h
index ef45b43a8f..11aa14eb79 100644
--- a/include/tpm_api.h
+++ b/include/tpm_api.h
@@ -319,4 +319,14 @@ u32 tpm_write_lock(struct udevice *dev, u32 index);
  */
 u32 tpm_resume(struct udevice *dev);
 
+static inline bool tpm_is_v1(struct udevice *dev)
+{
+   return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
+}
+
+static inline bool tpm_is_v2(struct udevice *dev)
+{
+   return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
+}
+
 #endif /* __TPM_API_H */
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 4c662640a9..4ac4612c81 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -11,21 +11,11 @@
 #include 
 #include 
 
-static bool is_tpm1(struct udevice *dev)
-{
-   return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
-}
-
-static bool is_tpm2(struct udevice *dev)
-{
-   return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
-}
-
 u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
 {
-   if (is_tpm1(dev)) {
+   if (tpm_is_v1(dev)) {
return tpm1_startup(dev, mode);
-   } else if (is_tpm2(dev)) {
+   } else if (tpm_is_v2(dev)) {
enum tpm2_startup_types type;
 
switch (mode) {
@@ -47,9 +37,9 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type 
mode)
 
 u32 tpm_resume(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_startup(dev, TPM_ST_STATE);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_startup(dev, TPM2_SU_STATE);
else
return -ENOSYS;
@@ -57,9 +47,9 @@ u32 tpm_resume(struct udevice *dev)
 
 u32 tpm_self_test_full(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_self_test_full(dev);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_self_test(dev, TPMI_YES);
else
return -ENOSYS;
@@ -67,9 +57,9 @@ u32 tpm_self_test_full(struct udevice *dev)
 
 u32 tpm_continue_self_test(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_continue_self_test(dev);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_self_test(dev, TPMI_NO);
else
return -ENOSYS;
@@ -86,7 +76,7 @@ u32 tpm_clear_and_reenable(struct udevice *dev)
return ret;
}
 
-   if (is_tpm1(dev)) {
+   if (tpm_is_v1(dev)) {
ret = tpm1_physical_enable(dev);
if (ret != TPM_SUCCESS) {
log_err("TPM: Can't set enabled state\n");
@@ -105,9 +95,9 @@ u32 tpm_clear_and_reenable(struct udevice *dev)
 
 u32 tpm_nv_enable_locking(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return -ENOSYS;
else
return -ENOSYS;
@@ -115,9 +105,9 @@ u32 tpm_nv_enable_locking(struct udevice *dev)
 
 u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_read_value(dev, index, data, count);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_nv_read_value(dev, index, data, count);
else
return -ENOSYS;
@@ -126,9 +116,9 @@ u32 tpm_nv_read_value(struct udevice *dev, u32 index, void 
*data, u32 count)
 u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
   u32 count)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_write_value(dev, index, data, count);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_nv_write_value(dev, index, data, count);
else
return -ENOSYS;
@@ -141,9 +131,9 @@ u32 tpm_set_global_lock(struct udevice *dev)
 
 u32 tpm_write_lock(struct udevice *dev, u32 index)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return -ENOSYS;
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_write_lock(dev, index);
else
return -ENOSYS;
@@ -152,9 +142,9 @@ u32 tpm_write_lock(struct udevice *dev, u32 index)
 u32 

[PATCH v7 0/7] tpm: rng: Move TPM RNG functionality to driver model

2022-07-20 Thread Sughosh Ganu


The TPM device provides the random number generator(RNG)
functionality, whereby sending a command to the TPM device results in
the TPM device responding with random bytes.

There was a discussion on the mailing list earlier[1], where it was
explained that platforms with a TPM device can install the
EFI_RNG_PROTOCOL for getting the random bytes instead of populating
the dtb with the kaslr-seed property. That would make it possible to
measure the dtb.

The TPM uclass driver adds the RNG child device as part of it's
post_probe function.

Some additional changes have also been made to facilitate the
use of the RNG devices, including extending the 'rng' command to take
the RNG device as one of the command-line parameters.

This series depends on a patch[2] from Simon Glass for moving the TPM
device version detection functions to the tpm_api.h header as static
inline functions.

These patches were under discussion earlier, specifically the patch to
add the RNG functionality under the TPM device as a child, either
through manual binding or through the device tree. Ilias had commented
on the discussion last[3]. The discussion can be resumed through this
version.

I have dropped certain patches which were changing some of the TPM API
functions to return an int instead of the current u32. These patches
have been dropped due to review comments from Simon[4]. This work can
be taken up separately, if desired.

[1] - 
https://lore.kernel.org/u-boot/20220103120738.47835-1-ilias.apalodi...@linaro.org/
[2] - 
https://lore.kernel.org/u-boot/20220301001125.1554442-2-...@chromium.org/T/#u
[3] - https://lists.denx.de/pipermail/u-boot/2022-April/481708.html
[4] - https://lists.denx.de/pipermail/u-boot/2022-March/477883.html


Simon Glass (1):
  tpm: Export the TPM-version functions

Sughosh Ganu (6):
  tpm: rng: Add driver model interface for TPM RNG device
  tpm: Add the RNG child device
  cmd: rng: Add support for selecting RNG device
  cmd: rng: Use a statically allocated array for random bytes
  doc: rng: Add documentation for the rng command
  test: rng: Add a UT testcase for the rng command

 cmd/Kconfig  |  1 +
 cmd/rng.c| 42 +++--
 doc/usage/cmd/rng.rst| 26 +++
 doc/usage/index.rst  |  1 +
 drivers/rng/Kconfig  |  9 
 drivers/rng/Makefile |  1 +
 drivers/rng/tpm_rng.c| 23 ++
 drivers/tpm/tpm-uclass.c | 37 +--
 include/tpm_api.h| 10 
 lib/Kconfig  |  1 +
 lib/tpm_api.c| 98 ++--
 test/dm/rng.c| 29 
 12 files changed, 205 insertions(+), 73 deletions(-)
 create mode 100644 doc/usage/cmd/rng.rst
 create mode 100644 drivers/rng/tpm_rng.c

-- 
2.34.1




Re: [PATCH v7 12/13] mkeficapsule: Add support for setting OEM flags in capsule header

2022-07-17 Thread Sughosh Ganu
hi Ilias,

On Fri, 15 Jul 2022 at 22:11, Ilias Apalodimas
 wrote:
>
> Hi Sughosh,
>
> On Thu, 14 Jul 2022 at 21:40, Sughosh Ganu  wrote:
> >
> > Add support for setting OEM flags in the capsule header. As per the
> > UEFI specification, bits 0-15 of the flags member of the capsule
> > header can be defined per capsule GUID.
> >
> > The oemflags will be used for the FWU Multi Bank update feature, as
> > specified by the Dependable Boot specification[1]. Bit
> > 15 of the flags member will be used to determine if the
> > acceptance/rejection of the updated images is to be done by the
> > firmware or an external component like the OS.
>
> Have we documented bit15 in the documentation? If not please add it.

Yes, the use of bit15 has been added in the documentation for this
feature. I will incorporate all your review comments, and in case I
hit any issues while incorporating any review comment, I will respond
to that. Thanks for the review.

-sughosh

>
> >
> > [1] - 
> > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> > Changes since V6: None
> >
> >  doc/mkeficapsule.1   |  4 
> >  tools/mkeficapsule.c | 17 ++---
> >  2 files changed, 18 insertions(+), 3 deletions(-)
> >
> > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > index 77ca061efd..6fb2dd0810 100644
> > --- a/doc/mkeficapsule.1
> > +++ b/doc/mkeficapsule.1
> > @@ -72,6 +72,10 @@ Generate a firmware acceptance empty capsule
> >  .BI "-R\fR,\fB --fw-revert "
> >  Generate a firmware revert empty capsule
> >
> > +.TP
> > +.BI "-o\fR,\fB --capoemflag "
> > +Capsule OEM flag, value between 0x to 0x
> > +
> >  .TP
> >  .BR -h ", " --help
> >  Print a help message
> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > index 244c80e1f7..237c1218fd 100644
> > --- a/tools/mkeficapsule.c
> > +++ b/tools/mkeficapsule.c
> > @@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule";
> >  efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> >  efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
> >
> > -static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
> > +static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR";
> >
> >  enum {
> > CAPSULE_NORMAL_BLOB = 0,
> > @@ -47,6 +47,7 @@ static struct option options[] = {
> > {"dump-sig", no_argument, NULL, 'd'},
> > {"fw-accept", no_argument, NULL, 'A'},
> > {"fw-revert", no_argument, NULL, 'R'},
> > +   {"capoemflag", required_argument, NULL, 'o'},
> > {"help", no_argument, NULL, 'h'},
> > {NULL, 0, NULL, 0},
> >  };
> > @@ -65,6 +66,7 @@ static void print_usage(void)
> > "\t-d, --dump_sig  dump signature (*.p7)\n"
> > "\t-A, --fw-accept  firmware accept capsule, requires GUID, 
> > no image blob\n"
> > "\t-R, --fw-revert  firmware revert capsule, takes no GUID, 
> > no image blob\n"
> > +   "\t-o, --capoemflag Capsule OEM Flag, an integer between 
> > 0x and 0x\n"
> > "\t-h, --help  print a help message\n",
> > tool_name);
> >  }
> > @@ -387,6 +389,7 @@ static void free_sig_data(struct auth_context *ctx)
> >   * @mcount:Monotonic count in authentication information
> >   * @private_file:  Path to a private key file
> >   * @cert_file: Path to a certificate file
> > + * @oemflags:  Capsule OEM Flags, bits 0-15
> >   *
> >   * This function actually does the job of creating an uefi capsule file.
> >   * All the arguments must be supplied.
> > @@ -399,7 +402,8 @@ static void free_sig_data(struct auth_context *ctx)
> >   */
> >  static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > unsigned long index, unsigned long instance,
> > -   uint64_t mcount, char *privkey_file, char 
> > *cert_file)
> > +   uint64_t mcount, char *privkey_file, char 
> > *cert_file,
> > +   uint16_t oemflags)
> >  {
> > struct efi_capsule_header header;
> > struct efi_firmware_management_capsule_header capsule;
> > @@ -464,6 +468,8 @@ static int create_fwbin

Re: [PATCH v7 01/13] dt/bindings: Add bindings for FWU Metadata storage device

2022-07-17 Thread Sughosh Ganu
On Sun, 17 Jul 2022 at 02:43, Jassi Brar  wrote:
>
> On Thu, 14 Jul 2022 at 13:39, Sughosh Ganu  wrote:
> >
> > Add bindings needed for accessing the FWU metadata partitions. These
> > include the compatible string which point to the access method and the
> > actual device which stores the FWU metadata.
> >
> > The current patch adds basic bindings needed for accessing the
> > metadata structure on GPT partitioned block devices.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> > Changes since V6: None
> >
> >  .../firmware/fwu-mdata.yaml   | 32 +++
> >  1 file changed, 32 insertions(+)
> >  create mode 100644 doc/device-tree-bindings/firmware/fwu-mdata.yaml
> >
> > diff --git a/doc/device-tree-bindings/firmware/fwu-mdata.yaml 
> > b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
> > new file mode 100644
> > index 00..97d30bd1c1
> > --- /dev/null
> > +++ b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
> >
> I think we want to call it fwu-mdata-gpt.yaml ?

Yes, makes sense. Will rename it. Thanks.

-sughosh


[PATCH v7 13/13] FWU: doc: Add documentation for the FWU feature

2022-07-14 Thread Sughosh Ganu
Add documentattion for the FWU Multi Bank Update feature. The document
describes the steps needed for setting up the platform for the
feature, as well as steps for enabling the feature on the platform.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 doc/develop/uefi/fwu_updates.rst | 156 +++
 doc/develop/uefi/index.rst   |   1 +
 doc/develop/uefi/uefi.rst|   2 +
 3 files changed, 159 insertions(+)
 create mode 100644 doc/develop/uefi/fwu_updates.rst

diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst
new file mode 100644
index 00..57d1b5b703
--- /dev/null
+++ b/doc/develop/uefi/fwu_updates.rst
@@ -0,0 +1,156 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (c) 2022 Linaro Limited
+
+FWU Multi Bank Updates in U-Boot
+
+
+The FWU Multi Bank Update feature implements the firmware update
+mechanism described in the PSA Firmware Update for A-profile Arm
+Architecture specification[1]. Certain aspects of the Dependable
+Boot specification[2] are also implemented. The feature provides a
+mechanism to have multiple banks of updatable firmware images and for
+updating the firmware images on the non-booted bank. On a successful
+update, the platform boots from the updated bank on subsequent
+boot. The UEFI capsule-on-disk update feature is used for performing
+the actual updates of the updatable firmware images.
+
+The bookkeeping of the updatable images is done through a structure
+called metadata. Currently, the FWU metadata supports identification
+of images based on image GUIDs stored on a GPT partitioned storage
+media. There are plans to extend the metadata structure for non GPT
+partitioned devices as well.
+
+Accessing the FWU metadata is done through generic API's which are
+defined in a driver which complies with the u-boot's driver model. A
+new uclass UCLASS_FWU_MDATA has been added for accessing the FWU
+metadata. Individual drivers can be added based on the type of storage
+media, and it's partitioning method. Details of the storage device
+containing the FWU metadata partitions are specified through a U-Boot
+specific device tree property `fwu-mdata-store`. Please refer to
+U-Boot `doc `__ for
+the device tree bindings.
+
+Enabling the FWU Multi Bank Update feature
+--
+
+The feature can be enabled by specifying the following configs::
+
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y
+CONFIG_EFI_CAPSULE_FIRMWARE=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+CONFIG_CMD_FWU_METADATA=y
+CONFIG_DM_FWU_MDATA=y
+CONFIG_FWU_MDATA_GPT_BLK=y
+CONFIG_FWU_NUM_BANKS=
+CONFIG_FWU_NUM_IMAGES_PER_BANK=
+
+in the .config file
+
+The first group of configs enable the UEFI capsule-on-disk update
+functionality. The second group of configs enable the FWU Multi Bank
+Update functionality. Please refer to the section
+:ref:`uefi_capsule_update_ref` for more details on generation of the
+UEFI capsule.
+
+Setting up the device for GPT partitioned storage
+-
+
+Before enabling the functionality in U-Boot, certain changes are
+required to be done on the storage device. Assuming a GPT partitioned
+storage device, the storage media needs to be partitioned with the
+correct number of partitions, given the number of banks and number of
+images per bank that the platform is going to support. Each updatable
+firmware image will be stored on an separate partition. In addition,
+the two copies of the FWU metadata will be stored on two separate
+partitions.
+
+As an example, a platform supporting two banks with each bank
+containing three images would need to have 2 * 3 = 6 parititions plus
+the two metadata partitions, or 8 partitions. In addition the storage
+media can have additional partitions of non-updatable images, like the
+EFI System Partition(ESP), a partition for the root file system etc.
+
+When generating the partitions, a few aspects need to be taken care
+of. Each GPT partition entry in the GPT header has two GUIDs::
+
+*PartitionTypeGUID*
+*UniquePartitionGUID*
+
+The PartitionTypeGUID value should correspond to the *image_type_uuid*
+field of the FWU metadata. This field is used to identify a given type
+of updatable firmware image, e.g. u-boot, op-tee, FIP etc. This GUID
+should also be used for specifying the `--guid` parameter when
+generating the capsule.
+
+The UniquePartitionGUID value should correspond to the *image_uuid*
+field in the FWU metadata. This GUID is used to identify images of a
+given image type in different banks.
+
+Similarly, the FWU specifications defines the GUID value to be used
+for the metadata partitions. This would be the PartitionTypeGUID for
+the metadata partitions.
+
+When generating the metadata, the *image_type_uuid* and the
+*image_uuid* values should match

[PATCH v7 12/13] mkeficapsule: Add support for setting OEM flags in capsule header

2022-07-14 Thread Sughosh Ganu
Add support for setting OEM flags in the capsule header. As per the
UEFI specification, bits 0-15 of the flags member of the capsule
header can be defined per capsule GUID.

The oemflags will be used for the FWU Multi Bank update feature, as
specified by the Dependable Boot specification[1]. Bit
15 of the flags member will be used to determine if the
acceptance/rejection of the updated images is to be done by the
firmware or an external component like the OS.

[1] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 doc/mkeficapsule.1   |  4 
 tools/mkeficapsule.c | 17 ++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index 77ca061efd..6fb2dd0810 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -72,6 +72,10 @@ Generate a firmware acceptance empty capsule
 .BI "-R\fR,\fB --fw-revert "
 Generate a firmware revert empty capsule
 
+.TP
+.BI "-o\fR,\fB --capoemflag "
+Capsule OEM flag, value between 0x to 0x
+
 .TP
 .BR -h ", " --help
 Print a help message
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 244c80e1f7..237c1218fd 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule";
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
+static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR";
 
 enum {
CAPSULE_NORMAL_BLOB = 0,
@@ -47,6 +47,7 @@ static struct option options[] = {
{"dump-sig", no_argument, NULL, 'd'},
{"fw-accept", no_argument, NULL, 'A'},
{"fw-revert", no_argument, NULL, 'R'},
+   {"capoemflag", required_argument, NULL, 'o'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
 };
@@ -65,6 +66,7 @@ static void print_usage(void)
"\t-d, --dump_sig  dump signature (*.p7)\n"
"\t-A, --fw-accept  firmware accept capsule, requires GUID, no 
image blob\n"
"\t-R, --fw-revert  firmware revert capsule, takes no GUID, no 
image blob\n"
+   "\t-o, --capoemflag Capsule OEM Flag, an integer between 0x 
and 0x\n"
"\t-h, --help  print a help message\n",
tool_name);
 }
@@ -387,6 +389,7 @@ static void free_sig_data(struct auth_context *ctx)
  * @mcount:Monotonic count in authentication information
  * @private_file:  Path to a private key file
  * @cert_file: Path to a certificate file
+ * @oemflags:  Capsule OEM Flags, bits 0-15
  *
  * This function actually does the job of creating an uefi capsule file.
  * All the arguments must be supplied.
@@ -399,7 +402,8 @@ static void free_sig_data(struct auth_context *ctx)
  */
 static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
unsigned long index, unsigned long instance,
-   uint64_t mcount, char *privkey_file, char *cert_file)
+   uint64_t mcount, char *privkey_file, char *cert_file,
+   uint16_t oemflags)
 {
struct efi_capsule_header header;
struct efi_firmware_management_capsule_header capsule;
@@ -464,6 +468,8 @@ static int create_fwbin(char *path, char *bin, efi_guid_t 
*guid,
header.header_size = sizeof(header);
/* TODO: The current implementation ignores flags */
header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
+   if (oemflags)
+   header.flags |= oemflags;
header.capsule_image_size = sizeof(header)
+ sizeof(capsule) + sizeof(uint64_t)
+ sizeof(image)
@@ -635,6 +641,7 @@ int main(int argc, char **argv)
unsigned char uuid_buf[16];
unsigned long index, instance;
uint64_t mcount;
+   uint16_t oemflags;
char *privkey_file, *cert_file;
int c, idx;
 
@@ -646,6 +653,7 @@ int main(int argc, char **argv)
cert_file = NULL;
dump_sig = 0;
capsule_type = CAPSULE_NORMAL_BLOB;
+   oemflags = 0;
for (;;) {
c = getopt_long(argc, argv, opts_short, options, );
if (c == -1)
@@ -699,6 +707,9 @@ int main(int argc, char **argv)
case 'R':
capsule_type |= CAPSULE_REVERT;
break;
+   case 'o':
+   oemflags = strtoul(optarg, NULL, 0);
+   break;
default:
print_usage();
   

[PATCH v7 11/13] mkeficapsule: Add support for generating empty capsules

2022-07-14 Thread Sughosh Ganu
The Dependable Boot specification[1] describes the structure of the
firmware accept and revert capsules. These are empty capsules which
are used for signalling the acceptance or rejection of the updated
firmware by the OS. Add support for generating these empty capsules.

[1] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 doc/mkeficapsule.1   | 29 ++
 tools/eficapsule.h   |  8 
 tools/mkeficapsule.c | 92 
 3 files changed, 115 insertions(+), 14 deletions(-)

diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index 09bdc24295..77ca061efd 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
 
 .SH SYNOPSIS
 .B mkeficapsule
-.RI [ options "] " image-blob " " capsule-file
+.RI [ options ] " " [ image-blob ] " " capsule-file
 
 .SH "DESCRIPTION"
 .B mkeficapsule
@@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given 
private key.
 In this case, the update will be authenticated by verifying the signature
 before applying.
 
+Additionally, an empty capsule file can be generated for acceptance or
+rejection of firmware images by a governing component like an Operating
+System. The empty capsules do not require an image-blob input file.
+
+
 .B mkeficapsule
-takes any type of image files, including:
+takes any type of image files when generating non empty capsules, including:
 .TP
 .I raw image
 format is a single binary blob of any type of firmware.
@@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
 This type of image file can be generated by
 .BR mkimage .
 
-.PP
-If you want to use other types than above two, you should explicitly
-specify a guid for the FMP driver.
-
 .SH "OPTIONS"
+
 .TP
 .BI "-g\fR,\fB --guid " guid-string
 Specify guid for image blob type. The format is:
 ----
 
 The first three elements are in little endian, while the rest
-is in big endian.
+is in big endian. The option must be specified for all non empty and
+image acceptance capsules
 
 .TP
 .BI "-i\fR,\fB --index " index
@@ -57,6 +60,18 @@ Specify an image index
 .BI "-I\fR,\fB --instance " instance
 Specify a hardware instance
 
+.PP
+For generation of firmware accept empty capsule
+.BR --guid
+is mandatory
+.TP
+.BI "-A\fR,\fB --fw-accept "
+Generate a firmware acceptance empty capsule
+
+.TP
+.BI "-R\fR,\fB --fw-revert "
+Generate a firmware revert empty capsule
+
 .TP
 .BR -h ", " --help
 Print a help message
diff --git a/tools/eficapsule.h b/tools/eficapsule.h
index d63b831443..072a4b5598 100644
--- a/tools/eficapsule.h
+++ b/tools/eficapsule.h
@@ -41,6 +41,14 @@ typedef struct {
EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \
 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
 
+#define FW_ACCEPT_OS_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
+#define FW_REVERT_OS_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
 /* flags */
 #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET  0x0001
 
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 5f74d23b9e..244c80e1f7 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,13 @@ static const char *tool_name = "mkeficapsule";
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:dh";
+static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
+
+enum {
+   CAPSULE_NORMAL_BLOB = 0,
+   CAPSULE_ACCEPT,
+   CAPSULE_REVERT,
+} capsule_type;
 
 static struct option options[] = {
{"guid", required_argument, NULL, 'g'},
@@ -39,6 +45,8 @@ static struct option options[] = {
{"certificate", required_argument, NULL, 'c'},
{"monotonic-count", required_argument, NULL, 'm'},
{"dump-sig", no_argument, NULL, 'd'},
+   {"fw-accept", no_argument, NULL, 'A'},
+   {"fw-revert", no_argument, NULL, 'R'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
 };
@@ -55,6 +63,8 @@ static void print_usage(void)
"\t-c, --certificate  signer's certificate 
file\n"
"\t-m, --monotonic-count  monotonic count\n"
"\t-d, --dump_sig  dump signature (*.p7)\n"
+   "\t-A, --fw-accept  firmware accept capsule, requires GUID, no 
image blob\n"
+   "\t-R, --fw-revert 

[PATCH v7 10/13] FWU: cmd: Add a command to read FWU metadata

2022-07-14 Thread Sughosh Ganu
Add a command to read the metadata as specified in the FWU
specification and print the fields of the metadata.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 cmd/Kconfig |  7 +
 cmd/Makefile|  1 +
 cmd/fwu_mdata.c | 80 +
 3 files changed, 88 insertions(+)
 create mode 100644 cmd/fwu_mdata.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index d5f842136c..2110f59f6a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -161,6 +161,13 @@ config CMD_CPU
  internal name) and clock frequency. Other information may be
  available depending on the CPU driver.
 
+config CMD_FWU_METADATA
+   bool "fwu metadata read"
+   depends on FWU_MULTI_BANK_UPDATE
+   default y
+   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 5e43a1e022..259a93bc65 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o
 obj-$(CONFIG_CMD_FPGAD) += fpgad.o
 obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
+obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
 obj-$(CONFIG_CMD_HVC) += smccc.o
diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c
new file mode 100644
index 00..ee9d035374
--- /dev/null
+++ b/cmd/fwu_mdata.c
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static void print_mdata(struct fwu_mdata *mdata)
+{
+   int i, j;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_info;
+
+   printf("\tFWU Metadata\n");
+   printf("crc32: %#x\n", mdata->crc32);
+   printf("version: %#x\n", mdata->version);
+   printf("active_index: %#x\n", mdata->active_index);
+   printf("previous_active_index: %#x\n", mdata->previous_active_index);
+
+   printf("\tImage Info\n");
+   for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) {
+   img_entry = >img_entry[i];
+   printf("\nImage Type Guid: %pUL\n",
+  _entry->image_type_uuid);
+   printf("Location Guid: %pUL\n", _entry->location_uuid);
+   for (j = 0; j < CONFIG_FWU_NUM_BANKS; j++) {
+   img_info = _entry->img_bank_info[j];
+   printf("Image Guid:  %pUL\n", _info->image_uuid);
+   printf("Image Acceptance: %s\n",
+  img_info->accepted == 0x1 ? "yes" : "no");
+   }
+   }
+}
+
+int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag,
+int argc, char * const argv[])
+{
+   struct udevice *dev;
+   int ret = CMD_RET_SUCCESS, res;
+   struct fwu_mdata *mdata = NULL;
+
+   if (uclass_get_device(UCLASS_FWU_MDATA, 0, ) || !dev) {
+   log_err("Unable to get FWU metadata device\n");
+   return CMD_RET_FAILURE;
+   }
+
+   res = fwu_mdata_check();
+   if (res < 0) {
+   log_err("FWU Metadata check failed\n");
+   ret = CMD_RET_FAILURE;
+   goto out;
+   }
+
+   res = fwu_get_mdata();
+   if (res < 0) {
+   log_err("Unable to get valid FWU metadata\n");
+   ret = CMD_RET_FAILURE;
+   goto out;
+   }
+
+   print_mdata(mdata);
+
+out:
+   free(mdata);
+   return ret;
+}
+
+U_BOOT_CMD(
+   fwu_mdata_read, 1,  1,  do_fwu_mdata_read,
+   "Read and print FWU metadata",
+   ""
+);
-- 
2.34.1



[PATCH v7 09/13] FWU: Add support for the FWU Multi Bank Update feature

2022-07-14 Thread Sughosh Ganu
The FWU Multi Bank Update feature supports updation of firmware images
to one of multiple sets(also called banks) of images. The firmware
images are clubbed together in banks, with the system booting images
from the active bank. Information on the images such as which bank
they belong to is stored as part of the metadata structure, which is
stored on the same storage media as the firmware images on a dedicated
partition.

At the time of update, the metadata is read to identify the bank to
which the images need to be flashed(update bank). On a successful
update, the metadata is modified to set the updated bank as active
bank to subsequently boot from.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 include/fwu.h|  10 ++
 lib/Kconfig  |   6 +
 lib/Makefile |   1 +
 lib/efi_loader/efi_capsule.c | 231 ++-
 lib/efi_loader/efi_setup.c   |   3 +-
 lib/fwu_updates/Kconfig  |  31 +
 lib/fwu_updates/Makefile |   3 +-
 lib/fwu_updates/fwu.c|  26 
 8 files changed, 304 insertions(+), 7 deletions(-)
 create mode 100644 lib/fwu_updates/Kconfig

diff --git a/include/fwu.h b/include/fwu.h
index b374fd1179..7ff1cd75d3 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -32,13 +32,23 @@ struct fwu_mdata_ops {
 };
 
 #define FWU_MDATA_VERSION  0x1
+#define FWU_IMAGE_ACCEPTED 0x1
 
 #define FWU_MDATA_GUID \
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
+#define FWU_OS_REQUEST_FW_REVERT_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
+#define FWU_OS_REQUEST_FW_ACCEPT_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
 u8 fwu_update_checks_pass(void);
 int fwu_boottime_checks(void);
+int fwu_trial_state_ctr_start(void);
 
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
diff --git a/lib/Kconfig b/lib/Kconfig
index 7dd777b56a..0e5390597c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -967,3 +967,9 @@ config LMB_RESERVED_REGIONS
  memory blocks.
 
 endmenu
+
+menu "FWU Multi Bank Updates"
+
+source lib/fwu_updates/Kconfig
+
+endmenu
diff --git a/lib/Makefile b/lib/Makefile
index e3deb15287..f2cfd1e428 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_FIT) += libfdt/
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index a6b98f066a..18a356ba08 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 
@@ -32,6 +33,17 @@ static const efi_guid_t 
efi_guid_firmware_management_capsule_id =
EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 const efi_guid_t efi_guid_firmware_management_protocol =
EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
+const efi_guid_t fwu_guid_os_request_fw_revert =
+   FWU_OS_REQUEST_FW_REVERT_GUID;
+const efi_guid_t fwu_guid_os_request_fw_accept =
+   FWU_OS_REQUEST_FW_ACCEPT_GUID;
+
+#define FW_ACCEPT_OS   (u32)0x8000
+
+__maybe_unused static u32 update_index;
+__maybe_unused static bool capsule_update;
+__maybe_unused static bool fw_accept_os;
+static bool image_index_check = true;
 
 #ifdef CONFIG_EFI_CAPSULE_ON_DISK
 /* for file system access */
@@ -205,7 +217,8 @@ efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 
instance,
log_debug("+++ desc[%d] index: %d, name: %ls\n",
  j, desc->image_index, desc->image_id_name);
if (!guidcmp(>image_type_id, image_type) &&
-   (desc->image_index == image_index) &&
+   (!image_index_check ||
+desc->image_index == image_index) &&
(!instance ||
 !desc->hardware_instance ||
  desc->hardware_instance == instance))
@@ -388,6 +401,87 @@ efi_status_t efi_capsule_authenticate(const void *capsule, 
efi_uintn_t capsule_s
 }
 #endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
 
+static bool fwu_empty_capsule(struct efi_capsule_header *capsule)
+{
+   return !guidcmp(>capsule_guid,
+   _guid_os_request_fw_revert) ||
+   !guidcmp(>capsule_guid,
+_guid_os_request_fw_accept);
+}
+
+static efi_status_t fwu_empty_capsule_process(
+   struct efi_capsule_header *capsule)

[PATCH v7 08/13] FWU: Add boot time checks as highlighted by the FWU specification

2022-07-14 Thread Sughosh Ganu
The FWU Multi Bank Update specification requires the Update Agent to
carry out certain checks at the time of platform boot. The Update
Agent is the component which is responsible for updating the firmware
components and maintaining and keeping the metadata in sync.

The spec requires that the Update Agent perform the following checks
at the time of boot
* Sanity check of both the metadata copies maintained by the platform.
* Get the boot index passed to U-Boot by the prior stage bootloader
  and use this value for metadata bookkeeping.
* Check if the system is booting in Trial State. If the system boots
  in the Trial State for more than a specified number of boot counts,
  change the Active Bank to be booting the platform from.

Add these checks in the board initialisation sequence, invoked after
relocation.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 common/board_r.c  |   5 ++
 include/fwu.h |   3 +
 lib/fwu_updates/fwu.c | 165 ++
 3 files changed, 173 insertions(+)
 create mode 100644 lib/fwu_updates/fwu.c

diff --git a/common/board_r.c b/common/board_r.c
index ed29069d2d..5210ed6f32 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -785,6 +786,10 @@ static init_fnc_t init_sequence_r[] = {
 #if defined(CONFIG_PRAM)
initr_mem,
 #endif
+
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+   fwu_boottime_checks,
+#endif
run_main_loop,
 };
 
diff --git a/include/fwu.h b/include/fwu.h
index edb28c9659..b374fd1179 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -37,6 +37,9 @@ struct fwu_mdata_ops {
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
+u8 fwu_update_checks_pass(void);
+int fwu_boottime_checks(void);
+
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
 int fwu_get_active_index(u32 *active_idx);
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
new file mode 100644
index 00..10a0522333
--- /dev/null
+++ b/lib/fwu_updates/fwu.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static u8 trial_state;
+static u8 boottime_check;
+
+static int fwu_trial_state_check(void)
+{
+   int ret, i;
+   efi_status_t status;
+   efi_uintn_t var_size;
+   u16 trial_state_ctr;
+   u32 nimages, active_bank, var_attributes, active_idx;
+   struct fwu_mdata *mdata = NULL;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_bank_info;
+
+   ret = fwu_get_mdata();
+   if (ret)
+   return ret;
+
+   ret = 0;
+   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
+   active_bank = mdata->active_index;
+   img_entry = >img_entry[0];
+   for (i = 0; i < nimages; i++) {
+   img_bank_info = _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;
+   status = efi_get_variable_int(u"TrialStateCtr",
+ _global_variable_guid,
+ _attributes,
+ _size, _state_ctr,
+ NULL);
+   if (status != EFI_SUCCESS) {
+   log_err("Unable to read TrialStateCtr variable\n");
+   ret = -1;
+   goto out;
+   }
+
+   ++trial_state_ctr;
+   if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) {
+   log_info("Trial State count exceeded. Revert back to 
previous_active_index\n");
+   active_idx = mdata->active_index;
+   ret = fwu_revert_boot_index();
+   if (ret) {
+   log_err("Unable to revert active_index\n");
+   goto out;
+   }
+
+   /* Delete the TrialStateCtr variable */
+   status = efi_set_variable_int(u"TrialStateCtr",
+ _global_variable_guid,
+ var_attributes,
+ 

[PATCH v7 07/13] FWU: STM32MP1: Add support to read boot index from backup register

2022-07-14 Thread Sughosh Ganu
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 
Reviewed-by: Patrick Delaunay 
---
Changes since V6: None

 arch/arm/mach-stm32mp/include/mach/stm32.h | 5 +
 board/st/stm32mp1/stm32mp1.c   | 8 
 include/fwu.h  | 1 +
 3 files changed, 14 insertions(+)

diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h 
b/arch/arm/mach-stm32mp/include/mach/stm32.h
index c70375a723..c85ae6a34e 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -112,11 +112,16 @@ enum boot_device {
 #ifdef CONFIG_STM32MP15x
 #define TAMP_BACKUP_MAGIC_NUMBER   TAMP_BACKUP_REGISTER(4)
 #define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5)
+#define TAMP_FWU_BOOT_INFO_REG 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)
 #define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21)
 
+#define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0)
+
+#define TAMP_FWU_BOOT_IDX_OFFSET   0
+
 #define TAMP_COPRO_STATE_OFF   0
 #define TAMP_COPRO_STATE_INIT  1
 #define TAMP_COPRO_STATE_CRUN  2
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 44c7943f1d..ddf5053601 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -1001,4 +1001,12 @@ int fwu_plat_get_update_index(u32 *update_idx)
 
return ret;
 }
+
+void fwu_plat_get_bootidx(void *boot_idx)
+{
+   u32 *bootidx = boot_idx;
+
+   *bootidx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
+   TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
+}
 #endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 38dceca9c5..edb28c9659 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -49,6 +49,7 @@ int fwu_revert_boot_index(void);
 int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
 int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
+void fwu_plat_get_bootidx(void *boot_idx);
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
 int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
-- 
2.34.1



[PATCH v7 06/13] FWU: stm32mp1: Add helper functions for accessing FWU metadata

2022-07-14 Thread Sughosh Ganu
Add helper functions needed for accessing the FWU metadata which
contains information on the updatable images. These functions have
been added for the STM32MP157C-DK2 board which has the updatable
images on the uSD card, formatted as GPT partitions.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Patrick Delaunay 
---
Changes since V6: None

 board/st/stm32mp1/stm32mp1.c | 40 
 include/fwu.h|  3 ++
 lib/fwu_updates/Makefile |  6 +++
 lib/fwu_updates/fwu_gpt.c| 88 
 4 files changed, 137 insertions(+)
 create mode 100644 lib/fwu_updates/Makefile
 create mode 100644 lib/fwu_updates/fwu_gpt.c

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index e3a04f8d8a..44c7943f1d 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -7,9 +7,11 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,9 +27,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -962,3 +966,39 @@ static void board_copro_image_process(ulong fw_image, 
size_t fw_size)
 }
 
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
+
+#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
+
+#include 
+#include 
+
+int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
+int *alt_num)
+{
+   struct blk_desc *desc;
+   struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
+
+   desc = dev_get_uclass_plat(priv->blk_dev);
+   if (!desc) {
+   log_err("Block device not found\n");
+   return -ENODEV;
+   }
+
+   return fwu_gpt_get_alt_num(desc, image_guid, alt_num, DFU_DEV_MMC);
+}
+
+int fwu_plat_get_update_index(u32 *update_idx)
+{
+   int ret;
+   u32 active_idx;
+
+   ret = fwu_get_active_index(_idx);
+
+   if (ret < 0)
+   return -1;
+
+   *update_idx = active_idx ^= 0x1;
+
+   return ret;
+}
+#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 8259c75d12..38dceca9c5 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -51,4 +51,7 @@ int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
+int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+   int *alt_num, unsigned char dfu_dev);
+int fwu_plat_get_update_index(u32 *update_idx);
 #endif /* _FWU_H_ */
diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile
new file mode 100644
index 00..5a59e4a833
--- /dev/null
+++ b/lib/fwu_updates/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2022, Linaro Limited
+#
+
+obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_gpt.o
diff --git a/lib/fwu_updates/fwu_gpt.c b/lib/fwu_updates/fwu_gpt.c
new file mode 100644
index 00..434ec76bde
--- /dev/null
+++ b/lib/fwu_updates/fwu_gpt.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t 
*image_guid)
+{
+   int i;
+   struct disk_partition info;
+   efi_guid_t unique_part_guid;
+
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.uuid, unique_part_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_part_guid, image_guid))
+   return i;
+   }
+
+   log_err("No partition found with image_guid %pUs\n", image_guid);
+   return -ENOENT;
+}
+
+int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+   int *alt_num, unsigned char dfu_dev)
+{
+   int ret = -1;
+   int i, part, dev_num;
+   int nalt;
+   struct dfu_entity *dfu;
+
+   dev_num = desc->devnum;
+   part = get_gpt_dfu_identifier(desc, image_guid);
+   if (part < 0)
+   return -ENOENT;
+
+   dfu_init_env_entities(NULL, NULL);
+
+   nalt = 0;
+   list_for_each_entry(dfu, _list, list) {
+   nalt++;
+   }
+
+   if (!nalt) {
+   log_warning("No entities in dfu_alt_info\n");
+   dfu_free_entities();
+   return -ENOENT;
+   }
+
+   for (i = 0; i < nalt; i++) {
+   dfu = dfu_get_entity(i);
+
+   if (!dfu)
+   continue;
+
+   /*
+* Currently, Multi Bank update
+* feature is being supported
+* only on GPT partitioned
+* MMC/SD devi

[PATCH v7 05/13] stm32mp1: dk2: Add image information for capsule updates

2022-07-14 Thread Sughosh Ganu
Enabling capsule update functionality on the platform requires
populating information on the images that are to be updated using the
functionality. Do so for the DK2 board.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Patrick Delaunay 
---
Changes since V6:
* s/STM32MP1/STM32MP15/ as suggested by Patrick

 board/st/stm32mp1/stm32mp1.c   | 19 +++
 include/configs/stm32mp15_common.h |  4 
 2 files changed, 23 insertions(+)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 9496890d16..e3a04f8d8a 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -87,6 +88,16 @@
 #define USB_START_LOW_THRESHOLD_UV 123
 #define USB_START_HIGH_THRESHOLD_UV215
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+struct efi_fw_image fw_images[1];
+
+struct efi_capsule_update_info update_info = {
+   .images = fw_images,
+};
+
+u8 num_image_type_guids = ARRAY_SIZE(fw_images);
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
 int board_early_init_f(void)
 {
/* nothing to do, only used in SPL */
@@ -670,6 +681,14 @@ int board_init(void)
 
setup_led(LEDST_ON);
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+   if (board_is_stm32mp15x_dk2()) {
+   efi_guid_t image_type_guid = STM32MP15_DK2_FIP_IMAGE_GUID;
+   guidcpy(_images[0].image_type_id, _type_guid);
+   fw_images[0].fw_name = u"STM32MP15-DK2-FIP";
+   fw_images[0].image_index = 5;
+   }
+#endif
return 0;
 }
 
diff --git a/include/configs/stm32mp15_common.h 
b/include/configs/stm32mp15_common.h
index c5412ffeb3..6ab10d8ce5 100644
--- a/include/configs/stm32mp15_common.h
+++ b/include/configs/stm32mp15_common.h
@@ -34,6 +34,10 @@
 #define CONFIG_SERVERIP 192.168.1.1
 #endif
 
+#define STM32MP15_DK2_FIP_IMAGE_GUID \
+   EFI_GUID(0x19d5df83, 0x11b0, 0x457b, 0xbe, 0x2c, \
+0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
+
 /*/
 #ifdef CONFIG_DISTRO_DEFAULTS
 /*/
-- 
2.34.1



[PATCH v7 04/13] stm32mp1: dk2: Add a node for the FWU metadata device

2022-07-14 Thread Sughosh Ganu
The FWU metadata structure is accessed through the driver model
interface. On the stm32mp157c-dk2 board, the FWU metadata is stored on
the uSD card. Add the fwu-mdata node on the u-boot specifc dtsi file
for accessing the metadata structure.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Patrick Delaunay 
---
Changes since V6: None

 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi 
b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
index 06ef3a4095..24f86209db 100644
--- a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
@@ -4,3 +4,10 @@
  */
 
 #include "stm32mp157a-dk1-u-boot.dtsi"
+
+/ {
+   fwu-mdata {
+   compatible = "u-boot,fwu-mdata-gpt";
+   fwu-mdata-store = <>;
+   };
+};
-- 
2.34.1



[PATCH v7 03/13] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-07-14 Thread Sughosh Ganu
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 a driver 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 
Reviewed-by: Patrick Delaunay 
---
Changes since V6:
* Define the LOG_CATEGORY macro as suggested by Patrick

 drivers/fwu-mdata/Kconfig |   9 +
 drivers/fwu-mdata/Makefile|   1 +
 drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 410 ++
 include/fwu.h |   5 +
 4 files changed, 425 insertions(+)
 create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c

diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
index d6a21c8e19..d5edef19d6 100644
--- a/drivers/fwu-mdata/Kconfig
+++ b/drivers/fwu-mdata/Kconfig
@@ -5,3 +5,12 @@ config DM_FWU_MDATA
  Enable support for accessing FWU Metadata partitions. The
  FWU Metadata partitions reside on the same storage device
  which contains the other FWU updatable firmware images.
+
+config FWU_MDATA_GPT_BLK
+   bool "FWU Metadata access for GPT partitioned Block devices"
+   select PARTITION_TYPE_GUID
+   select PARTITION_UUIDS
+   depends on DM && HAVE_BLOCK_DEVICE && EFI_PARTITION
+   help
+ Enable support for accessing FWU Metadata on GPT partitioned
+ block devices.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
index e53a8c9983..313049f67a 100644
--- a/drivers/fwu-mdata/Makefile
+++ b/drivers/fwu-mdata/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
+obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
new file mode 100644
index 00..f694c4369b
--- /dev/null
+++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#define LOG_CATEGORY UCLASS_FWU_MDATA
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define PRIMARY_PART   BIT(0)
+#define SECONDARY_PART BIT(1)
+#define BOTH_PARTS (PRIMARY_PART | SECONDARY_PART)
+
+#define MDATA_READ BIT(0)
+#define MDATA_WRITEBIT(1)
+
+static int gpt_get_mdata_partitions(struct blk_desc *desc,
+   u16 *primary_mpart,
+   u16 *secondary_mpart)
+{
+   int i, ret;
+   u32 mdata_parts;
+   efi_guid_t part_type_guid;
+   struct disk_partition info;
+   const efi_guid_t fwu_mdata_guid = FWU_MDATA_GUID;
+
+   mdata_parts = 0;
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.type_guid, part_type_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_mdata_guid, _type_guid)) {
+   ++mdata_parts;
+   if (!*primary_mpart)
+   *primary_mpart = i;
+   else
+   *secondary_mpart = i;
+   }
+   }
+
+   if (mdata_parts != 2) {
+   log_err("Expect two copies of the FWU metadata instead of %d\n",
+   mdata_parts);
+   ret = -EINVAL;
+   } else {
+   ret = 0;
+   }
+
+   return ret;
+}
+
+static int gpt_get_mdata_disk_part(struct blk_desc *desc,
+  struct disk_partition *info,
+  u32 part_num)
+{
+   int ret;
+   char *mdata_guid_str = "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23";
+
+   ret = part_get_info(desc, part_num, info);
+   if (ret < 0) {
+   log_err("Unable to get the partition info for the FWU metadata 
part %d",
+   part_num);
+   return -1;
+   }
+
+   /* Check that it is indeed the FWU metadata partition */
+   if (!strncmp(info->type_guid, mdata_guid_str, UUID_STR_LEN)) {
+   /* Found the FWU metadata partition */
+   return 0;
+   }
+
+   return -1;
+}
+
+static int gpt_read_write_mdata(struct blk_desc *desc,
+   struct fwu_mdata *mdata,
+   u8 access, u32 part_num)
+{
+   int ret;
+   u32 len, blk_start, blkcnt;
+   struct disk_partition info;
+
+   ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_mdata, mdata_aligned, 1,
+desc->blksz);
+
+   ret = gpt_get_mdata_disk_p

[PATCH v7 02/13] FWU: Add FWU metadata structure and driver for accessing metadata

2022-07-14 Thread Sughosh Ganu
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 a driver model
uclass which provides 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 
Reviewed-by: Patrick Delaunay 
---
Changes since V6:
* Define the LOG_CATEGORY macro as suggested by Patrick
* Add some documentation in the fwu_get_mdata and fwu_update_mdata
  functions to describe the sequence of calls to be made for modifying
  the metadata, as suggested by Etienne

 drivers/Kconfig  |   2 +
 drivers/Makefile |   1 +
 drivers/fwu-mdata/Kconfig|   7 +
 drivers/fwu-mdata/Makefile   |   6 +
 drivers/fwu-mdata/fwu-mdata-uclass.c | 469 +++
 include/dm/uclass-id.h   |   1 +
 include/fwu.h|  49 +++
 include/fwu_mdata.h  |  67 
 8 files changed, 602 insertions(+)
 create mode 100644 drivers/fwu-mdata/Kconfig
 create mode 100644 drivers/fwu-mdata/Makefile
 create mode 100644 drivers/fwu-mdata/fwu-mdata-uclass.c
 create mode 100644 include/fwu.h
 create mode 100644 include/fwu_mdata.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 8b6fead351..75ac149d31 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -44,6 +44,8 @@ source "drivers/fuzz/Kconfig"
 
 source "drivers/fpga/Kconfig"
 
+source "drivers/fwu-mdata/Kconfig"
+
 source "drivers/gpio/Kconfig"
 
 source "drivers/hwspinlock/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index d63fd1c04d..7710f18236 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -83,6 +83,7 @@ obj-y += cache/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FASTBOOT) += fastboot/
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata/
 obj-y += misc/
 obj-$(CONFIG_MMC) += mmc/
 obj-$(CONFIG_NVME) += nvme/
diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
new file mode 100644
index 00..d6a21c8e19
--- /dev/null
+++ b/drivers/fwu-mdata/Kconfig
@@ -0,0 +1,7 @@
+config DM_FWU_MDATA
+   bool "Driver support for accessing FWU Metadata"
+   depends on DM
+   help
+ Enable support for accessing FWU Metadata partitions. The
+ FWU Metadata partitions reside on the same storage device
+ which contains the other FWU updatable firmware images.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
new file mode 100644
index 00..e53a8c9983
--- /dev/null
+++ b/drivers/fwu-mdata/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2022, Linaro Limited
+#
+
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c 
b/drivers/fwu-mdata/fwu-mdata-uclass.c
new file mode 100644
index 00..4ba102ff81
--- /dev/null
+++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#define LOG_CATEGORY UCLASS_FWU_MDATA
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define IMAGE_ACCEPT_SET   BIT(0)
+#define IMAGE_ACCEPT_CLEAR BIT(1)
+
+static int fwu_get_dev_ops(struct udevice **dev,
+  const struct fwu_mdata_ops **ops)
+{
+   int ret;
+
+   ret = uclass_get_device(UCLASS_FWU_MDATA, 0, dev);
+   if (ret) {
+   log_debug("Cannot find fwu device\n");
+   return ret;
+   }
+
+   if ((*ops = device_get_ops(*dev)) == NULL) {
+   log_debug("Cannot get fwu device ops\n");
+   return -ENOSYS;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_verify_mdata() - Verify the FWU metadata
+ * @mdata: FWU metadata structure
+ * @pri_part: FWU metadata partition is primary or secondary
+ *
+ * Verify the FWU metadata by computing the CRC32 for the metadata
+ * structure and comparing it against the CRC32 value stored as part
+ * of the structure.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_verify_mdata(struct fwu_mdata *mdata, bool pri_part)
+{
+   u32 calc_crc32;
+   void *buf;
+
+   buf = >version;
+   calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32));
+
+   if (calc_crc32 != mdata->crc32) {
+   log_err("crc32 check failed for %s FWU metadata partition\n",
+   pri_part ? "primary" : "secondary");
+   return -1;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_get_active_index() - Get active_index from the FWU metadata
+ * @active_idx: active_index value to be read
+ *
+ * Re

[PATCH v7 01/13] dt/bindings: Add bindings for FWU Metadata storage device

2022-07-14 Thread Sughosh Ganu
Add bindings needed for accessing the FWU metadata partitions. These
include the compatible string which point to the access method and the
actual device which stores the FWU metadata.

The current patch adds basic bindings needed for accessing the
metadata structure on GPT partitioned block devices.

Signed-off-by: Sughosh Ganu 
---
Changes since V6: None

 .../firmware/fwu-mdata.yaml   | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 doc/device-tree-bindings/firmware/fwu-mdata.yaml

diff --git a/doc/device-tree-bindings/firmware/fwu-mdata.yaml 
b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
new file mode 100644
index 00..97d30bd1c1
--- /dev/null
+++ b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/fwu-mdata.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: FWU metadata on device with GPT partitioned layout
+
+maintainers:
+ - Sughosh Ganu 
+
+properties:
+  compatible:
+items:
+  - const: u-boot,fwu-mdata-gpt
+
+  fwu-mdata-store:
+maxItems: 1
+description: Phandle of the device which contains the FWU medatata 
partition.
+
+required:
+  - compatible
+  - fwu-mdata-store
+
+additionalProperties: false
+
+examples:
+  - |
+fwu-mdata {
+compatible = "u-boot,fwu-mdata-gpt";
+fwu-mdata-store = <>;
+};
-- 
2.34.1



[PATCH v7 00/13] FWU: Add FWU Multi Bank Update feature support

2022-07-14 Thread Sughosh Ganu


The patchset adds support for the FWU Multi Bank Update[1]
feature. Certain aspects of the Dependable Boot[2] specification have
also been implemented.

The FWU multi bank update feature is used for supporting multiple
sets(also called banks) of firmware image(s), allowing the platform to
boot from a different bank, in case it fails to boot from the active
bank. This functionality is supported by keeping the relevant
information in a structure called metadata, which provides information
on the images. Among other parameters, the metadata structure contains
information on the currect active bank that is being used to boot
image(s).

Functionality is being added to work with the UEFI capsule driver in
u-boot. The metadata is read to gather information on the update bank,
which is the bank to which the firmware images would be flashed to. On
a successful completion of the update of all components, the active
bank field in the metadata is updated, to reflect the bank from which
the platform will boot on the subsequent boots.

Currently, the feature is being enabled on the STM32MP157C-DK2 and
Synquacer boards. The DK2 board boots a FIP image from a uSD card
partitioned with the GPT partioning scheme, while the Synquacer board
boots a FIP image from a MTD partitioned SPI NOR flash device.

This feature also requires changes in a previous stage of
bootloader, which parses the metadata and selects the bank to boot the
image(s) from. Support has being added in tf-a(BL2 stage) for the
STM32MP157C-DK2 board to boot the active bank images. These changes 
have been merged to the upstream tf-a repository.

The earlier patchset contained patches for both the DK2 and the
Synquacer platforms. The handling of review comments for the Synquacer
platform is to be taken up by a different engineer, and has not been
done yet. After discussion with Tom Rini and Heinrich, it was decided
to send the patches for the DK2 platform separately for review. The
patch for adding a python test for the feature has been developed, and
was sent in the version 5 of the patches[3]. However, the test script
depends on adding support for the feature on MTD SPI NOR devices, and
that is being done as part of the Synquacer patches. Hence these set
of patches do not have the test script for the feature. That will be
added through the patches for adding support for the feauture on
Synquacer platform.

[1] - https://developer.arm.com/documentation/den0118/a
[2] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
[3] - https://lists.denx.de/pipermail/u-boot/2022-June/485992.html

Changes since V6:
* Define the LOG_CATEGORY macro as suggested by Patrick
* Add some documentation in the fwu_get_mdata and fwu_update_mdata
  functions to describe the sequence of calls to be made for modifying
  the metadata, as suggested by Etienn
* Define the LOG_CATEGORY macro as suggested by Patrick
* s/STM32MP1/STM32MP15/ as suggested by Patrick


Sughosh Ganu (13):
  dt/bindings: Add bindings for FWU Metadata storage device
  FWU: Add FWU metadata structure and driver for accessing metadata
  FWU: Add FWU metadata access driver for GPT partitioned block devices
  stm32mp1: dk2: Add a node for the FWU metadata device
  stm32mp1: dk2: Add image information for capsule updates
  FWU: stm32mp1: Add helper functions for accessing FWU metadata
  FWU: STM32MP1: Add support to read boot index from backup register
  FWU: Add boot time checks as highlighted by the FWU specification
  FWU: Add support for the FWU Multi Bank Update feature
  FWU: cmd: Add a command to read FWU metadata
  mkeficapsule: Add support for generating empty capsules
  mkeficapsule: Add support for setting OEM flags in capsule header
  FWU: doc: Add documentation for the FWU feature

 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi  |   7 +
 arch/arm/mach-stm32mp/include/mach/stm32.h|   5 +
 board/st/stm32mp1/stm32mp1.c  |  67 +++
 cmd/Kconfig   |   7 +
 cmd/Makefile  |   1 +
 cmd/fwu_mdata.c   |  80 +++
 common/board_r.c  |   5 +
 doc/develop/uefi/fwu_updates.rst  | 156 ++
 doc/develop/uefi/index.rst|   1 +
 doc/develop/uefi/uefi.rst |   2 +
 .../firmware/fwu-mdata.yaml   |  32 ++
 doc/mkeficapsule.1|  33 +-
 drivers/Kconfig   |   2 +
 drivers/Makefile  |   1 +
 drivers/fwu-mdata/Kconfig |  16 +
 drivers/fwu-mdata/Makefile|   7 +
 drivers/fwu-mdata/fwu-mdata-uclass.c  | 469 ++
 drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 410 +++
 include/configs/stm32mp15_common.h|   4 +
 include/dm/uclass-id.h|   1 +
 include/fwu.h

Re: [PATCH v6 02/13] FWU: Add FWU metadata structure and driver for accessing metadata

2022-07-13 Thread Sughosh Ganu
hi Patrick,

On Wed, 13 Jul 2022 at 18:42, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 7/4/22 07:16, Sughosh Ganu wrote:
> > 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 a driver model
> > uclass which provides functions to access the metadata. These are
> > generic API's, and implementations can be added based on parameters
> > like how the metadata partition is accessed and what type of storage
> > device houses the metadata.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> > Changes since V5:
> > * Change the parameter to the function fwu_plat_get_alt_num to pass
> >the FWU udevice pointer instead of passing the metadata device
> >directly.
> >
> >   drivers/Kconfig  |   2 +
> >   drivers/Makefile |   1 +
> >   drivers/fwu-mdata/Kconfig|   7 +
> >   drivers/fwu-mdata/Makefile   |   6 +
> >   drivers/fwu-mdata/fwu-mdata-uclass.c | 458 +++
> >   include/dm/uclass-id.h   |   1 +
> >   include/fwu.h|  49 +++
> >   include/fwu_mdata.h  |  67 
> >   8 files changed, 591 insertions(+)
> >   create mode 100644 drivers/fwu-mdata/Kconfig
> >   create mode 100644 drivers/fwu-mdata/Makefile
> >   create mode 100644 drivers/fwu-mdata/fwu-mdata-uclass.c
> >   create mode 100644 include/fwu.h
> >   create mode 100644 include/fwu_mdata.h
> >
> > diff --git a/drivers/Kconfig b/drivers/Kconfig
> > index b26ca8cf70..adc6079ecf 100644
> > --- a/drivers/Kconfig
> > +++ b/drivers/Kconfig
> > @@ -42,6 +42,8 @@ source "drivers/firmware/Kconfig"
> >
> >   source "drivers/fpga/Kconfig"
> >
> > +source "drivers/fwu-mdata/Kconfig"
> > +
> >   source "drivers/gpio/Kconfig"
> >
> >   source "drivers/hwspinlock/Kconfig"
> > diff --git a/drivers/Makefile b/drivers/Makefile
> > index 67c8af7442..901150bb35 100644
> > --- a/drivers/Makefile
> > +++ b/drivers/Makefile
> > @@ -83,6 +83,7 @@ obj-y += cache/
> >   obj-$(CONFIG_CPU) += cpu/
> >   obj-y += crypto/
> >   obj-$(CONFIG_FASTBOOT) += fastboot/
> > +obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata/
> >   obj-y += misc/
> >   obj-$(CONFIG_MMC) += mmc/
> >   obj-$(CONFIG_NVME) += nvme/
> > diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
> > new file mode 100644
> > index 00..d6a21c8e19
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/Kconfig
> > @@ -0,0 +1,7 @@
> > +config DM_FWU_MDATA
> > + bool "Driver support for accessing FWU Metadata"
> > + depends on DM
> > + help
> > +   Enable support for accessing FWU Metadata partitions. The
> > +   FWU Metadata partitions reside on the same storage device
> > +   which contains the other FWU updatable firmware images.
> > diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
> > new file mode 100644
> > index 00..e53a8c9983
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/Makefile
> > @@ -0,0 +1,6 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (c) 2022, Linaro Limited
> > +#
> > +
> > +obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
> > diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c 
> > b/drivers/fwu-mdata/fwu-mdata-uclass.c
> > new file mode 100644
> > index 00..2092fcfc23
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
> > @@ -0,0 +1,458 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
>
> #define LOG_CATEGORY UCLASS_FWU_MDATA

Will add. Thanks.

-sughosh

>
>
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define IMAGE_ACCEPT_SET BIT(0)
> > +#define IMAGE_ACCEPT_CLEAR   BIT(1)
> > +
> > +static int fwu_get_dev_ops(struct udevice **dev,
> > +const struct fwu_mdata_ops **ops)
> > +{
> > + int ret;
> > +
> > + ret = uclass_get_device(UCLASS_FWU_MDATA, 0, dev);
> > + if (ret) {
> > + log_debug("Cannot find fwu device\n");
> > + return ret;
> > + }
> > +
> > + if ((*ops = device_get_ops(*dev)) == NULL) {
> > + log_debug("Cannot get fwu device ops\n");
> > + return -ENOSYS;
> > + }
> > +
> > + return 0;
> > +}
> > +
>
> (...)
>
> with this minor update
>
> Reviewed-by: Patrick Delaunay 
>
> Thanks
> Patrick
>


Re: [PATCH v6 03/13] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-07-13 Thread Sughosh Ganu
hi Patrick,

On Wed, 13 Jul 2022 at 18:47, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 7/4/22 07:16, Sughosh Ganu wrote:
> > 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 a driver for reading from and writing to the metadata
> > when the updatable images and the metadata are stored on a block
> > device which is formated with GPT based partition scheme.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> > Changes since V5:
> > * Changed the logic to store the GPT partitioned block device through
> >a priv structure as suggested by Patrick
> > * Used dev_read_prop() to get the phandle_p instead of
> >ofnode_get_property() used earlier as suggested by Patrick
> > * Make relevant functions static as suggested by Etienne
> >
> >   drivers/fwu-mdata/Kconfig |   9 +
> >   drivers/fwu-mdata/Makefile|   1 +
> >   drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 408 ++
> >   include/fwu.h |   5 +
> >   4 files changed, 423 insertions(+)
> >   create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> >
> > diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
> > index d6a21c8e19..d5edef19d6 100644
> > --- a/drivers/fwu-mdata/Kconfig
> > +++ b/drivers/fwu-mdata/Kconfig
> > @@ -5,3 +5,12 @@ config DM_FWU_MDATA
> > Enable support for accessing FWU Metadata partitions. The
> > FWU Metadata partitions reside on the same storage device
> > which contains the other FWU updatable firmware images.
> > +
> > +config FWU_MDATA_GPT_BLK
> > + bool "FWU Metadata access for GPT partitioned Block devices"
> > + select PARTITION_TYPE_GUID
> > + select PARTITION_UUIDS
> > + depends on DM && HAVE_BLOCK_DEVICE && EFI_PARTITION
> > + help
> > +   Enable support for accessing FWU Metadata on GPT partitioned
> > +   block devices.
> > diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
> > index e53a8c9983..313049f67a 100644
> > --- a/drivers/fwu-mdata/Makefile
> > +++ b/drivers/fwu-mdata/Makefile
> > @@ -4,3 +4,4 @@
> >   #
> >
> >   obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
> > +obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
> > diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
> > b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > new file mode 100644
> > index 00..d904c9492d
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > @@ -0,0 +1,408 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
>
> #define LOG_CATEGORY UCLASS_FWU_MDATA

I think you had mentioned this in your earlier review as well. Sorry,
I missed out on this. Will add in the next version.

>
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PRIMARY_PART BIT(0)
> > +#define SECONDARY_PART   BIT(1)
> > +#define BOTH_PARTS   (PRIMARY_PART | SECONDARY_PART)
> > +
> > +#define MDATA_READ   BIT(0)
> > +#define MDATA_WRITE  BIT(1)
> > +
>
> (...)
>
>
> > +
> > +static const struct fwu_mdata_ops fwu_gpt_blk_ops = {
> > + .mdata_check = fwu_gpt_mdata_check,
> > + .get_mdata = fwu_gpt_get_mdata,
> > + .update_mdata = fwu_gpt_update_mdata,
> > +};UCLASS_FWU_MDATA
> >
> > +
> > +static const struct udevice_id fwu_mdata_ids[] = {
> > + { .compatible = "u-boot,fwu-mdata-gpt" },
> > + { }
> > +};
> > +
> > +U_BOOT_DRIVER(fwu_mdata_gpt_blk) = {
> > + .name   = "fwu-mdata-gpt-blk",
> > + .id = UCLASS_FWU_MDATA,
> > + .of_match   = fwu_mdata_ids,
> > + .ops= _gpt_blk_ops,
> > + .probe  = fwu_mdata_gpt_blk_probe,
> > + .priv_auto  = sizeof(struct fwu_mdata_gpt_blk_priv),
> > +};
> > diff --git a/include/fwu.h b/include/fwu.h
> > index e03cfff800..8259c75d12 100644
> > --- a/include/fwu.h
> > +++ b/include/fwu.h
> > @@ -14,6 +14,10 @@
> >   struct fwu_mdata;
> >   struct udevice;
> >
&

Re: [PATCH v6 2/7] tpm: rng: Add driver model interface for TPM RNG device

2022-07-05 Thread Sughosh Ganu
hi Simon,

On Tue, 5 Jul 2022 at 15:17, Simon Glass  wrote:
>
> Hi Sughosh,
>
> On Mon, 4 Jul 2022 at 07:35, Sughosh Ganu  wrote:
> >
> > The TPM device has a builtin random number generator(RNG)
> > functionality. Expose the RNG functions of the TPM device to the
> > driver model so that they can be used by the EFI_RNG_PROTOCOL if the
> > protocol is installed.
> >
> > Also change the function arguments and return type of the random
> > number functions to comply with the driver model api.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> > Changes since V5:
> > * Use the dev_get_parent() interface for getting the TPM device when
> >   calling the tpm_get_random() function
> >
> >  drivers/rng/Kconfig   | 11 +++
> >  drivers/rng/Makefile  |  1 +
> >  drivers/rng/tpm_rng.c | 23 +++
> >  lib/Kconfig   |  1 +
> >  lib/tpm-v1.c  | 13 +++--
> >  lib/tpm-v2.c  |  6 +++---
> >  lib/tpm_api.c |  6 +++---
> >  7 files changed, 49 insertions(+), 12 deletions(-)
> >  create mode 100644 drivers/rng/tpm_rng.c
>
> The API change should not be needed. The code that calls the TPM
> routines should adapt for that.

Are you referring to the changes made in tpm[1,2]_get_random
functions? If so, those changes in the return values have been made
based on review comments from Heinrich[1]. If you are referring to
some other changes, please let me know. Thanks.

-sughosh

[1] - https://lists.denx.de/pipermail/u-boot/2022-February/476085.html

>
> Regards,
> Simon


[PATCH v6 7/7] test: rng: Add a UT testcase for the rng command

2022-07-04 Thread Sughosh Ganu
The 'rng' command dumps a number of random bytes on the console. Add a
set of tests for the 'rng' command. The test function performs basic
sanity testing of the command.

Since a unit test is being added for the command, enable it by default
in the sandbox platforms.

Reviewed-by: Simon Glass 
Signed-off-by: Sughosh Ganu 
---
 cmd/Kconfig   |  1 +
 test/dm/rng.c | 29 +
 2 files changed, 30 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..eee5d44348 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1916,6 +1916,7 @@ config CMD_GETTIME
 config CMD_RNG
bool "rng command"
depends on DM_RNG
+   default y if SANDBOX
select HEXDUMP
help
  Print bytes from the hardware random number generator.
diff --git a/test/dm/rng.c b/test/dm/rng.c
index 5b34c93ed6..6d1f68848d 100644
--- a/test/dm/rng.c
+++ b/test/dm/rng.c
@@ -25,3 +25,32 @@ static int dm_test_rng_read(struct unit_test_state *uts)
return 0;
 }
 DM_TEST(dm_test_rng_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Test the rng command */
+static int dm_test_rng_cmd(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+
+   ut_assertok(uclass_get_device(UCLASS_RNG, 0, ));
+   ut_assertnonnull(dev);
+
+   ut_assertok(console_record_reset_enable());
+
+   run_command("rng", 0);
+   ut_assert_nextlinen(":");
+   ut_assert_nextlinen("0010:");
+   ut_assert_nextlinen("0020:");
+   ut_assert_nextlinen("0030:");
+   ut_assert_console_end();
+
+   run_command("rng 0 10", 0);
+   ut_assert_nextlinen(":");
+   ut_assert_console_end();
+
+   run_command("rng 20", 0);
+   ut_assert_nextlinen("No RNG device");
+   ut_assert_console_end();
+
+   return 0;
+}
+DM_TEST(dm_test_rng_cmd, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | 
UT_TESTF_CONSOLE_REC);
-- 
2.25.1



[PATCH v6 6/7] doc: rng: Add documentation for the rng command

2022-07-04 Thread Sughosh Ganu
Add a usage document for the 'rng' u-boot command.

Reviewed-by: Ilias Apalodimas 
Reviewed-by: Simon Glass 
Signed-off-by: Sughosh Ganu 
---
Changes since V5: None

 doc/usage/cmd/rng.rst | 26 ++
 doc/usage/index.rst   |  1 +
 2 files changed, 27 insertions(+)
 create mode 100644 doc/usage/cmd/rng.rst

diff --git a/doc/usage/cmd/rng.rst b/doc/usage/cmd/rng.rst
new file mode 100644
index 00..1a352da41a
--- /dev/null
+++ b/doc/usage/cmd/rng.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+rng command
+===
+
+Synopsis
+
+
+::
+
+rng [devnum [n]]
+
+Description
+---
+
+The *rng* command reads the random number generator(RNG) device and
+prints the random bytes read on the console. A maximum of 64 bytes can
+be read in one invocation of the command.
+
+devnum
+The RNG device from which the random bytes are to be
+read. Defaults to 0.
+
+n
+Number of random bytes to be read and displayed on the
+console. Default value is 0x40. Max value is 0x40.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 770418434a..ed3a78aa14 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -53,6 +53,7 @@ Shell commands
cmd/pstore
cmd/qfw
cmd/reset
+   cmd/rng
cmd/sbi
cmd/sf
cmd/scp03
-- 
2.25.1



[PATCH v6 5/7] cmd: rng: Use a statically allocated array for random bytes

2022-07-04 Thread Sughosh Ganu
Use a statically allocated buffer on stack instead of using malloc for
reading the random bytes. Using a local array is faster than
allocating heap memory on every initiation of the command.

Signed-off-by: Sughosh Ganu 
---
Changes since V5: None

 cmd/rng.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/cmd/rng.c b/cmd/rng.c
index 2ddf27545f..81a23964b8 100644
--- a/cmd/rng.c
+++ b/cmd/rng.c
@@ -14,9 +14,9 @@
 static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const 
argv[])
 {
size_t n;
-   struct udevice *dev;
-   void *buf;
+   u8 buf[64];
int devnum;
+   struct udevice *dev;
int ret = CMD_RET_SUCCESS;
 
switch (argc) {
@@ -41,11 +41,10 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
return CMD_RET_FAILURE;
}
 
-   buf = malloc(n);
-   if (!buf) {
-   printf("Out of memory\n");
-   return CMD_RET_FAILURE;
-   }
+   if (!n)
+   return 0;
+
+   n = min(n, sizeof(buf));
 
if (dm_rng_read(dev, buf, n)) {
printf("Reading RNG failed\n");
@@ -54,15 +53,13 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, n);
}
 
-   free(buf);
-
return ret;
 }
 
 #ifdef CONFIG_SYS_LONGHELP
 static char rng_help_text[] =
"[dev [n]]\n"
-   "  - print n random bytes read from dev\n";
+   "  - print n random bytes(max 64) read from dev\n";
 #endif
 
 U_BOOT_CMD(
-- 
2.25.1



[PATCH v6 4/7] cmd: rng: Add support for selecting RNG device

2022-07-04 Thread Sughosh Ganu
The 'rng' u-boot command is used for printing a select number of
random bytes on the console. Currently, the RNG device from which the
random bytes are read is fixed. However, a platform can have multiple
RNG devices, one example being qemu, which has a virtio RNG device and
the RNG pseudo device through the TPM chip.

Extend the 'rng' command so that the user can provide the RNG device
number from which the random bytes are to be read. This will be the
device index under the RNG uclass.

Tested-by: Heinrich Schuchardt 
Reviewed-by: Ilias Apalodimas 
Signed-off-by: Sughosh Ganu 
---
Changes since V5: None

 cmd/rng.c | 31 +++
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/cmd/rng.c b/cmd/rng.c
index 1ad5a096c0..2ddf27545f 100644
--- a/cmd/rng.c
+++ b/cmd/rng.c
@@ -13,19 +13,34 @@
 
 static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const 
argv[])
 {
-   size_t n = 0x40;
+   size_t n;
struct udevice *dev;
void *buf;
+   int devnum;
int ret = CMD_RET_SUCCESS;
 
-   if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) {
+   switch (argc) {
+   case 1:
+   devnum = 0;
+   n = 0x40;
+   break;
+   case 2:
+   devnum = hextoul(argv[1], NULL);
+   n = 0x40;
+   break;
+   case 3:
+   devnum = hextoul(argv[1], NULL);
+   n = hextoul(argv[2], NULL);
+   break;
+   default:
+   return CMD_RET_USAGE;
+   }
+
+   if (uclass_get_device_by_seq(UCLASS_RNG, devnum, ) || !dev) {
printf("No RNG device\n");
return CMD_RET_FAILURE;
}
 
-   if (argc >= 2)
-   n = hextoul(argv[1], NULL);
-
buf = malloc(n);
if (!buf) {
printf("Out of memory\n");
@@ -46,12 +61,12 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
 
 #ifdef CONFIG_SYS_LONGHELP
 static char rng_help_text[] =
-   "[n]\n"
-   "  - print n random bytes\n";
+   "[dev [n]]\n"
+   "  - print n random bytes read from dev\n";
 #endif
 
 U_BOOT_CMD(
-   rng, 2, 0, do_rng,
+   rng, 3, 0, do_rng,
"print bytes from the hardware random number generator",
rng_help_text
 );
-- 
2.25.1



[PATCH v6 3/7] tpm: Add the RNG child device

2022-07-04 Thread Sughosh Ganu
The TPM device comes with the random number generator(RNG)
functionality which is built into the TPM device. Add logic to add the
RNG child device in the TPM uclass post probe callback.

The RNG device can then be used to pass a set of random bytes to the
linux kernel, need for address space randomisation through the
EFI_RNG_PROTOCOL interface.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Check if the TPM RNG device has already been added, through a call
  to device_find_first_child_by_uclass()

 drivers/tpm/tpm-uclass.c | 37 +
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index f67fe1019b..e1f1ef01e1 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -11,10 +11,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "tpm_internal.h"
 
+#include 
+
+#define TPM_RNG_DRV_NAME   "tpm-rng"
+
 int tpm_open(struct udevice *dev)
 {
struct tpm_ops *ops = tpm_get_ops(dev);
@@ -136,12 +141,36 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, 
size_t send_size,
return 0;
 }
 
+static int tpm_uclass_post_probe(struct udevice *dev)
+{
+   int ret;
+   const char *drv = TPM_RNG_DRV_NAME;
+   struct udevice *child;
+
+   if (CONFIG_IS_ENABLED(TPM_RNG)) {
+   ret = device_find_first_child_by_uclass(dev, UCLASS_RNG,
+   );
+
+   if (ret != -ENODEV) {
+   log_debug("RNG child already added to the TPM 
device\n");
+   return ret;
+   }
+
+   ret = device_bind_driver(dev, drv, "tpm-rng0", );
+   if (ret)
+   return log_msg_ret("bind", ret);
+   }
+
+   return 0;
+}
+
 UCLASS_DRIVER(tpm) = {
-   .id = UCLASS_TPM,
-   .name   = "tpm",
-   .flags  = DM_UC_FLAG_SEQ_ALIAS,
+   .id = UCLASS_TPM,
+   .name   = "tpm",
+   .flags  = DM_UC_FLAG_SEQ_ALIAS,
 #if CONFIG_IS_ENABLED(OF_REAL)
-   .post_bind  = dm_scan_fdt_dev,
+   .post_bind  = dm_scan_fdt_dev,
 #endif
+   .post_probe = tpm_uclass_post_probe,
.per_device_auto= sizeof(struct tpm_chip_priv),
 };
-- 
2.25.1



[PATCH v6 2/7] tpm: rng: Add driver model interface for TPM RNG device

2022-07-04 Thread Sughosh Ganu
The TPM device has a builtin random number generator(RNG)
functionality. Expose the RNG functions of the TPM device to the
driver model so that they can be used by the EFI_RNG_PROTOCOL if the
protocol is installed.

Also change the function arguments and return type of the random
number functions to comply with the driver model api.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Use the dev_get_parent() interface for getting the TPM device when
  calling the tpm_get_random() function

 drivers/rng/Kconfig   | 11 +++
 drivers/rng/Makefile  |  1 +
 drivers/rng/tpm_rng.c | 23 +++
 lib/Kconfig   |  1 +
 lib/tpm-v1.c  | 13 +++--
 lib/tpm-v2.c  |  6 +++---
 lib/tpm_api.c |  6 +++---
 7 files changed, 49 insertions(+), 12 deletions(-)
 create mode 100644 drivers/rng/tpm_rng.c

diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index c10f7d345b..67c65311c7 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -58,4 +58,15 @@ config RNG_IPROC200
depends on DM_RNG
help
  Enable random number generator for RPI4.
+
+config TPM_RNG
+   bool "Enable random number generator on TPM device"
+   depends on TPM
+   default y
+   help
+ The TPM device has an inbuilt random number generator
+ functionality. Enable random number generator on TPM
+ devices.
+
+
 endif
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 435b3b965a..e4ca9c4149 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_RNG_OPTEE) += optee_rng.o
 obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
 obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
 obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
+obj-$(CONFIG_TPM_RNG) += tpm_rng.o
diff --git a/drivers/rng/tpm_rng.c b/drivers/rng/tpm_rng.c
new file mode 100644
index 00..1a5e9e2e4b
--- /dev/null
+++ b/drivers/rng/tpm_rng.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+
+static int rng_tpm_random_read(struct udevice *dev, void *data, size_t count)
+{
+   return tpm_get_random(dev_get_parent(dev), data, count);
+}
+
+static const struct dm_rng_ops tpm_rng_ops = {
+   .read = rng_tpm_random_read,
+};
+
+U_BOOT_DRIVER(tpm_rng) = {
+   .name   = "tpm-rng",
+   .id = UCLASS_RNG,
+   .ops= _rng_ops,
+};
diff --git a/lib/Kconfig b/lib/Kconfig
index acc0ac081a..17efaa4c80 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -358,6 +358,7 @@ source lib/crypt/Kconfig
 config TPM
bool "Trusted Platform Module (TPM) Support"
depends on DM
+   imply DM_RNG
help
  This enables support for TPMs which can be used to provide security
  features for your board. The TPM can be connected via LPC or I2C
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
index 22a769c587..f7091e5bc7 100644
--- a/lib/tpm-v1.c
+++ b/lib/tpm-v1.c
@@ -9,12 +9,13 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
 #include 
 #include "tpm-utils.h"
 
+#include 
+#include 
+
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 
 #ifndef CONFIG_SHA1
@@ -892,19 +893,19 @@ u32 tpm1_get_random(struct udevice *dev, void *data, u32 
count)
if (pack_byte_string(buf, sizeof(buf), "sd",
 0, command, sizeof(command),
 length_offset, this_bytes))
-   return TPM_LIB_ERROR;
+   return -EIO;
err = tpm_sendrecv_command(dev, buf, response,
   _length);
if (err)
return err;
if (unpack_byte_string(response, response_length, "d",
   data_size_offset, _size))
-   return TPM_LIB_ERROR;
+   return -EIO;
if (data_size > count)
-   return TPM_LIB_ERROR;
+   return -EIO;
if (unpack_byte_string(response, response_length, "s",
   data_offset, out, data_size))
-   return TPM_LIB_ERROR;
+   return -EIO;
 
count -= data_size;
out += data_size;
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 1bf627853a..abca9a14b0 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -585,19 +585,19 @@ u32 tpm2_get_random(struct udevice *dev, void *data, u32 
count)
if (pack_byte_string(buf, sizeof(buf), "sw",
 0, command_v2, sizeof(command_v2),
 sizeof(command_v2), this_bytes))
-   return TPM_LIB_ERROR;
+   return -EIO;
err = tpm_send

[PATCH v6 0/7] tpm: rng: Move TPM RNG functionality to driver model

2022-07-04 Thread Sughosh Ganu


The TPM device provides the random number generator(RNG)
functionality, whereby sending a command to the TPM device results in
the TPM device responding with random bytes.

There was a discussion on the mailing list earlier[1], where it was
explained that platforms with a TPM device can install the
EFI_RNG_PROTOCOL for getting the random bytes instead of populating
the dtb with the kaslr-seed property. That would make it possible to
measure the dtb.

The TPM uclass driver adds the RNG child device as part of it's
post_probe function.

Some additional changes have also been made to facilitate the
use of the RNG devices, including extending the 'rng' command to take
the RNG device as one of the command-line parameters.

This series depends on a patch[2] from Simon Glass for moving the TPM
device version detection functions to the tpm_api.h header as static
inline functions.

These patches were under discussion earlier, specifically the patch to
add the RNG functionality under the TPM device as a child, either
through manual binding or through the device tree. Ilias had commented
on the discussion last[3]. The discussion can be resumed through this
version.

I have dropped certain patches which were changing some of the TPM API
functions to return an int instead of the current u32. These patches
have been dropped due to review comments from Simon[4]. This work can
be taken up separately, if desired.

[1] - 
https://lore.kernel.org/u-boot/20220103120738.47835-1-ilias.apalodi...@linaro.org/
[2] - 
https://lore.kernel.org/u-boot/20220301001125.1554442-2-...@chromium.org/T/#u
[3] - https://lists.denx.de/pipermail/u-boot/2022-April/481708.html
[4] - https://lists.denx.de/pipermail/u-boot/2022-March/477883.html

Simon Glass (1):
  tpm: Export the TPM-version functions

Sughosh Ganu (6):
  tpm: rng: Add driver model interface for TPM RNG device
  tpm: Add the RNG child device
  cmd: rng: Add support for selecting RNG device
  cmd: rng: Use a statically allocated array for random bytes
  doc: rng: Add documentation for the rng command
  test: rng: Add a UT testcase for the rng command

 cmd/Kconfig  |  1 +
 cmd/rng.c| 42 +++--
 doc/usage/cmd/rng.rst| 26 +++
 doc/usage/index.rst  |  1 +
 drivers/rng/Kconfig  | 11 +
 drivers/rng/Makefile |  1 +
 drivers/rng/tpm_rng.c| 23 ++
 drivers/tpm/tpm-uclass.c | 37 +--
 include/tpm_api.h| 10 
 lib/Kconfig  |  1 +
 lib/tpm-v1.c | 13 +++---
 lib/tpm-v2.c |  6 +--
 lib/tpm_api.c| 98 ++--
 test/dm/rng.c| 29 
 14 files changed, 217 insertions(+), 82 deletions(-)
 create mode 100644 doc/usage/cmd/rng.rst
 create mode 100644 drivers/rng/tpm_rng.c

-- 
2.25.1




[PATCH v6 1/7] tpm: Export the TPM-version functions

2022-07-04 Thread Sughosh Ganu
From: Simon Glass 

These functions should really be available outside the TPM code, so that
other callers can find out which version the TPM is. Rename them to have
a tpm_ prefix() and add them to the header file.

Signed-off-by: Simon Glass 
---
Changes since V5: None

 include/tpm_api.h | 10 ++
 lib/tpm_api.c | 92 +--
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/include/tpm_api.h b/include/tpm_api.h
index ef45b43a8f..11aa14eb79 100644
--- a/include/tpm_api.h
+++ b/include/tpm_api.h
@@ -319,4 +319,14 @@ u32 tpm_write_lock(struct udevice *dev, u32 index);
  */
 u32 tpm_resume(struct udevice *dev);
 
+static inline bool tpm_is_v1(struct udevice *dev)
+{
+   return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
+}
+
+static inline bool tpm_is_v2(struct udevice *dev)
+{
+   return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
+}
+
 #endif /* __TPM_API_H */
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 4c662640a9..4ac4612c81 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -11,21 +11,11 @@
 #include 
 #include 
 
-static bool is_tpm1(struct udevice *dev)
-{
-   return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
-}
-
-static bool is_tpm2(struct udevice *dev)
-{
-   return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
-}
-
 u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
 {
-   if (is_tpm1(dev)) {
+   if (tpm_is_v1(dev)) {
return tpm1_startup(dev, mode);
-   } else if (is_tpm2(dev)) {
+   } else if (tpm_is_v2(dev)) {
enum tpm2_startup_types type;
 
switch (mode) {
@@ -47,9 +37,9 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type 
mode)
 
 u32 tpm_resume(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_startup(dev, TPM_ST_STATE);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_startup(dev, TPM2_SU_STATE);
else
return -ENOSYS;
@@ -57,9 +47,9 @@ u32 tpm_resume(struct udevice *dev)
 
 u32 tpm_self_test_full(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_self_test_full(dev);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_self_test(dev, TPMI_YES);
else
return -ENOSYS;
@@ -67,9 +57,9 @@ u32 tpm_self_test_full(struct udevice *dev)
 
 u32 tpm_continue_self_test(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_continue_self_test(dev);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_self_test(dev, TPMI_NO);
else
return -ENOSYS;
@@ -86,7 +76,7 @@ u32 tpm_clear_and_reenable(struct udevice *dev)
return ret;
}
 
-   if (is_tpm1(dev)) {
+   if (tpm_is_v1(dev)) {
ret = tpm1_physical_enable(dev);
if (ret != TPM_SUCCESS) {
log_err("TPM: Can't set enabled state\n");
@@ -105,9 +95,9 @@ u32 tpm_clear_and_reenable(struct udevice *dev)
 
 u32 tpm_nv_enable_locking(struct udevice *dev)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return -ENOSYS;
else
return -ENOSYS;
@@ -115,9 +105,9 @@ u32 tpm_nv_enable_locking(struct udevice *dev)
 
 u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_read_value(dev, index, data, count);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_nv_read_value(dev, index, data, count);
else
return -ENOSYS;
@@ -126,9 +116,9 @@ u32 tpm_nv_read_value(struct udevice *dev, u32 index, void 
*data, u32 count)
 u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
   u32 count)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return tpm1_nv_write_value(dev, index, data, count);
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_nv_write_value(dev, index, data, count);
else
return -ENOSYS;
@@ -141,9 +131,9 @@ u32 tpm_set_global_lock(struct udevice *dev)
 
 u32 tpm_write_lock(struct udevice *dev, u32 index)
 {
-   if (is_tpm1(dev))
+   if (tpm_is_v1(dev))
return -ENOSYS;
-   else if (is_tpm2(dev))
+   else if (tpm_is_v2(dev))
return tpm2_write_lock(dev, index);
else
return -ENOSYS;
@@ -152,9 +142,9 @@ u32 tpm_write_lock(struct udevice *dev, u32 index)
 u32 

[PATCH v6 13/13] FWU: doc: Add documentation for the FWU feature

2022-07-03 Thread Sughosh Ganu
Add documentattion for the FWU Multi Bank Update feature. The document
describes the steps needed for setting up the platform for the
feature, as well as steps for enabling the feature on the platform.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Add some description about the reasoning for accept capsule needing
  image GUID as suggested by Takahiro

 doc/develop/uefi/fwu_updates.rst | 156 +++
 doc/develop/uefi/index.rst   |   1 +
 doc/develop/uefi/uefi.rst|   2 +
 3 files changed, 159 insertions(+)
 create mode 100644 doc/develop/uefi/fwu_updates.rst

diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst
new file mode 100644
index 00..57d1b5b703
--- /dev/null
+++ b/doc/develop/uefi/fwu_updates.rst
@@ -0,0 +1,156 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (c) 2022 Linaro Limited
+
+FWU Multi Bank Updates in U-Boot
+
+
+The FWU Multi Bank Update feature implements the firmware update
+mechanism described in the PSA Firmware Update for A-profile Arm
+Architecture specification[1]. Certain aspects of the Dependable
+Boot specification[2] are also implemented. The feature provides a
+mechanism to have multiple banks of updatable firmware images and for
+updating the firmware images on the non-booted bank. On a successful
+update, the platform boots from the updated bank on subsequent
+boot. The UEFI capsule-on-disk update feature is used for performing
+the actual updates of the updatable firmware images.
+
+The bookkeeping of the updatable images is done through a structure
+called metadata. Currently, the FWU metadata supports identification
+of images based on image GUIDs stored on a GPT partitioned storage
+media. There are plans to extend the metadata structure for non GPT
+partitioned devices as well.
+
+Accessing the FWU metadata is done through generic API's which are
+defined in a driver which complies with the u-boot's driver model. A
+new uclass UCLASS_FWU_MDATA has been added for accessing the FWU
+metadata. Individual drivers can be added based on the type of storage
+media, and it's partitioning method. Details of the storage device
+containing the FWU metadata partitions are specified through a U-Boot
+specific device tree property `fwu-mdata-store`. Please refer to
+U-Boot `doc `__ for
+the device tree bindings.
+
+Enabling the FWU Multi Bank Update feature
+--
+
+The feature can be enabled by specifying the following configs::
+
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y
+CONFIG_EFI_CAPSULE_FIRMWARE=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+CONFIG_CMD_FWU_METADATA=y
+CONFIG_DM_FWU_MDATA=y
+CONFIG_FWU_MDATA_GPT_BLK=y
+CONFIG_FWU_NUM_BANKS=
+CONFIG_FWU_NUM_IMAGES_PER_BANK=
+
+in the .config file
+
+The first group of configs enable the UEFI capsule-on-disk update
+functionality. The second group of configs enable the FWU Multi Bank
+Update functionality. Please refer to the section
+:ref:`uefi_capsule_update_ref` for more details on generation of the
+UEFI capsule.
+
+Setting up the device for GPT partitioned storage
+-
+
+Before enabling the functionality in U-Boot, certain changes are
+required to be done on the storage device. Assuming a GPT partitioned
+storage device, the storage media needs to be partitioned with the
+correct number of partitions, given the number of banks and number of
+images per bank that the platform is going to support. Each updatable
+firmware image will be stored on an separate partition. In addition,
+the two copies of the FWU metadata will be stored on two separate
+partitions.
+
+As an example, a platform supporting two banks with each bank
+containing three images would need to have 2 * 3 = 6 parititions plus
+the two metadata partitions, or 8 partitions. In addition the storage
+media can have additional partitions of non-updatable images, like the
+EFI System Partition(ESP), a partition for the root file system etc.
+
+When generating the partitions, a few aspects need to be taken care
+of. Each GPT partition entry in the GPT header has two GUIDs::
+
+*PartitionTypeGUID*
+*UniquePartitionGUID*
+
+The PartitionTypeGUID value should correspond to the *image_type_uuid*
+field of the FWU metadata. This field is used to identify a given type
+of updatable firmware image, e.g. u-boot, op-tee, FIP etc. This GUID
+should also be used for specifying the `--guid` parameter when
+generating the capsule.
+
+The UniquePartitionGUID value should correspond to the *image_uuid*
+field in the FWU metadata. This GUID is used to identify images of a
+given image type in different banks.
+
+Similarly, the FWU specifications defines the GUID value to be used
+for the metadata partitions. This would be the PartitionTypeGUID for
+the metadata partitions.
+
+When

[PATCH v6 12/13] mkeficapsule: Add support for setting OEM flags in capsule header

2022-07-03 Thread Sughosh Ganu
Add support for setting OEM flags in the capsule header. As per the
UEFI specification, bits 0-15 of the flags member of the capsule
header can be defined per capsule GUID.

The oemflags will be used for the FWU Multi Bank update feature, as
specified by the Dependable Boot specification[1]. Bit
15 of the flags member will be used to determine if the
acceptance/rejection of the updated images is to be done by the
firmware or an external component like the OS.

[1] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Signed-off-by: Sughosh Ganu 
---
Changes since V5: None

 doc/mkeficapsule.1   |  4 
 tools/mkeficapsule.c | 17 ++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index 77ca061efd..6fb2dd0810 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -72,6 +72,10 @@ Generate a firmware acceptance empty capsule
 .BI "-R\fR,\fB --fw-revert "
 Generate a firmware revert empty capsule
 
+.TP
+.BI "-o\fR,\fB --capoemflag "
+Capsule OEM flag, value between 0x to 0x
+
 .TP
 .BR -h ", " --help
 Print a help message
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 244c80e1f7..237c1218fd 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule";
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
+static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR";
 
 enum {
CAPSULE_NORMAL_BLOB = 0,
@@ -47,6 +47,7 @@ static struct option options[] = {
{"dump-sig", no_argument, NULL, 'd'},
{"fw-accept", no_argument, NULL, 'A'},
{"fw-revert", no_argument, NULL, 'R'},
+   {"capoemflag", required_argument, NULL, 'o'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
 };
@@ -65,6 +66,7 @@ static void print_usage(void)
"\t-d, --dump_sig  dump signature (*.p7)\n"
"\t-A, --fw-accept  firmware accept capsule, requires GUID, no 
image blob\n"
"\t-R, --fw-revert  firmware revert capsule, takes no GUID, no 
image blob\n"
+   "\t-o, --capoemflag Capsule OEM Flag, an integer between 0x 
and 0x\n"
"\t-h, --help  print a help message\n",
tool_name);
 }
@@ -387,6 +389,7 @@ static void free_sig_data(struct auth_context *ctx)
  * @mcount:Monotonic count in authentication information
  * @private_file:  Path to a private key file
  * @cert_file: Path to a certificate file
+ * @oemflags:  Capsule OEM Flags, bits 0-15
  *
  * This function actually does the job of creating an uefi capsule file.
  * All the arguments must be supplied.
@@ -399,7 +402,8 @@ static void free_sig_data(struct auth_context *ctx)
  */
 static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
unsigned long index, unsigned long instance,
-   uint64_t mcount, char *privkey_file, char *cert_file)
+   uint64_t mcount, char *privkey_file, char *cert_file,
+   uint16_t oemflags)
 {
struct efi_capsule_header header;
struct efi_firmware_management_capsule_header capsule;
@@ -464,6 +468,8 @@ static int create_fwbin(char *path, char *bin, efi_guid_t 
*guid,
header.header_size = sizeof(header);
/* TODO: The current implementation ignores flags */
header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
+   if (oemflags)
+   header.flags |= oemflags;
header.capsule_image_size = sizeof(header)
+ sizeof(capsule) + sizeof(uint64_t)
+ sizeof(image)
@@ -635,6 +641,7 @@ int main(int argc, char **argv)
unsigned char uuid_buf[16];
unsigned long index, instance;
uint64_t mcount;
+   uint16_t oemflags;
char *privkey_file, *cert_file;
int c, idx;
 
@@ -646,6 +653,7 @@ int main(int argc, char **argv)
cert_file = NULL;
dump_sig = 0;
capsule_type = CAPSULE_NORMAL_BLOB;
+   oemflags = 0;
for (;;) {
c = getopt_long(argc, argv, opts_short, options, );
if (c == -1)
@@ -699,6 +707,9 @@ int main(int argc, char **argv)
case 'R':
capsule_type |= CAPSULE_REVERT;
break;
+   case 'o':
+   oemflags = strtoul(optarg, NULL, 0);
+   break;
default:
print_usage();
   

[PATCH v6 11/13] mkeficapsule: Add support for generating empty capsules

2022-07-03 Thread Sughosh Ganu
The Dependable Boot specification[1] describes the structure of the
firmware accept and revert capsules. These are empty capsules which
are used for signalling the acceptance or rejection of the updated
firmware by the OS. Add support for generating these empty capsules.

[1] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Use capsule_type instead of capsule variable that was created
  earlier to check for the type of capsule
* Remove use of payload variable in create_empty_capsule() as
  suggested by Etienne
* Initialise the struct efi_capsule_header as suggested by Etienne

 doc/mkeficapsule.1   | 29 ++
 tools/eficapsule.h   |  8 
 tools/mkeficapsule.c | 92 
 3 files changed, 115 insertions(+), 14 deletions(-)

diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index 09bdc24295..77ca061efd 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
 
 .SH SYNOPSIS
 .B mkeficapsule
-.RI [ options "] " image-blob " " capsule-file
+.RI [ options ] " " [ image-blob ] " " capsule-file
 
 .SH "DESCRIPTION"
 .B mkeficapsule
@@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given 
private key.
 In this case, the update will be authenticated by verifying the signature
 before applying.
 
+Additionally, an empty capsule file can be generated for acceptance or
+rejection of firmware images by a governing component like an Operating
+System. The empty capsules do not require an image-blob input file.
+
+
 .B mkeficapsule
-takes any type of image files, including:
+takes any type of image files when generating non empty capsules, including:
 .TP
 .I raw image
 format is a single binary blob of any type of firmware.
@@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
 This type of image file can be generated by
 .BR mkimage .
 
-.PP
-If you want to use other types than above two, you should explicitly
-specify a guid for the FMP driver.
-
 .SH "OPTIONS"
+
 .TP
 .BI "-g\fR,\fB --guid " guid-string
 Specify guid for image blob type. The format is:
 ----
 
 The first three elements are in little endian, while the rest
-is in big endian.
+is in big endian. The option must be specified for all non empty and
+image acceptance capsules
 
 .TP
 .BI "-i\fR,\fB --index " index
@@ -57,6 +60,18 @@ Specify an image index
 .BI "-I\fR,\fB --instance " instance
 Specify a hardware instance
 
+.PP
+For generation of firmware accept empty capsule
+.BR --guid
+is mandatory
+.TP
+.BI "-A\fR,\fB --fw-accept "
+Generate a firmware acceptance empty capsule
+
+.TP
+.BI "-R\fR,\fB --fw-revert "
+Generate a firmware revert empty capsule
+
 .TP
 .BR -h ", " --help
 Print a help message
diff --git a/tools/eficapsule.h b/tools/eficapsule.h
index d63b831443..072a4b5598 100644
--- a/tools/eficapsule.h
+++ b/tools/eficapsule.h
@@ -41,6 +41,14 @@ typedef struct {
EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \
 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
 
+#define FW_ACCEPT_OS_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
+#define FW_REVERT_OS_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
 /* flags */
 #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET  0x0001
 
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 5f74d23b9e..244c80e1f7 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,13 @@ static const char *tool_name = "mkeficapsule";
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:dh";
+static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
+
+enum {
+   CAPSULE_NORMAL_BLOB = 0,
+   CAPSULE_ACCEPT,
+   CAPSULE_REVERT,
+} capsule_type;
 
 static struct option options[] = {
{"guid", required_argument, NULL, 'g'},
@@ -39,6 +45,8 @@ static struct option options[] = {
{"certificate", required_argument, NULL, 'c'},
{"monotonic-count", required_argument, NULL, 'm'},
{"dump-sig", no_argument, NULL, 'd'},
+   {"fw-accept", no_argument, NULL, 'A'},
+   {"fw-revert", no_argument, NULL, 'R'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
 };
@@ -55,6 +63,8 @@ static void print_usage(void)
"\t-c, --certificate  signer's certificate 
file\n"
"\t-m, --monotonic-count  m

[PATCH v6 10/13] FWU: cmd: Add a command to read FWU metadata

2022-07-03 Thread Sughosh Ganu
Add a command to read the metadata as specified in the FWU
specification and print the fields of the metadata.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Do a metadata validity check by calling fwu_mdata_check() before
  printing the FWU metadata as suggested by Michal
* Use ret and res variables in do_fwu_mdata_read() as suggested by
  Patrick
* Change 'default y if FWU_MULTI_BANK_UPDATE' to default y as
  suggested by Patrick

 cmd/Kconfig |  7 +
 cmd/Makefile|  1 +
 cmd/fwu_mdata.c | 80 +
 3 files changed, 88 insertions(+)
 create mode 100644 cmd/fwu_mdata.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..1a287d528f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -144,6 +144,13 @@ config CMD_CPU
  internal name) and clock frequency. Other information may be
  available depending on the CPU driver.
 
+config CMD_FWU_METADATA
+   bool "fwu metadata read"
+   depends on FWU_MULTI_BANK_UPDATE
+   default y
+   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 5e43a1e022..259a93bc65 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o
 obj-$(CONFIG_CMD_FPGAD) += fpgad.o
 obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
+obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
 obj-$(CONFIG_CMD_HVC) += smccc.o
diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c
new file mode 100644
index 00..ee9d035374
--- /dev/null
+++ b/cmd/fwu_mdata.c
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static void print_mdata(struct fwu_mdata *mdata)
+{
+   int i, j;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_info;
+
+   printf("\tFWU Metadata\n");
+   printf("crc32: %#x\n", mdata->crc32);
+   printf("version: %#x\n", mdata->version);
+   printf("active_index: %#x\n", mdata->active_index);
+   printf("previous_active_index: %#x\n", mdata->previous_active_index);
+
+   printf("\tImage Info\n");
+   for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) {
+   img_entry = >img_entry[i];
+   printf("\nImage Type Guid: %pUL\n",
+  _entry->image_type_uuid);
+   printf("Location Guid: %pUL\n", _entry->location_uuid);
+   for (j = 0; j < CONFIG_FWU_NUM_BANKS; j++) {
+   img_info = _entry->img_bank_info[j];
+   printf("Image Guid:  %pUL\n", _info->image_uuid);
+   printf("Image Acceptance: %s\n",
+  img_info->accepted == 0x1 ? "yes" : "no");
+   }
+   }
+}
+
+int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag,
+int argc, char * const argv[])
+{
+   struct udevice *dev;
+   int ret = CMD_RET_SUCCESS, res;
+   struct fwu_mdata *mdata = NULL;
+
+   if (uclass_get_device(UCLASS_FWU_MDATA, 0, ) || !dev) {
+   log_err("Unable to get FWU metadata device\n");
+   return CMD_RET_FAILURE;
+   }
+
+   res = fwu_mdata_check();
+   if (res < 0) {
+   log_err("FWU Metadata check failed\n");
+   ret = CMD_RET_FAILURE;
+   goto out;
+   }
+
+   res = fwu_get_mdata();
+   if (res < 0) {
+   log_err("Unable to get valid FWU metadata\n");
+   ret = CMD_RET_FAILURE;
+   goto out;
+   }
+
+   print_mdata(mdata);
+
+out:
+   free(mdata);
+   return ret;
+}
+
+U_BOOT_CMD(
+   fwu_mdata_read, 1,  1,  do_fwu_mdata_read,
+   "Read and print FWU metadata",
+   ""
+);
-- 
2.25.1



[PATCH v6 09/13] FWU: Add support for the FWU Multi Bank Update feature

2022-07-03 Thread Sughosh Ganu
The FWU Multi Bank Update feature supports updation of firmware images
to one of multiple sets(also called banks) of images. The firmware
images are clubbed together in banks, with the system booting images
from the active bank. Information on the images such as which bank
they belong to is stored as part of the metadata structure, which is
stored on the same storage media as the firmware images on a dedicated
partition.

At the time of update, the metadata is read to identify the bank to
which the images need to be flashed(update bank). On a successful
update, the metadata is modified to set the updated bank as active
bank to subsequently boot from.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Use u"TrialStateCtr" as suggested by Patrick

 include/fwu.h|  10 ++
 lib/Kconfig  |   6 +
 lib/Makefile |   1 +
 lib/efi_loader/efi_capsule.c | 231 ++-
 lib/efi_loader/efi_setup.c   |   3 +-
 lib/fwu_updates/Kconfig  |  31 +
 lib/fwu_updates/Makefile |   3 +-
 lib/fwu_updates/fwu.c|  26 
 8 files changed, 304 insertions(+), 7 deletions(-)
 create mode 100644 lib/fwu_updates/Kconfig

diff --git a/include/fwu.h b/include/fwu.h
index b374fd1179..7ff1cd75d3 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -32,13 +32,23 @@ struct fwu_mdata_ops {
 };
 
 #define FWU_MDATA_VERSION  0x1
+#define FWU_IMAGE_ACCEPTED 0x1
 
 #define FWU_MDATA_GUID \
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
+#define FWU_OS_REQUEST_FW_REVERT_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
+#define FWU_OS_REQUEST_FW_ACCEPT_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
 u8 fwu_update_checks_pass(void);
 int fwu_boottime_checks(void);
+int fwu_trial_state_ctr_start(void);
 
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
diff --git a/lib/Kconfig b/lib/Kconfig
index acc0ac081a..4ca6ea226b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -966,3 +966,9 @@ config PHANDLE_CHECK_SEQ
  phandles in fdtdec_get_alias_seq() function.
 
 endmenu
+
+menu "FWU Multi Bank Updates"
+
+source lib/fwu_updates/Kconfig
+
+endmenu
diff --git a/lib/Makefile b/lib/Makefile
index d9b1811f75..0cf8527c2d 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 a6b98f066a..18a356ba08 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 
@@ -32,6 +33,17 @@ static const efi_guid_t 
efi_guid_firmware_management_capsule_id =
EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 const efi_guid_t efi_guid_firmware_management_protocol =
EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
+const efi_guid_t fwu_guid_os_request_fw_revert =
+   FWU_OS_REQUEST_FW_REVERT_GUID;
+const efi_guid_t fwu_guid_os_request_fw_accept =
+   FWU_OS_REQUEST_FW_ACCEPT_GUID;
+
+#define FW_ACCEPT_OS   (u32)0x8000
+
+__maybe_unused static u32 update_index;
+__maybe_unused static bool capsule_update;
+__maybe_unused static bool fw_accept_os;
+static bool image_index_check = true;
 
 #ifdef CONFIG_EFI_CAPSULE_ON_DISK
 /* for file system access */
@@ -205,7 +217,8 @@ efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 
instance,
log_debug("+++ desc[%d] index: %d, name: %ls\n",
  j, desc->image_index, desc->image_id_name);
if (!guidcmp(>image_type_id, image_type) &&
-   (desc->image_index == image_index) &&
+   (!image_index_check ||
+desc->image_index == image_index) &&
(!instance ||
 !desc->hardware_instance ||
  desc->hardware_instance == instance))
@@ -388,6 +401,87 @@ efi_status_t efi_capsule_authenticate(const void *capsule, 
efi_uintn_t capsule_s
 }
 #endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
 
+static bool fwu_empty_capsule(struct efi_capsule_header *capsule)
+{
+   return !guidcmp(>capsule_guid,
+   _guid_os_request_fw_revert) ||
+   !guidcmp(>capsule_guid,
+_guid_os_request_fw_accept);
+}
+
+static e

[PATCH v6 08/13] FWU: Add boot time checks as highlighted by the FWU specification

2022-07-03 Thread Sughosh Ganu
The FWU Multi Bank Update specification requires the Update Agent to
carry out certain checks at the time of platform boot. The Update
Agent is the component which is responsible for updating the firmware
components and maintaining and keeping the metadata in sync.

The spec requires that the Update Agent perform the following checks
at the time of boot
* Sanity check of both the metadata copies maintained by the platform.
* Get the boot index passed to U-Boot by the prior stage bootloader
  and use this value for metadata bookkeeping.
* Check if the system is booting in Trial State. If the system boots
  in the Trial State for more than a specified number of boot counts,
  change the Active Bank to be booting the platform from.

Add these checks in the board initialisation sequence, invoked after
relocation.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Use u"TrialStateCtr" for the EFI variable name as suggested by
  Patrick
* Dropped the call to uclass_get_device() in fwu_boottime_checks() as
  suggested by Patrick
* Pass NULL instead of a pointer to trial_state_ctr variable when
  deleting the variable as suggested by Etienne

 common/board_r.c  |   5 ++
 include/fwu.h |   3 +
 lib/fwu_updates/fwu.c | 165 ++
 3 files changed, 173 insertions(+)
 create mode 100644 lib/fwu_updates/fwu.c

diff --git a/common/board_r.c b/common/board_r.c
index 6f4aca2077..33a600715d 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -797,6 +798,10 @@ static init_fnc_t init_sequence_r[] = {
 #if defined(CONFIG_PRAM)
initr_mem,
 #endif
+
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+   fwu_boottime_checks,
+#endif
run_main_loop,
 };
 
diff --git a/include/fwu.h b/include/fwu.h
index edb28c9659..b374fd1179 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -37,6 +37,9 @@ struct fwu_mdata_ops {
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
+u8 fwu_update_checks_pass(void);
+int fwu_boottime_checks(void);
+
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
 int fwu_get_active_index(u32 *active_idx);
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
new file mode 100644
index 00..10a0522333
--- /dev/null
+++ b/lib/fwu_updates/fwu.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static u8 trial_state;
+static u8 boottime_check;
+
+static int fwu_trial_state_check(void)
+{
+   int ret, i;
+   efi_status_t status;
+   efi_uintn_t var_size;
+   u16 trial_state_ctr;
+   u32 nimages, active_bank, var_attributes, active_idx;
+   struct fwu_mdata *mdata = NULL;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_bank_info;
+
+   ret = fwu_get_mdata();
+   if (ret)
+   return ret;
+
+   ret = 0;
+   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
+   active_bank = mdata->active_index;
+   img_entry = >img_entry[0];
+   for (i = 0; i < nimages; i++) {
+   img_bank_info = _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;
+   status = efi_get_variable_int(u"TrialStateCtr",
+ _global_variable_guid,
+ _attributes,
+ _size, _state_ctr,
+ NULL);
+   if (status != EFI_SUCCESS) {
+   log_err("Unable to read TrialStateCtr variable\n");
+   ret = -1;
+   goto out;
+   }
+
+   ++trial_state_ctr;
+   if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) {
+   log_info("Trial State count exceeded. Revert back to 
previous_active_index\n");
+   active_idx = mdata->active_index;
+   ret = fwu_revert_boot_index();
+   if (ret) {
+   log_err("Unable to revert active_index\n");
+   goto out;
+   }
+
+   /* Delete the TrialStateCtr var

[PATCH v6 07/13] FWU: STM32MP1: Add support to read boot index from backup register

2022-07-03 Thread Sughosh Ganu
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 
Reviewed-by: Patrick Delaunay 
---
Changes since V5:
* Shuffled the location of the TAMP_FWU_* macros as suggested by
  Patrick

 arch/arm/mach-stm32mp/include/mach/stm32.h | 5 +
 board/st/stm32mp1/stm32mp1.c   | 8 
 include/fwu.h  | 1 +
 3 files changed, 14 insertions(+)

diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h 
b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 47e88fc3dc..0344de796e 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -100,11 +100,16 @@ 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_INFO_REG 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)
 #define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21)
 
+#define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0)
+
+#define TAMP_FWU_BOOT_IDX_OFFSET   0
+
 #define TAMP_COPRO_STATE_OFF   0
 #define TAMP_COPRO_STATE_INIT  1
 #define TAMP_COPRO_STATE_CRUN  2
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 3aa223d795..6b249fafbb 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -1006,4 +1006,12 @@ int fwu_plat_get_update_index(u32 *update_idx)
 
return ret;
 }
+
+void fwu_plat_get_bootidx(void *boot_idx)
+{
+   u32 *bootidx = boot_idx;
+
+   *bootidx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
+   TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
+}
 #endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 38dceca9c5..edb28c9659 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -49,6 +49,7 @@ int fwu_revert_boot_index(void);
 int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
 int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
+void fwu_plat_get_bootidx(void *boot_idx);
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
 int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
-- 
2.25.1



[PATCH v6 06/13] FWU: stm32mp1: Add helper functions for accessing FWU metadata

2022-07-03 Thread Sughosh Ganu
Add helper functions needed for accessing the FWU metadata which
contains information on the updatable images. These functions have
been added for the STM32MP157C-DK2 board which has the updatable
images on the uSD card, formatted as GPT partitions.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Change the mechanism to get the block device descriptor in
  fwu_plat_get_alt_num() due to introduction of struct
  fwu_mdata_gpt_blk_priv in the earlier patch.

 board/st/stm32mp1/stm32mp1.c | 40 
 include/fwu.h|  3 ++
 lib/fwu_updates/Makefile |  6 +++
 lib/fwu_updates/fwu_gpt.c| 88 
 4 files changed, 137 insertions(+)
 create mode 100644 lib/fwu_updates/Makefile
 create mode 100644 lib/fwu_updates/fwu_gpt.c

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index c6bb7562f6..3aa223d795 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -7,9 +7,11 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,9 +27,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -967,3 +971,39 @@ static void board_copro_image_process(ulong fw_image, 
size_t fw_size)
 }
 
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
+
+#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
+
+#include 
+#include 
+
+int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
+int *alt_num)
+{
+   struct blk_desc *desc;
+   struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
+
+   desc = dev_get_uclass_plat(priv->blk_dev);
+   if (!desc) {
+   log_err("Block device not found\n");
+   return -ENODEV;
+   }
+
+   return fwu_gpt_get_alt_num(desc, image_guid, alt_num, DFU_DEV_MMC);
+}
+
+int fwu_plat_get_update_index(u32 *update_idx)
+{
+   int ret;
+   u32 active_idx;
+
+   ret = fwu_get_active_index(_idx);
+
+   if (ret < 0)
+   return -1;
+
+   *update_idx = active_idx ^= 0x1;
+
+   return ret;
+}
+#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 8259c75d12..38dceca9c5 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -51,4 +51,7 @@ int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
+int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+   int *alt_num, unsigned char dfu_dev);
+int fwu_plat_get_update_index(u32 *update_idx);
 #endif /* _FWU_H_ */
diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile
new file mode 100644
index 00..5a59e4a833
--- /dev/null
+++ b/lib/fwu_updates/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2022, Linaro Limited
+#
+
+obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_gpt.o
diff --git a/lib/fwu_updates/fwu_gpt.c b/lib/fwu_updates/fwu_gpt.c
new file mode 100644
index 00..434ec76bde
--- /dev/null
+++ b/lib/fwu_updates/fwu_gpt.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t 
*image_guid)
+{
+   int i;
+   struct disk_partition info;
+   efi_guid_t unique_part_guid;
+
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.uuid, unique_part_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_part_guid, image_guid))
+   return i;
+   }
+
+   log_err("No partition found with image_guid %pUs\n", image_guid);
+   return -ENOENT;
+}
+
+int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+   int *alt_num, unsigned char dfu_dev)
+{
+   int ret = -1;
+   int i, part, dev_num;
+   int nalt;
+   struct dfu_entity *dfu;
+
+   dev_num = desc->devnum;
+   part = get_gpt_dfu_identifier(desc, image_guid);
+   if (part < 0)
+   return -ENOENT;
+
+   dfu_init_env_entities(NULL, NULL);
+
+   nalt = 0;
+   list_for_each_entry(dfu, _list, list) {
+   nalt++;
+   }
+
+   if (!nalt) {
+   log_warning("No entities in dfu_alt_info\n");
+   dfu_free_entities();
+   return -ENOENT;
+   }
+
+   for (i = 0; i < nalt; i++) {
+   dfu = dfu_get_entity(i);
+
+   if (!dfu)
+   continue;
+
+   /*
+* Currently, Multi Bank upda

[PATCH v6 05/13] stm32mp1: dk2: Add image information for capsule updates

2022-07-03 Thread Sughosh Ganu
Enabling capsule update functionality on the platform requires
populating information on the images that are to be updated using the
functionality. Do so for the DK2 board.

Signed-off-by: Sughosh Ganu 
---
Changes since V5: None

 board/st/stm32mp1/stm32mp1.c   | 19 +++
 include/configs/stm32mp15_common.h |  4 
 2 files changed, 23 insertions(+)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 07b1a63db7..c6bb7562f6 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -92,6 +93,16 @@ DECLARE_GLOBAL_DATA_PTR;
 #define USB_START_LOW_THRESHOLD_UV 123
 #define USB_START_HIGH_THRESHOLD_UV215
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+struct efi_fw_image fw_images[1];
+
+struct efi_capsule_update_info update_info = {
+   .images = fw_images,
+};
+
+u8 num_image_type_guids = ARRAY_SIZE(fw_images);
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
 int board_early_init_f(void)
 {
/* nothing to do, only used in SPL */
@@ -675,6 +686,14 @@ int board_init(void)
 
setup_led(LEDST_ON);
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+   if (board_is_dk2()) {
+   efi_guid_t image_type_guid = STM32MP1_DK2_FIP_IMAGE_GUID;
+   guidcpy(_images[0].image_type_id, _type_guid);
+   fw_images[0].fw_name = u"STM32MP1-DK2-FIP";
+   fw_images[0].image_index = 5;
+   }
+#endif
return 0;
 }
 
diff --git a/include/configs/stm32mp15_common.h 
b/include/configs/stm32mp15_common.h
index 6b40cdb017..6a1ae9788d 100644
--- a/include/configs/stm32mp15_common.h
+++ b/include/configs/stm32mp15_common.h
@@ -54,6 +54,10 @@
 #define CONFIG_SYS_AUTOLOAD"no"
 #endif
 
+#define STM32MP1_DK2_FIP_IMAGE_GUID \
+   EFI_GUID(0x19d5df83, 0x11b0, 0x457b, 0xbe, 0x2c, \
+0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
+
 /*/
 #ifdef CONFIG_DISTRO_DEFAULTS
 /*/
-- 
2.25.1



[PATCH v6 04/13] stm32mp1: dk2: Add a node for the FWU metadata device

2022-07-03 Thread Sughosh Ganu
The FWU metadata structure is accessed through the driver model
interface. On the stm32mp157c-dk2 board, the FWU metadata is stored on
the uSD card. Add the fwu-mdata node on the u-boot specifc dtsi file
for accessing the metadata structure.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Patrick Delaunay 
---
Changes since V5: None

 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi 
b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
index 06ef3a4095..24f86209db 100644
--- a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
@@ -4,3 +4,10 @@
  */
 
 #include "stm32mp157a-dk1-u-boot.dtsi"
+
+/ {
+   fwu-mdata {
+   compatible = "u-boot,fwu-mdata-gpt";
+   fwu-mdata-store = <>;
+   };
+};
-- 
2.25.1



[PATCH v6 03/13] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-07-03 Thread Sughosh Ganu
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 a driver for reading from and writing to the metadata
when the updatable images and the metadata are stored on a block
device which is formated with GPT based partition scheme.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Changed the logic to store the GPT partitioned block device through
  a priv structure as suggested by Patrick
* Used dev_read_prop() to get the phandle_p instead of
  ofnode_get_property() used earlier as suggested by Patrick
* Make relevant functions static as suggested by Etienne

 drivers/fwu-mdata/Kconfig |   9 +
 drivers/fwu-mdata/Makefile|   1 +
 drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 408 ++
 include/fwu.h |   5 +
 4 files changed, 423 insertions(+)
 create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c

diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
index d6a21c8e19..d5edef19d6 100644
--- a/drivers/fwu-mdata/Kconfig
+++ b/drivers/fwu-mdata/Kconfig
@@ -5,3 +5,12 @@ config DM_FWU_MDATA
  Enable support for accessing FWU Metadata partitions. The
  FWU Metadata partitions reside on the same storage device
  which contains the other FWU updatable firmware images.
+
+config FWU_MDATA_GPT_BLK
+   bool "FWU Metadata access for GPT partitioned Block devices"
+   select PARTITION_TYPE_GUID
+   select PARTITION_UUIDS
+   depends on DM && HAVE_BLOCK_DEVICE && EFI_PARTITION
+   help
+ Enable support for accessing FWU Metadata on GPT partitioned
+ block devices.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
index e53a8c9983..313049f67a 100644
--- a/drivers/fwu-mdata/Makefile
+++ b/drivers/fwu-mdata/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
+obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
new file mode 100644
index 00..d904c9492d
--- /dev/null
+++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define PRIMARY_PART   BIT(0)
+#define SECONDARY_PART BIT(1)
+#define BOTH_PARTS (PRIMARY_PART | SECONDARY_PART)
+
+#define MDATA_READ BIT(0)
+#define MDATA_WRITEBIT(1)
+
+static int gpt_get_mdata_partitions(struct blk_desc *desc,
+   u16 *primary_mpart,
+   u16 *secondary_mpart)
+{
+   int i, ret;
+   u32 mdata_parts;
+   efi_guid_t part_type_guid;
+   struct disk_partition info;
+   const efi_guid_t fwu_mdata_guid = FWU_MDATA_GUID;
+
+   mdata_parts = 0;
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.type_guid, part_type_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_mdata_guid, _type_guid)) {
+   ++mdata_parts;
+   if (!*primary_mpart)
+   *primary_mpart = i;
+   else
+   *secondary_mpart = i;
+   }
+   }
+
+   if (mdata_parts != 2) {
+   log_err("Expect two copies of the FWU metadata instead of %d\n",
+   mdata_parts);
+   ret = -EINVAL;
+   } else {
+   ret = 0;
+   }
+
+   return ret;
+}
+
+static int gpt_get_mdata_disk_part(struct blk_desc *desc,
+  struct disk_partition *info,
+  u32 part_num)
+{
+   int ret;
+   char *mdata_guid_str = "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23";
+
+   ret = part_get_info(desc, part_num, info);
+   if (ret < 0) {
+   log_err("Unable to get the partition info for the FWU metadata 
part %d",
+   part_num);
+   return -1;
+   }
+
+   /* Check that it is indeed the FWU metadata partition */
+   if (!strncmp(info->type_guid, mdata_guid_str, UUID_STR_LEN)) {
+   /* Found the FWU metadata partition */
+   return 0;
+   }
+
+   return -1;
+}
+
+static int gpt_read_write_mdata(struct blk_desc *desc,
+   struct fwu_mdata *mdata,
+   u8 access, u32 part_num)
+{
+   int ret;
+   u32 len, blk_start, blkcnt;
+   struct disk_partition info;
+
+ 

[PATCH v6 02/13] FWU: Add FWU metadata structure and driver for accessing metadata

2022-07-03 Thread Sughosh Ganu
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 a driver model
uclass which provides functions to access the metadata. These are
generic API's, and implementations can be added based on parameters
like how the metadata partition is accessed and what type of storage
device houses the metadata.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Change the parameter to the function fwu_plat_get_alt_num to pass
  the FWU udevice pointer instead of passing the metadata device
  directly.

 drivers/Kconfig  |   2 +
 drivers/Makefile |   1 +
 drivers/fwu-mdata/Kconfig|   7 +
 drivers/fwu-mdata/Makefile   |   6 +
 drivers/fwu-mdata/fwu-mdata-uclass.c | 458 +++
 include/dm/uclass-id.h   |   1 +
 include/fwu.h|  49 +++
 include/fwu_mdata.h  |  67 
 8 files changed, 591 insertions(+)
 create mode 100644 drivers/fwu-mdata/Kconfig
 create mode 100644 drivers/fwu-mdata/Makefile
 create mode 100644 drivers/fwu-mdata/fwu-mdata-uclass.c
 create mode 100644 include/fwu.h
 create mode 100644 include/fwu_mdata.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index b26ca8cf70..adc6079ecf 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -42,6 +42,8 @@ source "drivers/firmware/Kconfig"
 
 source "drivers/fpga/Kconfig"
 
+source "drivers/fwu-mdata/Kconfig"
+
 source "drivers/gpio/Kconfig"
 
 source "drivers/hwspinlock/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 67c8af7442..901150bb35 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -83,6 +83,7 @@ obj-y += cache/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FASTBOOT) += fastboot/
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata/
 obj-y += misc/
 obj-$(CONFIG_MMC) += mmc/
 obj-$(CONFIG_NVME) += nvme/
diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
new file mode 100644
index 00..d6a21c8e19
--- /dev/null
+++ b/drivers/fwu-mdata/Kconfig
@@ -0,0 +1,7 @@
+config DM_FWU_MDATA
+   bool "Driver support for accessing FWU Metadata"
+   depends on DM
+   help
+ Enable support for accessing FWU Metadata partitions. The
+ FWU Metadata partitions reside on the same storage device
+ which contains the other FWU updatable firmware images.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
new file mode 100644
index 00..e53a8c9983
--- /dev/null
+++ b/drivers/fwu-mdata/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2022, Linaro Limited
+#
+
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c 
b/drivers/fwu-mdata/fwu-mdata-uclass.c
new file mode 100644
index 00..2092fcfc23
--- /dev/null
+++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
@@ -0,0 +1,458 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define IMAGE_ACCEPT_SET   BIT(0)
+#define IMAGE_ACCEPT_CLEAR BIT(1)
+
+static int fwu_get_dev_ops(struct udevice **dev,
+  const struct fwu_mdata_ops **ops)
+{
+   int ret;
+
+   ret = uclass_get_device(UCLASS_FWU_MDATA, 0, dev);
+   if (ret) {
+   log_debug("Cannot find fwu device\n");
+   return ret;
+   }
+
+   if ((*ops = device_get_ops(*dev)) == NULL) {
+   log_debug("Cannot get fwu device ops\n");
+   return -ENOSYS;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_verify_mdata() - Verify the FWU metadata
+ * @mdata: FWU metadata structure
+ * @pri_part: FWU metadata partition is primary or secondary
+ *
+ * Verify the FWU metadata by computing the CRC32 for the metadata
+ * structure and comparing it against the CRC32 value stored as part
+ * of the structure.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_verify_mdata(struct fwu_mdata *mdata, bool pri_part)
+{
+   u32 calc_crc32;
+   void *buf;
+
+   buf = >version;
+   calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32));
+
+   if (calc_crc32 != mdata->crc32) {
+   log_err("crc32 check failed for %s FWU metadata partition\n",
+   pri_part ? "primary" : "secondary");
+   return -1;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_get_active_index() - Get active_index from the FWU metadata
+ * @active_idx: active_index value to be read
+ *
+ * Read the active_index field from the FWU metadata and place it in
+ * the variable pointed to be the function argument.
+ *
+ * Return: 0 if OK, -ve on 

[PATCH v6 01/13] dt/bindings: Add bindings for FWU Metadata storage device

2022-07-03 Thread Sughosh Ganu
Add bindings needed for accessing the FWU metadata partitions. These
include the compatible string which point to the access method and the
actual device which stores the FWU metadata.

The current patch adds basic bindings needed for accessing the
metadata structure on GPT partitioned block devices.

Signed-off-by: Sughosh Ganu 
---
Changes since V5:
* Changed to yaml file from txt as per review comment

 .../firmware/fwu-mdata.yaml   | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 doc/device-tree-bindings/firmware/fwu-mdata.yaml

diff --git a/doc/device-tree-bindings/firmware/fwu-mdata.yaml 
b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
new file mode 100644
index 00..97d30bd1c1
--- /dev/null
+++ b/doc/device-tree-bindings/firmware/fwu-mdata.yaml
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/fwu-mdata.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: FWU metadata on device with GPT partitioned layout
+
+maintainers:
+ - Sughosh Ganu 
+
+properties:
+  compatible:
+items:
+  - const: u-boot,fwu-mdata-gpt
+
+  fwu-mdata-store:
+maxItems: 1
+description: Phandle of the device which contains the FWU medatata 
partition.
+
+required:
+  - compatible
+  - fwu-mdata-store
+
+additionalProperties: false
+
+examples:
+  - |
+fwu-mdata {
+compatible = "u-boot,fwu-mdata-gpt";
+fwu-mdata-store = <>;
+};
-- 
2.25.1



[PATCH v6 00/13] FWU: Add FWU Multi Bank Update feature support

2022-07-03 Thread Sughosh Ganu


The patchset adds support for the FWU Multi Bank Update[1]
feature. Certain aspects of the Dependable Boot[2] specification have
also been implemented.

The FWU multi bank update feature is used for supporting multiple
sets(also called banks) of firmware image(s), allowing the platform to
boot from a different bank, in case it fails to boot from the active
bank. This functionality is supported by keeping the relevant
information in a structure called metadata, which provides information
on the images. Among other parameters, the metadata structure contains
information on the currect active bank that is being used to boot
image(s).

Functionality is being added to work with the UEFI capsule driver in
u-boot. The metadata is read to gather information on the update bank,
which is the bank to which the firmware images would be flashed to. On
a successful completion of the update of all components, the active
bank field in the metadata is updated, to reflect the bank from which
the platform will boot on the subsequent boots.

Currently, the feature is being enabled on the STM32MP157C-DK2 and
Synquacer boards. The DK2 board boots a FIP image from a uSD card
partitioned with the GPT partioning scheme, while the Synquacer board
boots a FIP image from a MTD partitioned SPI NOR flash device.

This feature also requires changes in a previous stage of
bootloader, which parses the metadata and selects the bank to boot the
image(s) from. Support has being added in tf-a(BL2 stage) for the
STM32MP157C-DK2 board to boot the active bank images. These changes 
have been merged to the upstream tf-a repository.

The earlier patchset contained patches for both the DK2 and the
Synquacer platforms. The handling of review comments for the Synquacer
platform is to be taken up by a different engineer, and has not been
done yet. After discussion with Tom Rini and Heinrich, it was decided
to send the patches for the DK2 platform separately for review. The
patch for adding a python test for the feature has been developed, and
was sent in the version 5 of the patches[3]. However, the test script
depends on adding support for the feature on MTD SPI NOR devices, and
that is being done as part of the Synquacer patches. Hence these set
of patches do not have the test script for the feature. That will be
added through the patches for adding support for the feauture on
Synquacer platform.

[1] - https://developer.arm.com/documentation/den0118/a
[2] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
[3] - https://lists.denx.de/pipermail/u-boot/2022-June/485992.html

Changes since V5:
* Changed to yaml file from txt as per review comment
* Change the parameter to the function fwu_plat_get_alt_num to pass
  the FWU udevice pointer instead of passing the metadata device
  directly.
* Changed the logic to store the GPT partitioned block device through
  a priv structure as suggested by Patrick
* Used dev_read_prop() to get the phandle_p instead of
  ofnode_get_property() used earlier as suggested by Patrick
* Made relevant functions static as suggested by Etienne
* Change the mechanism to get the block device descriptor in
  fwu_plat_get_alt_num() due to introduction of struct
  fwu_mdata_gpt_blk_priv in the earlier patch.
* Shuffled the location of the TAMP_FWU_* macros as suggested by
  Patrick
* Use u"TrialStateCtr" for the EFI variable name as suggested by
  Patrick
* Dropped the call to uclass_get_device() in fwu_boottime_checks() as
  suggested by Patrick
* Pass NULL instead of a pointer to trial_state_ctr variable when
  deleting the variable as suggested by Etienne
* Use u"TrialStateCtr" as suggested by Patrick
* Do a metadata validity check by calling fwu_mdata_check() before
  printing the FWU metadata as suggested by Michal
* Use ret and res variables in do_fwu_mdata_read() as suggested by
  Patrick
* Change 'default y if FWU_MULTI_BANK_UPDATE' to default y as
  suggested by Patrick
* Use capsule_type instead of capsule variable that was created
  earlier to check for the type of capsule
* Remove use of payload variable in create_empty_capsule() as
  suggested by Etienne
* Initialise the struct efi_capsule_header as suggested by Etienne
* Add some description about the reasoning for accept capsule needing
  image GUID as suggested by Takahiro


Sughosh Ganu (13):
  dt/bindings: Add bindings for FWU Metadata storage device
  FWU: Add FWU metadata structure and driver for accessing metadata
  FWU: Add FWU metadata access driver for GPT partitioned block devices
  stm32mp1: dk2: Add a node for the FWU metadata device
  stm32mp1: dk2: Add image information for capsule updates
  FWU: stm32mp1: Add helper functions for accessing FWU metadata
  FWU: STM32MP1: Add support to read boot index from backup register
  FWU: Add boot time checks as highlighted by the FWU specification
  FWU: Add support for the FWU Multi Bank Update feature
  FWU: cmd: Add a command 

Re: [PATCH v5 08/23] FWU: Add boot time checks as highlighted by the FWU specification

2022-06-28 Thread Sughosh Ganu
hi Etienne,

On Thu, 23 Jun 2022 at 18:02, Etienne Carriere
 wrote:
>
> Hi Sughosh,
>
> On Thu, 23 Jun 2022 at 11:46, Sughosh Ganu  wrote:
> >
> > hi Etienne,
> >
> > On Tue, 21 Jun 2022 at 16:26, Etienne Carriere
> >  wrote:
> > >
> > > Hi Sughosh,
> > >
> > > On Thu, 9 Jun 2022 at 14:31, Sughosh Ganu  wrote:
> > > >
> > > > 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  |   5 ++
> > > >  include/fwu.h |   3 +
> > > >  lib/fwu_updates/fwu.c | 170 ++
> > > >  3 files changed, 178 insertions(+)
> > > >  create mode 100644 lib/fwu_updates/fwu.c
> >
> > 
> >
> > > > --- /dev/null
> > > > +++ b/lib/fwu_updates/fwu.c
> > > > @@ -0,0 +1,170 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*
> > > > + * Copyright (c) 2022, Linaro Limited
> > > > + */
> > > > +
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +
> > > > +#include 
> > > > +#include 
> > > > +
> > > > +static u8 trial_state;
> > > > +static u8 boottime_check;
> > > > +
> > > > +static int fwu_trial_state_check(void)
> > > > +{
> > > > +   int ret, i;
> > > > +   efi_status_t status;
> > > > +   efi_uintn_t var_size;
> > > > +   u16 trial_state_ctr;
> > > > +   u32 nimages, active_bank, var_attributes, active_idx;
> > > > +   struct fwu_mdata *mdata = NULL;
> > > > +   struct fwu_image_entry *img_entry;
> > > > +   struct fwu_image_bank_info *img_bank_info;
> > > > +
> > > > +   ret = fwu_get_mdata();
> > > > +   if (ret)
> > > > +   return ret;
> > > > +
> > > > +   ret = 0;
> > > > +   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
> > > > +   active_bank = mdata->active_index;
> > > > +   img_entry = >img_entry[0];
> > > > +   for (i = 0; i < nimages; i++) {
> > > > +   img_bank_info = 
> > > > _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;
> > > > +   status = efi_get_variable_int(L"TrialStateCtr",
> > > > + _global_variable_guid,
> > > > + _attributes,
> > > > + _size, 
> > > > _state_ctr,
> > > > + NULL);
> >

Re: [PATCH v5 03/23] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-06-28 Thread Sughosh Ganu
hi Etienne,

On Tue, 21 Jun 2022 at 16:26, Etienne Carriere
 wrote:
>
> Hello Sughosh,
>
> On Thu, 9 Jun 2022 at 14:30, Sughosh Ganu  wrote:
> >
> > 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 a driver 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 
> > ---
> >  drivers/fwu-mdata/Kconfig |   9 +
> >  drivers/fwu-mdata/Makefile|   1 +
> >  drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 404 ++
> >  include/fwu.h |   2 +
> >  4 files changed, 416 insertions(+)
> >  create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> >
> > diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
> > index d6a21c8e19..d5edef19d6 100644
> > --- a/drivers/fwu-mdata/Kconfig
> > +++ b/drivers/fwu-mdata/Kconfig
> > @@ -5,3 +5,12 @@ config DM_FWU_MDATA
> >   Enable support for accessing FWU Metadata partitions. The
> >   FWU Metadata partitions reside on the same storage device
> >   which contains the other FWU updatable firmware images.
> > +
> > +config FWU_MDATA_GPT_BLK
> > +   bool "FWU Metadata access for GPT partitioned Block devices"
> > +   select PARTITION_TYPE_GUID
> > +   select PARTITION_UUIDS
> > +   depends on DM && HAVE_BLOCK_DEVICE && EFI_PARTITION
> > +   help
> > + Enable support for accessing FWU Metadata on GPT partitioned
> > + block devices.
> > diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
> > index 7fec7171f4..12a5b4fe04 100644
> > --- a/drivers/fwu-mdata/Makefile
> > +++ b/drivers/fwu-mdata/Makefile
> > @@ -4,3 +4,4 @@
> >  #
> >
> >  obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
> > +obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
> > diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
> > b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > new file mode 100644
> > index 00..329bd3779b
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > @@ -0,0 +1,404 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PRIMARY_PART   BIT(0)
> > +#define SECONDARY_PART BIT(1)
> > +#define BOTH_PARTS (PRIMARY_PART | SECONDARY_PART)
> > +
> > +#define MDATA_READ BIT(0)
> > +#define MDATA_WRITEBIT(1)
> > +



> > +
> > +static int gpt_get_mdata(struct blk_desc *desc, struct fwu_mdata **mdata)
> > +{
> > +   int ret;
> > +   u16 primary_mpart = 0, secondary_mpart = 0;
> > +
> > +   ret = gpt_get_mdata_partitions(desc, _mpart,
> > +  _mpart);
> > +
> > +   if (ret < 0) {
> > +   log_err("Error getting the FWU metadata partitions\n");
> > +   return -ENODEV;
> > +   }
> > +
> > +   *mdata = malloc(sizeof(struct fwu_mdata));
> > +   if (!*mdata) {
> > +   log_err("Unable to allocate memory for reading FWU 
> > metadata\n");
> > +   return -ENOMEM;
> > +   }
> > +
> > +   ret = gpt_read_mdata(desc, *mdata, primary_mpart);
> > +   if (ret < 0) {
> > +   log_err("Failed to read the FWU metadata from the 
> > device\n");
> > +   return -EIO;
> > +   }
> > +
> > +   ret = fwu_verify_mdata(*mdata, 1);
> > +   if (!ret)
>
> Upon success, I think this function should also either ensure
> secondary_part contains a valid copy of primary part,
> Maybe this function should call gpt_check_mdata_validity() and then
> read mdata content.

Okay

>
> > +   return 0;
> > +
> > +   /*
> > +* Verification of the primary FWU metadata copy failed.
> > +* Try to read the replica.
> > +*/
>

Re: [PATCH v5 03/23] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-06-28 Thread Sughosh Ganu
hi Patrick,
Apologies for the late reply. I had missed out replying to the review
comments on this patch. There are some review comments on the
Synquacer patches which need to be taken care of by another engineer.
Once those review comments are taken care of, I will be sending the
next version.

On Tue, 21 Jun 2022 at 15:04, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > 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 a driver 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 
> > ---
> >   drivers/fwu-mdata/Kconfig |   9 +
> >   drivers/fwu-mdata/Makefile|   1 +
> >   drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 404 ++
> >   include/fwu.h |   2 +
> >   4 files changed, 416 insertions(+)
> >   create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> >



> > diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
> > index 7fec7171f4..12a5b4fe04 100644
> > --- a/drivers/fwu-mdata/Makefile
> > +++ b/drivers/fwu-mdata/Makefile
> > @@ -4,3 +4,4 @@
> >   #
> >
> >   obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
> > +obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
>
>
> It is strange to have '_' and '-' in file name for the same directory
>
> => to be coherent = fwu-mdata-gpt-blk.c

I see this kind of naming style in many other directories under
drivers/. The uclass file is named using the foo-uclass.c, while the
other driver files are named bar_driver.c

>
>
> > diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
> > b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > new file mode 100644
> > index 00..329bd3779b
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
> > @@ -0,0 +1,404 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PRIMARY_PART BIT(0)
> > +#define SECONDARY_PART   BIT(1)
> > +#define BOTH_PARTS   (PRIMARY_PART | SECONDARY_PART)
> > +
> > +#define MDATA_READ   BIT(0)
> > +#define MDATA_WRITE  BIT(1)
> > +
> > +
>
>
> [...]
>
> > +
> > +int fwu_gpt_mdata_check(struct udevice *dev)
> > +{
> > + /*
> > +  * Check if both the copies of the FWU metadata are
> > +  * valid. If one has gone bad, restore it from the
> > +  * other good copy.
> > +  */
> > + return gpt_check_mdata_validity(dev);
> > +}
> > +
> > +int fwu_gpt_get_mdata(struct udevice *dev, struct fwu_mdata **mdata)
> > +{
> > + struct blk_desc *desc;
> > +
> > + desc = dev_get_uclass_plat(dev_get_priv(dev));
>
> as dev = fwu_mdata_gpt_blk(UCLASS_FWU_MDATA)
>
> dev_get_priv(dev) => get value saved in dev_set_priv(dev, mdata_dev);
>
> even if it is OK, it not clear here.
>
> can you add a struct to prepare addition of other elements in privdata:
>
> struct fwu_mdata_gpt_blk_priv {
> struct udevice *blk_dev;
> }
>
>
> + struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
>
> + struct blk_desc *desc;
>
> + desc = dev_get_uclass_plat(priv->blk_dev);

Okay. Will add a priv structure as you suggest.

>
>
> > + if (!desc) {
> > + log_err("Block device not found\n");
> > + return -ENODEV;
> > + }
> > +
> > + return gpt_get_mdata(desc, mdata);
> > +}
> > +
> > +int fwu_get_mdata_device(struct udevice *dev, struct udevice **mdata_dev)
> > +{
> > + u32 phandle;
> > + int ret, size;
> > + struct udevice *parent, *child;
> > + const fdt32_t *phandle_p = NULL;
> > +
> > + phandle_p = ofnode_get_property(dev_ofnode(dev), "fwu-mdata-store",
> > + );
>
> phandle_p = dev_read_prop(dev, "fwu-mdata-store", );
>
>
> it is more simple

Okay

>
>
> > + if (!phandle_

Re: [PATCH v5 08/23] FWU: Add boot time checks as highlighted by the FWU specification

2022-06-23 Thread Sughosh Ganu
hi Patrick,

On Tue, 21 Jun 2022 at 17:16, Patrick DELAUNAY
 wrote:
>
> Hi,
>
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > 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  |   5 ++
> >   include/fwu.h |   3 +
> >   lib/fwu_updates/fwu.c | 170 ++
> >   3 files changed, 178 insertions(+)
> >   create mode 100644 lib/fwu_updates/fwu.c
> >
> > diff --git a/common/board_r.c b/common/board_r.c
> > index 6f4aca2077..33a600715d 100644
> > --- a/common/board_r.c
> > +++ b/common/board_r.c
> > @@ -15,6 +15,7 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -797,6 +798,10 @@ static init_fnc_t init_sequence_r[] = {
> >   #if defined(CONFIG_PRAM)
> >   initr_mem,
> >   #endif
> > +
> > +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
> > + fwu_boottime_checks,
> > +#endif
> >   run_main_loop,
> >   };
> >
> > diff --git a/include/fwu.h b/include/fwu.h
> > index 41774ff9e2..8fbd91b463 100644
> > --- a/include/fwu.h
> > +++ b/include/fwu.h
> > @@ -33,6 +33,9 @@ struct fwu_mdata_ops {
> >   EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
> >0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
> >
> > +int fwu_boottime_checks(void);
> > +u8 fwu_update_checks_pass(void);
> > +
> >   int fwu_get_mdata(struct fwu_mdata **mdata);
> >   int fwu_update_mdata(struct fwu_mdata *mdata);
> >   int fwu_get_active_index(u32 *active_idx);
> > diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
> > new file mode 100644
> > index 00..af884439fb
> > --- /dev/null
> > +++ b/lib/fwu_updates/fwu.c
> > @@ -0,0 +1,170 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +static u8 trial_state;
> > +static u8 boottime_check;
> > +
> > +static int fwu_trial_state_check(void)
> > +{
> > + int ret, i;
> > + efi_status_t status;
> > + efi_uintn_t var_size;
> > + u16 trial_state_ctr;
> > + u32 nimages, active_bank, var_attributes, active_idx;
> > + struct fwu_mdata *mdata = NULL;
> > + struct fwu_image_entry *img_entry;
> > + struct fwu_image_bank_info *img_bank_info;
> > +
> > + ret = fwu_get_mdata();
> > + if (ret)
> > + return ret;
> > +
> > + ret = 0;
> > + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
> > + active_bank = mdata->active_index;
> > + img_entry = >img_entry[0];
> > + for (i = 0; i < nimages; i++) {
> > + img_bank_info = _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;
> > + status = efi_get_variable_int(L"TrialStateCtr",
> > +   _global_variable_guid,
> > +  

Re: [PATCH v5 08/23] FWU: Add boot time checks as highlighted by the FWU specification

2022-06-23 Thread Sughosh Ganu
hi Etienne,

On Tue, 21 Jun 2022 at 16:26, Etienne Carriere
 wrote:
>
> Hi Sughosh,
>
> On Thu, 9 Jun 2022 at 14:31, Sughosh Ganu  wrote:
> >
> > 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  |   5 ++
> >  include/fwu.h |   3 +
> >  lib/fwu_updates/fwu.c | 170 ++
> >  3 files changed, 178 insertions(+)
> >  create mode 100644 lib/fwu_updates/fwu.c



> > --- /dev/null
> > +++ b/lib/fwu_updates/fwu.c
> > @@ -0,0 +1,170 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +static u8 trial_state;
> > +static u8 boottime_check;
> > +
> > +static int fwu_trial_state_check(void)
> > +{
> > +   int ret, i;
> > +   efi_status_t status;
> > +   efi_uintn_t var_size;
> > +   u16 trial_state_ctr;
> > +   u32 nimages, active_bank, var_attributes, active_idx;
> > +   struct fwu_mdata *mdata = NULL;
> > +   struct fwu_image_entry *img_entry;
> > +   struct fwu_image_bank_info *img_bank_info;
> > +
> > +   ret = fwu_get_mdata();
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = 0;
> > +   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
> > +   active_bank = mdata->active_index;
> > +   img_entry = >img_entry[0];
> > +   for (i = 0; i < nimages; i++) {
> > +   img_bank_info = _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;
> > +   status = efi_get_variable_int(L"TrialStateCtr",
> > + _global_variable_guid,
> > + _attributes,
> > + _size, _state_ctr,
> > + NULL);
> > +   if (status != EFI_SUCCESS) {
> > +   log_err("Unable to read TrialStateCtr variable\n");
> > +   ret = -1;
> > +   goto out;
> > +   }
> > +
> > +   ++trial_state_ctr;
> > +   if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) {
> > +   log_info("Trial State count exceeded. Revert back 
> > to previous_active_index\n");
> > +   active_idx = mdata->active_index;
> > +   ret = fwu_revert_boot_index();
> > +   if (ret) {
> > +   log_err("Unable to revert active_index\n");
> > +   goto out;
> > +   }
> > +
> > +   trial_state_ctr = 0;
> > +   status = efi_set_variable_int(L"TrialStateCtr",
> > + 
> > _global_variable_g

Re: [PATCH v5 07/23] FWU: STM32MP1: Add support to read boot index from backup register

2022-06-23 Thread Sughosh Ganu
On Tue, 21 Jun 2022 at 16:57, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > 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 | 4 
> >   board/st/stm32mp1/stm32mp1.c   | 7 +++
> >   include/fwu.h  | 2 +-
> >   3 files changed, 12 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h 
> > b/arch/arm/mach-stm32mp/include/mach/stm32.h
> > index 47e88fc3dc..40995ee142 100644
> > --- a/arch/arm/mach-stm32mp/include/mach/stm32.h
> > +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
> > @@ -100,6 +100,7 @@ enum boot_device {
> >   #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 
> > * x)
> >   #define TAMP_BACKUP_MAGIC_NUMBERTAMP_BACKUP_REGISTER(4)
> >   #define TAMP_BACKUP_BRANCH_ADDRESS  TAMP_BACKUP_REGISTER(5)
> > +#define TAMP_FWU_BOOT_INFO_REG   TAMP_BACKUP_REGISTER(10)
> >   #define TAMP_COPRO_RSC_TBL_ADDRESS  TAMP_BACKUP_REGISTER(17)
> >   #define TAMP_COPRO_STATETAMP_BACKUP_REGISTER(18)
> >   #define TAMP_BOOT_CONTEXT   TAMP_BACKUP_REGISTER(20)
> > @@ -118,6 +119,9 @@ enum boot_device {
> >   #define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0)
> >   #define TAMP_BOOT_FORCED_MASK   GENMASK(7, 0)
> >   #define TAMP_BOOT_DEBUG_ON  BIT(16)
> > +#define TAMP_FWU_BOOT_IDX_MASK   GENMASK(3, 0)
> > +
> > +#define TAMP_FWU_BOOT_IDX_OFFSET 0
> >
>
>
> please don't mix the 2 TAMP_FWU defines with define and enum for TAMP_BOOT
>
> => move the 2 defines before TAMP_COPRO defines.
>
>
> #define TAMP_BACKUP_MAGIC_NUMBERTAMP_BACKUP_REGISTER(4)
> #define TAMP_BACKUP_BRANCH_ADDRESSTAMP_BACKUP_REGISTER(5)
> + #define TAMP_FWU_BOOT_INFO_REGTAMP_BACKUP_REGISTER(10)
> #define TAMP_COPRO_RSC_TBL_ADDRESSTAMP_BACKUP_REGISTER(17)
> #define TAMP_COPRO_STATETAMP_BACKUP_REGISTER(18)
> #define TAMP_BOOT_CONTEXTTAMP_BACKUP_REGISTER(20)
> #define TAMP_BOOTCOUNTTAMP_BACKUP_REGISTER(21)
>
> +
>
> +#define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0)
>
> + #define TAMP_FWU_BOOT_IDX_OFFSET 0

Will change as per your suggestion. Thanks.

-sughosh

>
>
> #define TAMP_COPRO_STATE_OFF0
> #define TAMP_COPRO_STATE_INIT1
>
>
> >   enum forced_boot_mode {
> >   BOOT_NORMAL = 0x00,
> > diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> > index e68bf09955..dff41ed6f6 100644
> > --- a/board/st/stm32mp1/stm32mp1.c
> > +++ b/board/st/stm32mp1/stm32mp1.c
> > @@ -1081,4 +1081,11 @@ int fwu_plat_get_update_index(u32 *update_idx)
> >   return ret;
> >   }
> >
> > +void fwu_plat_get_bootidx(void *boot_idx)
> > +{
> > + u32 *bootidx = boot_idx;
> > +
> > + *bootidx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
> > + TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
> > +}
> >   #endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
> > diff --git a/include/fwu.h b/include/fwu.h
> > index 36e58afa29..41774ff9e2 100644
> > --- a/include/fwu.h
> > +++ b/include/fwu.h
> > @@ -46,7 +46,7 @@ int fwu_revert_boot_index(void);
> >   int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
> >   int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
> >
> > -
> > +void fwu_plat_get_bootidx(void *boot_idx);
> >   int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
> >int *alt_num);
> >   int fwu_plat_get_update_index(u32 *update_idx);
>
> With the modifications:
>
> Reviewed-by: Patrick Delaunay 
>
> Thanks
> Patrick
>
>


Re: [PATCH v5 02/23] FWU: Add FWU metadata structure and driver for accessing metadata

2022-06-23 Thread Sughosh Ganu
hi Etienne,

On Tue, 21 Jun 2022 at 16:24, Etienne Carriere
 wrote:
>
> Hello Sughosh,
>
>
>
> On Thu, 9 Jun 2022 at 14:30, Sughosh Ganu  wrote:
> >
> > 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 a driver model
> > uclass which provides 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 
> > ---
> >  drivers/Kconfig  |   2 +
> >  drivers/Makefile |   1 +
> >  drivers/fwu-mdata/Kconfig|   7 +
> >  drivers/fwu-mdata/Makefile   |   6 +
> >  drivers/fwu-mdata/fwu-mdata-uclass.c | 459 +++
> >  include/dm/uclass-id.h   |   1 +
> >  include/fwu.h|  49 +++
> >  include/fwu_mdata.h  |  67 
> >  8 files changed, 592 insertions(+)
> >  create mode 100644 drivers/fwu-mdata/Kconfig
> >  create mode 100644 drivers/fwu-mdata/Makefile
> >  create mode 100644 drivers/fwu-mdata/fwu-mdata-uclass.c
> >  create mode 100644 include/fwu.h
> >  create mode 100644 include/fwu_mdata.h
> >



> > diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c 
> > b/drivers/fwu-mdata/fwu-mdata-uclass.c
> > new file mode 100644
> > index 00..1530ceb01d
> > --- /dev/null
> > +++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
> > @@ -0,0 +1,459 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define IMAGE_ACCEPT_SET   BIT(0)
> > +#define IMAGE_ACCEPT_CLEAR BIT(1)
> > +
> > +static int fwu_get_dev_ops(struct udevice **dev,
> > +  const struct fwu_mdata_ops **ops)
> > +{
> > +   int ret;
> > +
> > +   ret = uclass_get_device(UCLASS_FWU_MDATA, 0, dev);
> > +   if (ret) {
> > +   log_debug("Cannot find fwu device\n");
> > +   return ret;
> > +   }
> > +
> > +   if ((*ops = device_get_ops(*dev)) == NULL) {
> > +   log_debug("Cannot get fwu device ops\n");
> > +   return -ENOSYS;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +/**
> > + * fwu_verify_mdata() - Verify the FWU metadata
> > + * @mdata: FWU metadata structure
> > + * @pri_part: FWU metadata partition is primary or secondary
> > + *
> > + * Verify the FWU metadata by computing the CRC32 for the metadata
> > + * structure and comparing it against the CRC32 value stored as part
> > + * of the structure.
> > + *
> > + * Return: 0 if OK, -ve on error
> > + *
> > + */
> > +int fwu_verify_mdata(struct fwu_mdata *mdata, bool pri_part)
> > +{
> > +   u32 calc_crc32;
> > +   void *buf;
> > +
> > +   buf = >version;
> > +   calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32));
> > +
> > +   if (calc_crc32 != mdata->crc32) {
> > +   log_err("crc32 check failed for %s FWU metadata 
> > partition\n",
> > +   pri_part ? "primary" : "secondary");
> > +   return -1;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +/**
> > + * fwu_get_active_index() - Get active_index from the FWU metadata
> > + * @active_idx: active_index value to be read
> > + *
> > + * Read the active_index field from the FWU metadata and place it in
> > + * the variable pointed to be the function argument.
> > + *
> > + * Return: 0 if OK, -ve on error
> > + *
> > + */
> > +int fwu_get_active_index(u32 *active_idx)
> > +{
> > +   int ret;
> > +   struct fwu_mdata *mdata = NULL;
> > +
> > +   ret = fwu_get_mdata();
> > +   if (ret < 0) {
> > +   log_err("Unable to get valid FWU metadata\n");
> > +   goto out;
> > +   }
> > +
> > +   /*
> > +* Found the FWU metad

Re: [PATCH v5 06/23] FWU: stm32mp1: Add helper functions for accessing FWU metadata

2022-06-23 Thread Sughosh Ganu
On Tue, 21 Jun 2022 at 15:19, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > Add helper functions needed for accessing the FWU metadata which
> > contains information on the updatable images. These functions have
> > been added for the STM32MP157C-DK2 board which has the updatable
> > images on the uSD card, formatted as GPT partitions.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >   board/st/stm32mp1/stm32mp1.c | 115 +++
> >   include/fwu.h|   2 +
> >   2 files changed, 117 insertions(+)
> >
> > diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> > index 62d98ad776..e68bf09955 100644
> > --- a/board/st/stm32mp1/stm32mp1.c
> > +++ b/board/st/stm32mp1/stm32mp1.c
> > @@ -7,9 +7,11 @@
> >
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -25,9 +27,11 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -967,3 +971,114 @@ static void board_copro_image_process(ulong fw_image, 
> > size_t fw_size)
> >   }
> >
> >   U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
> > +
> > +#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
> > +#include 
> > +#include 
> > +
> [...]
> > +
> > +#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
> > diff --git a/include/fwu.h b/include/fwu.h
> > index 3b1ee4e83e..36e58afa29 100644
> > --- a/include/fwu.h
> > +++ b/include/fwu.h
> > @@ -46,6 +46,8 @@ int fwu_revert_boot_index(void);
> >   int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
> >   int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
> >
> > +
>
>
> Added empty line

Will remove

>
>
> >   int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
> >int *alt_num);
> > +int fwu_plat_get_update_index(u32 *update_idx);
> >   #endif /* _FWU_H_ */
>
>
> And I am agree with Ilias remark, should be generic
>
> => search on the current UCLASS_FWU_MDATA
>
> perhaps need a new ops in u-class ? as implementation can be
> different for GPT and MTD.

My understanding of Ilias's comments was that the function can be
generic for all GPT based platforms. But I will check if this can be
reused for both GPT and MTD devices, on the lines that you mention
above. Thanks.

-sughosh


Re: [PATCH v5 00/23] FWU: Add FWU Multi Bank Update feature support

2022-06-21 Thread Sughosh Ganu
hi,

On Mon, 20 Jun 2022 at 23:42, Patrick DELAUNAY
 wrote:
>
> Hi,
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > The patchset adds support for the FWU Multi Bank Update[1]
> > feature. Certain aspects of the Dependable Boot[2] specification have
> > also been implemented.
> >
> > The FWU multi bank update feature is used for supporting multiple
> > sets(also called banks) of firmware image(s), allowing the platform to
> > boot from a different bank, in case it fails to boot from the active
> > bank. This functionality is supported by keeping the relevant
> > information in a structure called metadata, which provides information
> > on the images. Among other parameters, the metadata structure contains
> > information on the currect active bank that is being used to boot
> > image(s).
> >
> > Functionality is being added to work with the UEFI capsule driver in
> > u-boot. The metadata is read to gather information on the update bank,
> > which is the bank to which the firmware images would be flashed to. On
> > a successful completion of the update of all components, the active
> > bank field in the metadata is updated, to reflect the bank from which
> > the platform will boot on the subsequent boots.
> >
> > Currently, the feature is being enabled on the STM32MP157C-DK2 and
> > Synquacer boards. The DK2 board boots a FIP image from a uSD card
> > partitioned with the GPT partioning scheme, while the Synquacer board
> > boots a FIP image from a MTD partitioned SPI NOR flash device.
> >
> > This feature also requires changes in a previous stage of
> > bootloader, which parses the metadata and selects the bank to boot the
> > image(s) from. Support has being added in tf-a(BL2 stage) for the
> > STM32MP157C-DK2 board to boot the active bank images. These changes
> > have been merged to the upstream tf-a repository.
> >
> > Earlier, two separate patchsets were being sent. The patchset sent by
> > me was adding support for the feature, and enabling the feature on the
> > ST board. The other set of patches were being sent by Masami
> > Hiramatsu, which were enabling the feature on the Synquacer
> > platform. This patchset contains both set of patches, along with the
> > associated documentation and the python test script for testing the
> > feature.
> >
> > The upstreaming effort for this feature had been put on a temporary
> > hold to address the fixing of some issues in the capsule update code,
> > primarily using a per platform image GUID for the updatable
> > images. Now that the series has been merged, upstreaming effort for
> > the FWU update feature is being resumed. Hence, this version does not
> > have any review comments being addressed.
> >
> >
> > [1] - https://developer.arm.com/documentation/den0118/a
> > [2] - 
> > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> >
> > Jassi Brar (1):
> >developerbox: synquacer: Use FIP as the updatable image
> >
> > Masami Hiramatsu (9):
> >FWU: Add FWU metadata access driver for non-GPT MTD devices
> >dt/bindings: firmware: Add FWU metadata on MTD devices binding
> >tools: Add mkfwumdata tool for FWU metadata image
> >FWU: doc: Update documentation for the FWU non-GPT MTD
> >synquacer: Update for TBBR (BL2) based new FIP layout
> >FWU: synquacer: Add FWU Multi bank update support for DeveloperBox
> >FWU: synquacer: Generate dfu_alt_info from devicetree partition
> >doc: synquacer: Add how to enable FWU Multi Bank Update
> >[TEMP]configs: synquacer: Add FWU support for DeveloperBox
> >
> > Sughosh Ganu (13):
> >dt/bindings: Add bindings for FWU Metadata storage device
> >FWU: Add FWU metadata structure and driver for accessing metadata
> >FWU: Add FWU metadata access driver for GPT partitioned block devices
> >stm32mp1: dk2: Add a node for the FWU metadata device
> >stm32mp1: dk2: Add image information for capsule updates
> >FWU: stm32mp1: Add helper functions for accessing FWU metadata
> >FWU: STM32MP1: Add support to read boot index from backup register
> >FWU: Add boot time checks as highlighted by the FWU specification
> >FWU: Add support for the FWU Multi Bank Update feature
> >FWU: cmd: Add a command to read FWU metadata
> >mkeficapsule: Add support for generating empty capsules
> >FWU: doc: Add documentation for the FWU feature
> >sandbox: fwu: Add support for testing FWU feature on sandbox
> >
> >   arch/arm/dts/

Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-17 Thread Sughosh Ganu
Takahiro,

On Fri, 17 Jun 2022 at 06:16, Takahiro Akashi
 wrote:
>
> Sughosh,
>
> On Thu, Jun 16, 2022 at 12:42:08PM +0530, Sughosh Ganu wrote:
> > hi Takahiro,
> >
> > On Thu, 16 Jun 2022 at 06:31, Takahiro Akashi
> >  wrote:
> > >
> > > Sughosh,
> > >
> > > On Wed, Jun 15, 2022 at 04:19:56PM +0530, Sughosh Ganu wrote:
> > > > On Wed, 15 Jun 2022 at 10:41, Takahiro Akashi
> > > >  wrote:
> > > > >
> > > > > On Thu, Jun 09, 2022 at 05:59:58PM +0530, Sughosh Ganu wrote:
> > > > > > The Dependable Boot specification[1] describes the structure of the
> > > > > > firmware accept and revert capsules. These are empty capsules which
> > > > > > are used for signalling the acceptance or rejection of the updated
> > > > > > firmware by the OS. Add support for generating these empty capsules.
> > > > > >
> > > > > > [1] - 
> > > > > > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> > > > > >
> > > > > > Signed-off-by: Sughosh Ganu 
> > > > > > ---
> > > > > >  doc/mkeficapsule.1   |  29 ++---
> > > > > >  tools/eficapsule.h   |   8 +++
> > > > > >  tools/mkeficapsule.c | 139 
> > > > > > +--
> > > > > >  3 files changed, 151 insertions(+), 25 deletions(-)
> > > > > >
> > > > > > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > > > > > index 09bdc24295..77ca061efd 100644
> > > > > > --- a/doc/mkeficapsule.1
> > > > > > +++ b/doc/mkeficapsule.1
> > > > > > @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
> > > > > >
> > > > > >  .SH SYNOPSIS
> > > > > >  .B mkeficapsule
> > > > > > -.RI [ options "] " image-blob " " capsule-file
> > > > > > +.RI [ options ] " " [ image-blob ] " " capsule-file
> > > > > >
> > > > > >  .SH "DESCRIPTION"
> > > > > >  .B mkeficapsule
> > > > > > @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a 
> > > > > > given private key.
> > > > > >  In this case, the update will be authenticated by verifying the 
> > > > > > signature
> > > > > >  before applying.
> > > > > >
> > > > > > +Additionally, an empty capsule file can be generated for 
> > > > > > acceptance or
> > > > > > +rejection of firmware images by a governing component like an 
> > > > > > Operating
> > > > > > +System. The empty capsules do not require an image-blob input file.
> > > > > > +
> > > > > > +
> > > > > >  .B mkeficapsule
> > > > > > -takes any type of image files, including:
> > > > > > +takes any type of image files when generating non empty capsules, 
> > > > > > including:
> > > > > >  .TP
> > > > > >  .I raw image
> > > > > >  format is a single binary blob of any type of firmware.
> > > > > > @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
> > > > > >  This type of image file can be generated by
> > > > > >  .BR mkimage .
> > > > > >
> > > > > > -.PP
> > > > > > -If you want to use other types than above two, you should 
> > > > > > explicitly
> > > > > > -specify a guid for the FMP driver.
> > > > > > -
> > > > > >  .SH "OPTIONS"
> > > > > > +
> > > > > >  .TP
> > > > > >  .BI "-g\fR,\fB --guid " guid-string
> > > > > >  Specify guid for image blob type. The format is:
> > > > > >  ----
> > > > > >
> > > > > >  The first three elements are in little endian, while the rest
> > > > > > -is in big endian.
> > > > > > +is in big endian. The option must be specified for all non empty 
> > > > > > and
> > > > > > +image acceptance capsules
> > > > >
> > > &g

Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-17 Thread Sughosh Ganu
On Fri, 17 Jun 2022 at 06:38, Takahiro Akashi
 wrote:
>
> Sughosh,
>
> On Wed, Jun 15, 2022 at 05:40:12PM +0530, Sughosh Ganu wrote:
> > On Wed, 15 Jun 2022 at 11:07, Takahiro Akashi
> >  wrote:
> > >
> > > On Thu, Jun 09, 2022 at 06:00:10PM +0530, Sughosh Ganu wrote:
> > > > Add a python test script for testing the FWU Multi Bank Update
> > > > functionality on the sandbox platform. The script has test cases for
> > > > updation of the u-boot binary and the u-boot environment image to the
> > > > non active bank.
> > > >
> > > > The FWU metadata is being stored on the SPI NOR flash, along with the
> > > > updatable images, and the FWU metadata driver for MTD devices is being
> > > > used for accessing the metadata. Certain FWU boottime checks are
> > > > bypassed due to the unavailability of the EFI variable access very
> > > > early in the boot on the sandbox platform -- the variable access is
> > > > only available once the block disk image has been bound through the
> > > > host interface.
> > > >
> > > > The FWU Multi Bank feature being enabled on the sandbox64 platform is
> > > > enabling the RAW Firmware Management Protocol(FMP) instance, therefore
> > > > the FIT FMP instance is being removed -- the FIT FMP is already being
> > > > tested on the sandbox flattree variant.
> > >
> > > IMO,
> > > Thinking of the importance of this feature, FIT FMP should also be
> > > tested *with FWU*.
> >
> > How will the FWU update feature work for FIT images? As I understand
>
> So are you deliberately designing and proposing a solution that is
> incompatible with (or not applicable to) an existing interface (FIT FMP)?

Heh, why would anyone do that? The very fact that we are introducing
support on two platforms, one with a GPT layout, and another with MTD
is because the idea is to encourage adoption on multiple platforms.
Secondly, this is a specification from Arm which was driven by Jose
Marinho, and I believe he has incorporated feedback from various
engineers for drafting the specification -- this specification is not
limited only to platforms booting with u-boot. The main issue, as I
see it, is that the FWU metadata is doing the bookkeeping for images
that are present on the platform's storage device, and this just does
not map with FIT which is a packaging mechanism. However, this being
software, you can make changes to the fit_update function and
incorporate the information from the metadata to write to the relevant
locations. However, this needs to be thought through.

>
> > FIT, it is a way of packaging different firmware images into a single
> > package. At the time of writing the images, the FIT image parser would
> > check the image configuration, and write the images to their
> > respective locations. As you are aware, for the FWU feature, the
> > information about the images, and the update bank is obtained from the
> > structure called metadata. How does the FIT update mechanism map with
> > the FWU metadata which is used to identify which bank needs to be
> > updated. The bank to which the image is to be written translates into
> > the DFU alt_num value for that image, and this gets computed at
> > runtime. In the case of the FIT image, as per my understanding, the
> > alt_num value is irrelevant. So my question is, how do we map the
> > information obtained from the FWU metadata to tell the FIT image
> > writing function(fit_update) which locations do the images need to be
> > written to. I think this needs some more thought.
> >
> > >
> > > > Signed-off-by: Sughosh Ganu 
> > > > ---
> > > >  arch/sandbox/Kconfig  |   6 +
> > > >  arch/sandbox/dts/test.dts |  45 ++-
> > > >  board/sandbox/sandbox.c   |  49 +++
> > > >  configs/sandbox64_defconfig   |  12 +-
> > > >  include/fwu.h |   2 +
> > > >  lib/fwu_updates/Kconfig   |   2 +-
> > > >  lib/fwu_updates/fwu.c |  18 +-
> > > >  lib/fwu_updates/fwu_mtd.c |  10 +-
> > > >  .../test_capsule_firmware_fit.py  |   1 -
> > > >  .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
> > > >  test/py/tests/test_fwu_updates/conftest.py|  78 
> > > >  .../test_fwu_updates/test_fwu_updates.py  | 367 ++
> > > >  12 files changed, 587 insertions(+), 13 deletions(

Re: [PATCH v5 01/23] dt/bindings: Add bindings for FWU Metadata storage device

2022-06-17 Thread Sughosh Ganu
On Thu, 16 Jun 2022 at 19:04, Michal Simek  wrote:
>
> čt 9. 6. 2022 v 14:30 odesílatel Sughosh Ganu  
> napsal:
> >
> > Add bindings needed for accessing the FWU metadata partitions. These
> > include the compatible string which point to the access method and the
> > actual device which stores the FWU metadata.
> >
> > The current patch adds basic bindings needed for accessing the
> > metadata structure on GPT partitioned block devices.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >  .../firmware/fwu-mdata.txt | 18 ++
>
> Why is this in txt file when mtd one is in yaml.
> doc/device-tree-bindings/firmware/uboot,fwu-mdata-mtd.yaml

The above binding was written by me in txt, while the mtd one is
authored by Masami Hiramatsu. I will change this to yaml in the next
version.

-sughosh

>
> Thanks,
> Michal
>
> --
> Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
> w: www.monstr.eu p: +42-0-721842854
> Maintainer of Linux kernel - Xilinx Microblaze
> Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
> U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-16 Thread Sughosh Ganu
hi Takahiro,

On Thu, 16 Jun 2022 at 06:31, Takahiro Akashi
 wrote:
>
> Sughosh,
>
> On Wed, Jun 15, 2022 at 04:19:56PM +0530, Sughosh Ganu wrote:
> > On Wed, 15 Jun 2022 at 10:41, Takahiro Akashi
> >  wrote:
> > >
> > > On Thu, Jun 09, 2022 at 05:59:58PM +0530, Sughosh Ganu wrote:
> > > > The Dependable Boot specification[1] describes the structure of the
> > > > firmware accept and revert capsules. These are empty capsules which
> > > > are used for signalling the acceptance or rejection of the updated
> > > > firmware by the OS. Add support for generating these empty capsules.
> > > >
> > > > [1] - 
> > > > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> > > >
> > > > Signed-off-by: Sughosh Ganu 
> > > > ---
> > > >  doc/mkeficapsule.1   |  29 ++---
> > > >  tools/eficapsule.h   |   8 +++
> > > >  tools/mkeficapsule.c | 139 +--
> > > >  3 files changed, 151 insertions(+), 25 deletions(-)
> > > >
> > > > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > > > index 09bdc24295..77ca061efd 100644
> > > > --- a/doc/mkeficapsule.1
> > > > +++ b/doc/mkeficapsule.1
> > > > @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
> > > >
> > > >  .SH SYNOPSIS
> > > >  .B mkeficapsule
> > > > -.RI [ options "] " image-blob " " capsule-file
> > > > +.RI [ options ] " " [ image-blob ] " " capsule-file
> > > >
> > > >  .SH "DESCRIPTION"
> > > >  .B mkeficapsule
> > > > @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a 
> > > > given private key.
> > > >  In this case, the update will be authenticated by verifying the 
> > > > signature
> > > >  before applying.
> > > >
> > > > +Additionally, an empty capsule file can be generated for acceptance or
> > > > +rejection of firmware images by a governing component like an Operating
> > > > +System. The empty capsules do not require an image-blob input file.
> > > > +
> > > > +
> > > >  .B mkeficapsule
> > > > -takes any type of image files, including:
> > > > +takes any type of image files when generating non empty capsules, 
> > > > including:
> > > >  .TP
> > > >  .I raw image
> > > >  format is a single binary blob of any type of firmware.
> > > > @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
> > > >  This type of image file can be generated by
> > > >  .BR mkimage .
> > > >
> > > > -.PP
> > > > -If you want to use other types than above two, you should explicitly
> > > > -specify a guid for the FMP driver.
> > > > -
> > > >  .SH "OPTIONS"
> > > > +
> > > >  .TP
> > > >  .BI "-g\fR,\fB --guid " guid-string
> > > >  Specify guid for image blob type. The format is:
> > > >  ----
> > > >
> > > >  The first three elements are in little endian, while the rest
> > > > -is in big endian.
> > > > +is in big endian. The option must be specified for all non empty and
> > > > +image acceptance capsules
> > >
> > > "image acceptance" -> "firmware acceptance"
> >
> > Okay
> >
> > >
> > > I don't still understand why we need a guid for acceptance
> > > while revert doesn't require it.
> > > I believe that firmware update is "all or nothing", isn't it?
> >
> > I believe this gives more flexibility in that different components
> > might be required to accept the various firmware images. So, one
> > component might accept the optee_os, while another might be
> > responsible for accepting u-boot. In any case, we do check that all
> > the components have their accepted bit set, and only if so, does the
> > bank boot in the regular state.
>
> Probably I don't understand the behavior.
> Let's assume that we have firmware A and firmware B and then
> update both.
> When the firmware A is accepted and B is not (not yet issuing
> acceptance capsule) and I try to reboot the system, what happens?
> From which bank does the system boot, old one or new one?

Onc

Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-15 Thread Sughosh Ganu
On Wed, 15 Jun 2022 at 12:00, Takahiro Akashi
 wrote:
>
> On Thu, Jun 09, 2022 at 06:00:10PM +0530, Sughosh Ganu wrote:
> > Add a python test script for testing the FWU Multi Bank Update
> > functionality on the sandbox platform. The script has test cases for
> > updation of the u-boot binary and the u-boot environment image to the
> > non active bank.
>
> IIUC, your test doesn't not exercise neither accept-capsule nor
> revert capsule.
> I think those tests are crucial for verifying the code.

Yes, this is on my todo list. By default, all the images get accepted
by the firmware itself, which is being done in u-boot. In case the
oemflag bit 15 is set to 1 in the capsule header, the image acceptance
is done through the accept capsule. I will need to add support for
passing the oemflag parameter to the mkeficapsule, and then I can test
this. Will keep this on my todo list, and try to put it in the
upcoming versions.

-sughosh

>
> -Takahiro Akashi
>
> > The FWU metadata is being stored on the SPI NOR flash, along with the
> > updatable images, and the FWU metadata driver for MTD devices is being
> > used for accessing the metadata. Certain FWU boottime checks are
> > bypassed due to the unavailability of the EFI variable access very
> > early in the boot on the sandbox platform -- the variable access is
> > only available once the block disk image has been bound through the
> > host interface.
> >
> > The FWU Multi Bank feature being enabled on the sandbox64 platform is
> > enabling the RAW Firmware Management Protocol(FMP) instance, therefore
> > the FIT FMP instance is being removed -- the FIT FMP is already being
> > tested on the sandbox flattree variant.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >  arch/sandbox/Kconfig  |   6 +
> >  arch/sandbox/dts/test.dts |  45 ++-
> >  board/sandbox/sandbox.c   |  49 +++
> >  configs/sandbox64_defconfig   |  12 +-
> >  include/fwu.h |   2 +
> >  lib/fwu_updates/Kconfig   |   2 +-
> >  lib/fwu_updates/fwu.c |  18 +-
> >  lib/fwu_updates/fwu_mtd.c |  10 +-
> >  .../test_capsule_firmware_fit.py  |   1 -
> >  .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
> >  test/py/tests/test_fwu_updates/conftest.py|  78 
> >  .../test_fwu_updates/test_fwu_updates.py  | 367 ++
> >  12 files changed, 587 insertions(+), 13 deletions(-)
> >  create mode 100644 test/py/tests/test_fwu_updates/capsule_defs.py
> >  create mode 100644 test/py/tests/test_fwu_updates/conftest.py
> >  create mode 100644 test/py/tests/test_fwu_updates/test_fwu_updates.py
> >
> > diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
> > index 5f55c7f28e..2985572083 100644
> > --- a/arch/sandbox/Kconfig
> > +++ b/arch/sandbox/Kconfig
> > @@ -84,3 +84,9 @@ config SYS_FDT_LOAD_ADDR
> > See `doc/arch/sandbox.rst` for more information.
> >
> >  endmenu
> > +
> > +config FWU_NUM_BANKS
> > +   default 2
> > +
> > +config FWU_NUM_IMAGES_PER_BANK
> > + default 2
> > diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> > index 8f93775ff4..f11fa8733f 100644
> > --- a/arch/sandbox/dts/test.dts
> > +++ b/arch/sandbox/dts/test.dts
> > @@ -1145,11 +1145,48 @@
> >   pinctrl-names = "default";
> >   pinctrl-0 = <_spi0_pins>;
> >
> > - spi.bin@0 {
> > + spi0: spi.bin@0 {
> >   reg = <0>;
> >   compatible = "spansion,m25p16", "jedec,spi-nor";
> >   spi-max-frequency = <4000>;
> >   sandbox,filename = "spi.bin";
> > +
> > + partitions {
> > + compatible = "fixed-partitions";
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + uuid = "af9e8c96-bec5-48be-9dab-3491c04b1366";
> > +
> > + partition@0 {
> > + label = "Metadata";
> > + reg = <0x0 0x2>;
> > + };
> > +
> > + /* FWU Multi bank update partitions */
> > +

Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-15 Thread Sughosh Ganu
On Wed, 15 Jun 2022 at 11:07, Takahiro Akashi
 wrote:
>
> On Thu, Jun 09, 2022 at 06:00:10PM +0530, Sughosh Ganu wrote:
> > Add a python test script for testing the FWU Multi Bank Update
> > functionality on the sandbox platform. The script has test cases for
> > updation of the u-boot binary and the u-boot environment image to the
> > non active bank.
> >
> > The FWU metadata is being stored on the SPI NOR flash, along with the
> > updatable images, and the FWU metadata driver for MTD devices is being
> > used for accessing the metadata. Certain FWU boottime checks are
> > bypassed due to the unavailability of the EFI variable access very
> > early in the boot on the sandbox platform -- the variable access is
> > only available once the block disk image has been bound through the
> > host interface.
> >
> > The FWU Multi Bank feature being enabled on the sandbox64 platform is
> > enabling the RAW Firmware Management Protocol(FMP) instance, therefore
> > the FIT FMP instance is being removed -- the FIT FMP is already being
> > tested on the sandbox flattree variant.
>
> IMO,
> Thinking of the importance of this feature, FIT FMP should also be
> tested *with FWU*.

How will the FWU update feature work for FIT images? As I understand
FIT, it is a way of packaging different firmware images into a single
package. At the time of writing the images, the FIT image parser would
check the image configuration, and write the images to their
respective locations. As you are aware, for the FWU feature, the
information about the images, and the update bank is obtained from the
structure called metadata. How does the FIT update mechanism map with
the FWU metadata which is used to identify which bank needs to be
updated. The bank to which the image is to be written translates into
the DFU alt_num value for that image, and this gets computed at
runtime. In the case of the FIT image, as per my understanding, the
alt_num value is irrelevant. So my question is, how do we map the
information obtained from the FWU metadata to tell the FIT image
writing function(fit_update) which locations do the images need to be
written to. I think this needs some more thought.

>
> > Signed-off-by: Sughosh Ganu 
> > ---
> >  arch/sandbox/Kconfig  |   6 +
> >  arch/sandbox/dts/test.dts |  45 ++-
> >  board/sandbox/sandbox.c   |  49 +++
> >  configs/sandbox64_defconfig   |  12 +-
> >  include/fwu.h |   2 +
> >  lib/fwu_updates/Kconfig   |   2 +-
> >  lib/fwu_updates/fwu.c |  18 +-
> >  lib/fwu_updates/fwu_mtd.c |  10 +-
> >  .../test_capsule_firmware_fit.py  |   1 -
> >  .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
> >  test/py/tests/test_fwu_updates/conftest.py|  78 
> >  .../test_fwu_updates/test_fwu_updates.py  | 367 ++
> >  12 files changed, 587 insertions(+), 13 deletions(-)
> >  create mode 100644 test/py/tests/test_fwu_updates/capsule_defs.py
> >  create mode 100644 test/py/tests/test_fwu_updates/conftest.py
> >  create mode 100644 test/py/tests/test_fwu_updates/test_fwu_updates.py
> >



> > diff --git a/test/py/tests/test_fwu_updates/conftest.py 
> > b/test/py/tests/test_fwu_updates/conftest.py
> > new file mode 100644
> > index 00..cdf824c3be
> > --- /dev/null
> > +++ b/test/py/tests/test_fwu_updates/conftest.py
> > @@ -0,0 +1,78 @@
> > +# SPDX-License-Identifier:  GPL-2.0+
> > +# Copyright (c) 2020, Linaro Limited
> > +# Author: AKASHI Takahiro 
>
> If this file is exactly same as test_efi_capsule/conftest.py,
> why not move all the tests (test_fwu_updates.py) to test_efi_capsule?

The files are not exactly the same. There is use of the mkfwumdata
utility used for FWU tests, along with the capsule files that are
being generated. I had tried putting the code under the
test_efi_capsule directory, but the result was getting cluttered.
Which is why I decided to put the changes separately under the
test_fwu_updates directory.

>
> The basic scenario of updating firmware, u-boot.bin and u-boot.env,
> is also the same, isn't it? The only difference is whether 
> FWU_MULTI_BANK_UPDATE
> is enabled or not.

There are two capsule files per image, one per bank. Also, the FWU
metadata is being written to the SPI NOR device, which is being
formatted as a MTD partitioned device. The underlying update mechanism
is the same, yes.

-sughosh

>
> -Takahiro Akashi
>
> > +
> > +import os
> > +import os.path
> > +import re
> > +from subprocess import call, chec

Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-15 Thread Sughosh Ganu
On Wed, 15 Jun 2022 at 10:41, Takahiro Akashi
 wrote:
>
> On Thu, Jun 09, 2022 at 05:59:58PM +0530, Sughosh Ganu wrote:
> > The Dependable Boot specification[1] describes the structure of the
> > firmware accept and revert capsules. These are empty capsules which
> > are used for signalling the acceptance or rejection of the updated
> > firmware by the OS. Add support for generating these empty capsules.
> >
> > [1] - 
> > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >  doc/mkeficapsule.1   |  29 ++---
> >  tools/eficapsule.h   |   8 +++
> >  tools/mkeficapsule.c | 139 +--
> >  3 files changed, 151 insertions(+), 25 deletions(-)
> >
> > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > index 09bdc24295..77ca061efd 100644
> > --- a/doc/mkeficapsule.1
> > +++ b/doc/mkeficapsule.1
> > @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
> >
> >  .SH SYNOPSIS
> >  .B mkeficapsule
> > -.RI [ options "] " image-blob " " capsule-file
> > +.RI [ options ] " " [ image-blob ] " " capsule-file
> >
> >  .SH "DESCRIPTION"
> >  .B mkeficapsule
> > @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given 
> > private key.
> >  In this case, the update will be authenticated by verifying the signature
> >  before applying.
> >
> > +Additionally, an empty capsule file can be generated for acceptance or
> > +rejection of firmware images by a governing component like an Operating
> > +System. The empty capsules do not require an image-blob input file.
> > +
> > +
> >  .B mkeficapsule
> > -takes any type of image files, including:
> > +takes any type of image files when generating non empty capsules, 
> > including:
> >  .TP
> >  .I raw image
> >  format is a single binary blob of any type of firmware.
> > @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
> >  This type of image file can be generated by
> >  .BR mkimage .
> >
> > -.PP
> > -If you want to use other types than above two, you should explicitly
> > -specify a guid for the FMP driver.
> > -
> >  .SH "OPTIONS"
> > +
> >  .TP
> >  .BI "-g\fR,\fB --guid " guid-string
> >  Specify guid for image blob type. The format is:
> >  ----
> >
> >  The first three elements are in little endian, while the rest
> > -is in big endian.
> > +is in big endian. The option must be specified for all non empty and
> > +image acceptance capsules
>
> "image acceptance" -> "firmware acceptance"

Okay

>
> I don't still understand why we need a guid for acceptance
> while revert doesn't require it.
> I believe that firmware update is "all or nothing", isn't it?

I believe this gives more flexibility in that different components
might be required to accept the various firmware images. So, one
component might accept the optee_os, while another might be
responsible for accepting u-boot. In any case, we do check that all
the components have their accepted bit set, and only if so, does the
bank boot in the regular state. In case of a firmware revert, it would
not matter which firmware component is being reverted -- the platform
would simply need to boot from the other bank. Do you see any issue
with the current method that we have?

>
> If there is a good reason, please describe a possible/expected
> scenario.

Where do you want me to explain this, in the feature documentation? Or
do you think this can be elaborated in greater detail in the spec.

>
> >  .TP
> >  .BI "-i\fR,\fB --index " index
> > @@ -57,6 +60,18 @@ Specify an image index
> >  .BI "-I\fR,\fB --instance " instance
> >  Specify a hardware instance
> >
> > +.PP
> > +For generation of firmware accept empty capsule
> > +.BR --guid
> > +is mandatory
> > +.TP
> > +.BI "-A\fR,\fB --fw-accept "
> > +Generate a firmware acceptance empty capsule
> > +
> > +.TP
> > +.BI "-R\fR,\fB --fw-revert "
> > +Generate a firmware revert empty capsule
> > +
> >  .TP
> >  .BR -h ", " --help
> >  Print a help message
> > diff --git a/tools/eficapsule.h b/tools/eficapsule.h
> > index d63b831443..072a4b5598 100644
> > --- a/tools/eficapsule.h
> > +++ b/tools/eficapsule.h
> > @@ -41,6 +41,14 @@ typede

Re: [PATCH v5 10/23] FWU: cmd: Add a command to read FWU metadata

2022-06-13 Thread Sughosh Ganu
hi Ilias,

On Fri, 10 Jun 2022 at 17:37, Ilias Apalodimas
 wrote:
>
> On Thu, Jun 09, 2022 at 05:59:57PM +0530, Sughosh Ganu wrote:
> > 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 |  7 +
> >  cmd/Makefile|  1 +
> >  cmd/fwu_mdata.c | 74 +
> >  3 files changed, 82 insertions(+)
> >  create mode 100644 cmd/fwu_mdata.c
> >
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 09193b61b9..275becd837 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -144,6 +144,13 @@ config CMD_CPU
> > internal name) and clock frequency. Other information may be
> > available depending on the CPU driver.
> >
> > +config CMD_FWU_METADATA
> > + bool "fwu metadata read"
> > + depends on FWU_MULTI_BANK_UPDATE
> > + default y if FWU_MULTI_BANK_UPDATE
> > + help
> > +   Command to read the metadata and dump it's contents
> > +
> >  config CMD_LICENSE
> >   bool "license"
> >   select BUILD_BIN2C
> > diff --git a/cmd/Makefile b/cmd/Makefile
> > index 5e43a1e022..259a93bc65 100644
> > --- a/cmd/Makefile
> > +++ b/cmd/Makefile
> > @@ -76,6 +76,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o
> >  obj-$(CONFIG_CMD_FPGAD) += fpgad.o
> >  obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
> >  obj-$(CONFIG_CMD_FUSE) += fuse.o
> > +obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o
> >  obj-$(CONFIG_CMD_GETTIME) += gettime.o
> >  obj-$(CONFIG_CMD_GPIO) += gpio.o
> >  obj-$(CONFIG_CMD_HVC) += smccc.o
> > diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c
> > new file mode 100644
> > index 00..bc20ca26a3
> > --- /dev/null
> > +++ b/cmd/fwu_mdata.c
> > @@ -0,0 +1,74 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +static void print_mdata(struct fwu_mdata *mdata)
> > +{
> > + int i, j;
> > + struct fwu_image_entry *img_entry;
> > + struct fwu_image_bank_info *img_info;
> > + u32 nimages, nbanks;
>
> nit but we don't really need those two.  Just use the define.

Okay. Will change.

>
> > +
> > + printf("\tFWU Metadata\n");
> > + printf("crc32: %#x\n", mdata->crc32);
> > + printf("version: %#x\n", mdata->version);
> > + printf("active_index: %#x\n", mdata->active_index);
> > + printf("previous_active_index: %#x\n", mdata->previous_active_index);
> > +
> > + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
> > + nbanks = CONFIG_FWU_NUM_BANKS;
> > + printf("\tImage Info\n");
> > + for (i = 0; i < nimages; i++) {
> > + img_entry = >img_entry[i];
> > + printf("\nImage Type Guid: %pUL\n", 
> > _entry->image_type_uuid);
> > + printf("Location Guid: %pUL\n", _entry->location_uuid);
> > + for (j = 0; j < nbanks; j++) {
> > + img_info = _entry->img_bank_info[j];
> > + printf("Image Guid:  %pUL\n", _info->image_uuid);
> > + printf("Image Acceptance: %#x\n", img_info->accepted);
>
> Can we do 'yes/no' on the image acceptance please?

Okay. Will change.

-sughosh

>
> > + }
> > + }
> > +}
> > +
> > +int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag,
> > +  int argc, char * const argv[])
> > +{
> > + struct udevice *dev;
> > + int ret = CMD_RET_SUCCESS;
> > + struct fwu_mdata *mdata = NULL;
> > +
> > + if (uclass_get_device(UCLASS_FWU_MDATA, 0, ) || !dev) {
> > + log_err("Unable to get FWU metadata device\n");
> > + return CMD_RET_FAILURE;
> > + }
> > +
> > + ret = fwu_get_mdata();
> > + if (ret < 0) {
> > + log_err("Unable to get valid FWU metadata\n");
> > + ret = CMD_RET_FAILURE;
> > + goto out;
> > + }
> > +
> > + print_mdata(mdata);
> > +
> > +out:
> > + free(mdata);
> > + return ret;
> > +}
> > +
> > +U_BOOT_CMD(
> > + fwu_mdata_read, 1,  1,  do_fwu_mdata_read,
> > + "Read and print FWU metadata",
> > + ""
> > +);
> > --
> > 2.25.1
> >
>
> Regards
> /Ilias


Re: [PATCH v5 06/23] FWU: stm32mp1: Add helper functions for accessing FWU metadata

2022-06-13 Thread Sughosh Ganu
hi Ilias,

On Fri, 10 Jun 2022 at 17:23, Ilias Apalodimas
 wrote:
>
> Hi Sughosh,
>
> On Thu, Jun 09, 2022 at 05:59:53PM +0530, Sughosh Ganu wrote:
> > Add helper functions needed for accessing the FWU metadata which
> > contains information on the updatable images. These functions have
> > been added for the STM32MP157C-DK2 board which has the updatable
> > images on the uSD card, formatted as GPT partitions.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >  board/st/stm32mp1/stm32mp1.c | 115 +++
> >  include/fwu.h|   2 +
> >  2 files changed, 117 insertions(+)
> >
> > diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> > index 62d98ad776..e68bf09955 100644
> > --- a/board/st/stm32mp1/stm32mp1.c
> > +++ b/board/st/stm32mp1/stm32mp1.c
> > @@ -7,9 +7,11 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -25,9 +27,11 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -967,3 +971,114 @@ static void board_copro_image_process(ulong fw_image, 
> > size_t fw_size)
> >  }
> >
> >  U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
> > +
> > +#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
> > +#include 
> > +#include 
> > +
> > +static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t 
> > *image_guid)
> > +{
> > + int i;
> > + struct disk_partition info;
> > + efi_guid_t unique_part_guid;
> > +
> > + for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
> > + if (part_get_info(desc, i, ))
> > + continue;
> > + uuid_str_to_bin(info.uuid, unique_part_guid.b,
> > + UUID_STR_FORMAT_GUID);
> > +
> > + if (!guidcmp(_part_guid, image_guid))
> > + return i;
> > + }
> > +
> > + log_err("No partition found with image_guid %pUs\n", image_guid);
> > + return -ENOENT;
> > +}
> > +
> > +static int gpt_plat_get_alt_num(struct blk_desc *desc, efi_guid_t 
> > *image_guid,
> > + int *alt_num)
>
> Does this really need to be defined per platform?
>
> Most of the stuff in here are generic apart from the info of were  the
> metadata is stored.  So wouldn't it better to move this in the generic API
> and add an argument for the dfu device type?
>
> The platform portion would then just call this function with an extra arg
> e.g DFU_DEV_MMC

Yes, it makes sense. I will make the change that you suggest. Thanks.

-sughosh

>
> > +{
> > + int ret = -1;
> > + int i, part, dev_num;
> > + int nalt;
> > + struct dfu_entity *dfu;
> > +
> > + dev_num = desc->devnum;
> > + part = get_gpt_dfu_identifier(desc, image_guid);
> > + if (part < 0)
> > + return -ENOENT;
> > +
> > + dfu_init_env_entities(NULL, NULL);
>
> [...]
>
>
> Regards
> /Ilias


Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-13 Thread Sughosh Ganu
On Thu, 9 Jun 2022 at 21:58, Heinrich Schuchardt  wrote:
>
> On 6/9/22 14:29, Sughosh Ganu wrote:
> > The Dependable Boot specification[1] describes the structure of the
> > firmware accept and revert capsules. These are empty capsules which
> > are used for signalling the acceptance or rejection of the updated
> > firmware by the OS. Add support for generating these empty capsules.
> >
> > [1] - 
> > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >   doc/mkeficapsule.1   |  29 ++---
> >   tools/eficapsule.h   |   8 +++
> >   tools/mkeficapsule.c | 139 +--
> >   3 files changed, 151 insertions(+), 25 deletions(-)



> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > index 5f74d23b9e..e8eb6b070d 100644
> > --- a/tools/mkeficapsule.c
> > +++ b/tools/mkeficapsule.c
> > @@ -29,7 +29,16 @@ static const char *tool_name = "mkeficapsule";
> >   efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> >   efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
> >
> > -static const char *opts_short = "g:i:I:v:p:c:m:dh";
> > +static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
> > +
> > +static bool empty_capsule;
> > +static unsigned char capsule;
> > +
> > +enum {
> > + CAPSULE_NORMAL_BLOB = 0,
> > + CAPSULE_ACCEPT,
> > + CAPSULE_REVERT,
> > +} capsule_type;
> >
> >   static struct option options[] = {
> >   {"guid", required_argument, NULL, 'g'},
> > @@ -39,24 +48,47 @@ static struct option options[] = {
> >   {"certificate", required_argument, NULL, 'c'},
> >   {"monotonic-count", required_argument, NULL, 'm'},
> >   {"dump-sig", no_argument, NULL, 'd'},
> > + {"fw-accept", no_argument, NULL, 'A'},
> > + {"fw-revert", no_argument, NULL, 'R'},
> >   {"help", no_argument, NULL, 'h'},
> >   {NULL, 0, NULL, 0},
> >   };
> >
> >   static void print_usage(void)
> >   {
> > - fprintf(stderr, "Usage: %s [options]  \n"
> > - "Options:\n"
> > -
> > - "\t-g, --guid guid for image blob type\n"
> > - "\t-i, --index  update image index\n"
> > - "\t-I, --instanceupdate hardware instance\n"
> > - "\t-p, --private-key   private key file\n"
> > - "\t-c, --certificate  signer's certificate 
> > file\n"
> > - "\t-m, --monotonic-count  monotonic count\n"
> > - "\t-d, --dump_sig  dump signature (*.p7)\n"
> > - "\t-h, --help  print a help message\n",
> > - tool_name);
> > + if (empty_capsule) {
> > + if (capsule == CAPSULE_ACCEPT) {
> > + fprintf(stderr, "Usage: %s [options] \n",
>
> My expectation is that this function always provides the same output.
>
> If different scenarios allow only specific combinations of arguments you
> may describe it here.

Okay

>
>
> > + tool_name);
> > + fprintf(stderr, "Options:\n"
> > + "\t-A, --fw-accept firmware 
> > accept capsule\n"
> > + "\t-g, --guid guid for image 
> > blob type\n"
> > + "\t-h, --help  print a help 
> > message\n"
> > + );
> > + } else {
> > + fprintf(stderr, "Usage: %s [options] \n",
> > + tool_name);
> > + fprintf(stderr, "Options:\n"
> > + "\t-R, --fw-revert firmware 
> > revert capsule\n"
> > + "\t-h, --help  print a help 
> > message\n"
> > + );
> > + }
> > + } else {
> > + fprintf(stderr, "Usage: %s [options]   > file>\n"
> > + "Options:\n"
> > +
> > + "\t-g, --guid guid for image blob 
> > type\n"
> > + 

[PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-09 Thread Sughosh Ganu
Add a python test script for testing the FWU Multi Bank Update
functionality on the sandbox platform. The script has test cases for
updation of the u-boot binary and the u-boot environment image to the
non active bank.

The FWU metadata is being stored on the SPI NOR flash, along with the
updatable images, and the FWU metadata driver for MTD devices is being
used for accessing the metadata. Certain FWU boottime checks are
bypassed due to the unavailability of the EFI variable access very
early in the boot on the sandbox platform -- the variable access is
only available once the block disk image has been bound through the
host interface.

The FWU Multi Bank feature being enabled on the sandbox64 platform is
enabling the RAW Firmware Management Protocol(FMP) instance, therefore
the FIT FMP instance is being removed -- the FIT FMP is already being
tested on the sandbox flattree variant.

Signed-off-by: Sughosh Ganu 
---
 arch/sandbox/Kconfig  |   6 +
 arch/sandbox/dts/test.dts |  45 ++-
 board/sandbox/sandbox.c   |  49 +++
 configs/sandbox64_defconfig   |  12 +-
 include/fwu.h |   2 +
 lib/fwu_updates/Kconfig   |   2 +-
 lib/fwu_updates/fwu.c |  18 +-
 lib/fwu_updates/fwu_mtd.c |  10 +-
 .../test_capsule_firmware_fit.py  |   1 -
 .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
 test/py/tests/test_fwu_updates/conftest.py|  78 
 .../test_fwu_updates/test_fwu_updates.py  | 367 ++
 12 files changed, 587 insertions(+), 13 deletions(-)
 create mode 100644 test/py/tests/test_fwu_updates/capsule_defs.py
 create mode 100644 test/py/tests/test_fwu_updates/conftest.py
 create mode 100644 test/py/tests/test_fwu_updates/test_fwu_updates.py

diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 5f55c7f28e..2985572083 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -84,3 +84,9 @@ config SYS_FDT_LOAD_ADDR
  See `doc/arch/sandbox.rst` for more information.
 
 endmenu
+
+config FWU_NUM_BANKS
+   default 2
+
+config FWU_NUM_IMAGES_PER_BANK
+   default 2
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 8f93775ff4..f11fa8733f 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1145,11 +1145,48 @@
pinctrl-names = "default";
pinctrl-0 = <_spi0_pins>;
 
-   spi.bin@0 {
+   spi0: spi.bin@0 {
reg = <0>;
compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <4000>;
sandbox,filename = "spi.bin";
+
+   partitions {
+   compatible = "fixed-partitions";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   uuid = "af9e8c96-bec5-48be-9dab-3491c04b1366";
+
+   partition@0 {
+   label = "Metadata";
+   reg = <0x0 0x2>;
+   };
+
+   /* FWU Multi bank update partitions */
+   partition@10 {
+   label = "U-Boot-Bank0";
+   reg = <0x10 0x1>;
+   uuid = 
"a8f61787-5d68-4c9d-9e4a-37bb0df99da7";
+   };
+
+   partition@12 {
+   label = "U-Boot-ENV-Bank0";
+   reg = <0x12 0x1>;
+   uuid = 
"ea9d59af-e0e8-4ef5-9b16-4c80ff67524c";
+   };
+
+   partition@14 {
+   label = "U-Boot-Bank1";
+   reg = <0x14 0x1>;
+   uuid = 
"52377abf-c4e4-4d0b-aafd-ba081a500847";
+   };
+
+   partition@16 {
+   label = "U-Boot-ENV-Bank1";
+   reg = <0x16 0x1>;
+   uuid = 
"4e01d1fa-eebb-437e-9cfe-e7dfbcd04bb3";
+   };
+   };
};
spi.bin@1 {
reg = <1>;
@@ -1633,6 +1670,12 @@
compatible = "sandbox,regmap_te

[PATCH v5 22/23] [TEMP]configs: synquacer: Add FWU support for DeveloperBox

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Enable FWU Multi-Bank support for DeveloperBox SynQuacer platform.
This also enables fwu_metadata_read command and "reboot soon after
update" option.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v3:
  - Use CONFIG_FWU_MDATA_MTD.
  - Remove unused CONFIG_FWU_INIT_BROKEN_METADATA and add
CONFIG_TOOLS_MKFWUMDATA.

Signed-off-by: Sughosh Ganu 
---
 configs/synquacer_developerbox_defconfig | 5 +
 1 file changed, 5 insertions(+)

diff --git a/configs/synquacer_developerbox_defconfig 
b/configs/synquacer_developerbox_defconfig
index 29b1e11401..f2c8c3cc4e 100644
--- a/configs/synquacer_developerbox_defconfig
+++ b/configs/synquacer_developerbox_defconfig
@@ -94,3 +94,8 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_ON_DISK=y
 CONFIG_EFI_IGNORE_OSINDICATIONS=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+CONFIG_EFI_SECURE_BOOT=y
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+CONFIG_FWU_MDATA_MTD=y
+CONFIG_CMD_FWU_METADATA=y
+CONFIG_TOOLS_MKFWUMDATA=y
-- 
2.25.1



[PATCH v5 21/23] doc: synquacer: Add how to enable FWU Multi Bank Update

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Add a section for the instruction of building the FWU Multi Bank
Update supported U-Boot and installation.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 doc/board/socionext/developerbox.rst | 110 +++
 1 file changed, 110 insertions(+)

diff --git a/doc/board/socionext/developerbox.rst 
b/doc/board/socionext/developerbox.rst
index 2d943c23be..d9f38a3897 100644
--- a/doc/board/socionext/developerbox.rst
+++ b/doc/board/socionext/developerbox.rst
@@ -85,3 +85,113 @@ Once the flasher tool is running we are ready flash the 
UEFI image::
 
 After transferring the SPI_NOR_UBOOT.fd, turn off the DSW2-7 and reset the 
board.
 
+
+Enable FWU Multi Bank Update
+
+
+DeveloperBox supports the FWU Multi Bank Update. You *MUST* update both *SCP 
firmware* and *TF-A* for this feature. This will change the layout and the boot 
process but you can switch back to the normal one by changing the DSW 1-4 off.
+
+Configure U-Boot
+
+
+To enable the FWU Multi Bank Update on the DeveloperBox, you need to add 
following configurations to configs/synquacer_developerbox_defconfig ::
+
+ CONFIG_FWU_MULTI_BANK_UPDATE=y
+ CONFIG_FWU_MDATA_MTD=y
+ CONFIG_CMD_FWU_METADATA=y
+ CONFIG_TOOLS_MKFWUMDATA=y
+
+And build it::
+
+  cd u-boot/
+  export ARCH=arm64
+  export CROSS_COMPILE=aarch64-linux-gnu-
+  make synqucer_developerbox_defconfig
+  make -j `noproc`
+  cd ../
+
+By default, the CONFIG_FWU_NUM_BANKS and COFNIG_FWU_NUM_IMAGES_PER_BANKS are 
set to 2 and 1 respectively. This uses FIP (Firmware Image Package) type image 
which contains TF-A, U-Boot and OP-TEE (the OP-TEE is optional.)
+You can use fiptool to compose the FIP image from those firmware images.
+
+Rebuild SCP firmware
+
+
+Rebuild SCP firmware which supports FWU Multi Bank Update as below::
+
+  cd SCP-firmware/
+  OUT=./build/product/synquacer
+  ROMFW_FILE=$OUT/scp_romfw/$SCP_BUILD_MODE/bin/scp_romfw.bin
+  RAMFW_FILE=$OUT/scp_ramfw/$SCP_BUILD_MODE/bin/scp_ramfw.bin
+  ROMRAMFW_FILE=scp_romramfw_release.bin
+
+  make CC=$ARM_EMB_GCC PRODUCT=synquacer MODE=release
+  tr "\000" "\377" < /dev/zero | dd of=${ROMRAMFW_FILE} bs=1 count=196608
+  dd if=${ROMFW_FILE} of=${ROMRAMFW_FILE} bs=1 conv=notrunc seek=0
+  dd if=${RAMFW_FILE} of=${ROMRAMFW_FILE} bs=1 seek=65536
+  cd ../
+
+And you can get the `scp_romramfw_release.bin` file
+
+Rebuild TF-A and FIP
+
+
+Rebuild TF-A which supports FWU Multi Bank Update as below::
+
+  cd arm-trusted-firmware/
+  make CROSS_COMPILE=aarch64-linux-gnu- -j`nproc` PLAT=synquacer \
+ SPD=opteed SQ_RESET_TO_BL2=1 GENERATE_COT=1 MBEDTLS_DIR=../mbedtls \
+ BL33=../u-boot/u-boot.bin all fip fiptool
+
+And make a FIP image.::
+
+  cp build/synquacer/release/fip.bin SPI_NOR_NEWFIP.fd
+  tools/fiptool/fiptool update --tb-fw build/synquacer/release/bl2.bin 
SPI_NOR_NEWFIP.fd
+
+
+UUIDs for the FWU Multi Bank Update
+---
+
+FWU multi-bank update requires some UUIDs. The DeveloperBox platform uses 
following UUIDs.
+
+ - Location UUID for the FIP image: 17e86d77-41f9-4fd7-87ec-a55df9842de5
+ - Image type UUID for the FIP image: 10c36d7d-ca52-b843-b7b9-f9d6c501d108
+ - Image UUID for Bank0 : 5a66a702-99fd-4fef-a392-c26e261a2828
+ - Image UUID for Bank1 : a8f868a1-6e5c-4757-878d-ce63375ef2c0
+
+These UUIDs are used for making a FWU metadata image.
+
+Generate FWU metadata image
+---
+
+Before installation, you need to generate a FWU metadata image file by 
mkfwumdata command as below::
+
+ tools/mkfwumdata -i 1 -b 2 
"17e86d77-41f9-4fd7-87ec-a55df9842de5,10c36d7d-ca52-b843-b7b9-f9d6c501d108,5a66a702-99fd-4fef-a392-c26e261a2828,a8f868a1-6e5c-4757-878d-ce63375ef2c0"
 fwu-mdata.img
+
+Then, you can get the `fwu-mdata.img` image file.
+
+Install via flash writer
+
+
+As explained in above section, the new FIP image and the FWU metadata image 
can be installed via NOR flash writer. Note that the installation offsets for 
the FWU multi bank update supported firmware.
+
+Once the flasher tool is running we are ready flash the images. At first, 
please install FWU metadata at 0x50 (primary) and 0x53 (secondary).::
+
+  flash rawwrite 50 60
+  >> Send fwu-mdata.img via XMODEM (Control-A S in minicom) <<
+
+  flash rawwrite 53 60
+  >> Send fwu-mdata.img via XMODEM (Control-A S in minicom) <<
+
+And write the FIP image to the 0x60 offset.::
+
+  flash rawwrite 60 18
+  >> Send SPI_NOR_NEWFIP.fd via XMODEM (Control-A S in minicom) <<
+
+And write the new SCP firmware.::
+
+  flash write cm3
+  >> Send scp_romramfw_release.bin via XMODEM (Control-A S in minicom) <<
+
+At last, turn on the DSW 3-4 on the board, and reboot.
+Note that if DSW 3-4 is turned off, the DeveloperBox will boot from
+the original EDK2 firmware (or non-FWU U-Boot if you already installed.)
-- 
2.25.1



[PATCH v5 20/23] FWU: synquacer: Generate dfu_alt_info from devicetree partition

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Generate dfu_alt_info from the partition uuid information in the
devicetree, and record the mapping of partition uuid and the
index of dfu_alt_num.

This could be a reference implementation of the automatic DFU
generation for FWU multi-bank update for non GPT firmware
platforms.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 .../synquacer-sc2a11-developerbox-u-boot.dtsi |   3 +
 board/socionext/developerbox/Kconfig  |   1 +
 board/socionext/developerbox/fwu_plat.c   |  79 
 include/configs/synquacer.h   |   6 +-
 include/fwu.h |   6 +
 lib/fwu_updates/Makefile  |   1 +
 lib/fwu_updates/fwu_mtd.c | 173 ++
 7 files changed, 221 insertions(+), 48 deletions(-)
 create mode 100644 lib/fwu_updates/fwu_mtd.c

diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi 
b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
index ab4e3d1c2b..c7ec8a0321 100644
--- a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
+++ b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
@@ -36,6 +36,7 @@
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
+   uuid = "17e86d77-41f9-4fd7-87ec-a55df9842de5";
 
partition@0 {
label = "BootStrap-BL1";
@@ -88,10 +89,12 @@
partition@60 {
label = "FIP-Bank0";
reg = <0x60 0x40>;
+   uuid = 
"5a66a702-99fd-4fef-a392-c26e261a2828";
};
partition@a0 {
label = "FIP-Bank1";
reg = <0xa0 0x40>;
+   uuid = 
"a8f868a1-6e5c-4757-878d-ce63375ef2c0";
};
};
};
diff --git a/board/socionext/developerbox/Kconfig 
b/board/socionext/developerbox/Kconfig
index 7df6750baf..ad2a284f13 100644
--- a/board/socionext/developerbox/Kconfig
+++ b/board/socionext/developerbox/Kconfig
@@ -38,6 +38,7 @@ config FWU_MULTI_BANK_UPDATE
select DM_SPI_FLASH
select DM_FWU_MDATA
select BOARD_LATE_INIT
+   select SET_DFU_ALT_INFO
 
 config FWU_NUM_BANKS
default 2
diff --git a/board/socionext/developerbox/fwu_plat.c 
b/board/socionext/developerbox/fwu_plat.c
index fd6d0e3659..ff06eade7d 100644
--- a/board/socionext/developerbox/fwu_plat.c
+++ b/board/socionext/developerbox/fwu_plat.c
@@ -10,8 +10,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -94,6 +96,36 @@ static int sf_save_data(u32 offs, u32 size, void *data)
return ret;
 }
 
+#define DFU_ALT_BUF_LEN 256
+#define DFU_ALT_NUM_MAX (CONFIG_FWU_NUM_IMAGES_PER_BANK * CONFIG_FWU_NUM_BANKS)
+
+/* Generate dfu_alt_info from partitions */
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+   int ret;
+   struct mtd_info *mtd;
+   static char *buf = NULL;
+
+   if (!buf) {
+   buf = malloc_cache_aligned(DFU_ALT_BUF_LEN);
+   memset(buf, 0, DFU_ALT_BUF_LEN);
+
+   mtd_probe_devices();
+
+   mtd = get_mtd_device_nm("nor1");
+   if (IS_ERR_OR_NULL(mtd))
+   return;
+
+   ret = fwu_gen_alt_info_from_mtd(buf, DFU_ALT_BUF_LEN, mtd);
+   if (ret < 0) {
+   log_err("Error: Failed to generate dfu_alt_info. 
(%d)\n", ret);
+   return;
+   }
+   log_debug("Make dfu_alt_info: '%s'\n", buf);
+   }
+   env_set("dfu_alt_info", buf);
+}
+
 #define PLAT_METADATA_OFFSET   0x51
 #define PLAT_METADATA_SIZE (sizeof(struct devbox_metadata))
 
@@ -105,49 +137,7 @@ struct __packed devbox_metadata {
 int fwu_plat_get_alt_num(struct udevice __always_unused *dev,
 efi_guid_t *image_id, int *alt_num)
 {
-   struct fwu_image_bank_info *bank;
-   struct fwu_mdata *mdata;
-   int i, ret;
-
-   ret = fwu_get_mdata();
-   if (ret < 0)
-   return ret;
-
-   /*
-* DeveloperBox FWU expects Bank:Image = 1:1, and the dfu_alt_info
-* only has the entries for banks. Thus the alt_no should be equal
-* to the bank index number.
-*/
-   ret = -ENOENT;
-   for (i = 0; i < CONFIG_FWU_NUM_BANKS; i++) {
-   bank = >img_entry[0].

[PATCH v5 19/23] FWU: synquacer: Add FWU Multi bank update support for DeveloperBox

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

The DeveloperBox platform can support the FWU Multi bank
update. SCP firmware will switch the boot mode by DSW3-4
and load the Multi bank update supported TF-A BL2 from
0x60 offset on the SPI flash. Thus it can co-exist
with the legacy boot mode (legacy U-Boot or EDK2).

Signed-off-by: Masami Hiramatsu 
---
 Changes in v3:
  - Change devicetree to add partitions.
  - Update fwu_plat_get_alt_num() to find the alt number from the bank index.
  - Use only 2 partitions for AB update.
  - Clear platform-mdata's boot_count to finish platform trial boot.

Signed-off-by: Sughosh Ganu 
---
 .../synquacer-sc2a11-developerbox-u-boot.dtsi |  15 +-
 board/socionext/developerbox/Kconfig  |  13 ++
 board/socionext/developerbox/Makefile |   1 +
 board/socionext/developerbox/fwu_plat.c   | 207 ++
 include/configs/synquacer.h   |   8 +
 5 files changed, 241 insertions(+), 3 deletions(-)
 create mode 100644 board/socionext/developerbox/fwu_plat.c

diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi 
b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
index 095727e03c..ab4e3d1c2b 100644
--- a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
+++ b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
@@ -23,7 +23,7 @@
active_clk_edges;
chipselect_num = <1>;
 
-   spi-flash@0 {
+   spi_flash: spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
@@ -84,11 +84,15 @@
label = "UBoot-Env";
reg = <0x58 0x8>;
};
-
+   /* FWU Multi bank update partitions */
partition@60 {
-   label = "FIP";
+   label = "FIP-Bank0";
reg = <0x60 0x40>;
};
+   partition@a0 {
+   label = "FIP-Bank1";
+   reg = <0xa0 0x40>;
+   };
};
};
};
@@ -114,6 +118,11 @@
optee {
status = "okay";
};
+   fwu-mdata {
+   compatible = "u-boot,fwu-mdata-mtd";
+   fwu-mdata-store = <_flash>;
+   mdata-offsets = <0x50 0x53>;
+   };
};
 };
 
diff --git a/board/socionext/developerbox/Kconfig 
b/board/socionext/developerbox/Kconfig
index c181d26a44..7df6750baf 100644
--- a/board/socionext/developerbox/Kconfig
+++ b/board/socionext/developerbox/Kconfig
@@ -32,4 +32,17 @@ config SYS_CONFIG_NAME
default "synquacer"
 
 endif
+
+config FWU_MULTI_BANK_UPDATE
+   select FWU_MDATA_MTD
+   select DM_SPI_FLASH
+   select DM_FWU_MDATA
+   select BOARD_LATE_INIT
+
+config FWU_NUM_BANKS
+   default 2
+
+config FWU_NUM_IMAGES_PER_BANK
+   default 1
+
 endif
diff --git a/board/socionext/developerbox/Makefile 
b/board/socionext/developerbox/Makefile
index 4a46de995a..9b80ee38e7 100644
--- a/board/socionext/developerbox/Makefile
+++ b/board/socionext/developerbox/Makefile
@@ -7,3 +7,4 @@
 #
 
 obj-y  := developerbox.o
+obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_plat.o
diff --git a/board/socionext/developerbox/fwu_plat.c 
b/board/socionext/developerbox/fwu_plat.c
new file mode 100644
index 00..fd6d0e3659
--- /dev/null
+++ b/board/socionext/developerbox/fwu_plat.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* SPI Flash accessors */
+static struct spi_flash *plat_spi_flash;
+
+static int __plat_sf_get_flash(void)
+{
+   /* TODO: define platform spi-flash somewhere. */
+   plat_spi_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+CONFIG_SF_DEFAULT_CS,
+CONFIG_SF_DEFAULT_SPEED,
+CONFIG_SF_DEFAULT_MODE);
+
+   return 0;
+}
+
+static int plat_sf_get_flash(struct spi_flash **flash)
+{
+   int ret = 0;
+
+   if (!plat_spi_flash)
+   ret = __plat_sf_get_flash();
+
+   *flash = plat_spi_flash;
+
+   return ret;
+}
+
+static int sf_load_data(u32 offs, u32 size, void **data)
+{
+   struct spi_flash *flash;
+   int ret;
+
+   ret = plat_sf_get_f

[PATCH v5 18/23] developerbox: synquacer: Use FIP as the updatable image

2022-06-09 Thread Sughosh Ganu
From: Jassi Brar 

The Synquacer board is migrating to using the FIP as the only
updatable image on the platform with the u-boot and op-tee images
packaged as part of the FIP image. Make changes to the structures used
for capsule updates to reflect this change.

Signed-off-by: Jassi Brar 
Signed-off-by: Sughosh Ganu 
---
 board/socionext/developerbox/developerbox.c | 17 +++--
 include/configs/synquacer.h | 13 ++---
 2 files changed, 5 insertions(+), 25 deletions(-)

diff --git a/board/socionext/developerbox/developerbox.c 
b/board/socionext/developerbox/developerbox.c
index f5a5fe0121..b946428ddb 100644
--- a/board/socionext/developerbox/developerbox.c
+++ b/board/socionext/developerbox/developerbox.c
@@ -20,27 +20,16 @@
 
 #if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
 struct efi_fw_image fw_images[] = {
-   {
-   .image_type_id = DEVELOPERBOX_UBOOT_IMAGE_GUID,
-   .fw_name = u"DEVELOPERBOX-UBOOT",
-   .image_index = 1,
-   },
{
.image_type_id = DEVELOPERBOX_FIP_IMAGE_GUID,
.fw_name = u"DEVELOPERBOX-FIP",
-   .image_index = 2,
-   },
-   {
-   .image_type_id = DEVELOPERBOX_OPTEE_IMAGE_GUID,
-   .fw_name = u"DEVELOPERBOX-OPTEE",
-   .image_index = 3,
+   .image_index = 1,
},
 };
 
 struct efi_capsule_update_info update_info = {
-   .dfu_string = "mtd nor1=u-boot.bin raw 20 10;"
-   "fip.bin raw 18 78000;"
-   "optee.bin raw 50 10",
+   .dfu_string = "mtd nor1=bank0 raw 60 40;"
+   "bank1 raw a0 40;",
.images = fw_images,
 };
 
diff --git a/include/configs/synquacer.h b/include/configs/synquacer.h
index 572f0a42ac..eafcc69e12 100644
--- a/include/configs/synquacer.h
+++ b/include/configs/synquacer.h
@@ -50,18 +50,9 @@
"mtd nor1=fip.bin raw 60 40\0"
 
 /* GUIDs for capsule updatable firmware images */
-#define DEVELOPERBOX_UBOOT_IMAGE_GUID \
-   EFI_GUID(0x53a92e83, 0x4ef4, 0x473a, 0x8b, 0x0d, \
-0xb5, 0xd8, 0xc7, 0xb2, 0xd6, 0x00)
-
 #define DEVELOPERBOX_FIP_IMAGE_GUID \
-   EFI_GUID(0x880866e9, 0x84ba, 0x4793, 0xa9, 0x08, \
-0x33, 0xe0, 0xb9, 0x16, 0xf3, 0x98)
-
-#define DEVELOPERBOX_OPTEE_IMAGE_GUID \
-   EFI_GUID(0xc1b629f1, 0xce0e, 0x4894, 0x82, 0xbf, \
-0xf0, 0xa3, 0x83, 0x87, 0xe6, 0x30)
-
+   EFI_GUID(0x7d6dc310, 0x52ca, 0x43b8, 0xb7, 0xb9, \
+0xf9, 0xd6, 0xc5, 0x01, 0xd1, 0x08)
 /* Distro boot settings */
 #ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_CMD_USB
-- 
2.25.1



[PATCH v5 16/23] FWU: doc: Update documentation for the FWU non-GPT MTD

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Update documentation for the FWU non-GPT MTD device and
mkfwumdata command.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 doc/develop/uefi/fwu_updates.rst | 82 +++-
 1 file changed, 70 insertions(+), 12 deletions(-)

diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst
index 1c34beb7d5..1ea54328d1 100644
--- a/doc/develop/uefi/fwu_updates.rst
+++ b/doc/develop/uefi/fwu_updates.rst
@@ -15,10 +15,11 @@ boot. The UEFI capsule-on-disk update feature is used for 
performing
 the actual updates of the updatable firmware images.
 
 The bookkeeping of the updatable images is done through a structure
-called metadata. Currently, the FWU metadata supports identification
+called FWU metadata. Currently, the FWU metadata supports identification
 of images based on image GUIDs stored on a GPT partitioned storage
-media. There are plans to extend the metadata structure for non GPT
-partitioned devices as well.
+media. If the firmware images are stored on the flash device which
+has no GPT, the platform driver can provide the image identification
+feature.
 
 Accessing the FWU metadata is done through generic API's which are
 defined in a driver which complies with the u-boot's driver model. A
@@ -43,21 +44,31 @@ The feature can be enabled by specifying the following 
configs::
 CONFIG_FWU_MULTI_BANK_UPDATE=y
 CONFIG_CMD_FWU_METADATA=y
 CONFIG_DM_FWU_MDATA=y
-CONFIG_FWU_MDATA_GPT_BLK=y
 CONFIG_FWU_NUM_BANKS=
 CONFIG_FWU_NUM_IMAGES_PER_BANK=
+CONFIG_TOOLS_MKFWUMDATA=y
+
+CONFIG_FWU_MDATA_GPT_BLK=y
+CONFIG_FWU_MDATA_SF=y
 
-in the .config file
+in the .config file.
 
 The first group of configs enable the UEFI capsule-on-disk update
 functionality. The second group of configs enable the FWU Multi Bank
-Update functionality. Please refer to the section
-:ref:`uefi_capsule_update_ref` for more details on generation of the
-UEFI capsule.
+Update functionality. And the third group of configs are FWU Metadata
+drivers. You can enable either one of ``CONFIG_FWU_MDATA_GPT_BLK`` and
+``CONFIG_FWU_MDATA_SF`` or both of them, according to the platform
+support. Anyway, a correct driver will be probed by devicetree node.
+
+Please refer to the section :ref:`uefi_capsule_update_ref` for
+more details on generation of the UEFI capsule.
 
 Setting up the device for GPT partitioned storage
 -
 
+If your platform stores the firmware on GPT partitioned storage
+device (e.g. eMMC/SD), please follow this section.
+
 Before enabling the functionality in U-Boot, certain changes are
 required to be done on the storage device. Assuming a GPT partitioned
 storage device, the storage media needs to be partitioned with the
@@ -74,7 +85,14 @@ media can have additional partitions of non-updatable 
images, like the
 EFI System Partition(ESP), a partition for the root file system etc.
 
 When generating the partitions, a few aspects need to be taken care
-of. Each GPT partition entry in the GPT header has two GUIDs::
+of. The GPT itself has one GUID::
+
+*DiskGUID*
+
+This DiskGUID value should correspond to the *location_uuid* field
+of the FWU metadata.
+
+And each GPT partition entry in the GPT header has two GUIDs::
 
 *PartitionTypeGUID*
 *UniquePartitionGUID*
@@ -93,9 +111,49 @@ Similarly, the FWU specifications defines the GUID value to 
be used
 for the metadata partitions. This would be the PartitionTypeGUID for
 the metadata partitions.
 
-When generating the metadata, the *image_type_uuid* and the
-*image_uuid* values should match the *PartitionTypeGUID* and the
-*UniquePartitionGUID* values respectively.
+Setting up the device for non-GPT partitioned MTD device
+
+
+If your platform stores the firmware on non-GPT partitioned MTD
+device, please follow this section.
+
+Before enabling the functionality in U-Boot, please confirm that
+your platform correctly define (or generate) `dfu_alt_info`, which
+has to have all *banks* as the dfu entries. Also, the devicetree's
+`fwu_mdata` node must be "u-boot,fwu-mdata-mtd" compatible node
+and has FWU metadata offsets on `mdata-offsets` property.
+Please refer to U-Boot
+`doc `__ for
+the device tree bindings.
+
+Similar to the GPT, you can also define the DiskGUID, and the
+UniquePartitionGUID in the devicetree as additional properties of
+the "fixed-partitions" compatible partition nodes, and the platform
+code can generate the `dfu_alt_info` from that. In this case,
+*image_type_uuid* field of the FWU mdata is used instead of the
+PartitionTypeGUID.
+
+Generate the FWU metadata image
+---
+
+To generate the FWU metadata raw image, you can use `tools/mkfwumdata`
+command.
+
+ tools/mkfwumdata -i <#images> -b <#banks> \
+\
+   [location_uuid1,image_type_uuid1,image_uuid1_0,image_uuid1_

[PATCH v5 17/23] synquacer: Update for TBBR (BL2) based new FIP layout

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

This changes SPI NOR flash partition layout for TBBR and
also make the U-Boot as position independent executable
again because BL33 is loaded on the memory.

With enabling TBBR, TF-A BL2 loads all BL3x images from
FIP image, and the U-Boot image is added to the FIP image
as BL33, and loaded to memory when boot instead of XIP
on SPI NOR flash. To avoid mixing up with the legacy images,
this new FIP image is stored on unused area (0x60-) and
the U-Boot env vars are also stored at 0x58 so that
it will not break existing EDK2 area.

NOTE: This introduces an incombatible change to the
synquacer_developerbox_defconfig. If you want to build
U-Boot for booting from legacy FIP image, you need to
specify previous configuration.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 .../synquacer-sc2a11-developerbox-u-boot.dtsi | 26 +--
 configs/synquacer_developerbox_defconfig  |  5 ++--
 include/configs/synquacer.h   |  4 +--
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi 
b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
index 7a56116d6f..095727e03c 100644
--- a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
+++ b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi
@@ -56,7 +56,7 @@
};
 
partition@18 {
-   label = "FIP-TFA";
+   label = "LegacyFIP";
reg = <0x18 0x78000>;
};
 
@@ -66,18 +66,28 @@
};
 
partition@20 {
-   label = "U-Boot";
-   reg = <0x20 0x10>;
+   label = "EDK2";
+   reg = <0x20 0x20>;
};
 
-   partition@30 {
-   label = "UBoot-Env";
-   reg = <0x30 0x10>;
+   partition@40 {
+   label = "EDK2-Env";
+   reg = <0x40 0x10>;
};
 
partition@50 {
-   label = "Ex-OPTEE";
-   reg = <0x50 0x20>;
+   label = "Metadata";
+   reg = <0x50 0x8>;
+   };
+
+   partition@58 {
+   label = "UBoot-Env";
+   reg = <0x58 0x8>;
+   };
+
+   partition@60 {
+   label = "FIP";
+   reg = <0x60 0x40>;
};
};
};
diff --git a/configs/synquacer_developerbox_defconfig 
b/configs/synquacer_developerbox_defconfig
index add6041e27..29b1e11401 100644
--- a/configs/synquacer_developerbox_defconfig
+++ b/configs/synquacer_developerbox_defconfig
@@ -1,10 +1,11 @@
 CONFIG_ARM=y
 CONFIG_ARCH_SYNQUACER=y
-CONFIG_SYS_TEXT_BASE=0x0820
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_SYS_TEXT_BASE=0
 CONFIG_SYS_MALLOC_LEN=0x100
 CONFIG_SYS_MALLOC_F_LEN=0x400
 CONFIG_ENV_SIZE=0x3
-CONFIG_ENV_OFFSET=0x30
+CONFIG_ENV_OFFSET=0x58
 CONFIG_ENV_SECT_SIZE=0x1
 CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="synquacer-sc2a11-developerbox"
diff --git a/include/configs/synquacer.h b/include/configs/synquacer.h
index 5686a5b910..572f0a42ac 100644
--- a/include/configs/synquacer.h
+++ b/include/configs/synquacer.h
@@ -47,9 +47,7 @@
 /* Since U-Boot 64bit PCIe support is limited, disable 64bit MMIO support */
 
 #define DEFAULT_DFU_ALT_INFO "dfu_alt_info="   \
-   "mtd nor1=u-boot.bin raw 20 10;"\
-   "fip.bin raw 18 78000;" \
-   "optee.bin raw 50 10\0"
+   "mtd nor1=fip.bin raw 60 40\0"
 
 /* GUIDs for capsule updatable firmware images */
 #define DEVELOPERBOX_UBOOT_IMAGE_GUID \
-- 
2.25.1



[PATCH v5 15/23] tools: Add mkfwumdata tool for FWU metadata image

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Add 'mkfwumdata' tool which can generate an image of the FWU metadata
which is required for initializing the platform.

Usage:
  mkfwumdata -i NR_IMAGES -b NR_BANKS [--guid] \
LOCATION_UUID0,IMAGE_TYPE_UUID0,BANK0_IMAGE_UUID[,BANK1_IMAGE_UUID[,...]] \
LOCATION_UUID1,... \
IMAGE_FILE

'-i' takes the number of images and '-b' takes the number of
banks. This takes lists of uuids for the images on arguments,
and the last argument must be the output image file name.

'--guid' (or '-g' in short) allows user to specify the location UUID
and image IDs in GUID instead of UUID. This option is useful if the
platform uses GPT partiotion. In this case, the UUID list
(for an image) becomes;

DiskGUID,ParitionTypeGUID,UniquePartitionGUID,...

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 tools/Kconfig  |   9 ++
 tools/Makefile |   4 +
 tools/mkfwumdata.c | 298 +
 3 files changed, 311 insertions(+)
 create mode 100644 tools/mkfwumdata.c

diff --git a/tools/Kconfig b/tools/Kconfig
index 117c921da3..3484be99d0 100644
--- a/tools/Kconfig
+++ b/tools/Kconfig
@@ -98,4 +98,13 @@ config TOOLS_MKEFICAPSULE
  optionally sign that file. If you want to enable UEFI capsule
  update feature on your target, you certainly need this.
 
+config TOOLS_MKFWUMDATA
+   bool "Build mkfwumdata command"
+   default y if FWU_MULTI_BANK_UPDATE
+   help
+ This command allows users to create a raw image of the FWU
+ metadata for initial installation of the FWU multi bank
+ update on the board. The installation method depends on
+ the platform.
+
 endmenu
diff --git a/tools/Makefile b/tools/Makefile
index 9f2339666a..cd39e5ff6f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -245,6 +245,10 @@ HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include
 HOSTLDLIBS_mkeficapsule += -lgnutls -luuid
 hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule
 
+mkfwumdata-objs := mkfwumdata.o lib/crc32.o
+HOSTLDLIBS_mkfwumdata += -luuid
+hostprogs-$(CONFIG_TOOLS_MKFWUMDATA) += mkfwumdata
+
 # We build some files with extra pedantic flags to try to minimize things
 # that won't build on some weird host compiler -- though there are lots of
 # exceptions for files that aren't complaint.
diff --git a/tools/mkfwumdata.c b/tools/mkfwumdata.c
new file mode 100644
index 00..4eb304cae3
--- /dev/null
+++ b/tools/mkfwumdata.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* This will dynamically allocate the fwu_mdata */
+#define CONFIG_FWU_NUM_BANKS   0
+#define CONFIG_FWU_NUM_IMAGES_PER_BANK 0
+
+/* Since we can not include fwu.h, redefine version here. */
+#define FWU_MDATA_VERSION  1
+
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#include 
+
+/* TODO: Endianess conversion may be required for some arch. */
+
+static const char *opts_short = "b:i:a:gh";
+
+static struct option options[] = {
+   {"banks", required_argument, NULL, 'b'},
+   {"images", required_argument, NULL, 'i'},
+   {"guid", required_argument, NULL, 'g'},
+   {"active-bank", required_argument, NULL, 'a'},
+   {"help", no_argument, NULL, 'h'},
+   {NULL, 0, NULL, 0},
+};
+
+static void print_usage(void)
+{
+   fprintf(stderr, "Usage: mkfwumdata [options]  [...] \n");
+   fprintf(stderr, "Options:\n"
+   "\t-i, --images   Number of images\n"
+   "\t-b, --banksNumber of banks\n"
+   "\t-a, --active-bank  Active bank\n"
+   "\t-g, --guid  Use GUID instead of UUID\n"
+   "\t-h, --help  print a help message\n"
+   );
+   fprintf(stderr, "UUIDs list syntax:\n"
+   "\t,,[,]\n"
+   "\n\tYou must specify # of banks of image-uuid and # of images 
of the lists.\n"
+   "\tIf the location uuid and image uuid are '0', those are 
filled with null uuid.\n"
+  );
+}
+
+static bool __use_guid;
+static u32 active_bank;
+
+struct fwu_mdata_object {
+   size_t images;
+   size_t banks;
+   size_t size;
+   struct fwu_mdata *mdata;
+};
+
+struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks)
+{
+   struct fwu_mdata_object *mobj;
+
+   mobj = malloc(sizeof(*mobj));
+   if (!mobj)
+   return NULL;
+   mobj->size = sizeof(struct fwu_mdata) +
+   (sizeof(struct fwu_image_entry) +
+sizeof(struct fwu_image_bank_info) * banks) * images;
+   mobj->images = images;

[PATCH v5 13/23] FWU: Add FWU metadata access driver for non-GPT MTD devices

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

For the platform which doesn't have GPT partitions for the firmware
but on MTD devices, the FWU metadata is stored on MTD device as raw
image at specific offset. This driver gives the access methods
for the FWU metadata information on such MTD devices.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 drivers/fwu-mdata/Kconfig |   8 +
 drivers/fwu-mdata/Makefile|   1 +
 drivers/fwu-mdata/fwu_mdata_mtd.c | 308 ++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/fwu-mdata/fwu_mdata_mtd.c

diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
index d5edef19d6..a8fa9ad783 100644
--- a/drivers/fwu-mdata/Kconfig
+++ b/drivers/fwu-mdata/Kconfig
@@ -14,3 +14,11 @@ config FWU_MDATA_GPT_BLK
help
  Enable support for accessing FWU Metadata on GPT partitioned
  block devices.
+
+config FWU_MDATA_MTD
+   bool "FWU Metadata access for non-GPT MTD devices"
+   depends on DM_FWU_MDATA && MTD
+   help
+ Enable support for accessing FWU Metadata on non-partitioned
+ (or non-GPT partitioned, e.g. partition nodes in devicetree)
+ MTD devices.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
index 12a5b4fe04..c574c59be2 100644
--- a/drivers/fwu-mdata/Makefile
+++ b/drivers/fwu-mdata/Makefile
@@ -5,3 +5,4 @@
 
 obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
 obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
+obj-$(CONFIG_FWU_MDATA_MTD) += fwu_mdata_mtd.o
diff --git a/drivers/fwu-mdata/fwu_mdata_mtd.c 
b/drivers/fwu-mdata/fwu_mdata_mtd.c
new file mode 100644
index 00..9eb471e73e
--- /dev/null
+++ b/drivers/fwu-mdata/fwu_mdata_mtd.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct fwu_mdata_mtd_priv {
+   struct mtd_info *mtd;
+   u32 pri_offset;
+   u32 sec_offset;
+};
+
+enum fwu_mtd_op {
+   FWU_MTD_READ,
+   FWU_MTD_WRITE,
+};
+
+static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
+{
+   return !do_div(size, mtd->erasesize);
+}
+
+static int mtd_io_data(struct mtd_info *mtd, u32 offs, u32 size, void *data,
+  enum fwu_mtd_op op)
+{
+   struct mtd_oob_ops io_op ={};
+   u64 lock_offs, lock_len;
+   size_t len;
+   void *buf;
+   int ret;
+
+   if (!mtd_is_aligned_with_block_size(mtd, offs))
+   return -EINVAL;
+   lock_offs = offs;
+   lock_len = round_up(size, mtd->erasesize);
+
+   ret = mtd_unlock(mtd, lock_offs, lock_len);
+   if (ret && ret != -EOPNOTSUPP)
+   return ret;
+
+   if (op == FWU_MTD_WRITE) {
+   struct erase_info erase_op = {};
+
+   /* This will expand erase size to align with the block size */
+   erase_op.mtd = mtd;
+   erase_op.addr = lock_offs;
+   erase_op.len = lock_len;
+   erase_op.scrub = 0;
+
+   ret = mtd_erase(mtd, _op);
+   if (ret)
+   goto lock_out;
+   }
+
+   /* Also, expand the write size to align with the write size */
+   len = round_up(size, mtd->writesize);
+
+   buf = memalign(ARCH_DMA_MINALIGN, len);
+   if (!buf) {
+   ret = -ENOMEM;
+   goto lock_out;
+   }
+   io_op.mode = MTD_OPS_AUTO_OOB;
+   io_op.len = len;
+   io_op.ooblen = 0;
+   io_op.datbuf = buf;
+   io_op.oobbuf = NULL;
+
+   if (op == FWU_MTD_WRITE) {
+   memcpy(buf, data, size);
+   ret = mtd_write_oob(mtd, offs, _op);
+   } else {
+   ret = mtd_read_oob(mtd, offs, _op);
+   if (!ret)
+   memcpy(data, buf, size);
+   }
+   free(buf);
+
+lock_out:
+   mtd_lock(mtd, lock_offs, lock_len);
+
+   return ret;
+}
+
+static int fwu_mtd_load_mdata(struct mtd_info *mtd, struct fwu_mdata **mdata,
+ u32 offs, bool primary)
+{
+   size_t size = sizeof(struct fwu_mdata);
+   int ret;
+
+   *mdata = malloc(size);
+   if (!*mdata)
+   return -ENOMEM;
+
+   ret = mtd_io_data(mtd, offs, size, (void *)*mdata, FWU_MTD_READ);
+   if (ret >= 0) {
+   ret = fwu_verify_mdata(*mdata, primary);
+   if (ret < 0) {
+   free(*mdata);
+   *mdata = NULL;
+   }
+   }
+
+   return ret;
+}
+
+static int fwu_mtd_load_primary_mdata(struct fwu_mdata_mtd_priv *mtd_priv,
+struct fwu_mdata **mdata)
+{
+   return fwu_mtd_load_mdata(mtd_priv->mtd, mdata, mtd_priv->pri_offset, 
true);
+}
+
+static int fwu_mtd_load_seco

[PATCH v5 14/23] dt/bindings: firmware: Add FWU metadata on MTD devices binding

2022-06-09 Thread Sughosh Ganu
From: Masami Hiramatsu 

Add a devicetree-binding YAML file for the FWU metadata on MTD
devices without GPT.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Sughosh Ganu 
---
 .../firmware/uboot,fwu-mdata-mtd.yaml | 38 +++
 1 file changed, 38 insertions(+)
 create mode 100644 doc/device-tree-bindings/firmware/uboot,fwu-mdata-mtd.yaml

diff --git a/doc/device-tree-bindings/firmware/uboot,fwu-mdata-mtd.yaml 
b/doc/device-tree-bindings/firmware/uboot,fwu-mdata-mtd.yaml
new file mode 100644
index 00..4f5404f999
--- /dev/null
+++ b/doc/device-tree-bindings/firmware/uboot,fwu-mdata-mtd.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/u-boot,fwu-mdata-sf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: FWU metadata on MTD device without GPT
+
+maintainers:
+ - Masami Hiramatsu 
+
+properties:
+  compatible:
+items:
+  - const: u-boot,fwu-mdata-mtd
+
+  fwu-mdata-store:
+maxItems: 1
+description: Phandle of the MTD device which contains the FWU medatata.
+
+  mdata-offsets:
+minItems: 2
+description: Offsets of the primary and secondary FWU metadata in the NOR 
flash.
+
+required:
+  - compatible
+  - fwu-mdata-store
+  - mdata-offsets
+
+additionalProperties: false
+
+examples:
+  - |
+fwu-mdata {
+compatible = "u-boot,fwu-mdata-mtd";
+fwu-mdata-store = <>;
+mdata-offsets = <0x50 0x53>;
+};
-- 
2.25.1



[PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-09 Thread Sughosh Ganu
The Dependable Boot specification[1] describes the structure of the
firmware accept and revert capsules. These are empty capsules which
are used for signalling the acceptance or rejection of the updated
firmware by the OS. Add support for generating these empty capsules.

[1] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Signed-off-by: Sughosh Ganu 
---
 doc/mkeficapsule.1   |  29 ++---
 tools/eficapsule.h   |   8 +++
 tools/mkeficapsule.c | 139 +--
 3 files changed, 151 insertions(+), 25 deletions(-)

diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index 09bdc24295..77ca061efd 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
 
 .SH SYNOPSIS
 .B mkeficapsule
-.RI [ options "] " image-blob " " capsule-file
+.RI [ options ] " " [ image-blob ] " " capsule-file
 
 .SH "DESCRIPTION"
 .B mkeficapsule
@@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given 
private key.
 In this case, the update will be authenticated by verifying the signature
 before applying.
 
+Additionally, an empty capsule file can be generated for acceptance or
+rejection of firmware images by a governing component like an Operating
+System. The empty capsules do not require an image-blob input file.
+
+
 .B mkeficapsule
-takes any type of image files, including:
+takes any type of image files when generating non empty capsules, including:
 .TP
 .I raw image
 format is a single binary blob of any type of firmware.
@@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
 This type of image file can be generated by
 .BR mkimage .
 
-.PP
-If you want to use other types than above two, you should explicitly
-specify a guid for the FMP driver.
-
 .SH "OPTIONS"
+
 .TP
 .BI "-g\fR,\fB --guid " guid-string
 Specify guid for image blob type. The format is:
 ----
 
 The first three elements are in little endian, while the rest
-is in big endian.
+is in big endian. The option must be specified for all non empty and
+image acceptance capsules
 
 .TP
 .BI "-i\fR,\fB --index " index
@@ -57,6 +60,18 @@ Specify an image index
 .BI "-I\fR,\fB --instance " instance
 Specify a hardware instance
 
+.PP
+For generation of firmware accept empty capsule
+.BR --guid
+is mandatory
+.TP
+.BI "-A\fR,\fB --fw-accept "
+Generate a firmware acceptance empty capsule
+
+.TP
+.BI "-R\fR,\fB --fw-revert "
+Generate a firmware revert empty capsule
+
 .TP
 .BR -h ", " --help
 Print a help message
diff --git a/tools/eficapsule.h b/tools/eficapsule.h
index d63b831443..072a4b5598 100644
--- a/tools/eficapsule.h
+++ b/tools/eficapsule.h
@@ -41,6 +41,14 @@ typedef struct {
EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \
 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
 
+#define FW_ACCEPT_OS_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
+#define FW_REVERT_OS_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
 /* flags */
 #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET  0x0001
 
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 5f74d23b9e..e8eb6b070d 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,16 @@ static const char *tool_name = "mkeficapsule";
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:dh";
+static const char *opts_short = "g:i:I:v:p:c:m:dhAR";
+
+static bool empty_capsule;
+static unsigned char capsule;
+
+enum {
+   CAPSULE_NORMAL_BLOB = 0,
+   CAPSULE_ACCEPT,
+   CAPSULE_REVERT,
+} capsule_type;
 
 static struct option options[] = {
{"guid", required_argument, NULL, 'g'},
@@ -39,24 +48,47 @@ static struct option options[] = {
{"certificate", required_argument, NULL, 'c'},
{"monotonic-count", required_argument, NULL, 'm'},
{"dump-sig", no_argument, NULL, 'd'},
+   {"fw-accept", no_argument, NULL, 'A'},
+   {"fw-revert", no_argument, NULL, 'R'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
 };
 
 static void print_usage(void)
 {
-   fprintf(stderr, "Usage: %s [options]  \n"
-   "Options:\n"
-
-   "\t-g, --guid guid for image blob type\n"
-   "\t-i, --index  update image index\n"
-   "\t-I, --instanceupdate hardware instance\n"
-   "\t-p,

[PATCH v5 12/23] FWU: doc: Add documentation for the FWU feature

2022-06-09 Thread Sughosh Ganu
Add documentattion for the FWU Multi Bank Update feature. The document
describes the steps needed for setting up the platform for the
feature, as well as steps for enabling the feature on the platform.

Signed-off-by: Sughosh Ganu 
---
 doc/develop/uefi/fwu_updates.rst | 142 +++
 doc/develop/uefi/index.rst   |   1 +
 doc/develop/uefi/uefi.rst|   2 +
 3 files changed, 145 insertions(+)
 create mode 100644 doc/develop/uefi/fwu_updates.rst

diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst
new file mode 100644
index 00..1c34beb7d5
--- /dev/null
+++ b/doc/develop/uefi/fwu_updates.rst
@@ -0,0 +1,142 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (c) 2022 Linaro Limited
+
+FWU Multi Bank Updates in U-Boot
+
+
+The FWU Multi Bank Update feature implements the firmware update
+mechanism described in the PSA Firmware Update for A-profile Arm
+Architecture specification[1]. Certain aspects of the Dependable
+Boot specification[2] are also implemented. The feature provides a
+mechanism to have multiple banks of updatable firmware images and for
+updating the firmware images on the non-booted bank. On a successful
+update, the platform boots from the updated bank on subsequent
+boot. The UEFI capsule-on-disk update feature is used for performing
+the actual updates of the updatable firmware images.
+
+The bookkeeping of the updatable images is done through a structure
+called metadata. Currently, the FWU metadata supports identification
+of images based on image GUIDs stored on a GPT partitioned storage
+media. There are plans to extend the metadata structure for non GPT
+partitioned devices as well.
+
+Accessing the FWU metadata is done through generic API's which are
+defined in a driver which complies with the u-boot's driver model. A
+new uclass UCLASS_FWU_MDATA has been added for accessing the FWU
+metadata. Individual drivers can be added based on the type of storage
+media, and it's partitioning method. Details of the storage device
+containing the FWU metadata partitions are specified through a U-Boot
+specific device tree property `fwu-mdata-store`. Please refer to
+U-Boot `doc `__ for
+the device tree bindings.
+
+Enabling the FWU Multi Bank Update feature
+--
+
+The feature can be enabled by specifying the following configs::
+
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y
+CONFIG_EFI_CAPSULE_FIRMWARE=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+CONFIG_CMD_FWU_METADATA=y
+CONFIG_DM_FWU_MDATA=y
+CONFIG_FWU_MDATA_GPT_BLK=y
+CONFIG_FWU_NUM_BANKS=
+CONFIG_FWU_NUM_IMAGES_PER_BANK=
+
+in the .config file
+
+The first group of configs enable the UEFI capsule-on-disk update
+functionality. The second group of configs enable the FWU Multi Bank
+Update functionality. Please refer to the section
+:ref:`uefi_capsule_update_ref` for more details on generation of the
+UEFI capsule.
+
+Setting up the device for GPT partitioned storage
+-
+
+Before enabling the functionality in U-Boot, certain changes are
+required to be done on the storage device. Assuming a GPT partitioned
+storage device, the storage media needs to be partitioned with the
+correct number of partitions, given the number of banks and number of
+images per bank that the platform is going to support. Each updatable
+firmware image will be stored on an separate partition. In addition,
+the two copies of the FWU metadata will be stored on two separate
+partitions.
+
+As an example, a platform supporting two banks with each bank
+containing three images would need to have 2 * 3 = 6 parititions plus
+the two metadata partitions, or 8 partitions. In addition the storage
+media can have additional partitions of non-updatable images, like the
+EFI System Partition(ESP), a partition for the root file system etc.
+
+When generating the partitions, a few aspects need to be taken care
+of. Each GPT partition entry in the GPT header has two GUIDs::
+
+*PartitionTypeGUID*
+*UniquePartitionGUID*
+
+The PartitionTypeGUID value should correspond to the *image_type_uuid*
+field of the FWU metadata. This field is used to identify a given type
+of updatable firmware image, e.g. u-boot, op-tee, FIP etc. This GUID
+should also be used for specifying the `--guid` parameter when
+generating the capsule.
+
+The UniquePartitionGUID value should correspond to the *image_uuid*
+field in the FWU metadata. This GUID is used to identify images of a
+given image type in different banks.
+
+Similarly, the FWU specifications defines the GUID value to be used
+for the metadata partitions. This would be the PartitionTypeGUID for
+the metadata partitions.
+
+When generating the metadata, the *image_type_uuid* and the
+*image_uuid* values should match the *PartitionTypeGUID

[PATCH v5 09/23] FWU: Add support for the FWU Multi Bank Update feature

2022-06-09 Thread Sughosh Ganu
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.h|  12 +-
 lib/Kconfig  |   6 +
 lib/Makefile |   1 +
 lib/efi_loader/efi_capsule.c | 231 ++-
 lib/efi_loader/efi_setup.c   |   3 +-
 lib/fwu_updates/Kconfig  |  31 +
 lib/fwu_updates/Makefile |   6 +
 lib/fwu_updates/fwu.c|  26 
 8 files changed, 309 insertions(+), 7 deletions(-)
 create mode 100644 lib/fwu_updates/Kconfig
 create mode 100644 lib/fwu_updates/Makefile

diff --git a/include/fwu.h b/include/fwu.h
index 8fbd91b463..9c8012407b 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -28,13 +28,23 @@ struct fwu_mdata_ops {
 };
 
 #define FWU_MDATA_VERSION  0x1
+#define FWU_IMAGE_ACCEPTED 0x1
 
 #define FWU_MDATA_GUID \
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
-int fwu_boottime_checks(void);
+#define FWU_OS_REQUEST_FW_REVERT_GUID \
+   EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
+0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
+
+#define FWU_OS_REQUEST_FW_ACCEPT_GUID \
+   EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \
+0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8)
+
 u8 fwu_update_checks_pass(void);
+int fwu_boottime_checks(void);
+int fwu_trial_state_ctr_start(void);
 
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
diff --git a/lib/Kconfig b/lib/Kconfig
index acc0ac081a..4ca6ea226b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -966,3 +966,9 @@ config PHANDLE_CHECK_SEQ
  phandles in fdtdec_get_alias_seq() function.
 
 endmenu
+
+menu "FWU Multi Bank Updates"
+
+source lib/fwu_updates/Kconfig
+
+endmenu
diff --git a/lib/Makefile b/lib/Makefile
index d9b1811f75..0cf8527c2d 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 c76a5f3570..8ca041e6a2 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 
@@ -32,6 +33,17 @@ static const efi_guid_t 
efi_guid_firmware_management_capsule_id =
EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 const efi_guid_t efi_guid_firmware_management_protocol =
EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
+const efi_guid_t fwu_guid_os_request_fw_revert =
+   FWU_OS_REQUEST_FW_REVERT_GUID;
+const efi_guid_t fwu_guid_os_request_fw_accept =
+   FWU_OS_REQUEST_FW_ACCEPT_GUID;
+
+#define FW_ACCEPT_OS   (u32)0x8000
+
+__maybe_unused static u32 update_index;
+__maybe_unused static bool capsule_update;
+__maybe_unused static bool fw_accept_os;
+static bool image_index_check = true;
 
 #ifdef CONFIG_EFI_CAPSULE_ON_DISK
 /* for file system access */
@@ -205,7 +217,8 @@ efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 
instance,
log_debug("+++ desc[%d] index: %d, name: %ls\n",
  j, desc->image_index, desc->image_id_name);
if (!guidcmp(>image_type_id, image_type) &&
-   (desc->image_index == image_index) &&
+   (!image_index_check ||
+desc->image_index == image_index) &&
(!instance ||
 !desc->hardware_instance ||
  desc->hardware_instance == instance))
@@ -388,6 +401,87 @@ efi_status_t efi_capsule_authenticate(const void *capsule, 
efi_uintn_t capsule_s
 }
 #endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
 
+static bool fwu_empty_capsule(struct efi_capsule_header *capsule)
+{
+   return !guidcmp(>capsule_guid,
+   _guid_os_request_fw_revert) ||
+   !guidcmp(>capsule_guid,
+_guid_os_request_fw_accept);
+}
+
+static ef

[PATCH v5 10/23] FWU: cmd: Add a command to read FWU metadata

2022-06-09 Thread Sughosh Ganu
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 |  7 +
 cmd/Makefile|  1 +
 cmd/fwu_mdata.c | 74 +
 3 files changed, 82 insertions(+)
 create mode 100644 cmd/fwu_mdata.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..275becd837 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -144,6 +144,13 @@ config CMD_CPU
  internal name) and clock frequency. Other information may be
  available depending on the CPU driver.
 
+config CMD_FWU_METADATA
+   bool "fwu metadata read"
+   depends on FWU_MULTI_BANK_UPDATE
+   default y if FWU_MULTI_BANK_UPDATE
+   help
+ Command to read the metadata and dump it's contents
+
 config CMD_LICENSE
bool "license"
select BUILD_BIN2C
diff --git a/cmd/Makefile b/cmd/Makefile
index 5e43a1e022..259a93bc65 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o
 obj-$(CONFIG_CMD_FPGAD) += fpgad.o
 obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
+obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
 obj-$(CONFIG_CMD_HVC) += smccc.o
diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c
new file mode 100644
index 00..bc20ca26a3
--- /dev/null
+++ b/cmd/fwu_mdata.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static void print_mdata(struct fwu_mdata *mdata)
+{
+   int i, j;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_info;
+   u32 nimages, nbanks;
+
+   printf("\tFWU Metadata\n");
+   printf("crc32: %#x\n", mdata->crc32);
+   printf("version: %#x\n", mdata->version);
+   printf("active_index: %#x\n", mdata->active_index);
+   printf("previous_active_index: %#x\n", mdata->previous_active_index);
+
+   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
+   nbanks = CONFIG_FWU_NUM_BANKS;
+   printf("\tImage Info\n");
+   for (i = 0; i < nimages; i++) {
+   img_entry = >img_entry[i];
+   printf("\nImage Type Guid: %pUL\n", 
_entry->image_type_uuid);
+   printf("Location Guid: %pUL\n", _entry->location_uuid);
+   for (j = 0; j < nbanks; j++) {
+   img_info = _entry->img_bank_info[j];
+   printf("Image Guid:  %pUL\n", _info->image_uuid);
+   printf("Image Acceptance: %#x\n", img_info->accepted);
+   }
+   }
+}
+
+int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag,
+int argc, char * const argv[])
+{
+   struct udevice *dev;
+   int ret = CMD_RET_SUCCESS;
+   struct fwu_mdata *mdata = NULL;
+
+   if (uclass_get_device(UCLASS_FWU_MDATA, 0, ) || !dev) {
+   log_err("Unable to get FWU metadata device\n");
+   return CMD_RET_FAILURE;
+   }
+
+   ret = fwu_get_mdata();
+   if (ret < 0) {
+   log_err("Unable to get valid FWU metadata\n");
+   ret = CMD_RET_FAILURE;
+   goto out;
+   }
+
+   print_mdata(mdata);
+
+out:
+   free(mdata);
+   return ret;
+}
+
+U_BOOT_CMD(
+   fwu_mdata_read, 1,  1,  do_fwu_mdata_read,
+   "Read and print FWU metadata",
+   ""
+);
-- 
2.25.1



[PATCH v5 08/23] FWU: Add boot time checks as highlighted by the FWU specification

2022-06-09 Thread Sughosh Ganu
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  |   5 ++
 include/fwu.h |   3 +
 lib/fwu_updates/fwu.c | 170 ++
 3 files changed, 178 insertions(+)
 create mode 100644 lib/fwu_updates/fwu.c

diff --git a/common/board_r.c b/common/board_r.c
index 6f4aca2077..33a600715d 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -797,6 +798,10 @@ static init_fnc_t init_sequence_r[] = {
 #if defined(CONFIG_PRAM)
initr_mem,
 #endif
+
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+   fwu_boottime_checks,
+#endif
run_main_loop,
 };
 
diff --git a/include/fwu.h b/include/fwu.h
index 41774ff9e2..8fbd91b463 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -33,6 +33,9 @@ struct fwu_mdata_ops {
EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
 
+int fwu_boottime_checks(void);
+u8 fwu_update_checks_pass(void);
+
 int fwu_get_mdata(struct fwu_mdata **mdata);
 int fwu_update_mdata(struct fwu_mdata *mdata);
 int fwu_get_active_index(u32 *active_idx);
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
new file mode 100644
index 00..af884439fb
--- /dev/null
+++ b/lib/fwu_updates/fwu.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static u8 trial_state;
+static u8 boottime_check;
+
+static int fwu_trial_state_check(void)
+{
+   int ret, i;
+   efi_status_t status;
+   efi_uintn_t var_size;
+   u16 trial_state_ctr;
+   u32 nimages, active_bank, var_attributes, active_idx;
+   struct fwu_mdata *mdata = NULL;
+   struct fwu_image_entry *img_entry;
+   struct fwu_image_bank_info *img_bank_info;
+
+   ret = fwu_get_mdata();
+   if (ret)
+   return ret;
+
+   ret = 0;
+   nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK;
+   active_bank = mdata->active_index;
+   img_entry = >img_entry[0];
+   for (i = 0; i < nimages; i++) {
+   img_bank_info = _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;
+   status = efi_get_variable_int(L"TrialStateCtr",
+ _global_variable_guid,
+ _attributes,
+ _size, _state_ctr,
+ NULL);
+   if (status != EFI_SUCCESS) {
+   log_err("Unable to read TrialStateCtr variable\n");
+   ret = -1;
+   goto out;
+   }
+
+   ++trial_state_ctr;
+   if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) {
+   log_info("Trial State count exceeded. Revert back to 
previous_active_index\n");
+   active_idx = mdata->active_index;
+   ret = fwu_revert_boot_index();
+   if (ret) {
+   log_err("Unable to revert active_index\n");
+   goto out;
+   }
+
+   trial_state_ctr = 0;
+   status = efi_set_variable_int(L"TrialStateCtr",
+ _global_variable_guid,
+ var_attributes,
+ 0,
+

[PATCH v5 07/23] FWU: STM32MP1: Add support to read boot index from backup register

2022-06-09 Thread Sughosh Ganu
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 | 4 
 board/st/stm32mp1/stm32mp1.c   | 7 +++
 include/fwu.h  | 2 +-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h 
b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 47e88fc3dc..40995ee142 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -100,6 +100,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_INFO_REG 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)
@@ -118,6 +119,9 @@ enum boot_device {
 #define TAMP_BOOT_INSTANCE_MASKGENMASK(3, 0)
 #define TAMP_BOOT_FORCED_MASK  GENMASK(7, 0)
 #define TAMP_BOOT_DEBUG_ON BIT(16)
+#define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0)
+
+#define TAMP_FWU_BOOT_IDX_OFFSET   0
 
 enum forced_boot_mode {
BOOT_NORMAL = 0x00,
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index e68bf09955..dff41ed6f6 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -1081,4 +1081,11 @@ int fwu_plat_get_update_index(u32 *update_idx)
return ret;
 }
 
+void fwu_plat_get_bootidx(void *boot_idx)
+{
+   u32 *bootidx = boot_idx;
+
+   *bootidx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
+   TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
+}
 #endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 36e58afa29..41774ff9e2 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -46,7 +46,7 @@ int fwu_revert_boot_index(void);
 int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
 int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
-
+void fwu_plat_get_bootidx(void *boot_idx);
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
 int fwu_plat_get_update_index(u32 *update_idx);
-- 
2.25.1



[PATCH v5 06/23] FWU: stm32mp1: Add helper functions for accessing FWU metadata

2022-06-09 Thread Sughosh Ganu
Add helper functions needed for accessing the FWU metadata which
contains information on the updatable images. These functions have
been added for the STM32MP157C-DK2 board which has the updatable
images on the uSD card, formatted as GPT partitions.

Signed-off-by: Sughosh Ganu 
---
 board/st/stm32mp1/stm32mp1.c | 115 +++
 include/fwu.h|   2 +
 2 files changed, 117 insertions(+)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 62d98ad776..e68bf09955 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -7,9 +7,11 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,9 +27,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -967,3 +971,114 @@ static void board_copro_image_process(ulong fw_image, 
size_t fw_size)
 }
 
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
+
+#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
+#include 
+#include 
+
+static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t 
*image_guid)
+{
+   int i;
+   struct disk_partition info;
+   efi_guid_t unique_part_guid;
+
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.uuid, unique_part_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_part_guid, image_guid))
+   return i;
+   }
+
+   log_err("No partition found with image_guid %pUs\n", image_guid);
+   return -ENOENT;
+}
+
+static int gpt_plat_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+   int *alt_num)
+{
+   int ret = -1;
+   int i, part, dev_num;
+   int nalt;
+   struct dfu_entity *dfu;
+
+   dev_num = desc->devnum;
+   part = get_gpt_dfu_identifier(desc, image_guid);
+   if (part < 0)
+   return -ENOENT;
+
+   dfu_init_env_entities(NULL, NULL);
+
+   nalt = 0;
+   list_for_each_entry(dfu, _list, list) {
+   nalt++;
+   }
+
+   if (!nalt) {
+   log_warning("No entities in dfu_alt_info\n");
+   dfu_free_entities();
+   return -ENOENT;
+   }
+
+
+   for (i = 0; i < nalt; i++) {
+   dfu = dfu_get_entity(i);
+
+   if (!dfu)
+   continue;
+
+   /*
+* Currently, Multi Bank update
+* feature is being supported
+* only on GPT partitioned
+* MMC/SD devices.
+*/
+   if (dfu->dev_type != DFU_DEV_MMC)
+   continue;
+
+   if (dfu->layout == DFU_RAW_ADDR &&
+   dfu->data.mmc.dev_num == dev_num &&
+   dfu->data.mmc.part == part) {
+   *alt_num = dfu->alt;
+   ret = 0;
+   break;
+   }
+   }
+
+   dfu_free_entities();
+
+   return ret;
+}
+
+int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
+int *alt_num)
+{
+   struct blk_desc *desc;
+
+   desc = dev_get_uclass_plat(dev);
+   if (!desc) {
+   log_err("Block device not found\n");
+   return -ENODEV;
+   }
+
+   return gpt_plat_get_alt_num(desc, image_guid, alt_num);
+}
+
+int fwu_plat_get_update_index(u32 *update_idx)
+{
+   int ret;
+   u32 active_idx;
+
+   ret = fwu_get_active_index(_idx);
+
+   if (ret < 0)
+   return -1;
+
+   *update_idx = active_idx ^= 0x1;
+
+   return ret;
+}
+
+#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/include/fwu.h b/include/fwu.h
index 3b1ee4e83e..36e58afa29 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -46,6 +46,8 @@ int fwu_revert_boot_index(void);
 int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
 int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
 
+
 int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
 int *alt_num);
+int fwu_plat_get_update_index(u32 *update_idx);
 #endif /* _FWU_H_ */
-- 
2.25.1



[PATCH v5 03/23] FWU: Add FWU metadata access driver for GPT partitioned block devices

2022-06-09 Thread Sughosh Ganu
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 a driver 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 
---
 drivers/fwu-mdata/Kconfig |   9 +
 drivers/fwu-mdata/Makefile|   1 +
 drivers/fwu-mdata/fwu_mdata_gpt_blk.c | 404 ++
 include/fwu.h |   2 +
 4 files changed, 416 insertions(+)
 create mode 100644 drivers/fwu-mdata/fwu_mdata_gpt_blk.c

diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
index d6a21c8e19..d5edef19d6 100644
--- a/drivers/fwu-mdata/Kconfig
+++ b/drivers/fwu-mdata/Kconfig
@@ -5,3 +5,12 @@ config DM_FWU_MDATA
  Enable support for accessing FWU Metadata partitions. The
  FWU Metadata partitions reside on the same storage device
  which contains the other FWU updatable firmware images.
+
+config FWU_MDATA_GPT_BLK
+   bool "FWU Metadata access for GPT partitioned Block devices"
+   select PARTITION_TYPE_GUID
+   select PARTITION_UUIDS
+   depends on DM && HAVE_BLOCK_DEVICE && EFI_PARTITION
+   help
+ Enable support for accessing FWU Metadata on GPT partitioned
+ block devices.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
index 7fec7171f4..12a5b4fe04 100644
--- a/drivers/fwu-mdata/Makefile
+++ b/drivers/fwu-mdata/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
+obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_mdata_gpt_blk.o
diff --git a/drivers/fwu-mdata/fwu_mdata_gpt_blk.c 
b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
new file mode 100644
index 00..329bd3779b
--- /dev/null
+++ b/drivers/fwu-mdata/fwu_mdata_gpt_blk.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define PRIMARY_PART   BIT(0)
+#define SECONDARY_PART BIT(1)
+#define BOTH_PARTS (PRIMARY_PART | SECONDARY_PART)
+
+#define MDATA_READ BIT(0)
+#define MDATA_WRITEBIT(1)
+
+static int gpt_get_mdata_partitions(struct blk_desc *desc,
+   u16 *primary_mpart,
+   u16 *secondary_mpart)
+{
+   int i, ret;
+   u32 mdata_parts;
+   efi_guid_t part_type_guid;
+   struct disk_partition info;
+   const efi_guid_t fwu_mdata_guid = FWU_MDATA_GUID;
+
+   mdata_parts = 0;
+   for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+   if (part_get_info(desc, i, ))
+   continue;
+   uuid_str_to_bin(info.type_guid, part_type_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   if (!guidcmp(_mdata_guid, _type_guid)) {
+   ++mdata_parts;
+   if (!*primary_mpart)
+   *primary_mpart = i;
+   else
+   *secondary_mpart = i;
+   }
+   }
+
+   if (mdata_parts != 2) {
+   log_err("Expect two copies of the FWU metadata instead of %d\n",
+   mdata_parts);
+   ret = -EINVAL;
+   } else {
+   ret = 0;
+   }
+
+   return ret;
+}
+
+static int gpt_get_mdata_disk_part(struct blk_desc *desc,
+  struct disk_partition *info,
+  u32 part_num)
+{
+   int ret;
+   char *mdata_guid_str = "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23";
+
+   ret = part_get_info(desc, part_num, info);
+   if (ret < 0) {
+   log_err("Unable to get the partition info for the FWU metadata 
part %d",
+   part_num);
+   return -1;
+   }
+
+   /* Check that it is indeed the FWU metadata partition */
+   if (!strncmp(info->type_guid, mdata_guid_str, UUID_STR_LEN)) {
+   /* Found the FWU metadata partition */
+   return 0;
+   }
+
+   return -1;
+}
+
+static int gpt_read_write_mdata(struct blk_desc *desc,
+   struct fwu_mdata *mdata,
+   u8 access, u32 part_num)
+{
+   int ret;
+   u32 len, blk_start, blkcnt;
+   struct disk_partition info;
+
+   ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_mdata, mdata_aligned, 1,
+desc->blksz);
+
+   ret = gpt_get_mdata_disk_part(desc, , part_num);
+   if (ret < 0) {
+   printf("Unable to get the FWU metadata partition\n");
+   return -ENODE

[PATCH v5 05/23] stm32mp1: dk2: Add image information for capsule updates

2022-06-09 Thread Sughosh Ganu
Enabling capsule update functionality on the platform requires
populating information on the images that are to be updated using the
functionality. Do so for the DK2 board.

Signed-off-by: Sughosh Ganu 
---
 board/st/stm32mp1/stm32mp1.c   | 19 +++
 include/configs/stm32mp15_common.h |  4 
 2 files changed, 23 insertions(+)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 07b1a63db7..62d98ad776 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -92,6 +93,16 @@ DECLARE_GLOBAL_DATA_PTR;
 #define USB_START_LOW_THRESHOLD_UV 123
 #define USB_START_HIGH_THRESHOLD_UV215
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+struct efi_fw_image fw_images[1];
+
+struct efi_capsule_update_info update_info = {
+   .images = fw_images,
+};
+
+u8 num_image_type_guids = ARRAY_SIZE(fw_images);
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
 int board_early_init_f(void)
 {
/* nothing to do, only used in SPL */
@@ -675,6 +686,14 @@ int board_init(void)
 
setup_led(LEDST_ON);
 
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) 
+   if (board_is_dk2()) {
+   efi_guid_t image_type_guid = STM32MP1_DK2_FIP_IMAGE_GUID;
+   guidcpy(_images[0].image_type_id, _type_guid);
+   fw_images[0].fw_name = u"STM32MP1-DK2-FIP";
+   fw_images[0].image_index = 5;
+   }
+#endif
return 0;
 }
 
diff --git a/include/configs/stm32mp15_common.h 
b/include/configs/stm32mp15_common.h
index 6b40cdb017..6a1ae9788d 100644
--- a/include/configs/stm32mp15_common.h
+++ b/include/configs/stm32mp15_common.h
@@ -54,6 +54,10 @@
 #define CONFIG_SYS_AUTOLOAD"no"
 #endif
 
+#define STM32MP1_DK2_FIP_IMAGE_GUID \
+   EFI_GUID(0x19d5df83, 0x11b0, 0x457b, 0xbe, 0x2c, \
+0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
+
 /*/
 #ifdef CONFIG_DISTRO_DEFAULTS
 /*/
-- 
2.25.1



[PATCH v5 02/23] FWU: Add FWU metadata structure and driver for accessing metadata

2022-06-09 Thread Sughosh Ganu
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 a driver model
uclass which provides 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 
---
 drivers/Kconfig  |   2 +
 drivers/Makefile |   1 +
 drivers/fwu-mdata/Kconfig|   7 +
 drivers/fwu-mdata/Makefile   |   6 +
 drivers/fwu-mdata/fwu-mdata-uclass.c | 459 +++
 include/dm/uclass-id.h   |   1 +
 include/fwu.h|  49 +++
 include/fwu_mdata.h  |  67 
 8 files changed, 592 insertions(+)
 create mode 100644 drivers/fwu-mdata/Kconfig
 create mode 100644 drivers/fwu-mdata/Makefile
 create mode 100644 drivers/fwu-mdata/fwu-mdata-uclass.c
 create mode 100644 include/fwu.h
 create mode 100644 include/fwu_mdata.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index b26ca8cf70..adc6079ecf 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -42,6 +42,8 @@ source "drivers/firmware/Kconfig"
 
 source "drivers/fpga/Kconfig"
 
+source "drivers/fwu-mdata/Kconfig"
+
 source "drivers/gpio/Kconfig"
 
 source "drivers/hwspinlock/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 67c8af7442..901150bb35 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -83,6 +83,7 @@ obj-y += cache/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FASTBOOT) += fastboot/
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata/
 obj-y += misc/
 obj-$(CONFIG_MMC) += mmc/
 obj-$(CONFIG_NVME) += nvme/
diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
new file mode 100644
index 00..d6a21c8e19
--- /dev/null
+++ b/drivers/fwu-mdata/Kconfig
@@ -0,0 +1,7 @@
+config DM_FWU_MDATA
+   bool "Driver support for accessing FWU Metadata"
+   depends on DM
+   help
+ Enable support for accessing FWU Metadata partitions. The
+ FWU Metadata partitions reside on the same storage device
+ which contains the other FWU updatable firmware images.
diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
new file mode 100644
index 00..7fec7171f4
--- /dev/null
+++ b/drivers/fwu-mdata/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2022, Linaro Limited
+#
+
+obj-$(CONFIG_DM_FWU_MDATA) += fwu-mdata-uclass.o
diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c 
b/drivers/fwu-mdata/fwu-mdata-uclass.c
new file mode 100644
index 00..1530ceb01d
--- /dev/null
+++ b/drivers/fwu-mdata/fwu-mdata-uclass.c
@@ -0,0 +1,459 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define IMAGE_ACCEPT_SET   BIT(0)
+#define IMAGE_ACCEPT_CLEAR BIT(1)
+
+static int fwu_get_dev_ops(struct udevice **dev,
+  const struct fwu_mdata_ops **ops)
+{
+   int ret;
+
+   ret = uclass_get_device(UCLASS_FWU_MDATA, 0, dev);
+   if (ret) {
+   log_debug("Cannot find fwu device\n");
+   return ret;
+   }
+
+   if ((*ops = device_get_ops(*dev)) == NULL) {
+   log_debug("Cannot get fwu device ops\n");
+   return -ENOSYS;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_verify_mdata() - Verify the FWU metadata
+ * @mdata: FWU metadata structure
+ * @pri_part: FWU metadata partition is primary or secondary
+ *
+ * Verify the FWU metadata by computing the CRC32 for the metadata
+ * structure and comparing it against the CRC32 value stored as part
+ * of the structure.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_verify_mdata(struct fwu_mdata *mdata, bool pri_part)
+{
+   u32 calc_crc32;
+   void *buf;
+
+   buf = >version;
+   calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32));
+
+   if (calc_crc32 != mdata->crc32) {
+   log_err("crc32 check failed for %s FWU metadata partition\n",
+   pri_part ? "primary" : "secondary");
+   return -1;
+   }
+
+   return 0;
+}
+
+/**
+ * fwu_get_active_index() - Get active_index from the FWU metadata
+ * @active_idx: active_index value to be read
+ *
+ * Read the active_index field from the FWU metadata and place it in
+ * the variable pointed to be the function argument.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_get_active_index(u32 *active_idx)
+{
+   int ret;
+   struct fwu_mdata *mdata = NULL;
+
+   ret = fwu_get_mdata();
+   if (ret < 0) {
+

[PATCH v5 04/23] stm32mp1: dk2: Add a node for the FWU metadata device

2022-06-09 Thread Sughosh Ganu
The FWU metadata structure is accessed through the driver model
interface. On the stm32mp157c-dk2 board, the FWU metadata is stored on
the uSD card. Add the fwu-mdata node on the u-boot specifc dtsi file
for accessing the metadata structure.

Signed-off-by: Sughosh Ganu 
---
 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi 
b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
index 06ef3a4095..24f86209db 100644
--- a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
@@ -4,3 +4,10 @@
  */
 
 #include "stm32mp157a-dk1-u-boot.dtsi"
+
+/ {
+   fwu-mdata {
+   compatible = "u-boot,fwu-mdata-gpt";
+   fwu-mdata-store = <>;
+   };
+};
-- 
2.25.1



[PATCH v5 01/23] dt/bindings: Add bindings for FWU Metadata storage device

2022-06-09 Thread Sughosh Ganu
Add bindings needed for accessing the FWU metadata partitions. These
include the compatible string which point to the access method and the
actual device which stores the FWU metadata.

The current patch adds basic bindings needed for accessing the
metadata structure on GPT partitioned block devices.

Signed-off-by: Sughosh Ganu 
---
 .../firmware/fwu-mdata.txt | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 doc/device-tree-bindings/firmware/fwu-mdata.txt

diff --git a/doc/device-tree-bindings/firmware/fwu-mdata.txt 
b/doc/device-tree-bindings/firmware/fwu-mdata.txt
new file mode 100644
index 00..2d8ed056a5
--- /dev/null
+++ b/doc/device-tree-bindings/firmware/fwu-mdata.txt
@@ -0,0 +1,18 @@
+FWU Metadata Access Devicetree Binding
+
+The FWU Multi Bank Update feature uses a metadata structure, stored on
+a separate partition for keeping information on the set of updatable
+images. The device tree node provides information on the storage
+device that contains the FWU metadata.
+
+Required properties :
+
+- compatible : "u-boot,fwu-mdata-gpt";
+- fwu-mdata-store : should point to the storage device which contains
+   the FWU metadata partition.
+
+Example :
+   fwu-mdata {
+   compatible = "u-boot,fwu-mdata-gpt";
+   fwu-mdata-store = <>;
+   };
-- 
2.25.1



[PATCH v5 00/23] FWU: Add FWU Multi Bank Update feature support

2022-06-09 Thread Sughosh Ganu


The patchset adds support for the FWU Multi Bank Update[1]
feature. Certain aspects of the Dependable Boot[2] specification have
also been implemented.

The FWU multi bank update feature is used for supporting multiple
sets(also called banks) of firmware image(s), allowing the platform to
boot from a different bank, in case it fails to boot from the active
bank. This functionality is supported by keeping the relevant
information in a structure called metadata, which provides information
on the images. Among other parameters, the metadata structure contains
information on the currect active bank that is being used to boot
image(s).

Functionality is being added to work with the UEFI capsule driver in
u-boot. The metadata is read to gather information on the update bank,
which is the bank to which the firmware images would be flashed to. On
a successful completion of the update of all components, the active
bank field in the metadata is updated, to reflect the bank from which
the platform will boot on the subsequent boots.

Currently, the feature is being enabled on the STM32MP157C-DK2 and
Synquacer boards. The DK2 board boots a FIP image from a uSD card
partitioned with the GPT partioning scheme, while the Synquacer board
boots a FIP image from a MTD partitioned SPI NOR flash device.

This feature also requires changes in a previous stage of
bootloader, which parses the metadata and selects the bank to boot the
image(s) from. Support has being added in tf-a(BL2 stage) for the
STM32MP157C-DK2 board to boot the active bank images. These changes 
have been merged to the upstream tf-a repository.

Earlier, two separate patchsets were being sent. The patchset sent by
me was adding support for the feature, and enabling the feature on the
ST board. The other set of patches were being sent by Masami
Hiramatsu, which were enabling the feature on the Synquacer
platform. This patchset contains both set of patches, along with the
associated documentation and the python test script for testing the
feature.

The upstreaming effort for this feature had been put on a temporary
hold to address the fixing of some issues in the capsule update code,
primarily using a per platform image GUID for the updatable
images. Now that the series has been merged, upstreaming effort for
the FWU update feature is being resumed. Hence, this version does not
have any review comments being addressed.


[1] - https://developer.arm.com/documentation/den0118/a
[2] - 
https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf

Jassi Brar (1):
  developerbox: synquacer: Use FIP as the updatable image

Masami Hiramatsu (9):
  FWU: Add FWU metadata access driver for non-GPT MTD devices
  dt/bindings: firmware: Add FWU metadata on MTD devices binding
  tools: Add mkfwumdata tool for FWU metadata image
  FWU: doc: Update documentation for the FWU non-GPT MTD
  synquacer: Update for TBBR (BL2) based new FIP layout
  FWU: synquacer: Add FWU Multi bank update support for DeveloperBox
  FWU: synquacer: Generate dfu_alt_info from devicetree partition
  doc: synquacer: Add how to enable FWU Multi Bank Update
  [TEMP]configs: synquacer: Add FWU support for DeveloperBox

Sughosh Ganu (13):
  dt/bindings: Add bindings for FWU Metadata storage device
  FWU: Add FWU metadata structure and driver for accessing metadata
  FWU: Add FWU metadata access driver for GPT partitioned block devices
  stm32mp1: dk2: Add a node for the FWU metadata device
  stm32mp1: dk2: Add image information for capsule updates
  FWU: stm32mp1: Add helper functions for accessing FWU metadata
  FWU: STM32MP1: Add support to read boot index from backup register
  FWU: Add boot time checks as highlighted by the FWU specification
  FWU: Add support for the FWU Multi Bank Update feature
  FWU: cmd: Add a command to read FWU metadata
  mkeficapsule: Add support for generating empty capsules
  FWU: doc: Add documentation for the FWU feature
  sandbox: fwu: Add support for testing FWU feature on sandbox

 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi  |   7 +
 .../synquacer-sc2a11-developerbox-u-boot.dtsi |  40 +-
 arch/arm/mach-stm32mp/include/mach/stm32.h|   4 +
 arch/sandbox/Kconfig  |   6 +
 arch/sandbox/dts/test.dts |  45 +-
 board/sandbox/sandbox.c   |  49 ++
 board/socionext/developerbox/Kconfig  |  14 +
 board/socionext/developerbox/Makefile |   1 +
 board/socionext/developerbox/developerbox.c   |  17 +-
 board/socionext/developerbox/fwu_plat.c   | 200 
 board/st/stm32mp1/stm32mp1.c  | 141 ++
 cmd/Kconfig   |   7 +
 cmd/Makefile  |   1 +
 cmd/fwu_mdata.c   |  74 +++
 common/board_r.c  |   5 +
 configs/sandbox64_defconfig   |  12 +-
 configs/synquacer_developerbox_defconfig  |  10 +-
 doc

[PATCH v2 4/4] EFI: FMP: Use a common GetImageInfo function for FIT and raw images

2022-06-01 Thread Sughosh Ganu
The GetImageInfo function definitions for the FIT images and raw
images are the same. Use a common function for the both the Firmware
Management Protocol(FMP) instances for raw and FIT images.

Signed-off-by: Sughosh Ganu 
---

Changes since V1: None

 lib/efi_loader/efi_firmware.c | 80 ++-
 1 file changed, 14 insertions(+), 66 deletions(-)

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 9cdefab41f..0ffee3fb1f 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -177,18 +177,8 @@ static efi_status_t efi_fill_image_desc_array(
return EFI_SUCCESS;
 }
 
-#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT
-/*
- * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
- * method with existing FIT image format, and handles
- *   - multiple regions of firmware via DFU
- * but doesn't support
- *   - versioning of firmware image
- *   - package information
- */
-
 /**
- * efi_firmware_fit_get_image_info - return information about the current
+ * efi_firmware_get_image_info - return information about the current
  *  firmware image
  * @this:  Protocol instance
  * @image_info_size:   Size of @image_info
@@ -206,7 +196,7 @@ static efi_status_t efi_fill_image_desc_array(
  * Return  status code
  */
 static
-efi_status_t EFIAPI efi_firmware_fit_get_image_info(
+efi_status_t EFIAPI efi_firmware_get_image_info(
struct efi_firmware_management_protocol *this,
efi_uintn_t *image_info_size,
struct efi_firmware_image_descriptor *image_info,
@@ -239,6 +229,16 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info(
return EFI_EXIT(ret);
 }
 
+#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT
+/*
+ * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
+ * method with existing FIT image format, and handles
+ *   - multiple regions of firmware via DFU
+ * but doesn't support
+ *   - versioning of firmware image
+ *   - package information
+ */
+
 /**
  * efi_firmware_fit_set_image - update the firmware image
  * @this:  Protocol instance
@@ -278,7 +278,7 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
 }
 
 const struct efi_firmware_management_protocol efi_fmp_fit = {
-   .get_image_info = efi_firmware_fit_get_image_info,
+   .get_image_info = efi_firmware_get_image_info,
.get_image = efi_firmware_get_image_unsupported,
.set_image = efi_firmware_fit_set_image,
.check_image = efi_firmware_check_image_unsupported,
@@ -293,58 +293,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit 
= {
  * method with raw data.
  */
 
-/**
- * efi_firmware_raw_get_image_info - return information about the current
- *  firmware image
- * @this:  Protocol instance
- * @image_info_size:   Size of @image_info
- * @image_info:Image information
- * @descriptor_version:Pointer to version number
- * @descriptor_count:  Pointer to number of descriptors
- * @descriptor_size:   Pointer to descriptor size
- * @package_version:   Package version
- * @package_version_name:  Package version's name
- *
- * Return information bout the current firmware image in @image_info.
- * @image_info will consist of a number of descriptors.
- * Each descriptor will be created based on "dfu_alt_info" variable.
- *
- * Return  status code
- */
-static
-efi_status_t EFIAPI efi_firmware_raw_get_image_info(
-   struct efi_firmware_management_protocol *this,
-   efi_uintn_t *image_info_size,
-   struct efi_firmware_image_descriptor *image_info,
-   u32 *descriptor_version,
-   u8 *descriptor_count,
-   efi_uintn_t *descriptor_size,
-   u32 *package_version,
-   u16 **package_version_name)
-{
-   efi_status_t ret = EFI_SUCCESS;
-
-   EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this,
- image_info_size, image_info,
- descriptor_version, descriptor_count, descriptor_size,
- package_version, package_version_name);
-
-   if (!image_info_size)
-   return EFI_EXIT(EFI_INVALID_PARAMETER);
-
-   if (*image_info_size &&
-   (!image_info || !descriptor_version || !descriptor_count ||
-!descriptor_size || !package_version || !package_version_name))
-   return EFI_EXIT(EFI_INVALID_PARAMETER);
-
-   ret = efi_fill_image_desc_array(image_info_size, image_info,
-   descriptor_version, descriptor_count,
-   descriptor_size, package_version,
-   package_version_name);
-
-   return EFI_EXIT(ret);
-}
-
 /**
  * efi_firmware_raw_set_image - update the firmware image
  * @this:  Protocol instance
@@ -430,7 +

[PATCH v2 3/4] EFI: Update the documentation to reflect the correct value of OsIndications

2022-06-01 Thread Sughosh Ganu
The OsIndications is a 64 bit variable, and the current code expects
the value of the variable to be 64 bit. Update the documentation to
reflect this fact.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Heinrich Schuchardt 
Reviewed-by: Ilias Apalodimas 
---

Changes since V1: None

 doc/develop/uefi/uefi.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index 753a4e5e29..941e427093 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -326,7 +326,7 @@ bit in OsIndications variable with
 
 .. code-block:: console
 
-=> setenv -e -nv -bs -rt -v OsIndications =0x04
+=> setenv -e -nv -bs -rt -v OsIndications =0x0004
 
 Since U-boot doesn't currently support SetVariable at runtime, its value
 won't be taken over across the reboot. If this is the case, you can skip
-- 
2.25.1



[PATCH v2 2/4] EFI: Do not consider OsIndications variable if CONFIG_EFI_IGNORE_OSINDICATIONS is enabled

2022-06-01 Thread Sughosh Ganu
The EFI_IGNORE_OSINDICATIONS config symbol was introduced as a
mechanism to have capsule updates work even on platforms where the
SetVariable runtime service was not supported. The current logic
requires the OsIndications variable to have been set to a 64 bit value
even when the EFI_IGNORE_OSINDICATIONS config is enabled. Return an
error code on not being able to read the variable only when
EFI_IGNORE_OSINDICATIONS is not enabled.

Signed-off-by: Sughosh Ganu 
---

Changes since V1:
* Read the OsIndications variable, if present and clear the
  EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED flag even if the
  CONFIG_EFI_IGNORE_OSINDICATIONS config is enabled.

 lib/efi_loader/efi_capsule.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index c76a5f3570..a6b98f066a 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -1058,14 +1058,15 @@ static void efi_capsule_scan_done(void)
  */
 static efi_status_t check_run_capsules(void)
 {
-   u64 os_indications;
+   u64 os_indications = 0x0;
efi_uintn_t size;
efi_status_t r;
 
size = sizeof(os_indications);
r = efi_get_variable_int(u"OsIndications", _global_variable_guid,
 NULL, , _indications, NULL);
-   if (r != EFI_SUCCESS || size != sizeof(os_indications))
+   if (!IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS) &&
+   (r != EFI_SUCCESS || size != sizeof(os_indications)))
return EFI_NOT_FOUND;
 
if (os_indications &
@@ -1084,7 +1085,7 @@ static efi_status_t check_run_capsules(void)
return EFI_SUCCESS;
} else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
return EFI_SUCCESS;
-   } else  {
+   } else {
return EFI_NOT_FOUND;
}
 }
-- 
2.25.1



[PATCH v2 1/4] EFI: Populate descriptor_count value only when image_info_size is not zero

2022-06-01 Thread Sughosh Ganu
The GetImageInfo function of the Firmware Mangement Protocol(FMP) gets
called initially to query the size of the image descriptor array that
would have to be allocated. During this call, the rest of the function
arguments, specifically pointers might be passed as NULL. Do not
populate the descriptor_count value before it is known that the call
to GetImageInfo has been made with the allocated buffer for the image
descriptors.

Signed-off-by: Sughosh Ganu 
Reviewed-by: Heinrich Schuchardt 
Reviewed-by: Ilias Apalodimas 
---

Changes since V1: None

 lib/efi_loader/efi_firmware.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index fe4e084106..9cdefab41f 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -130,9 +130,6 @@ static efi_status_t efi_fill_image_desc_array(
struct efi_fw_image *fw_array;
int i;
 
-   fw_array = update_info.images;
-   *descriptor_count = num_image_type_guids;
-
total_size = sizeof(*image_info) * num_image_type_guids;
 
if (*image_info_size < total_size) {
@@ -142,6 +139,8 @@ static efi_status_t efi_fill_image_desc_array(
}
*image_info_size = total_size;
 
+   fw_array = update_info.images;
+   *descriptor_count = num_image_type_guids;
*descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
*descriptor_size = sizeof(*image_info);
*package_version = 0x; /* not supported */
-- 
2.25.1



[PATCH v2 0/4] EFI: Miscellaneous capsule update fixes

2022-06-01 Thread Sughosh Ganu


The following set of patches fix separate issues relating to the
capsule update code.

The first patch moves the setting of the descriptor_count parameter to
the GetImageInfo function after assertion of a non zero image
descriptor buffer.

The second patch enables capsule update to proceed even when the
OsIndications variable is not set with EFI_IGNORE_OSINDICATIONS config
enabled.

The third patch updates the capsule update documentation to highlight
the 64 bit value of OsIndications that needs to be set.

The fourth patch defines a common function for the GetImageInfo
functionality for both FIT and raw image FMP instances.

Sughosh Ganu (4):
  EFI: Populate descriptor_count value only when image_info_size is not
zero
  EFI: Do not consider OsIndications variable if
CONFIG_EFI_IGNORE_OSINDICATIONS is enabled
  EFI: Update the documentation to reflect the correct value of
OsIndications
  EFI: FMP: Use a common GetImageInfo function for FIT and raw images

 doc/develop/uefi/uefi.rst |  2 +-
 lib/efi_loader/efi_capsule.c  |  7 +--
 lib/efi_loader/efi_firmware.c | 85 +++
 3 files changed, 21 insertions(+), 73 deletions(-)

-- 
2.25.1




Re: [PATCH 2/3] EFI: Do not read OsIndications variable if EFI_IGNORE_OSINDICATIONS is enabled

2022-06-01 Thread Sughosh Ganu
hi Heinrich,

On Wed, 1 Jun 2022 at 11:33, Heinrich Schuchardt  wrote:
>
> On 5/31/22 09:15, Sughosh Ganu wrote:
> > The EFI_IGNORE_OSINDICATIONS config symbol was introduced as a
> > mechanism to have capsule updates work even on platforms where the
> > SetVariable runtime service was not supported. The current logic
> > requires the OsIndications variable to have been set to a 64 bit value
> > even when the EFI_IGNORE_OSINDICATIONS config is enabled. Move the
> > check to see if the config symbol is enabled at the beginning of the
> > function. If the config is enabled, return a success code without
> > checking for the existence of the variable.
> >
> > Signed-off-by: Sughosh Ganu 
> > ---
> >   lib/efi_loader/efi_capsule.c | 5 +++--
> >   1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
> > index c76a5f3570..0ea21dc168 100644
> > --- a/lib/efi_loader/efi_capsule.c
> > +++ b/lib/efi_loader/efi_capsule.c
> > @@ -1062,6 +1062,9 @@ static efi_status_t check_run_capsules(void)
> >   efi_uintn_t size;
> >   efi_status_t r;
> >
> > + if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
> > + return EFI_SUCCESS;
> > +
>
> If CONFIG_EFI_IGNORE_OSINDICATIONS=y it is correct to ignore a missing
> OsIndications variable.
>
> But I think we should stay as close as possible to the UEFI specification:
>
> If the variable exists and the flag
> EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED is set, we should
> remove the flag even if CONFIG_EFI_IGNORE_OSINDICATIONS=y.

Okay. I get your point. Will make the change to not return
EFI_NOT_FOUND when the OsIndications variable is not set with
CONFIG_EFI_IGNORE_OSINDICATIONS=y. The subsequent code will clear the
EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED bit if the variable
is found irrespective of the value of the above config.

>
> Please, have a look at the configuration symbols
> EFI_CAPSULE_ON_DISK_EARLY and EFI_SETUP_EARLY.
>
> As block devices now can be added to the UEFI sub-system after
> initialization of the same shouldn't we always initialize the sub-system
> early. And shouldn't we always consider capsules before distro-boot,
> U-Boot menu, or entering the U-Boot shell?

I believe that can be done by enabling CONFIG_EFI_CAPSULE_ON_DISK_EARLY.

-sughosh

>
> Best regards
>
> Heinrich
>
> >   size = sizeof(os_indications);
> >   r = efi_get_variable_int(u"OsIndications", _global_variable_guid,
> >NULL, , _indications, NULL);
> > @@ -1082,8 +1085,6 @@ static efi_status_t check_run_capsules(void)
> >   if (r != EFI_SUCCESS)
> >   log_err("Setting %ls failed\n", L"OsIndications");
> >   return EFI_SUCCESS;
> > - } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
> > - return EFI_SUCCESS;
> >   } else  {
> >   return EFI_NOT_FOUND;
> >   }


Re: efi_firmware_raw_get_image_info and efi_firmware_fit_get_image_info

2022-06-01 Thread Sughosh Ganu
hello Heinrich,

On Wed, 1 Jun 2022 at 11:11, Heinrich Schuchardt  wrote:
>
> Hello Sughosh,
>
> I can't see any difference between efi_firmware_raw_get_image_info() and
> efi_firmware_fit_get_image_info(). Shouldn't we replace them by a single
> function to avoid maintaining duplicate code?

The two functions can indeed be refactored into a single function. I
will add this patch to the miscellaneous capsule fixes series that I
posted yesterday. Thanks.

-sughosh

>
> Best regards
>
> Heinrich


[PATCH 3/3] EFI: Update the documentation to reflect the correct value of OsIndications

2022-05-31 Thread Sughosh Ganu
The OsIndications is a 64 bit variable, and the current code expects
the value of the variable to be 64 bit. Update the documentation to
reflect this fact.

Signed-off-by: Sughosh Ganu 
---
 doc/develop/uefi/uefi.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index 753a4e5e29..941e427093 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -326,7 +326,7 @@ bit in OsIndications variable with
 
 .. code-block:: console
 
-=> setenv -e -nv -bs -rt -v OsIndications =0x04
+=> setenv -e -nv -bs -rt -v OsIndications =0x0004
 
 Since U-boot doesn't currently support SetVariable at runtime, its value
 won't be taken over across the reboot. If this is the case, you can skip
-- 
2.25.1



[PATCH 2/3] EFI: Do not read OsIndications variable if EFI_IGNORE_OSINDICATIONS is enabled

2022-05-31 Thread Sughosh Ganu
The EFI_IGNORE_OSINDICATIONS config symbol was introduced as a
mechanism to have capsule updates work even on platforms where the
SetVariable runtime service was not supported. The current logic
requires the OsIndications variable to have been set to a 64 bit value
even when the EFI_IGNORE_OSINDICATIONS config is enabled. Move the
check to see if the config symbol is enabled at the beginning of the
function. If the config is enabled, return a success code without
checking for the existence of the variable.

Signed-off-by: Sughosh Ganu 
---
 lib/efi_loader/efi_capsule.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index c76a5f3570..0ea21dc168 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -1062,6 +1062,9 @@ static efi_status_t check_run_capsules(void)
efi_uintn_t size;
efi_status_t r;
 
+   if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
+   return EFI_SUCCESS;
+
size = sizeof(os_indications);
r = efi_get_variable_int(u"OsIndications", _global_variable_guid,
 NULL, , _indications, NULL);
@@ -1082,8 +1085,6 @@ static efi_status_t check_run_capsules(void)
if (r != EFI_SUCCESS)
log_err("Setting %ls failed\n", L"OsIndications");
return EFI_SUCCESS;
-   } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
-   return EFI_SUCCESS;
} else  {
return EFI_NOT_FOUND;
}
-- 
2.25.1



[PATCH 1/3] EFI: Populate descriptor_count value only when image_info_size is not zero

2022-05-31 Thread Sughosh Ganu
The GetImageInfo function of the Firmware Mangement Protocol(FMP) gets
called initially to query the size of the image descriptor array that
would have to be allocated. During this call, the rest of the function
arguments, specifically pointers might be passed as NULL. Do not
populate the descriptor_count value before it is known that the call
to GetImageInfo has been made with the allocated buffer for the image
descriptors.

Signed-off-by: Sughosh Ganu 
---
 lib/efi_loader/efi_firmware.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 27953fe769..6290ca0190 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -130,9 +130,6 @@ static efi_status_t efi_fill_image_desc_array(
struct efi_fw_image *fw_array;
int i;
 
-   fw_array = update_info.images;
-   *descriptor_count = num_image_type_guids;
-
total_size = sizeof(*image_info) * num_image_type_guids;
 
if (*image_info_size < total_size) {
@@ -142,6 +139,8 @@ static efi_status_t efi_fill_image_desc_array(
}
*image_info_size = total_size;
 
+   fw_array = update_info.images;
+   *descriptor_count = num_image_type_guids;
*descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
*descriptor_size = sizeof(*image_info);
*package_version = 0x; /* not supported */
-- 
2.25.1



[PATCH 0/3] EFI: Miscellaneous capsule update fixes

2022-05-31 Thread Sughosh Ganu


The following set of patches fix separate issues relating to the
capsule update code.

The first patch moves the setting of the descriptor_count parameter to
the GetImageInfo function after assertion of a non zero image
descriptor buffer.

The second patch enables capsule update to proceed even when the
OsIndications variable is not set with EFI_IGNORE_OSINDICATIONS config
enabled.

The third patch updates the capsule update documentation to highlight
the 64 bit value of OsIndications that needs to be set.

Sughosh Ganu (3):
  EFI: Populate descriptor_count value only when image_info_size is not
zero
  EFI: Do not read OsIndications variable if EFI_IGNORE_OSINDICATIONS is
enabled
  EFI: Update the documentation to reflect the correct value of
OsIndications

 doc/develop/uefi/uefi.rst | 2 +-
 lib/efi_loader/efi_capsule.c  | 5 +++--
 lib/efi_loader/efi_firmware.c | 5 ++---
 3 files changed, 6 insertions(+), 6 deletions(-)

-- 
2.25.1




<    3   4   5   6   7   8   9   10   11   12   >