Merge changes from topic "fwu-on-stm32mp1" into integration

* changes:
  feat(stm32mp1): add support for building the FWU feature
  feat(stm32mp1): add logic to pass the boot index to the Update Agent
  feat(stm32mp1): add support for reading the metadata partition
  feat(stm32mp1): add logic to select the images to be booted
  feat(stm32mp1): add GUID's for identifying firmware images to be booted
  feat(stm32mp1): add GUID values for updatable images
  feat(fwu): add platform hook for getting the boot index
  feat(fwu): simplify the assert to check for fwu init
  feat(fwu): add a function to pass metadata structure to platforms
  feat(partition): add a function to identify a partition by GUID
  feat(partition): copy the partition GUID into the partition structure
  feat(partition): make provision to store partition GUID value
  feat(partition): cleanup partition and gpt headers
  feat(fwu): add basic definitions for GUID handling
  feat(fwu): pass a const metadata structure to platform routines
  build(changelog): add a valid scope for partition code
diff --git a/changelog.yaml b/changelog.yaml
index 4e187ef..b591da3 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -566,6 +566,9 @@
                 deprecated:
                   - spi_nand
 
+      - title: Partition
+        scope: partition
+
       - title: SCMI
         scope: scmi
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 24af13e..7f10ca6 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -889,7 +889,7 @@
 
 ::
 
-    Argument : struct fwu_metadata *metadata
+    Argument : const struct fwu_metadata *metadata
     Return   : void
 
 This function is mandatory when PSA_FWU_SUPPORT is enabled.
@@ -932,6 +932,25 @@
 Alongside, returns device handle and image specification from the I/O policy
 of the requested FWU metadata image.
 
+Function : plat_fwu_get_boot_idx() [when PSA_FWU_SUPPORT == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint32_t
+
+This function is mandatory when PSA_FWU_SUPPORT is enabled. It provides the
+means to retrieve the boot index value from the platform. The boot index is the
+bank from which the platform has booted the firmware images.
+
+By default, the platform will read the metadata structure and try to boot from
+the active bank. If the platform fails to boot from the active bank due to
+reasons like an Authentication failure, or on crossing a set number of watchdog
+resets while booting from the active bank, the platform can then switch to boot
+from a different bank. This function then returns the bank that the platform
+should boot its images from.
+
 Common optional modifications
 -----------------------------
 
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index 7cb4c29..80f870b 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -142,7 +142,7 @@
 {
 	bool trial_run = false;
 
-	assert(is_fwu_initialized == true);
+	assert(is_fwu_initialized);
 
 	for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
 		struct fwu_image_entry *entry = &metadata.img_entry[i];
@@ -157,6 +157,13 @@
 	return trial_run;
 }
 
+const struct fwu_metadata *fwu_get_metadata(void)
+{
+	assert(is_fwu_initialized);
+
+	return &metadata;
+}
+
 /*******************************************************************************
  * Load verified copy of FWU metadata image kept in the platform NV storage
  * into local FWU metadata structure.
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index 1b804de..ee0bddf 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include <common/debug.h>
+#include <drivers/partition/efi.h>
 #include <drivers/partition/gpt.h>
 #include <lib/utils.h>
 
@@ -57,5 +58,7 @@
 	entry->length = (uint64_t)(gpt_entry->last_lba -
 				   gpt_entry->first_lba + 1) *
 			PLAT_PARTITION_BLOCK_SIZE;
+	guidcpy(&entry->part_guid, &gpt_entry->unique_uuid);
+
 	return 0;
 }
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index fdea10d..7706f88 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -11,6 +11,7 @@
 
 #include <common/debug.h>
 #include <drivers/io/io_storage.h>
+#include <drivers/partition/efi.h>
 #include <drivers/partition/partition.h>
 #include <drivers/partition/gpt.h>
 #include <drivers/partition/mbr.h>
@@ -246,6 +247,19 @@
 	return NULL;
 }
 
+const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
+{
+	int i;
+
+	for (i = 0; i < list.entry_count; i++) {
+		if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) {
+			return &list.list[i];
+		}
+	}
+
+	return NULL;
+}
+
 const partition_entry_list_t *get_partition_entry_list(void)
 {
 	return &list;
diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h
index ae06da9..9f18e22 100644
--- a/include/drivers/fwu/fwu.h
+++ b/include/drivers/fwu/fwu.h
@@ -11,5 +11,6 @@
 
 void fwu_init(void);
 bool fwu_is_trial_run_state(void);
+const struct fwu_metadata *fwu_get_metadata(void);
 
 #endif /* FWU_H */
diff --git a/include/drivers/partition/efi.h b/include/drivers/partition/efi.h
new file mode 100644
index 0000000..e463f96
--- /dev/null
+++ b/include/drivers/partition/efi.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021, Linaro Limited
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DRIVERS_PARTITION_EFI_H
+#define DRIVERS_PARTITION_EFI_H
+
+#include <string.h>
+
+#include <tools_share/uuid.h>
+
+#define EFI_NAMELEN		36
+
+static inline int guidcmp(const void *g1, const void *g2)
+{
+	return memcmp(g1, g2, sizeof(struct efi_guid));
+}
+
+static inline void *guidcpy(void *dst, const void *src)
+{
+	return memcpy(dst, src, sizeof(struct efi_guid));
+}
+
+#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+	{ (a) & 0xffffffff,		\
+	  (b) & 0xffff,			\
+	  (c) & 0xffff,			\
+	  { (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } }
+
+#define NULL_GUID \
+	EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
+		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+
+#endif /* DRIVERS_PARTITION_EFI_H */
diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h
index d923e95..c2a229e 100644
--- a/include/drivers/partition/gpt.h
+++ b/include/drivers/partition/gpt.h
@@ -7,19 +7,20 @@
 #ifndef GPT_H
 #define GPT_H
 
+#include <drivers/partition/efi.h>
 #include <drivers/partition/partition.h>
+#include <tools_share/uuid.h>
 
 #define PARTITION_TYPE_GPT		0xee
 #define GPT_HEADER_OFFSET		PLAT_PARTITION_BLOCK_SIZE
 #define GPT_ENTRY_OFFSET		(GPT_HEADER_OFFSET +		\
 					 PLAT_PARTITION_BLOCK_SIZE)
-#define GUID_LEN			16
 
 #define GPT_SIGNATURE			"EFI PART"
 
 typedef struct gpt_entry {
-	unsigned char		type_uuid[GUID_LEN];
-	unsigned char		unique_uuid[GUID_LEN];
+	struct efi_guid		type_uuid;
+	struct efi_guid		unique_uuid;
 	unsigned long long	first_lba;
 	unsigned long long	last_lba;
 	unsigned long long	attr;
@@ -36,7 +37,7 @@
 	unsigned long long	backup_lba;
 	unsigned long long	first_lba;
 	unsigned long long	last_lba;
-	unsigned char		disk_uuid[16];
+	struct efi_guid		disk_uuid;
 	/* starting LBA of array of partition entries */
 	unsigned long long	part_lba;
 	/* number of partition entries in array */
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index 5f64833..b292ec7 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -10,6 +10,8 @@
 #include <stdint.h>
 
 #include <lib/cassert.h>
+#include <drivers/partition/efi.h>
+#include <tools_share/uuid.h>
 
 #if !PLAT_PARTITION_MAX_ENTRIES
 # define PLAT_PARTITION_MAX_ENTRIES	128
@@ -27,12 +29,11 @@
 
 #define LEGACY_PARTITION_BLOCK_SIZE	512
 
-#define EFI_NAMELEN			36
-
 typedef struct partition_entry {
 	uint64_t		start;
 	uint64_t		length;
 	char			name[EFI_NAMELEN];
+	struct efi_guid		part_guid;
 } partition_entry_t;
 
 typedef struct partition_entry_list {
@@ -42,6 +43,7 @@
 
 int load_partition_table(unsigned int image_id);
 const partition_entry_t *get_partition_entry(const char *name);
+const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
 const partition_entry_list_t *get_partition_entry_list(void);
 void partition_init(unsigned int image_id);
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 9a61b50..509fd58 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -389,6 +389,7 @@
 int plat_fwu_set_metadata_image_source(unsigned int image_id,
 				       uintptr_t *dev_handle,
 				       uintptr_t *image_spec);
-void plat_fwu_set_images_source(struct fwu_metadata *metadata);
+void plat_fwu_set_images_source(const struct fwu_metadata *metadata);
+uint32_t plat_fwu_get_boot_idx(void);
 
 #endif /* PLATFORM_H */
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index 387086a..19ee1b0 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -217,7 +217,7 @@
  * bank to get its offset and length, and update these details in the I/O policy
  * of the FIP image.
  ******************************************************************************/
-void plat_fwu_set_images_source(struct fwu_metadata *metadata)
+void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
 {
 	arm_set_fip_addr(metadata->active_index);
 }
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 6069e5f..e129dfd 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -10,6 +10,8 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
+#include <drivers/fwu/fwu.h>
+#include <drivers/fwu/fwu_metadata.h>
 #include <drivers/io/io_block.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_fip.h>
@@ -17,6 +19,7 @@
 #include <drivers/io/io_mtd.h>
 #include <drivers/io/io_storage.h>
 #include <drivers/mmc.h>
+#include <drivers/partition/efi.h>
 #include <drivers/partition/partition.h>
 #include <drivers/raw_nand.h>
 #include <drivers/spi_nand.h>
@@ -384,6 +387,12 @@
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
 		if (!gpt_init_done) {
+/*
+ * With FWU Multi Bank feature enabled, the selection of
+ * the image to boot will be done by fwu_init calling the
+ * platform hook, plat_fwu_set_images_source.
+ */
+#if !PSA_FWU_SUPPORT
 			const partition_entry_t *entry;
 
 			partition_init(GPT_IMAGE_ID);
@@ -396,7 +405,7 @@
 
 			image_block_spec.offset = entry->start;
 			image_block_spec.length = entry->length;
-
+#endif
 			gpt_init_done = true;
 		} else {
 			bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
@@ -473,3 +482,117 @@
 
 	return rc;
 }
+
+#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+/*
+ * Eventually, this function will return the
+ * boot index to be passed on to the Update
+ * Agent after performing certain checks like
+ * a watchdog timeout, or Auth failure while
+ * trying to load from a certain bank.
+ * For now, since we do not have that logic
+ * implemented, just pass the active_index
+ * read from the metadata.
+ */
+uint32_t plat_fwu_get_boot_idx(void)
+{
+	const struct fwu_metadata *metadata;
+
+	metadata = fwu_get_metadata();
+
+	return metadata->active_index;
+}
+
+static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
+{
+	unsigned int i;
+
+	for (i = 0U; i < MAX_NUMBER_IDS; i++) {
+		if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
+			return (void *)policies[i].image_spec;
+		}
+	}
+
+	return NULL;
+}
+
+void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
+{
+	unsigned int i;
+	uint32_t boot_idx;
+	const partition_entry_t *entry;
+	const uuid_t *img_type_uuid, *img_uuid;
+	io_block_spec_t *image_spec;
+
+	boot_idx = plat_fwu_get_boot_idx();
+	assert(boot_idx < NR_OF_FW_BANKS);
+
+	for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
+		img_type_uuid = &metadata->img_entry[i].img_type_uuid;
+		image_spec = stm32_get_image_spec(img_type_uuid);
+		if (image_spec == NULL) {
+			ERROR("Unable to get image spec for the image in the metadata\n");
+			panic();
+		}
+
+		img_uuid =
+			&metadata->img_entry[i].img_props[boot_idx].img_uuid;
+
+		entry = get_partition_entry_by_uuid(img_uuid);
+		if (entry == NULL) {
+			ERROR("Unable to find the partition with the uuid mentioned in metadata\n");
+			panic();
+		}
+
+		image_spec->offset = entry->start;
+		image_spec->length = entry->length;
+	}
+}
+
+static int plat_set_image_source(unsigned int image_id,
+				 uintptr_t *handle,
+				 uintptr_t *image_spec,
+				 const char *part_name)
+{
+	struct plat_io_policy *policy;
+	io_block_spec_t *spec;
+	const partition_entry_t *entry = get_partition_entry(part_name);
+
+	if (entry == NULL) {
+		ERROR("Unable to find the %s partition\n", part_name);
+		return -ENOENT;
+	}
+
+	policy = &policies[image_id];
+
+	spec = (io_block_spec_t *)policy->image_spec;
+	spec->offset = entry->start;
+	spec->length = entry->length;
+
+	*image_spec = policy->image_spec;
+	*handle = *policy->dev_handle;
+
+	return 0;
+}
+
+int plat_fwu_set_metadata_image_source(unsigned int image_id,
+				       uintptr_t *handle,
+				       uintptr_t *image_spec)
+{
+	char *part_name;
+
+	assert((image_id == FWU_METADATA_IMAGE_ID) ||
+	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
+
+	partition_init(GPT_IMAGE_ID);
+
+	if (image_id == FWU_METADATA_IMAGE_ID) {
+		part_name = METADATA_PART_1;
+	} else {
+		part_name = METADATA_PART_2;
+	}
+
+	return plat_set_image_source(image_id, handle, image_spec,
+				     part_name);
+}
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 9ca5d16..7508004 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -113,4 +113,8 @@
 void stm32_save_boot_interface(uint32_t interface, uint32_t instance);
 void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance);
 
+#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+void stm32mp1_fwu_set_boot_idx(void);
+#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
+
 #endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/include/stm32mp_efi.h b/plat/st/common/include/stm32mp_efi.h
new file mode 100644
index 0000000..490560f
--- /dev/null
+++ b/plat/st/common/include/stm32mp_efi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#ifndef STM32MP_EFI_H
+#define STM32MP_EFI_H
+
+#include <drivers/partition/efi.h>
+
+#define STM32MP_FIP_GUID \
+	EFI_GUID(0x19d5df83, 0x11b0, 0x457b, \
+		 0xbe, 0x2c, 0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
+
+#endif /* STM32MP_EFI_H */
diff --git a/plat/st/common/include/stm32mp_fconf_getter.h b/plat/st/common/include/stm32mp_fconf_getter.h
index 3a8bb11..18884ae 100644
--- a/plat/st/common/include/stm32mp_fconf_getter.h
+++ b/plat/st/common/include/stm32mp_fconf_getter.h
@@ -10,6 +10,7 @@
 #include <assert.h>
 
 #include <lib/fconf/fconf.h>
+#include <tools_share/uuid.h>
 
 /* IO policies */
 #define stm32mp__io_policies_getter(id) __extension__ ({	\
@@ -20,6 +21,7 @@
 struct plat_io_policy {
 	uintptr_t *dev_handle;
 	uintptr_t image_spec;
+	struct efi_guid img_type_guid;
 	int (*check)(const uintptr_t spec);
 };
 
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index aa8cd54..ca71958 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -16,6 +16,7 @@
 #include <tools_share/firmware_image_package.h>
 
 #include <platform_def.h>
+#include <stm32mp_efi.h>
 #include <stm32mp_fconf_getter.h>
 #include <stm32mp_io_storage.h>
 
@@ -26,20 +27,43 @@
 };
 #endif
 
+#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+io_block_spec_t metadata_block_spec = {
+	.offset = 0,    /* To be filled at runtime */
+	.length = 0,    /* To be filled at runtime */
+};
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
+
 /* By default, STM32 platforms load images from the FIP */
 struct plat_io_policy policies[MAX_NUMBER_IDS] = {
 	[FIP_IMAGE_ID] = {
-		&storage_dev_handle,
-		(uintptr_t)&image_block_spec,
-		open_storage
+		.dev_handle = &storage_dev_handle,
+		.image_spec = (uintptr_t)&image_block_spec,
+		.img_type_guid = STM32MP_FIP_GUID,
+		.check = open_storage
 	},
 #if STM32MP_SDMMC || STM32MP_EMMC
 	[GPT_IMAGE_ID] = {
-		&storage_dev_handle,
-		(uintptr_t)&gpt_block_spec,
-		open_storage
+		.dev_handle = &storage_dev_handle,
+		.image_spec = (uintptr_t)&gpt_block_spec,
+		.img_type_guid = NULL_GUID,
+		.check = open_storage
 	},
 #endif
+#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+	[FWU_METADATA_IMAGE_ID] = {
+		.dev_handle = &storage_dev_handle,
+		.image_spec = (uintptr_t)&metadata_block_spec,
+		.img_type_guid = NULL_GUID,
+		.check = open_storage
+	},
+	[BKUP_FWU_METADATA_IMAGE_ID] = {
+		.dev_handle = &storage_dev_handle,
+		.image_spec = (uintptr_t)&metadata_block_spec,
+		.img_type_guid = NULL_GUID,
+		.check = open_storage
+	},
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
 };
 
 #define FCONF_ST_IO_UUID_NUMBER	U(8)
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 0c93f27..b5fc3ff 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -30,6 +30,7 @@
 #include <plat/common/platform.h>
 
 #include <platform_def.h>
+#include <stm32mp_common.h>
 #include <stm32mp1_dbgmcu.h>
 
 static struct stm32mp_auth_ops stm32mp1_auth_ops;
@@ -452,6 +453,9 @@
 		bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
 		assert(bl32_mem_params != NULL);
 		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
+#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+		stm32mp1_fwu_set_boot_idx();
+#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
 		break;
 
 	default:
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 511a0e2..8ecb4c3 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -40,6 +40,9 @@
 #define BL33_BINARY_TYPE		U(0x0)
 #else /* STM32MP_USE_STM32IMAGE */
 #define FIP_IMAGE_NAME			"fip"
+#define METADATA_PART_1			"metadata1"
+#define METADATA_PART_2			"metadata2"
+
 #endif /* STM32MP_USE_STM32IMAGE */
 
 #define STM32MP_PRIMARY_CPU		U(0x0)
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 13dea2a..6f7c79b 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -38,8 +38,22 @@
 # Not needed for Cortex-A7
 WORKAROUND_CVE_2017_5715:=	0
 
+ifeq (${PSA_FWU_SUPPORT},1)
+ifneq (${STM32MP_USE_STM32IMAGE},1)
+# Number of banks of updatable firmware
+NR_OF_FW_BANKS			:=	2
+NR_OF_IMAGES_IN_FW_BANK		:=	1
+
 # Number of TF-A copies in the device
 STM32_TF_A_COPIES		:=	2
+STM32_BL33_PARTS_NUM		:=	2
+STM32_RUNTIME_PARTS_NUM		:=	4
+else
+$(error FWU Feature enabled only with FIP images)
+endif
+else
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES		:=	2
 STM32_BL33_PARTS_NUM		:=	1
 ifeq ($(AARCH32_SP),optee)
 STM32_RUNTIME_PARTS_NUM		:=	3
@@ -48,6 +62,7 @@
 else
 STM32_RUNTIME_PARTS_NUM		:=	1
 endif
+endif
 PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + \
 							 $(STM32_BL33_PARTS_NUM) + \
 							 $(STM32_RUNTIME_PARTS_NUM))))
@@ -237,6 +252,13 @@
 				plat/st/stm32mp1/stm32mp1_security.c
 endif
 
+ifeq (${PSA_FWU_SUPPORT},1)
+include lib/zlib/zlib.mk
+include drivers/fwu/fwu.mk
+
+BL2_SOURCES		+=	$(ZLIB_SOURCES)
+endif
+
 BL2_SOURCES		+=	drivers/io/io_block.c					\
 				drivers/io/io_mtd.c					\
 				drivers/io/io_storage.c					\
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 0bed12a..9016b0d 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -13,6 +13,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <libfdt.h>
 
+#include <plat/common/platform.h>
 #include <platform_def.h>
 
 /* Internal layout of the 32bit OTP word board_id */
@@ -40,6 +41,8 @@
 #define TAMP_BOOT_MODE_ITF_MASK		U(0x0000FF00)
 #define TAMP_BOOT_MODE_ITF_SHIFT	8
 
+#define TAMP_BOOT_COUNTER_REG_ID	U(21)
+
 #if defined(IMAGE_BL2)
 #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
 					STM32MP_SYSRAM_SIZE, \
@@ -597,3 +600,13 @@
 	*interface = itf >> 4;
 	*instance = itf & 0xFU;
 }
+
+#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+void stm32mp1_fwu_set_boot_idx(void)
+{
+	clk_enable(RTCAPB);
+	mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
+		      plat_fwu_get_boot_idx());
+	clk_disable(RTCAPB);
+}
+#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */