Merge "errata: workaround for Neoverse V1 errata 1774420" into integration
diff --git a/Makefile b/Makefile
index 4dbc2be..b4bebf1 100644
--- a/Makefile
+++ b/Makefile
@@ -746,6 +746,10 @@
     endif
 endif
 
+ifeq ($(PSA_FWU_SUPPORT),1)
+    $(info PSA_FWU_SUPPORT is an experimental feature)
+endif
+
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
     ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
         $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
@@ -959,6 +963,7 @@
         USE_SP804_TIMER \
         ENABLE_FEAT_RNG \
         ENABLE_FEAT_SB \
+        PSA_FWU_SUPPORT \
 )))
 
 $(eval $(call assert_numerics,\
@@ -967,6 +972,8 @@
         ARM_ARCH_MINOR \
         BRANCH_PROTECTION \
         FW_ENC_STATUS \
+        NR_OF_FW_BANKS \
+        NR_OF_IMAGES_IN_FW_BANK \
 )))
 
 ifdef KEY_SIZE
@@ -1054,6 +1061,9 @@
         USE_SP804_TIMER \
         ENABLE_FEAT_RNG \
         ENABLE_FEAT_SB \
+        NR_OF_FW_BANKS \
+        NR_OF_IMAGES_IN_FW_BANK \
+        PSA_FWU_SUPPORT \
 )))
 
 ifeq (${SANITIZE_UB},trap)
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 203e1d4..d2de135 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
+#include <drivers/fwu/fwu.h>
 #if MEASURED_BOOT
 #include <drivers/measured_boot/measured_boot.h>
 #endif
@@ -88,6 +89,10 @@
 	/* Perform remaining generic architectural setup in S-EL1 */
 	bl2_arch_setup();
 
+#if PSA_FWU_SUPPORT
+	fwu_init();
+#endif /* PSA_FWU_SUPPORT */
+
 #if TRUSTED_BOARD_BOOT
 	/* Initialize authentication module */
 	auth_mod_init();
diff --git a/common/bl_common.c b/common/bl_common.c
index f17afcb..a7e2816 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -239,9 +239,18 @@
 {
 	int err;
 
+/*
+ * All firmware banks should be part of the same non-volatile storage as per
+ * PSA FWU specification, hence don't check for any alternate boot source
+ * when PSA FWU is enabled.
+ */
+#if PSA_FWU_SUPPORT
+	err = load_auth_image_internal(image_id, image_data);
+#else
 	do {
 		err = load_auth_image_internal(image_id, image_data);
 	} while ((err != 0) && (plat_try_next_boot_source() != 0));
+#endif /* PSA_FWU_SUPPORT */
 
 	return err;
 }
diff --git a/common/hw_crc32.c b/common/tf_crc32.c
similarity index 86%
rename from common/hw_crc32.c
rename to common/tf_crc32.c
index a8731da..b33d36e 100644
--- a/common/hw_crc32.c
+++ b/common/tf_crc32.c
@@ -9,8 +9,9 @@
 
 #include <arm_acle.h>
 #include <common/debug.h>
+#include <common/tf_crc32.h>
 
-/* hw_crc32 - compute CRC using Arm intrinsic function
+/* compute CRC using Arm intrinsic function
  *
  * This function is useful for the platforms with the CPU ARMv8.0
  * (with CRC instructions supported), and onwards.
@@ -23,7 +24,7 @@
  *
  * Return calculated CRC value
  */
-uint32_t hw_crc32(uint32_t crc, const unsigned char *buf, size_t size)
+uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size)
 {
 	assert(buf != NULL);
 
diff --git a/common/tf_log.c b/common/tf_log.c
index 08d3cf4..68f1be4 100644
--- a/common/tf_log.c
+++ b/common/tf_log.c
@@ -49,6 +49,20 @@
 	va_end(args);
 }
 
+void tf_log_newline(const char log_fmt[2])
+{
+	unsigned int log_level = log_fmt[0];
+
+	/* Verify that log_level is one of LOG_MARKER_* macro defined in debug.h */
+	assert((log_level > 0U) && (log_level <= LOG_LEVEL_VERBOSE));
+	assert((log_level % 10U) == 0U);
+
+	if (log_level > max_log_level)
+		return;
+
+	putchar('\n');
+}
+
 /*
  * The helper function to set the log level dynamically by platform. The
  * maximum log level is determined by `LOG_LEVEL` build flag at compile time
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index 9e3919d..437df67 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -106,14 +106,14 @@
      The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
 
 - messaging-method [mandatory]
-   - value type: <u32>
-   - Specifies which messaging methods are supported by the partition:
+   - value type: <u8>
+   - Specifies which messaging methods are supported by the partition, set bit
+     means the feature is supported, clear bit - not supported:
 
-      - 0x0: direct messaging method
-      - 0x1: indirect messaging method
-      - 0x2: both direct and indirect messaging methods
-      - 0x3: direct messaging method with managed exit support
-      - 0x4: both messaging methods with managed exit support
+      - Bit[0]: support for receiving direct message requests
+      - Bit[1]: support for sending direct messages
+      - Bit[2]: support for indirect messaging
+      - Bit[3]: support for managed exit
 
 - has-primary-scheduler
    - value type: <empty>
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 86618e4..901a72a 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -860,9 +860,31 @@
     # Resume execution
     continue
 
+Firmware update options
+-----------------------
+
+-  ``NR_OF_FW_BANKS``: Define the number of firmware banks. This flag is used
+   in defining the firmware update metadata structure. This flag is by default
+   set to '2'.
+
+-  ``NR_OF_IMAGES_IN_FW_BANK``: Define the number of firmware images in each
+   firmware bank. Each firmware bank must have the same number of images as per
+   the `PSA FW update specification`_.
+   This flag is used in defining the firmware update metadata structure. This
+   flag is by default set to '1'.
+
+-  ``PSA_FWU_SUPPORT``: Enable the firmware update mechanism as per the
+   `PSA FW update specification`_. The default value is 0, and this is an
+   experimental feature.
+   PSA firmware update implementation has some limitations, such as BL2 is
+   not part of the protocol-updatable images, if BL2 needs to be updated, then
+   it should be done through another platform-defined mechanism, and it assumes
+   that the platform's hardware supports CRC32 instructions.
+
 --------------
 
 *Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
 
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 906daf8..54754fe 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -894,6 +894,54 @@
 Note that this API depends on ``DECRYPTION_SUPPORT`` build flag which is
 marked as experimental.
 
+Function : plat_fwu_set_images_source() [when PSA_FWU_SUPPORT == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : struct fwu_metadata *metadata
+    Return   : void
+
+This function is mandatory when PSA_FWU_SUPPORT is enabled.
+It provides a means to retrieve image specification (offset in
+non-volatile storage and length) of active/updated images using the passed
+FWU metadata, and update I/O policies of active/updated images using retrieved
+image specification information.
+Further I/O layer operations such as I/O open, I/O read, etc. on these
+images rely on this function call.
+
+In Arm platforms, this function is used to set an I/O policy of the FIP image,
+container of all active/updated secure and non-secure images.
+
+Function : plat_fwu_set_metadata_image_source() [when PSA_FWU_SUPPORT == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : unsigned int image_id, uintptr_t *dev_handle,
+               uintptr_t *image_spec
+    Return   : int
+
+This function is mandatory when PSA_FWU_SUPPORT is enabled. It is
+responsible for setting up the platform I/O policy of the requested metadata
+image (either FWU_METADATA_IMAGE_ID or BKUP_FWU_METADATA_IMAGE_ID) that will
+be used to load this image from the platform's non-volatile storage.
+
+FWU metadata can not be always stored as a raw image in non-volatile storage
+to define its image specification (offset in non-volatile storage and length)
+statically in I/O policy.
+For example, the FWU metadata image is stored as a partition inside the GUID
+partition table image. Its specification is defined in the partition table
+that needs to be parsed dynamically.
+This function provides a means to retrieve such dynamic information to set
+the I/O policy of the FWU metadata image.
+Further I/O layer operations such as I/O open, I/O read, etc. on FWU metadata
+image relies on this function call.
+
+It returns '0' on success, otherwise a negative error value on error.
+Alongside, returns device handle and image specification from the I/O policy
+of the requested FWU metadata image.
+
 Common optional modifications
 -----------------------------
 
diff --git a/docs/index.rst b/docs/index.rst
index 29e5839..edc2535 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -30,6 +30,7 @@
 -  `SMC Calling Convention`_
 -  `System Control and Management Interface (SCMI)`_
 -  `Software Delegated Exception Interface (SDEI)`_
+-  `PSA FW update specification`_
 
 Where possible, the code is designed for reuse or porting to other Armv7-A and
 Armv8-A model and hardware platforms.
@@ -92,3 +93,4 @@
 .. _System Control and Management Interface (SCMI): http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
 .. _Software Delegated Exception Interface (SDEI): http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index c7f84af..917ee4a 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,7 @@
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/auth/img_parser_mod.h>
+#include <drivers/fwu/fwu.h>
 #include <lib/fconf/fconf_tbbr_getter.h>
 #include <plat/common/platform.h>
 
@@ -242,6 +243,7 @@
 	unsigned int data_len, len, i;
 	unsigned int plat_nv_ctr;
 	int rc = 0;
+	bool is_trial_run = false;
 
 	/* Get the counter value from current image. The AM expects the IPM
 	 * to return the counter value as a DER encoded integer */
@@ -284,7 +286,10 @@
 		/* Invalid NV-counter */
 		return 1;
 	} else if (*cert_nv_ctr > plat_nv_ctr) {
-		*need_nv_ctr_upgrade = true;
+#if PSA_FWU_SUPPORT && IMAGE_BL2
+		is_trial_run = fwu_is_trial_run_state();
+#endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */
+		*need_nv_ctr_upgrade = !is_trial_run;
 	}
 
 	return 0;
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
new file mode 100644
index 0000000..7cb4c29
--- /dev/null
+++ b/drivers/fwu/fwu.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/tf_crc32.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/fwu/fwu.h>
+#include <drivers/fwu/fwu_metadata.h>
+#include <drivers/io/io_storage.h>
+
+#include <plat/common/platform.h>
+
+/*
+ * Assert that crc_32 is the first member of fwu_metadata structure.
+ * It avoids accessing data outside of the metadata structure during
+ * CRC32 computation if the crc_32 field gets moved due the structure
+ * member(s) addition in the future.
+ */
+CASSERT((offsetof(struct fwu_metadata, crc_32) == 0),
+	crc_32_must_be_first_member_of_structure);
+
+static struct fwu_metadata metadata;
+static bool is_fwu_initialized;
+
+/*******************************************************************************
+ * Compute CRC32 of the FWU metadata, and check it against the CRC32 value
+ * present in the FWU metadata.
+ *
+ * return -1 on error, otherwise 0
+ ******************************************************************************/
+static int fwu_metadata_crc_check(void)
+{
+	unsigned char *data = (unsigned char *)&metadata;
+
+	uint32_t calc_crc = tf_crc32(0U, data + sizeof(metadata.crc_32),
+				     (sizeof(metadata) -
+				      sizeof(metadata.crc_32)));
+
+	if (metadata.crc_32 != calc_crc) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Check the sanity of FWU metadata.
+ *
+ * return -1 on error, otherwise 0
+ ******************************************************************************/
+static int fwu_metadata_sanity_check(void)
+{
+	/* ToDo: add more conditions for sanity check */
+	if ((metadata.active_index >= NR_OF_FW_BANKS) ||
+	    (metadata.previous_active_index >= NR_OF_FW_BANKS)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Verify and load specified FWU metadata image to local FWU metadata structure.
+ *
+ * @image_id: FWU metadata image id (either FWU_METADATA_IMAGE_ID or
+ *				     BKUP_FWU_METADATA_IMAGE_ID)
+ *
+ * return a negative value on error, otherwise 0
+ ******************************************************************************/
+static int fwu_metadata_load(unsigned int image_id)
+{
+	int result;
+	uintptr_t dev_handle, image_handle, image_spec;
+	size_t bytes_read;
+
+	assert((image_id == FWU_METADATA_IMAGE_ID) ||
+	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
+
+	result = plat_fwu_set_metadata_image_source(image_id,
+						    &dev_handle,
+						    &image_spec);
+	if (result != 0) {
+		WARN("Failed to set reference to image id=%u (%i)\n",
+		     image_id, result);
+		return result;
+	}
+
+	result = io_open(dev_handle, image_spec, &image_handle);
+	if (result != 0) {
+		WARN("Failed to load image id id=%u (%i)\n",
+		     image_id, result);
+		return result;
+	}
+
+	result = io_read(image_handle, (uintptr_t)&metadata,
+			 sizeof(struct fwu_metadata), &bytes_read);
+
+	if (result != 0) {
+		WARN("Failed to read image id=%u (%i)\n", image_id, result);
+		goto exit;
+	}
+
+	if (sizeof(struct fwu_metadata) != bytes_read) {
+		/* return -1 in case of partial/no read */
+		result = -1;
+		WARN("Read bytes (%zu) instead of expected (%zu) bytes\n",
+		     bytes_read, sizeof(struct fwu_metadata));
+		goto exit;
+	}
+
+	/* sanity check on loaded parameters */
+	result = fwu_metadata_sanity_check();
+	if (result != 0) {
+		WARN("Sanity %s\n", "check failed on FWU metadata");
+		goto exit;
+	}
+
+	/* CRC check on loaded parameters */
+	result = fwu_metadata_crc_check();
+	if (result != 0) {
+		WARN("CRC %s\n", "check failed on FWU metadata");
+	}
+
+exit:
+	(void)io_close(image_handle);
+
+	return result;
+}
+
+/*******************************************************************************
+ * The system runs in the trial run state if any of the images in the active
+ * firmware bank has not been accepted yet.
+ *
+ * Returns true if the system is running in the trial state.
+ ******************************************************************************/
+bool fwu_is_trial_run_state(void)
+{
+	bool trial_run = false;
+
+	assert(is_fwu_initialized == true);
+
+	for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
+		struct fwu_image_entry *entry = &metadata.img_entry[i];
+		struct fwu_image_properties *img_props =
+			&entry->img_props[metadata.active_index];
+		if (img_props->accepted == 0) {
+			trial_run = true;
+			break;
+		}
+	}
+
+	return trial_run;
+}
+
+/*******************************************************************************
+ * Load verified copy of FWU metadata image kept in the platform NV storage
+ * into local FWU metadata structure.
+ * Also, update platform I/O policies with the offset address and length of
+ * firmware-updated images kept in the platform NV storage.
+ ******************************************************************************/
+void fwu_init(void)
+{
+	/* Load FWU metadata which will be used to load the images in the
+	 * active bank as per PSA FWU specification
+	 */
+	int result = fwu_metadata_load(FWU_METADATA_IMAGE_ID);
+
+	if (result != 0) {
+		WARN("loading of FWU-Metadata failed, "
+		     "using Bkup-FWU-Metadata\n");
+
+		result = fwu_metadata_load(BKUP_FWU_METADATA_IMAGE_ID);
+		if (result != 0) {
+			ERROR("loading of Bkup-FWU-Metadata failed\n");
+			panic();
+		}
+	}
+
+	plat_fwu_set_images_source(&metadata);
+
+	is_fwu_initialized = true;
+}
diff --git a/drivers/fwu/fwu.mk b/drivers/fwu/fwu.mk
new file mode 100644
index 0000000..f4452e0
--- /dev/null
+++ b/drivers/fwu/fwu.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+FWU_SRC_DIR	:= drivers/fwu/
+
+FWU_SRCS	:= ${FWU_SRC_DIR}fwu.c
+
+BL2_SOURCES	+= ${FWU_SRCS}
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
index d518dbb..1af51f8 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
+++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +9,7 @@
 
 CSF_HDR_SOURCES	+=  $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/plat_img_parser.c
 
-PLAT_INCLUDES	+= -I$(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/
+PLAT_INCLUDES	+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/auth/csf_hdr_parser/
 
 $(eval $(call add_define, CSF_HEADER_PREPENDED))
 
diff --git a/drivers/nxp/console/console.mk b/drivers/nxp/console/console.mk
index 22d1336..6174650 100644
--- a/drivers/nxp/console/console.mk
+++ b/drivers/nxp/console/console.mk
@@ -14,7 +14,7 @@
 
 ADD_CONSOLE		:= 1
 
-PLAT_INCLUDES		+=	-I$(PLAT_DRIVERS_PATH)/console
+PLAT_INCLUDES		+=	-I$(PLAT_DRIVERS_INCLUDE_PATH)/console
 
 ifeq ($(CONSOLE), NS16550)
 NXP_CONSOLE		:=	NS16550
diff --git a/drivers/nxp/crypto/caam/caam.mk b/drivers/nxp/crypto/caam/caam.mk
index 548c7b1..f929f53 100644
--- a/drivers/nxp/crypto/caam/caam.mk
+++ b/drivers/nxp/crypto/caam/caam.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2020-2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,11 +8,10 @@
 ifeq (${ADD_CAAM},)
 
 ADD_CAAM		:= 1
-CAAM_DRIVER_PATH	:= drivers/nxp/crypto/caam
 
-CAAM_DRIVER_SOURCES	+=  $(wildcard $(CAAM_DRIVER_PATH)/src/*.c)
+CAAM_DRIVER_SOURCES	+=  $(wildcard $(PLAT_DRIVERS_PATH)/crypto/caam/src/*.c)
 
-PLAT_INCLUDES		+= -I$(CAAM_DRIVER_PATH)/include
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/crypto/caam
 
 ifeq (${BL_COMM_CRYPTO_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${CAAM_DRIVER_SOURCES}
diff --git a/drivers/nxp/csu/csu.mk b/drivers/nxp/csu/csu.mk
index ebdf674..bc16035 100644
--- a/drivers/nxp/csu/csu.mk
+++ b/drivers/nxp/csu/csu.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,11 +8,9 @@
 
 CSU_ADDED		:= 1
 
-CSU_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/csu
-
-PLAT_INCLUDES		+= -I$(CSU_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/csu
 
-CSU_SOURCES		+= $(CSU_DRIVERS_PATH)/csu.c
+CSU_SOURCES		+= $(PLAT_DRIVERS_PATH)/csu/csu.c
 
 ifeq (${BL_COMM_CSU_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${CSU_SOURCES}
diff --git a/drivers/nxp/dcfg/dcfg.mk b/drivers/nxp/dcfg/dcfg.mk
index 61d1850..206595f 100644
--- a/drivers/nxp/dcfg/dcfg.mk
+++ b/drivers/nxp/dcfg/dcfg.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,11 +8,9 @@
 
 ADD_DCFG		:= 1
 
-DCFG_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/dcfg
-
-PLAT_INCLUDES		+= -I$(DCFG_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/dcfg
 
-DCFG_SOURCES		+= $(DCFG_DRIVERS_PATH)/dcfg.c
+DCFG_SOURCES		+= $(PLAT_DRIVERS_PATH)/dcfg/dcfg.c
 
 ifeq (${BL_COMM_DCFG_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${DCFG_SOURCES}
diff --git a/drivers/nxp/ddr/fsl-mmdc/ddr.mk b/drivers/nxp/ddr/fsl-mmdc/ddr.mk
index e6cc7c1..afccb62 100644
--- a/drivers/nxp/ddr/fsl-mmdc/ddr.mk
+++ b/drivers/nxp/ddr/fsl-mmdc/ddr.mk
@@ -9,11 +9,11 @@
 
 DDR_DRIVERS_PATH	:=	drivers/nxp/ddr
 
-DDR_CNTLR_SOURCES	:=	${DDR_DRIVERS_PATH}/fsl-mmdc/fsl_mmdc.c \
-				${DDR_DRIVERS_PATH}/nxp-ddr/utility.c	\
-				${DDR_DRIVERS_PATH}/nxp-ddr/ddr.c	\
-				${DDR_DRIVERS_PATH}/nxp-ddr/ddrc.c
+DDR_CNTLR_SOURCES	:=	${PLAT_DRIVERS_PATH}/ddr/fsl-mmdc/fsl_mmdc.c \
+				${PLAT_DRIVERS_PATH}/ddr/nxp-ddr/utility.c	\
+				${PLAT_DRIVERS_PATH}/ddr/nxp-ddr/ddr.c	\
+				${PLAT_DRIVERS_PATH}/ddr/nxp-ddr/ddrc.c
 
-PLAT_INCLUDES		+=	-I$(DDR_DRIVERS_PATH)/include	\
-				-I$(DDR_DRIVERS_PATH)/fsl-mmdc
+PLAT_INCLUDES		+=	-I$(PLAT_DRIVERS_INCLUDE_PATH)/ddr	\
+				-I$(PLAT_DRIVERS_INCLUDE_PATH)/ddr/fsl-mmdc
 #------------------------------------------------
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.mk b/drivers/nxp/ddr/nxp-ddr/ddr.mk
index 866c092..6bdd947 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.mk
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.mk
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-DDR_DRIVERS_PATH	:= ${PLAT_DRIVERS_PATH}/ddr
-
 ifeq ($(PLAT_DDR_PHY), PHY_GEN2)
 $(eval $(call add_define, PHY_GEN2))
 PLAT_DDR_PHY_DIR		:= phy-gen2
@@ -68,12 +66,11 @@
 $(eval $(call add_define, DEBUG_DDR_INPUT_CONFIG))
 endif
 
-DDR_CNTLR_SOURCES	:= $(DDR_DRIVERS_PATH)/nxp-ddr/ddr.c \
-			   $(DDR_DRIVERS_PATH)/nxp-ddr/ddrc.c \
-			   $(DDR_DRIVERS_PATH)/nxp-ddr/dimm.c \
-			   $(DDR_DRIVERS_PATH)/nxp-ddr/regs.c \
-			   $(DDR_DRIVERS_PATH)/nxp-ddr/utility.c \
-			   $(DDR_DRIVERS_PATH)/$(PLAT_DDR_PHY_DIR)/phy.c
+DDR_CNTLR_SOURCES	:= $(PLAT_DRIVERS_PATH)/ddr/nxp-ddr/ddr.c \
+			   $(PLAT_DRIVERS_PATH)/ddr/nxp-ddr/ddrc.c \
+			   $(PLAT_DRIVERS_PATH)/ddr/nxp-ddr/dimm.c \
+			   $(PLAT_DRIVERS_PATH)/ddr/nxp-ddr/regs.c \
+			   $(PLAT_DRIVERS_PATH)/ddr/nxp-ddr/utility.c \
+			   $(PLAT_DRIVERS_PATH)/ddr/$(PLAT_DDR_PHY_DIR)/phy.c
 
-PLAT_INCLUDES		+= -I$(DDR_DRIVERS_PATH)/nxp-ddr \
-			   -I$(DDR_DRIVERS_PATH)/include
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/ddr
diff --git a/drivers/nxp/drivers.mk b/drivers/nxp/drivers.mk
index c6d5541..c2db363 100644
--- a/drivers/nxp/drivers.mk
+++ b/drivers/nxp/drivers.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,8 @@
 ###############################################################################
 
 
-PLAT_DRIVERS_PATH	:=	drivers/nxp
+PLAT_DRIVERS_PATH		:=	drivers/nxp
+PLAT_DRIVERS_INCLUDE_PATH	:=	include/drivers/nxp
 
 ifeq (${SMMU_NEEDED},yes)
 PLAT_INCLUDES	+= -Iinclude/drivers/nxp/smmu/
diff --git a/drivers/nxp/gic/gic.mk b/drivers/nxp/gic/gic.mk
index 68091e8..d75e071 100644
--- a/drivers/nxp/gic/gic.mk
+++ b/drivers/nxp/gic/gic.mk
@@ -17,7 +17,7 @@
 GIC_SOURCES		+=	${PLAT_DRIVERS_PATH}/gic/ls_gicv2.c	\
 				plat/common/plat_gicv2.c
 
-PLAT_INCLUDES		+=	-I${PLAT_DRIVERS_PATH}/gic/include/gicv2
+PLAT_INCLUDES		+=	-I${PLAT_DRIVERS_INCLUDE_PATH}/gic/gicv2
 else
 ifeq ($(GIC), GIC500)
 include drivers/arm/gic/v3/gicv3.mk
@@ -25,7 +25,7 @@
 GIC_SOURCES		+=	${PLAT_DRIVERS_PATH}/gic/ls_gicv3.c	\
 				plat/common/plat_gicv3.c
 
-PLAT_INCLUDES		+=	-I${PLAT_DRIVERS_PATH}/gic/include/gicv3
+PLAT_INCLUDES		+=	-I${PLAT_DRIVERS_INCLUDE_PATH}/gic/gicv3
 else
     $(error -> GIC type not set!)
 endif
diff --git a/drivers/nxp/gpio/gpio.mk b/drivers/nxp/gpio/gpio.mk
index 157c60a..74f0dc4 100644
--- a/drivers/nxp/gpio/gpio.mk
+++ b/drivers/nxp/gpio/gpio.mk
@@ -9,11 +9,9 @@
 
 GPIO_ADDED		:= 1
 
-GPIO_DRIVERS_PATH	:=  drivers/nxp/gpio
-
-PLAT_INCLUDES		+=  -I$(GPIO_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/gpio
 
-GPIO_SOURCES		:= $(GPIO_DRIVERS_PATH)/nxp_gpio.c
+GPIO_SOURCES		:= $(PLAT_DRIVERS_PATH)/gpio/nxp_gpio.c
 
 ifeq (${BL_COMM_GPIO_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${GPIO_SOURCES}
diff --git a/drivers/nxp/i2c/i2c.mk b/drivers/nxp/i2c/i2c.mk
index ae89115..716e14a 100644
--- a/drivers/nxp/i2c/i2c.mk
+++ b/drivers/nxp/i2c/i2c.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,10 +7,10 @@
 ifeq (${ADD_I2C},)
 
 ADD_I2C			:= 1
-I2C_DRIVERS_PATH        := ${PLAT_DRIVERS_PATH}/i2c
+
+I2C_SOURCES		+= $(PLAT_DRIVERS_PATH)/i2c/i2c.c
 
-I2C_SOURCES		+= $(I2C_DRIVERS_PATH)/i2c.c
-PLAT_INCLUDES		+= -I$(I2C_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/i2c
 
 ifeq (${BL_COMM_I2C_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${I2C_SOURCES}
diff --git a/drivers/nxp/interconnect/interconnect.mk b/drivers/nxp/interconnect/interconnect.mk
index 81e3fa9..aa51be4 100644
--- a/drivers/nxp/interconnect/interconnect.mk
+++ b/drivers/nxp/interconnect/interconnect.mk
@@ -1,4 +1,4 @@
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,7 +12,7 @@
 ifeq (${ADD_INTERCONNECT},)
 
 ADD_INTERCONNECT	:= 1
-PLAT_INCLUDES		+= -I${PLAT_DRIVERS_PATH}/interconnect
+PLAT_INCLUDES		+= -I${PLAT_DRIVERS_INCLUDE_PATH}/interconnect
 
 ifeq (, $(filter $(INTERCONNECT), CCI400 CCN502 CCN504 CCN508))
     $(error -> Interconnect type not set!)
diff --git a/drivers/nxp/pmu/pmu.mk b/drivers/nxp/pmu/pmu.mk
index 56b0422..8d2ef07 100644
--- a/drivers/nxp/pmu/pmu.mk
+++ b/drivers/nxp/pmu/pmu.mk
@@ -8,11 +8,9 @@
 
 PMU_ADDED		:= 1
 
-PMU_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/pmu
-
-PLAT_INCLUDES		+= -I$(PMU_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/pmu
 
-PMU_SOURCES		+= $(PMU_DRIVERS_PATH)/pmu.c
+PMU_SOURCES		+= $(PLAT_DRIVERS_PATH)/pmu/pmu.c
 
 ifeq (${BL_COMM_PMU_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${PMU_SOURCES}
diff --git a/drivers/nxp/qspi/qspi.mk b/drivers/nxp/qspi/qspi.mk
index 3e2c735..b83dee2 100644
--- a/drivers/nxp/qspi/qspi.mk
+++ b/drivers/nxp/qspi/qspi.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,11 +8,9 @@
 
 QSPI_ADDED		:= 1
 
-QSPI_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/qspi
-
-QSPI_SOURCES		:=  $(QSPI_DRIVERS_PATH)/qspi.c
+QSPI_SOURCES		:= $(PLAT_DRIVERS_PATH)/qspi/qspi.c
 
-PLAT_INCLUDES		+= -I$(QSPI_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_PATH)/qspi
 
 ifeq (${BL_COMM_QSPI_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${QSPI_SOURCES}
diff --git a/drivers/nxp/sd/sd_mmc.mk b/drivers/nxp/sd/sd_mmc.mk
index af91b1f..c83b1bd 100644
--- a/drivers/nxp/sd/sd_mmc.mk
+++ b/drivers/nxp/sd/sd_mmc.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,12 +8,10 @@
 
 ADD_SD_MMC	:= 1
 
-SD_DRIVERS_PATH		:=  ${PLAT_DRIVERS_PATH}/sd
-
-SD_MMC_BOOT_SOURCES	+= ${SD_DRIVERS_PATH}/sd_mmc.c \
+SD_MMC_BOOT_SOURCES	+= ${PLAT_DRIVERS_PATH}/sd/sd_mmc.c \
 			   drivers/io/io_block.c
 
-PLAT_INCLUDES		+= -I$(SD_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/sd
 
 ifeq (${BL_COMM_SD_MMC_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${SD_MMC_BOOT_SOURCES}
diff --git a/drivers/nxp/sec_mon/sec_mon.mk b/drivers/nxp/sec_mon/sec_mon.mk
index 51e3e86..aaac53f 100644
--- a/drivers/nxp/sec_mon/sec_mon.mk
+++ b/drivers/nxp/sec_mon/sec_mon.mk
@@ -8,11 +8,9 @@
 
 ADD_SNVS		:= 1
 
-SNVS_DRIVERS_PATH	:= ${PLAT_DRIVERS_PATH}/sec_mon
-
-PLAT_INCLUDES		+= -I$(SNVS_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/sec_mon
 
-SNVS_SOURCES		+= $(SNVS_DRIVERS_PATH)/snvs.c
+SNVS_SOURCES		+= $(PLAT_DRIVERS_PATH)/sec_mon/snvs.c
 
 ifeq (${BL_COMM_SNVS_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${SNVS_SOURCES}
diff --git a/drivers/nxp/sfp/sfp.mk b/drivers/nxp/sfp/sfp.mk
index 2546dc2..de708c5 100644
--- a/drivers/nxp/sfp/sfp.mk
+++ b/drivers/nxp/sfp/sfp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2021 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,14 +9,12 @@
 SFP_ADDED		:= 1
 $(eval $(call add_define, NXP_SFP_ENABLED))
 
-SFP_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/sfp
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/sfp
 
-PLAT_INCLUDES		+= -I$(SFP_DRIVERS_PATH)
-
-SFP_SOURCES		+= $(SFP_DRIVERS_PATH)/sfp.c
+SFP_SOURCES		+= $(PLAT_DRIVERS_PATH)/sfp/sfp.c
 
 ifeq (${FUSE_PROG}, 1)
-SFP_BL2_SOURCES		+= $(SFP_DRIVERS_PATH)/fuse_prov.c
+SFP_BL2_SOURCES		+= $(PLAT_DRIVERS_PATH)/sfp/fuse_prov.c
 endif
 
 ifeq (${BL_COMM_SFP_NEEDED},yes)
diff --git a/drivers/nxp/timer/timer.mk b/drivers/nxp/timer/timer.mk
index b9e298f..d658d19 100644
--- a/drivers/nxp/timer/timer.mk
+++ b/drivers/nxp/timer/timer.mk
@@ -8,10 +8,8 @@
 
 ADD_TIMER		:= 1
 
-TIMER_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/timer
-
-PLAT_INCLUDES		+= -I$(TIMER_DRIVERS_PATH)
-TIMER_SOURCES	+= drivers/delay_timer/delay_timer.c	\
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/timer
+TIMER_SOURCES		+= drivers/delay_timer/delay_timer.c	\
 			   $(PLAT_DRIVERS_PATH)/timer/nxp_timer.c
 
 ifeq (${BL_COMM_TIMER_NEEDED},yes)
diff --git a/drivers/nxp/tzc/tzc.mk b/drivers/nxp/tzc/tzc.mk
index 830d78e..3fba28f 100644
--- a/drivers/nxp/tzc/tzc.mk
+++ b/drivers/nxp/tzc/tzc.mk
@@ -8,13 +8,11 @@
 
 ADD_TZASC		:= 1
 
-TZASC_DRIVERS_PATH	:=  ${PLAT_DRIVERS_PATH}/tzc
-
-PLAT_INCLUDES		+= -I$(TZASC_DRIVERS_PATH)
+PLAT_INCLUDES		+= -I$(PLAT_DRIVERS_INCLUDE_PATH)/tzc
 
 ifeq ($(TZC_ID), TZC400)
 TZASC_SOURCES		+= drivers/arm/tzc/tzc400.c\
-			   $(TZASC_DRIVERS_PATH)/plat_tzc400.c
+			   $(PLAT_DRIVERS_PATH)/tzc/plat_tzc400.c
 else ifeq ($(TZC_ID), NONE)
     $(info -> No TZC present on platform)
 else
diff --git a/include/common/debug.h b/include/common/debug.h
index ed0e8bf..a7ca0d7 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -61,8 +61,10 @@
 
 #if LOG_LEVEL >= LOG_LEVEL_ERROR
 # define ERROR(...)	tf_log(LOG_MARKER_ERROR __VA_ARGS__)
+# define ERROR_NL()	tf_log_newline(LOG_MARKER_ERROR)
 #else
 # define ERROR(...)	no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
+# define ERROR_NL()
 #endif
 
 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
@@ -109,6 +111,7 @@
 void __dead2 __stack_chk_fail(void);
 
 void tf_log(const char *fmt, ...) __printflike(1, 2);
+void tf_log_newline(const char log_fmt[2]);
 void tf_log_set_max_level(unsigned int log_level);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/common/hw_crc32.h b/include/common/tf_crc32.h
similarity index 62%
rename from include/common/hw_crc32.h
rename to include/common/tf_crc32.h
index 0d14d57..38c56a5 100644
--- a/include/common/hw_crc32.h
+++ b/include/common/tf_crc32.h
@@ -4,13 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef HW_CRC32_H
-#define HW_CRC32_H
+#ifndef TF_CRC32_H
+#define TF_CRC32_H
 
 #include <stddef.h>
 #include <stdint.h>
 
 /* compute CRC using Arm intrinsic function */
-uint32_t hw_crc32(uint32_t crc, const unsigned char *buf, size_t size);
+uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size);
 
-#endif /* HW_CRC32_H */
+#endif /* TF_CRC32_H */
diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h
new file mode 100644
index 0000000..ae06da9
--- /dev/null
+++ b/include/drivers/fwu/fwu.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FWU_H
+#define FWU_H
+
+#include <stdbool.h>
+
+void fwu_init(void);
+bool fwu_is_trial_run_state(void);
+
+#endif /* FWU_H */
diff --git a/include/drivers/fwu/fwu_metadata.h b/include/drivers/fwu/fwu_metadata.h
new file mode 100644
index 0000000..2e88de5
--- /dev/null
+++ b/include/drivers/fwu/fwu_metadata.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * FWU metadata information as per the specification section 4.1:
+ * https://developer.arm.com/documentation/den0118/a/
+ *
+ */
+
+#ifndef FWU_METADATA_H
+#define FWU_METADATA_H
+
+#include <stdint.h>
+#include <tools_share/uuid.h>
+
+/* Properties of image in a bank */
+struct fwu_image_properties {
+
+	/* UUID of the image in this bank */
+	uuid_t img_uuid;
+
+	/* [0]: bit describing the image acceptance status –
+	 *      1 means the image is accepted
+	 * [31:1]: MBZ
+	 */
+	uint32_t accepted;
+
+	/* reserved (MBZ) */
+	uint32_t reserved;
+
+} __packed;
+
+/* Image entry information */
+struct fwu_image_entry {
+
+	/* UUID identifying the image type */
+	uuid_t img_type_uuid;
+
+	/* UUID of the storage volume where the image is located */
+	uuid_t location_uuid;
+
+	/* Properties of images with img_type_uuid in the different FW banks */
+	struct fwu_image_properties img_props[NR_OF_FW_BANKS];
+
+} __packed;
+
+/*
+ * FWU metadata filled by the updater and consumed by TF-A for
+ * various purposes as below:
+ * 1. Get active FW bank.
+ * 2. Rollback to previous working FW bank.
+ * 3. Get properties of all images present in all banks.
+ */
+struct fwu_metadata {
+
+	/* Metadata CRC value */
+	uint32_t crc_32;
+
+	/* Metadata version */
+	uint32_t version;
+
+	/* Bank index with which device boots */
+	uint32_t active_index;
+
+	/* Previous bank index with which device booted successfully */
+	uint32_t previous_active_index;
+
+	/* Image entry information */
+	struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+
+} __packed;
+
+#endif /* FWU_METADATA_H */
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h b/include/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h
similarity index 98%
rename from drivers/nxp/auth/csf_hdr_parser/csf_hdr.h
rename to include/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h
index eaead76..ae56d3b 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h
+++ b/include/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/console/plat_console.h b/include/drivers/nxp/console/plat_console.h
similarity index 100%
rename from drivers/nxp/console/plat_console.h
rename to include/drivers/nxp/console/plat_console.h
diff --git a/drivers/nxp/crypto/caam/include/caam.h b/include/drivers/nxp/crypto/caam/caam.h
similarity index 97%
rename from drivers/nxp/crypto/caam/include/caam.h
rename to include/drivers/nxp/crypto/caam/caam.h
index 580e133..4984b54 100644
--- a/drivers/nxp/crypto/caam/include/caam.h
+++ b/include/drivers/nxp/crypto/caam/caam.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/caam_io.h b/include/drivers/nxp/crypto/caam/caam_io.h
similarity index 97%
rename from drivers/nxp/crypto/caam/include/caam_io.h
rename to include/drivers/nxp/crypto/caam/caam_io.h
index 4fdb04d..b68f836 100644
--- a/drivers/nxp/crypto/caam/include/caam_io.h
+++ b/include/drivers/nxp/crypto/caam/caam_io.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/hash.h b/include/drivers/nxp/crypto/caam/hash.h
similarity index 98%
rename from drivers/nxp/crypto/caam/include/hash.h
rename to include/drivers/nxp/crypto/caam/hash.h
index 946087d..9136dca 100644
--- a/drivers/nxp/crypto/caam/include/hash.h
+++ b/include/drivers/nxp/crypto/caam/hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/jobdesc.h b/include/drivers/nxp/crypto/caam/jobdesc.h
similarity index 97%
rename from drivers/nxp/crypto/caam/include/jobdesc.h
rename to include/drivers/nxp/crypto/caam/jobdesc.h
index 5921f7b..efef228 100644
--- a/drivers/nxp/crypto/caam/include/jobdesc.h
+++ b/include/drivers/nxp/crypto/caam/jobdesc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/jr_driver_config.h b/include/drivers/nxp/crypto/caam/jr_driver_config.h
similarity index 99%
rename from drivers/nxp/crypto/caam/include/jr_driver_config.h
rename to include/drivers/nxp/crypto/caam/jr_driver_config.h
index f25c42e..1b3c447 100644
--- a/drivers/nxp/crypto/caam/include/jr_driver_config.h
+++ b/include/drivers/nxp/crypto/caam/jr_driver_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/rsa.h b/include/drivers/nxp/crypto/caam/rsa.h
similarity index 96%
rename from drivers/nxp/crypto/caam/include/rsa.h
rename to include/drivers/nxp/crypto/caam/rsa.h
index bd5dc71..dd9ecdc 100644
--- a/drivers/nxp/crypto/caam/include/rsa.h
+++ b/include/drivers/nxp/crypto/caam/rsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/sec_hw_specific.h b/include/drivers/nxp/crypto/caam/sec_hw_specific.h
similarity index 99%
rename from drivers/nxp/crypto/caam/include/sec_hw_specific.h
rename to include/drivers/nxp/crypto/caam/sec_hw_specific.h
index a82a1a0..a4fc022 100644
--- a/drivers/nxp/crypto/caam/include/sec_hw_specific.h
+++ b/include/drivers/nxp/crypto/caam/sec_hw_specific.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/crypto/caam/include/sec_jr_driver.h b/include/drivers/nxp/crypto/caam/sec_jr_driver.h
similarity index 99%
rename from drivers/nxp/crypto/caam/include/sec_jr_driver.h
rename to include/drivers/nxp/crypto/caam/sec_jr_driver.h
index 1381eab..57e0fa0 100644
--- a/drivers/nxp/crypto/caam/include/sec_jr_driver.h
+++ b/include/drivers/nxp/crypto/caam/sec_jr_driver.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/csu/csu.h b/include/drivers/nxp/csu/csu.h
similarity index 96%
rename from drivers/nxp/csu/csu.h
rename to include/drivers/nxp/csu/csu.h
index 9f82feb..3a43e45 100644
--- a/drivers/nxp/csu/csu.h
+++ b/include/drivers/nxp/csu/csu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
similarity index 98%
rename from drivers/nxp/dcfg/dcfg.h
rename to include/drivers/nxp/dcfg/dcfg.h
index 161e295..3f4855a 100644
--- a/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/dcfg/dcfg_lsch2.h b/include/drivers/nxp/dcfg/dcfg_lsch2.h
similarity index 98%
rename from drivers/nxp/dcfg/dcfg_lsch2.h
rename to include/drivers/nxp/dcfg/dcfg_lsch2.h
index c021aa1..2838aca 100644
--- a/drivers/nxp/dcfg/dcfg_lsch2.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/dcfg/dcfg_lsch3.h b/include/drivers/nxp/dcfg/dcfg_lsch3.h
similarity index 98%
rename from drivers/nxp/dcfg/dcfg_lsch3.h
rename to include/drivers/nxp/dcfg/dcfg_lsch3.h
index 8144542..40f02c1 100644
--- a/drivers/nxp/dcfg/dcfg_lsch3.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/dcfg/scfg.h b/include/drivers/nxp/dcfg/scfg.h
similarity index 98%
rename from drivers/nxp/dcfg/scfg.h
rename to include/drivers/nxp/dcfg/scfg.h
index 81df9a6..b6e3df5 100644
--- a/drivers/nxp/dcfg/scfg.h
+++ b/include/drivers/nxp/dcfg/scfg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/ddr/include/ddr.h b/include/drivers/nxp/ddr/ddr.h
similarity index 100%
rename from drivers/nxp/ddr/include/ddr.h
rename to include/drivers/nxp/ddr/ddr.h
diff --git a/drivers/nxp/ddr/include/ddr_io.h b/include/drivers/nxp/ddr/ddr_io.h
similarity index 100%
rename from drivers/nxp/ddr/include/ddr_io.h
rename to include/drivers/nxp/ddr/ddr_io.h
diff --git a/drivers/nxp/ddr/include/dimm.h b/include/drivers/nxp/ddr/dimm.h
similarity index 100%
rename from drivers/nxp/ddr/include/dimm.h
rename to include/drivers/nxp/ddr/dimm.h
diff --git a/drivers/nxp/ddr/fsl-mmdc/fsl_mmdc.h b/include/drivers/nxp/ddr/fsl-mmdc/fsl_mmdc.h
similarity index 100%
rename from drivers/nxp/ddr/fsl-mmdc/fsl_mmdc.h
rename to include/drivers/nxp/ddr/fsl-mmdc/fsl_mmdc.h
diff --git a/drivers/nxp/ddr/include/immap.h b/include/drivers/nxp/ddr/immap.h
similarity index 100%
rename from drivers/nxp/ddr/include/immap.h
rename to include/drivers/nxp/ddr/immap.h
diff --git a/drivers/nxp/ddr/include/opts.h b/include/drivers/nxp/ddr/opts.h
similarity index 100%
rename from drivers/nxp/ddr/include/opts.h
rename to include/drivers/nxp/ddr/opts.h
diff --git a/drivers/nxp/ddr/include/regs.h b/include/drivers/nxp/ddr/regs.h
similarity index 100%
rename from drivers/nxp/ddr/include/regs.h
rename to include/drivers/nxp/ddr/regs.h
diff --git a/drivers/nxp/ddr/include/utility.h b/include/drivers/nxp/ddr/utility.h
similarity index 100%
rename from drivers/nxp/ddr/include/utility.h
rename to include/drivers/nxp/ddr/utility.h
diff --git a/drivers/nxp/gic/include/gicv2/plat_gic.h b/include/drivers/nxp/gic/gicv2/plat_gic.h
similarity index 100%
rename from drivers/nxp/gic/include/gicv2/plat_gic.h
rename to include/drivers/nxp/gic/gicv2/plat_gic.h
diff --git a/drivers/nxp/gic/include/gicv3/plat_gic.h b/include/drivers/nxp/gic/gicv3/plat_gic.h
similarity index 100%
rename from drivers/nxp/gic/include/gicv3/plat_gic.h
rename to include/drivers/nxp/gic/gicv3/plat_gic.h
diff --git a/drivers/nxp/gpio/nxp_gpio.h b/include/drivers/nxp/gpio/nxp_gpio.h
similarity index 100%
rename from drivers/nxp/gpio/nxp_gpio.h
rename to include/drivers/nxp/gpio/nxp_gpio.h
diff --git a/drivers/nxp/i2c/i2c.h b/include/drivers/nxp/i2c/i2c.h
similarity index 97%
rename from drivers/nxp/i2c/i2c.h
rename to include/drivers/nxp/i2c/i2c.h
index 925bbc0..85e6eb4 100644
--- a/drivers/nxp/i2c/i2c.h
+++ b/include/drivers/nxp/i2c/i2c.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2020 NXP
+ * Copyright 2016-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/interconnect/ls_interconnect.h b/include/drivers/nxp/interconnect/ls_interconnect.h
similarity index 92%
rename from drivers/nxp/interconnect/ls_interconnect.h
rename to include/drivers/nxp/interconnect/ls_interconnect.h
index 26787fb..777089c 100644
--- a/drivers/nxp/interconnect/ls_interconnect.h
+++ b/include/drivers/nxp/interconnect/ls_interconnect.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/pmu/pmu.h b/include/drivers/nxp/pmu/pmu.h
similarity index 100%
rename from drivers/nxp/pmu/pmu.h
rename to include/drivers/nxp/pmu/pmu.h
diff --git a/drivers/nxp/qspi/qspi.h b/include/drivers/nxp/qspi/qspi.h
similarity index 100%
rename from drivers/nxp/qspi/qspi.h
rename to include/drivers/nxp/qspi/qspi.h
diff --git a/drivers/nxp/sd/sd_mmc.h b/include/drivers/nxp/sd/sd_mmc.h
similarity index 99%
rename from drivers/nxp/sd/sd_mmc.h
rename to include/drivers/nxp/sd/sd_mmc.h
index 29ad328..32b41f1 100644
--- a/drivers/nxp/sd/sd_mmc.h
+++ b/include/drivers/nxp/sd/sd_mmc.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/drivers/nxp/sec_mon/snvs.h b/include/drivers/nxp/sec_mon/snvs.h
similarity index 100%
rename from drivers/nxp/sec_mon/snvs.h
rename to include/drivers/nxp/sec_mon/snvs.h
diff --git a/drivers/nxp/sfp/fuse_prov.h b/include/drivers/nxp/sfp/fuse_prov.h
similarity index 100%
rename from drivers/nxp/sfp/fuse_prov.h
rename to include/drivers/nxp/sfp/fuse_prov.h
diff --git a/drivers/nxp/sfp/sfp.h b/include/drivers/nxp/sfp/sfp.h
similarity index 100%
rename from drivers/nxp/sfp/sfp.h
rename to include/drivers/nxp/sfp/sfp.h
diff --git a/drivers/nxp/sfp/sfp_error_codes.h b/include/drivers/nxp/sfp/sfp_error_codes.h
similarity index 100%
rename from drivers/nxp/sfp/sfp_error_codes.h
rename to include/drivers/nxp/sfp/sfp_error_codes.h
diff --git a/drivers/nxp/timer/nxp_timer.h b/include/drivers/nxp/timer/nxp_timer.h
similarity index 100%
rename from drivers/nxp/timer/nxp_timer.h
rename to include/drivers/nxp/timer/nxp_timer.h
diff --git a/drivers/nxp/tzc/plat_tzc400.h b/include/drivers/nxp/tzc/plat_tzc400.h
similarity index 100%
rename from drivers/nxp/tzc/plat_tzc400.h
rename to include/drivers/nxp/tzc/plat_tzc400.h
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 18f0125..2623c75 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,7 +91,17 @@
 /* FW_CONFIG */
 #define FW_CONFIG_ID			U(31)
 
+/*
+ * Primary FWU metadata image ID
+ */
+#define FWU_METADATA_IMAGE_ID		U(32)
+
+/*
+ * Backup FWU metadata image ID
+ */
+#define BKUP_FWU_METADATA_IMAGE_ID	U(33)
+
 /* Max Images */
-#define MAX_IMAGE_IDS			U(32)
+#define MAX_IMAGE_IDS			U(34)
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 846c9a4..0a19d8b 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -153,7 +153,9 @@
 int arm_io_setup(void);
 
 /* Set image specification in IO block policy */
-int arm_set_image_source(unsigned int image_id, const char *part_name);
+int arm_set_image_source(unsigned int image_id, const char *part_name,
+			 uintptr_t *dev_handle, uintptr_t *image_spec);
+void arm_set_fip_addr(uint32_t active_fw_bank_idx);
 
 /* Security utility functions */
 void arm_tzc400_setup(uintptr_t tzc_base,
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 1def86e..2d5c521 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -16,6 +16,7 @@
 #if TRNG_SUPPORT
 #include "plat_trng.h"
 #endif
+#include <drivers/fwu/fwu_metadata.h>
 
 /*******************************************************************************
  * Forward declarations
@@ -349,4 +350,12 @@
  */
 int32_t plat_is_smccc_feature_available(u_register_t fid);
 
+/*******************************************************************************
+ * FWU platform specific functions
+ ******************************************************************************/
+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);
+
 #endif /* PLATFORM_H */
diff --git a/lib/zlib/tf_gunzip.c b/lib/zlib/tf_gunzip.c
index fd56dfc..3ac80bc 100644
--- a/lib/zlib/tf_gunzip.c
+++ b/lib/zlib/tf_gunzip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include <common/debug.h>
+#include <common/tf_crc32.h>
 #include <lib/utils.h>
 #include <tf_gunzip.h>
 
@@ -100,3 +101,15 @@
 
 	return ret;
 }
+
+/* Wrapper function to calculate CRC
+ * @crc: previous accumulated CRC
+ * @buf: buffer base address
+ * @size: size of the buffer
+ *
+ * Return calculated CRC32 value
+ */
+uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size)
+{
+	return (uint32_t)crc32((unsigned long)crc, buf, size);
+}
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index b2d1ee2..72f84b5 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -344,3 +344,14 @@
 
 # Build option to use the SP804 timer instead of the generic one
 USE_SP804_TIMER			:= 0
+
+# Build option to define number of firmware banks, used in firmware update
+# metadata structure.
+NR_OF_FW_BANKS			:= 2
+
+# Build option to define number of images in firmware bank, used in firmware
+# update metadata structure.
+NR_OF_IMAGES_IN_FW_BANK		:= 1
+
+# Disable Firmware update support by default
+PSA_FWU_SUPPORT			:= 0
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index 928d0d3..07235b0 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -25,7 +25,7 @@
 	entrypoint-offset = <0x1000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
-	messaging-method = <0>; /* Direct messaging only */
+	messaging-method = <3>; /* Direct messaging only */
 	run-time-model = <1>; /* Run to completion */
 
 	/* Boot protocol */
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 63ed9fe..26af383 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -94,13 +94,10 @@
 {
 	arm_bl2_dyn_cfg_init();
 
-#if ARM_GPT_SUPPORT
-	int result = arm_set_image_source(FIP_IMAGE_ID, "FIP_A");
-
-	if (result != 0) {
-		panic();
-	}
-#endif /* ARM_GPT_SUPPORT */
+#if ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT
+	/* Always use the FIP from bank 0 */
+	arm_set_fip_addr(0U);
+#endif /* ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT */
 }
 
 /*
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index de25a53..4d5e8b4 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -185,6 +185,18 @@
   BL2_CPPFLAGS += -march=armv8-a+crc
 endif
 
+ifeq ($(PSA_FWU_SUPPORT),1)
+    # GPT support is recommended as per PSA FWU specification hence
+    # PSA FWU implementation is tightly coupled with GPT support,
+    # and it does not support other formats.
+    ifneq ($(ARM_GPT_SUPPORT),1)
+      $(error For PSA_FWU_SUPPORT, ARM_GPT_SUPPORT must be enabled)
+    endif
+    FWU_MK := drivers/fwu/fwu.mk
+    $(info Including ${FWU_MK})
+    include ${FWU_MK}
+endif
+
 ifeq (${ARCH}, aarch64)
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/aarch64
 endif
@@ -230,7 +242,7 @@
 				drivers/io/io_storage.c				\
 				plat/arm/common/arm_bl2_setup.c			\
 				plat/arm/common/arm_err.c			\
-				common/hw_crc32.c				\
+				common/tf_crc32.c				\
 				${ARM_IO_SOURCES}
 
 # Firmware Configuration Framework sources
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index c5d913e..387086a 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -5,6 +5,7 @@
  */
 
 #include <common/debug.h>
+#include <drivers/fwu/fwu_metadata.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_fip.h>
 #include <drivers/io/io_memmap.h>
@@ -24,6 +25,13 @@
 static const io_dev_connector_t *memmap_dev_con;
 uintptr_t memmap_dev_handle;
 
+#if ARM_GPT_SUPPORT
+/* fip partition names */
+static const char * const fip_part_names[] = {"FIP_A", "FIP_B"};
+CASSERT(sizeof(fip_part_names)/sizeof(char *) == NR_OF_FW_BANKS,
+	assert_fip_partition_names_missing);
+#endif /* ARM_GPT_SUPPORT */
+
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_arm_io_setup
 #pragma weak plat_arm_get_alt_image_source
@@ -139,17 +147,20 @@
 }
 
 #if ARM_GPT_SUPPORT
-/**********************************************************************
- * arm_set_image_source: Set image specification in IO policy
+/******************************************************************************
+ * Retrieve partition entry details such as offset and length, and set these
+ * details in the I/O policy of the requested image.
  *
- * @image_id: id of the image whose specification to be set
+ * @image_id: image id whose I/O policy to be updated
  *
- * @part_name: name of the partition that to be read for entry details
+ * @part_name: partition name whose details to be retrieved
  *
- * set the entry and offset details of partition in global IO policy
- * of the image
- *********************************************************************/
-int arm_set_image_source(unsigned int image_id, const char *part_name)
+ * Returns 0 on success, error otherwise
+ * Alongside, returns device handle and image specification of requested
+ * image.
+ ******************************************************************************/
+int arm_set_image_source(unsigned int image_id, const char *part_name,
+			 uintptr_t *dev_handle, uintptr_t *image_spec)
 {
 	const partition_entry_t *entry = get_partition_entry(part_name);
 
@@ -158,19 +169,82 @@
 		return -ENOENT;
 	}
 
-	const struct plat_io_policy *policy = FCONF_GET_PROPERTY(arm,
-								 io_policies,
-								 image_id);
+	struct plat_io_policy *policy = FCONF_GET_PROPERTY(arm,
+							   io_policies,
+							   image_id);
 
 	assert(policy != NULL);
 	assert(policy->image_spec != 0UL);
 
+	io_block_spec_t *spec = (io_block_spec_t *)policy->image_spec;
 	/* set offset and length of the image */
-	io_block_spec_t *image_spec = (io_block_spec_t *)policy->image_spec;
+	spec->offset = PLAT_ARM_FLASH_IMAGE_BASE + entry->start;
+	spec->length = entry->length;
 
-	image_spec->offset = PLAT_ARM_FLASH_IMAGE_BASE + entry->start;
-	image_spec->length = entry->length;
+	*dev_handle = *(policy->dev_handle);
+	*image_spec = policy->image_spec;
 
 	return 0;
 }
+
+/*******************************************************************************
+ * Set the source offset and length of the FIP image in its I/O policy.
+ *
+ * @active_fw_bank_idx: active firmware bank index gathered from FWU metadata.
+ ******************************************************************************/
+void arm_set_fip_addr(uint32_t active_fw_bank_idx)
+{
+	uintptr_t dev_handle __unused;
+	uintptr_t image_spec __unused;
+
+	assert(active_fw_bank_idx < NR_OF_FW_BANKS);
+
+	INFO("Booting with partition %s\n", fip_part_names[active_fw_bank_idx]);
+
+	int result = arm_set_image_source(FIP_IMAGE_ID,
+					  fip_part_names[active_fw_bank_idx],
+					  &dev_handle,
+					  &image_spec);
+	if (result != 0) {
+		panic();
+	}
+}
+#endif /* ARM_GPT_SUPPORT */
+
+#if PSA_FWU_SUPPORT
+/*******************************************************************************
+ * Read the FIP partition of the GPT image corresponding to the active firmware
+ * 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)
+{
+	arm_set_fip_addr(metadata->active_index);
+}
+
+/*******************************************************************************
+ * Read the requested FWU metadata partition of the GPT image to get its offset
+ * and length, and update these details in the I/O policy of the requested FWU
+ * metadata image.
+ ******************************************************************************/
+int plat_fwu_set_metadata_image_source(unsigned int image_id,
+				       uintptr_t *dev_handle,
+				       uintptr_t *image_spec)
+{
+	int result = -1;
+
+	if (image_id == FWU_METADATA_IMAGE_ID) {
+		result = arm_set_image_source(FWU_METADATA_IMAGE_ID,
+					      "FWU-Metadata",
+					      dev_handle,
+					      image_spec);
+	} else if (image_id == BKUP_FWU_METADATA_IMAGE_ID) {
+		result = arm_set_image_source(BKUP_FWU_METADATA_IMAGE_ID,
+					      "Bkup-FWU-Metadata",
+					      dev_handle,
+					      image_spec);
+	}
+
+	return result;
+}
-#endif
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 8e4469f..86fd6d5 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -18,6 +18,11 @@
 #include <plat/arm/common/arm_fconf_io_storage.h>
 #include <platform_def.h>
 
+#if PSA_FWU_SUPPORT
+/* metadata entry details */
+static io_block_spec_t fwu_metadata_spec;
+#endif /* PSA_FWU_SUPPORT */
+
 io_block_spec_t fip_block_spec = {
 /*
  * This is fixed FIP address used by BL1, BL2 loads partition table
@@ -92,6 +97,20 @@
 		open_memmap
 	},
 #endif /* ARM_GPT_SUPPORT */
+#if PSA_FWU_SUPPORT
+	[FWU_METADATA_IMAGE_ID] = {
+		&memmap_dev_handle,
+		/* filled runtime from partition information */
+		(uintptr_t)&fwu_metadata_spec,
+		open_memmap
+	},
+	[BKUP_FWU_METADATA_IMAGE_ID] = {
+		&memmap_dev_handle,
+		/* filled runtime from partition information */
+		(uintptr_t)&fwu_metadata_spec,
+		open_memmap
+	},
+#endif /* PSA_FWU_SUPPORT */
 	[FIP_IMAGE_ID] = {
 		&memmap_dev_handle,
 		(uintptr_t)&fip_block_spec,
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index 7aa477d..4f03ac4 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -20,13 +20,6 @@
 static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
 				int probe_data,
 				const struct err_handler_data *const data);
-struct efi_guid {
-	uint32_t	data1;
-	uint16_t	data2;
-	uint16_t	data3;
-	uint8_t		data4[8];
-};
-
 typedef struct mm_communicate_header {
 	struct efi_guid	header_guid;
 	size_t		message_len;
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index ba4c366..5b3262c 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -90,6 +90,7 @@
 #endif
 	unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
 
+	ERROR_NL();
 	ERROR("Unhandled External Abort received on 0x%lx from %s\n",
 		read_mpidr_el1(), get_el_str(level));
 	ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);