Merge "drivers: stm32_reset adapt interface to timeout argument" into integration
diff --git a/Makefile b/Makefile
index 5c4f36c..2f53cdf 100644
--- a/Makefile
+++ b/Makefile
@@ -651,6 +651,12 @@
     endif
 endif
 
+# SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled.
+ifeq ($(SDEI_SUPPORT)-$(SDEI_IN_FCONF),0-1)
+$(error "SDEI_IN_FCONF is an experimental feature and is only supported when \
+	SDEI_SUPPORT is enabled")
+endif
+
 # If pointer authentication is used in the firmware, make sure that all the
 # registers associated to it are also saved and restored.
 # Not doing it would leak the value of the keys used by EL3 to EL1 and S-EL1.
@@ -882,6 +888,7 @@
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
 $(eval $(call assert_boolean,USE_DEBUGFS))
 $(eval $(call assert_boolean,ARM_IO_IN_DTB))
+$(eval $(call assert_boolean,SDEI_IN_FCONF))
 $(eval $(call assert_boolean,USE_ROMLIB))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -891,6 +898,7 @@
 $(eval $(call assert_boolean,USE_SPINLOCK_CAS))
 $(eval $(call assert_boolean,ENCRYPT_BL31))
 $(eval $(call assert_boolean,ENCRYPT_BL32))
+$(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -960,6 +968,7 @@
 $(eval $(call add_define,USE_COHERENT_MEM))
 $(eval $(call add_define,USE_DEBUGFS))
 $(eval $(call add_define,ARM_IO_IN_DTB))
+$(eval $(call add_define,SDEI_IN_FCONF))
 $(eval $(call add_define,USE_ROMLIB))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -967,6 +976,7 @@
 $(eval $(call add_define,BL2_IN_XIP_MEM))
 $(eval $(call add_define,BL2_INV_DCACHE))
 $(eval $(call add_define,USE_SPINLOCK_CAS))
+$(eval $(call add_define,ERRATA_SPECULATIVE_AT))
 
 ifeq (${SANITIZE_UB},trap)
         $(eval $(call add_define,MONITOR_TRAPS))
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index 47c80aa..30b97e0 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -214,9 +214,6 @@
 {
 	bl_params_node_t *params_node;
 	unsigned int fw_config_id;
-#ifdef SPD_spmd
-	uint32_t fw_config_size = 0;
-#endif
 	uintptr_t fw_config_base;
 	bl_mem_params_node_t *mem_params;
 	uintptr_t hw_config_base = 0;
@@ -264,10 +261,6 @@
 			mem_params = get_bl_mem_params_node(fw_config_id);
 			if (mem_params != NULL) {
 				fw_config_base = mem_params->image_info.image_base;
-#ifdef SPD_spmd
-				fw_config_size =
-					mem_params->image_info.image_size;
-#endif
 			}
 		}
 
@@ -306,11 +299,6 @@
 				if (params_node->ep_info->args.arg1 == 0U)
 					params_node->ep_info->args.arg1 =
 								hw_config_base;
-#ifdef SPD_spmd
-				if (params_node->ep_info->args.arg2 == 0U)
-					params_node->ep_info->args.arg2 =
-								fw_config_size;
-#endif
 			}
 #ifdef SPD_opteed
 		}
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 1901a20..5aad14e 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -341,3 +341,199 @@
 
 	return fdt_path_offset(dtb, path);
 }
+
+
+/*******************************************************************************
+ * Only devices which are direct children of root node use CPU address domain.
+ * All other devices use addresses that are local to the device node and cannot
+ * directly used by CPU. Device tree provides an address translation mechanism
+ * through "ranges" property which provides mappings from local address space to
+ * parent address space. Since a device could be a child of a child node to the
+ * root node, there can be more than one level of address translation needed to
+ * map the device local address space to CPU address space.
+ * fdtw_translate_address() API performs address translation of a local address
+ * to a global address with help of various helper functions.
+ ******************************************************************************/
+
+static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size,
+		int parent_addr_size, int range_size, uint64_t base_address,
+		uint64_t *translated_addr)
+{
+	uint64_t local_address, parent_address, addr_range;
+
+	local_address = fdt_read_prop_cells(value, child_addr_size);
+	parent_address = fdt_read_prop_cells(value + child_addr_size,
+				parent_addr_size);
+	addr_range = fdt_read_prop_cells(value + child_addr_size +
+				parent_addr_size,
+				range_size);
+	VERBOSE("DT: Address %llx mapped to %llx with range %llx\n",
+		local_address, parent_address, addr_range);
+
+	/* Perform range check */
+	if ((base_address < local_address) ||
+		(base_address >= local_address + addr_range)) {
+		return false;
+	}
+
+	/* Found hit for the addr range that needs to be translated */
+	*translated_addr = parent_address + (base_address - local_address);
+	VERBOSE("DT: child address %llx mapped to %llx in parent bus\n",
+			local_address, parent_address);
+	return true;
+}
+
+#define ILLEGAL_ADDR	ULL(~0)
+
+static uint64_t fdtw_search_all_xlat_entries(const void *dtb,
+				const struct fdt_property *ranges_prop,
+				int local_bus, uint64_t base_address)
+{
+	uint64_t translated_addr;
+	const uint32_t *next_entry;
+	int parent_bus_node, nxlat_entries, length;
+	int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat;
+
+	/*
+	 * The number of cells in one translation entry in ranges is the sum of
+	 * the following values:
+	 * self#address-cells + parent#address-cells + self#size-cells
+	 * Ex: the iofpga ranges property has one translation entry with 4 cells
+	 * They represent iofpga#addr-cells + motherboard#addr-cells + iofpga#size-cells
+	 *              = 1                 + 2                      + 1
+	 */
+
+	parent_bus_node = fdt_parent_offset(dtb, local_bus);
+	self_addr_cells = fdt_address_cells(dtb, local_bus);
+	self_size_cells = fdt_size_cells(dtb, local_bus);
+	parent_addr_cells = fdt_address_cells(dtb, parent_bus_node);
+
+	/* Number of cells per translation entry i.e., mapping */
+	ncells_xlat = self_addr_cells + parent_addr_cells + self_size_cells;
+
+	assert(ncells_xlat > 0);
+
+	/*
+	 * Find the number of translations(mappings) specified in the current
+	 * `ranges` property. Note that length represents number of bytes and
+	 * is stored in big endian mode.
+	 */
+	length = fdt32_to_cpu(ranges_prop->len);
+	nxlat_entries = (length/sizeof(uint32_t))/ncells_xlat;
+
+	assert(nxlat_entries > 0);
+
+	next_entry = (const uint32_t *)ranges_prop->data;
+
+	/* Iterate over the entries in the "ranges" */
+	for (int i = 0; i < nxlat_entries; i++) {
+		if (fdtw_xlat_hit(next_entry, self_addr_cells,
+				parent_addr_cells, self_size_cells, base_address,
+				&translated_addr)){
+			return translated_addr;
+		}
+		next_entry = next_entry + ncells_xlat;
+	}
+
+	INFO("DT: No translation found for address %llx in node %s\n",
+		base_address, fdt_get_name(dtb, local_bus, NULL));
+	return ILLEGAL_ADDR;
+}
+
+
+/*******************************************************************************
+ * address mapping needs to be done recursively starting from current node to
+ * root node through all intermediate parent nodes.
+ * Sample device tree is shown here:
+
+smb@0,0 {
+	compatible = "simple-bus";
+
+	#address-cells = <2>;
+	#size-cells = <1>;
+	ranges = <0 0 0 0x08000000 0x04000000>,
+		 <1 0 0 0x14000000 0x04000000>,
+		 <2 0 0 0x18000000 0x04000000>,
+		 <3 0 0 0x1c000000 0x04000000>,
+		 <4 0 0 0x0c000000 0x04000000>,
+		 <5 0 0 0x10000000 0x04000000>;
+
+	motherboard {
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+			v2m_serial1: uart@a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <0 6 4>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+		};
+	};
+};
+
+ * As seen above, there are 3 levels of address translations needed. An empty
+ * `ranges` property denotes identity mapping (as seen in `motherboard` node).
+ * Each ranges property can map a set of child addresses to parent bus. Hence
+ * there can be more than 1 (translation) entry in the ranges property as seen
+ * in the `smb` node which has 6 translation entries.
+ ******************************************************************************/
+
+/* Recursive implementation */
+uint64_t fdtw_translate_address(const void *dtb, int node,
+				uint64_t base_address)
+{
+	int length, local_bus_node;
+	const char *node_name;
+	uint64_t global_address;
+
+	local_bus_node = fdt_parent_offset(dtb, node);
+	node_name = fdt_get_name(dtb, local_bus_node, NULL);
+
+	/*
+	 * In the example given above, starting from the leaf node:
+	 * uart@a000 represents the current node
+	 * iofpga@3,00000000 represents the local bus
+	 * motherboard represents the parent bus
+	 */
+
+	/* Read the ranges property */
+	const struct fdt_property *property = fdt_get_property(dtb,
+					local_bus_node, "ranges", &length);
+
+	if (property == NULL) {
+		if (local_bus_node == 0) {
+			/*
+			 * root node doesn't have range property as addresses
+			 * are in CPU address space.
+			 */
+			return base_address;
+		}
+		INFO("DT: Couldn't find ranges property in node %s\n",
+			node_name);
+		return ILLEGAL_ADDR;
+	} else if (length == 0) {
+		/* empty ranges indicates identity map to parent bus */
+		return fdtw_translate_address(dtb, local_bus_node, base_address);
+	}
+
+	VERBOSE("DT: Translation lookup in node %s at offset %d\n", node_name,
+		local_bus_node);
+	global_address = fdtw_search_all_xlat_entries(dtb, property,
+				local_bus_node, base_address);
+
+	if (global_address == ILLEGAL_ADDR) {
+		return ILLEGAL_ADDR;
+	}
+
+	/* Translate the local device address recursively */
+	return fdtw_translate_address(dtb, local_bus_node, global_address);
+}
diff --git a/docs/about/features.rst b/docs/about/features.rst
index 7c73952..964cb25 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -108,8 +108,8 @@
 
 -  Refinements to Position Independent Executable (PIE) support.
 
--  Continued support for the draft SPCI specification, to enable the use of
-   secure partition management in the secure world.
+-  Continued support for the PSA FF-A v1.0 (formally known as SPCI) specification, to enable the
+   use of secure partition management in the secure world.
 
 -  Documentation enhancements.
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index e4fb09d..9d298d0 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -1,14 +1,20 @@
-Maintainers
-===========
+Project Maintenance
+===================
 
-Trusted Firmware-A (TF-A) is an Arm maintained project. All contributions are
-ultimately merged by the maintainers listed below. Technical ownership of some
-parts of the codebase is delegated to the sub-maintainers listed below. An
-acknowledgement from these sub-maintainers may be required before the
+Trusted Firmware-A (TF-A) is an open governance community project. All
+contributions are ultimately merged by the maintainers listed below. Technical
+ownership of most parts of the codebase falls on the code owners listed
+below. An acknowledgement from these code owners is required before the
 maintainers merge a contribution.
 
+More details may be found in the `Project Maintenance Process`_ document.
+
+
+.. _maintainers:
+
+Maintainers
+-----------
+
-Main maintainers
-----------------
 :M: Dan Handley <dan.handley@arm.com>
 :G: `danh-arm`_
 :M: Soby Mathew <soby.mathew@arm.com>
@@ -27,9 +33,254 @@
 :G: `bipinravi-arm`_
 :M: Joanna Farley <joanna.farley@arm.com>
 :G: `joannafarley-arm`_
+:M: Julius Werner <jwerner@chromium.org>
+:G: `jwerner-chromium`_
+:M: Varun Wadekar <vwadekar@nvidia.com>
+:G: `vwadekar`_
+:M: Andre Przywara <andre.przywara@arm.com>
+:G: `Andre-ARM`_
+:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:G: `laurenw-arm`_
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+
+
+.. _code owners:
+
+Code owners
+-----------
+
+Core Code
+~~~~~~~~~
+
+Armv7-A architecture port
+^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Etienne Carriere <etienne.carriere@linaro.org>
+:G: `etienne-lms`_
+
+Software Delegated Exception Interface (SDEI)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Mark Dykes <mark.dykes@arm.com>
+:G: `mardyk01`_
+:M: John Powell <John.Powell@arm.com>
+:G: `john-powell-arm`_
+:F: services/std_svc/sdei/
+
+Trusted Boot
+^^^^^^^^^^^^
+:M: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:G: `sandrine-bailleux-arm`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Manish Badarkhe <manish.badarkhe@arm.com>
+:G: `ManishVB-Arm`_
+:F: drivers/auth/
+
+Secure Partition Manager (SPM)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Maksims Svecovs <maksims.svecovs@arm.com>
+:G: `max-shvetsov`_
+:M: Joao Alves <Joao.Alves@arm.com>
+:G: `J-Alves`_
+:F: services/std_svc/spm\*
+
+Exception Handling Framework (EHF)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Manish Badarkhe <manish.badarkhe@arm.com>
+:G: `ManishVB-Arm`_
+:M: John Powell <John.Powell@arm.com>
+:G: `john-powell-arm`_
+:F: bl31/ehf.c
+
+
+Drivers, Libraries and Framework Code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Console API framework
+^^^^^^^^^^^^^^^^^^^^^
+:M: Julius Werner <jwerner@chromium.org>
+:G: `jwerner-chromium`_
+:F: drivers/console/
+:F: include/drivers/console.h
+:F: plat/common/aarch64/crash_console_helpers.S
+
+coreboot support libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Julius Werner <jwerner@chromium.org>
+:G: `jwerner-chromium`_
+:F: drivers/coreboot/
+:F: include/drivers/coreboot/
+:F: include/lib/coreboot.h
+:F: lib/coreboot/
+
+eMMC/UFS drivers
+^^^^^^^^^^^^^^^^
+:M: Haojian Zhuang <haojian.zhuang@linaro.org>
+:G: `hzhuang1`_
+:F: drivers/partition/
+:F: drivers/synopsys/emmc/
+:F: drivers/synopsys/ufs/
+:F: drivers/ufs/
+:F: include/drivers/dw_ufs.h
+:F: include/drivers/ufs.h
+:F: include/drivers/synopsys/dw_mmc.h
+
+Power State Coordination Interface (PSCI)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:G: `javieralso-arm`_
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:G: `laurenw-arm`_
+:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:G: `zelalem-aweke`_
+:F: lib/psci/
+
+DebugFS
+^^^^^^^
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:F: lib/debugfs/
+
+Firmware Configuration Framework (FCONF)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+:M: Manish Badarkhe <manish.badarkhe@arm.com>
+:G: `ManishVB-Arm`_
+:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:G: `laurenw-arm`_
+:F: lib/fconf/
+
+Performance Measurement Framework (PMF)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Joao Alves <Joao.Alves@arm.com>
+:G: `J-Alves`_
+:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:G: `theotherjimmy`_
+:F: lib/pmf/
+
+Arm CPU libraries
+^^^^^^^^^^^^^^^^^
+:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:G: `laurenw-arm`_
+:M: John Powell <John.Powell@arm.com>
+:G: `john-powell-arm`_
+:F: lib/cpus/
+
+Reliability Availability Serviceabilty (RAS) framework
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:F: lib/extensions/ras/
+
+Activity Monitors Unit (AMU) extensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Alexei Fedorov <alexei.fedorov@arm.com>
+:G: `AlexeiFedorov`_
+:F: lib/extensions/amu/
+
+Memory Partitioning And Monitoring (MPAM) extensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:G: `zelalem-aweke`_
+:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:G: `theotherjimmy`_
+:F: lib/extensions/mpam/
+
+Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Alexei Fedorov <alexei.fedorov@arm.com>
+:G: `AlexeiFedorov`_
+:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:G: `zelalem-aweke`_
+:F: lib/extensions/pauth/
+
+Statistical Profiling Extension (SPE)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:G: `zelalem-aweke`_
+:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:G: `theotherjimmy`_
+:F: lib/extensions/spe/
+
+Scalable Vector Extension (SVE)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:G: `theotherjimmy`_
+:F: lib/extensions/sve/
+
+Standard C library
+^^^^^^^^^^^^^^^^^^
+:M: Alexei Fedorov <alexei.fedorov@arm.com>
+:G: `AlexeiFedorov`_
+:M: John Powell <John.Powell@arm.com>
+:G: `john-powell-arm`_
+:F: lib/libc/
+
+Library At ROM (ROMlib)
+^^^^^^^^^^^^^^^^^^^^^^^
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+:F: lib/romlib/
+
+Translation tables (``xlat_tables``) library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:G: `javieralso-arm`_
+:M: Joao Alves <Joao.Alves@arm.com>
+:G: `J-Alves`_
+:F: lib/xlat\_tables_\*/
+
+IO abstraction layer
+^^^^^^^^^^^^^^^^^^^^
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:F: drivers/io/
+
+GIC driver
+^^^^^^^^^^
+:M: Alexei Fedorov <alexei.fedorov@arm.com>
+:G: `AlexeiFedorov`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:F: drivers/arm/gic/
+
+Libfdt wrappers
+^^^^^^^^^^^^^^^
+:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:G: `madhukar-Arm`_
+:M: Manish Badarkhe <manish.badarkhe@arm.com>
+:G: `ManishVB-Arm`_
+:F: common/fdt_wrappers.c
+
+Firmware Encryption Framework
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Sumit Garg <sumit.garg@linaro.org>
+:G: `b49020`_
+:F: drivers/io/io_encrypted.c
+:F: include/drivers/io/io_encrypted.h
+:F: include/tools_share/firmware_encrypted.h
+
+
+Platform Ports
+~~~~~~~~~~~~~~
 
 Allwinner ARMv8 platform port
------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Andre Przywara <andre.przywara@arm.com>
 :G: `Andre-ARM`_
 :M: Samuel Holland <samuel@sholland.org>
@@ -39,7 +290,7 @@
 :F: drivers/allwinner/
 
 Amlogic Meson S905 (GXBB) platform port
----------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Andre Przywara <andre.przywara@arm.com>
 :G: `Andre-ARM`_
 :F: docs/plat/meson-gxbb.rst
@@ -47,33 +298,28 @@
 :F: plat/amlogic/gxbb/
 
 Amlogic Meson S905x (GXL) platform port
----------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Remi Pommarel <repk@triplefau.lt>
 :G: `remi-triplefault`_
 :F: docs/plat/meson-gxl.rst
 :F: plat/amlogic/gxl/
 
 Amlogic Meson S905X2 (G12A) platform port
------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Carlo Caione <ccaione@baylibre.com>
 :G: `carlocaione`_
 :F: docs/plat/meson-g12a.rst
 :F: plat/amlogic/g12a/
 
 Amlogic Meson A113D (AXG) platform port
------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Carlo Caione <ccaione@baylibre.com>
 :G: `carlocaione`_
 :F: docs/plat/meson-axg.rst
 :F: plat/amlogic/axg/
 
-Armv7-A architecture port
--------------------------
-:M: Etienne Carriere <etienne.carriere@linaro.org>
-:G: `etienne-lms`_
-
 Arm System Guidance for Infrastructure / Mobile FVP platforms
--------------------------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Nariman Poushin <nariman.poushin@linaro.org>
 :G: `npoushin`_
 :M: Thomas Abraham <thomas.abraham@arm.com>
@@ -83,37 +329,8 @@
 :F: plat/arm/board/sgi575/
 :F: plat/arm/board/sgm775/
 
-Console API framework
----------------------
-:M: Julius Werner <jwerner@chromium.org>
-:G: `jwerner-chromium`_
-:F: drivers/console/
-:F: include/drivers/console.h
-:F: plat/common/aarch64/crash_console_helpers.S
-
-coreboot support libraries
---------------------------
-:M: Julius Werner <jwerner@chromium.org>
-:G: `jwerner-chromium`_
-:F: drivers/coreboot/
-:F: include/drivers/coreboot/
-:F: include/lib/coreboot.h
-:F: lib/coreboot/
-
-eMMC/UFS drivers
-----------------
-:M: Haojian Zhuang <haojian.zhuang@linaro.org>
-:G: `hzhuang1`_
-:F: drivers/partition/
-:F: drivers/synopsys/emmc/
-:F: drivers/synopsys/ufs/
-:F: drivers/ufs/
-:F: include/drivers/dw_ufs.h
-:F: include/drivers/ufs.h
-:F: include/drivers/synopsys/dw_mmc.h
-
 HiSilicon HiKey and HiKey960 platform ports
--------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Haojian Zhuang <haojian.zhuang@linaro.org>
 :G: `hzhuang1`_
 :F: docs/plat/hikey.rst
@@ -122,14 +339,14 @@
 :F: plat/hisilicon/hikey960/
 
 HiSilicon Poplar platform port
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Shawn Guo <shawn.guo@linaro.org>
 :G: `shawnguo2`_
 :F: docs/plat/poplar.rst
 :F: plat/hisilicon/poplar/
 
 Intel SocFPGA platform ports
-----------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Tien Hock Loh <tien.hock.loh@intel.com>
 :G: `thloh85-intel`_
 :M: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
@@ -138,13 +355,13 @@
 :F: drivers/intel/soc/
 
 MediaTek platform ports
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
 :M: Yidi Lin (林以廸) <yidi.lin@mediatek.com>
 :G: `mtk09422`_
 :F: plat/mediatek/
 
 Marvell platform ports and SoC drivers
---------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Konstantin Porotchkin <kostap@marvell.com>
 :G: `kostapr`_
 :F: docs/plat/marvell/
@@ -153,7 +370,7 @@
 :F: tools/marvell/
 
 NVidia platform ports
----------------------
+^^^^^^^^^^^^^^^^^^^^^
 :M: Varun Wadekar <vwadekar@nvidia.com>
 :G: `vwadekar`_
 :F: docs/plat/nvidia-tegra.rst
@@ -162,14 +379,14 @@
 :F: plat/nvidia/
 
 NXP QorIQ Layerscape platform ports
------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Jiafei Pan <jiafei.pan@nxp.com>
 :G: `qoriq-open-source`_
 :F: docs/plat/ls1043a.rst
 :F: plat/layerscape/
 
 NXP i.MX 7 WaRP7 platform port and SoC drivers
-----------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
 :G: `bryanodonoghue`_
 :M: Jun Nie <jun.nie@linaro.org>
@@ -182,35 +399,28 @@
 :F: drivers/imx/usdhc/
 
 NXP i.MX 8 platform port
-------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Anson Huang <Anson.Huang@nxp.com>
 :G: `Anson-Huang`_
 :F: docs/plat/imx8.rst
 :F: plat/imx/
 
 NXP i.MX8M platform port
-------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Jacky Bai <ping.bai@nxp.com>
 :G: `JackyBai`_
 :F: docs/plat/imx8m.rst
 :F: plat/imx/imx8m/
 
-OP-TEE dispatcher
------------------
-:M: Jens Wiklander <jens.wiklander@linaro.org>
-:G: `jenswi-linaro`_
-:F: docs/components/spd/optee-dispatcher.rst
-:F: services/spd/opteed/
-
 QEMU platform port
-------------------
+^^^^^^^^^^^^^^^^^^
 :M: Jens Wiklander <jens.wiklander@linaro.org>
 :G: `jenswi-linaro`_
 :F: docs/plat/qemu.rst
 :F: plat/qemu/
 
 Raspberry Pi 3 platform port
-----------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
 :G: `grandpaul`_
 :F: docs/plat/rpi3.rst
@@ -220,7 +430,7 @@
 :F: include/drivers/rpi3/
 
 Raspberry Pi 4 platform port
-----------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Andre Przywara <andre.przywara@arm.com>
 :G: `Andre-ARM`_
 :F: docs/plat/rpi4.rst
@@ -230,7 +440,7 @@
 :F: include/drivers/rpi3/
 
 Renesas rcar-gen3 platform port
--------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Jorge Ramirez-Ortiz  <jramirez@baylibre.com>
 :G: `ldts`_
 :M: Marek Vasut <marek.vasut@gmail.com>
@@ -241,7 +451,7 @@
 :F: tools/renesas/rcar_layout_create
 
 RockChip platform port
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
 :M: Tony Xie <tony.xie@rock-chips.com>
 :G: `TonyXie06`_
 :G: `rockchip-linux`_
@@ -250,7 +460,7 @@
 :F: plat/rockchip/
 
 STM32MP1 platform port
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
 :M: Yann Gautier <yann.gautier@st.com>
 :G: `Yann-lms`_
 :F: docs/plat/stm32mp1.rst
@@ -262,43 +472,95 @@
 :F: tools/stm32image/
 
 Synquacer platform port
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
 :M: Sumit Garg <sumit.garg@linaro.org>
 :G: `b49020`_
 :F: docs/plat/synquacer.rst
 :F: plat/socionext/synquacer/
 
 Texas Instruments platform port
--------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Andrew F. Davis <afd@ti.com>
 :G: `glneo`_
 :F: docs/plat/ti-k3.rst
 :F: plat/ti/
 
-TLK/Trusty secure payloads
---------------------------
-:M: Varun Wadekar <vwadekar@nvidia.com>
-:G: `vwadekar`_
-:F: docs/components/spd/tlk-dispatcher.rst
-:F: docs/components/spd/trusty-dispatcher.rst
-:F: include/bl32/payloads/tlk.h
-:F: services/spd/tlkd/
-:F: services/spd/trusty/
-
 UniPhier platform port
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
 :M: Masahiro Yamada <yamada.masahiro@socionext.com>
 :G: `masahir0y`_
 :F: docs/plat/socionext-uniphier.rst
 :F: plat/socionext/uniphier/
 
 Xilinx platform port
---------------------
+^^^^^^^^^^^^^^^^^^^^
 :M: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
 :G: `sivadur`_
 :F: docs/plat/xilinx-zynqmp.rst
 :F: plat/xilinx/
 
+
+Secure Payloads and Dispatchers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+OP-TEE dispatcher
+^^^^^^^^^^^^^^^^^
+:M: Jens Wiklander <jens.wiklander@linaro.org>
+:G: `jenswi-linaro`_
+:F: docs/components/spd/optee-dispatcher.rst
+:F: services/spd/opteed/
+
+TLK/Trusty secure payloads
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Varun Wadekar <vwadekar@nvidia.com>
+:G: `vwadekar`_
+:F: docs/components/spd/tlk-dispatcher.rst
+:F: docs/components/spd/trusty-dispatcher.rst
+:F: include/bl32/payloads/tlk.h
+:F: services/spd/tlkd/
+:F: services/spd/trusty/
+
+Test Secure Payload (TSP)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+:M: Manish Badarkhe <manish.badarkhe@arm.com>
+:G: `ManishVB-Arm`_
+:F: bl32/tsp/
+:F: services/spd/tspd/
+
+Tools
+~~~~~
+
+Fiptool
+^^^^^^^
+:M: Joao Alves <Joao.Alves@arm.com>
+:G: `J-Alves`_
+:F: tools/fiptool/
+
+Cert_create tool
+^^^^^^^^^^^^^^^^
+:M: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:G: `sandrine-bailleux-arm`_
+:F: tools/cert_create/
+
+Encrypt_fw tool
+^^^^^^^^^^^^^^^
+:M: Sumit Garg <sumit.garg@linaro.org>
+:G: `b49020`_
+:F: tools/encrypt_fw/
+
+Sptool
+^^^^^^
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:F: tools/sptool/
+
+Build system
+^^^^^^^^^^^^
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:F: Makefile
+:F: make_helpers/
+
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
@@ -339,3 +601,15 @@
 .. _odeprez: https://github.com/odeprez
 .. _bipinravi-arm: https://github.com/bipinravi-arm
 .. _joannafarley-arm: https://github.com/joannafarley-arm
+.. _ManishVB-Arm: https://github.com/ManishVB-Arm
+.. _max-shvetsov: https://github.com/max-shvetsov
+.. _javieralso-arm: https://github.com/javieralso-arm
+.. _laurenw-arm: https://github.com/laurenw-arm
+.. _zelalem-aweke: https://github.com/zelalem-aweke
+.. _theotherjimmy: https://github.com/theotherjimmy
+.. _J-Alves: https://github.com/J-Alves
+.. _madhukar-Arm: https://github.com/madhukar-Arm
+.. _john-powell-arm: https://github.com/john-powell-arm
+
+
+.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/components/index.rst b/docs/components/index.rst
index e3ce614..c5f6264 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -17,5 +17,5 @@
    romlib-design
    sdei
    secure-partition-manager-design
-   spci-manifest-binding
+   psa-ffa-manifest-binding
    xlat-tables-lib-v2-design
diff --git a/docs/components/spci-manifest-binding.rst b/docs/components/psa-ffa-manifest-binding.rst
similarity index 83%
rename from docs/components/spci-manifest-binding.rst
rename to docs/components/psa-ffa-manifest-binding.rst
index 5848169..09894ae 100644
--- a/docs/components/spci-manifest-binding.rst
+++ b/docs/components/psa-ffa-manifest-binding.rst
@@ -1,49 +1,39 @@
-SPCI manifest binding to device tree
-====================================
+PSA FF-A manifest binding to device tree
+========================================
 
 This document defines the nodes and properties used to define a partition,
-according to the SPCI specification.
+according to the PSA FF-A specification.
 
 Version 1.0
 -----------
 
-spci-manifest-partition
-^^^^^^^^^^^^^^^^^^^^^^^
+Partition Properties
+^^^^^^^^^^^^^^^^^^^^
 
 - compatible [mandatory]
    - value type: <string>
-   - Must be the string "arm,spci-manifest-X.Y" which specifies the major and
-     minor versions fo the device tree binding for the SPCI manifest represented
+   - Must be the string "arm,ffa-manifest-X.Y" which specifies the major and
+     minor versions fo the device tree binding for the FFA manifest represented
      by this node. The minor number is incremented if the binding changes in a
      backwards compatible manner.
 
       - X is an integer representing the major version number of this document.
       - Y is an integer representing the minor version number of this document.
 
-- spci-version [mandatory]
+- ffa-version [mandatory]
    - value type: <u32>
    - Must be two 16 bits values (X, Y), concatenated as 31:16 -> X,
      15:0 -> Y, where:
 
-      - X is the major version of PSA-FF-A expected by the partition at the SPCI
+      - X is the major version of PSA-FF-A expected by the partition at the FFA
         instance it will execute.
-      - Y is the minor version of PSA-FF-A expected by the partition at the SPCI
+      - Y is the minor version of PSA-FF-A expected by the partition at the FFA
         instance it will execute.
 
 - uuid [mandatory]
    - value type: <prop-encoded-array>
    - An array consisting of 4 <u32> values, identifying the UUID of the service
      implemented by this partition. The UUID format is described in RFC 4122.
-     UUID can be shared by multiple instances of partitions that offer the same
-     service For example:
-
-      - If there are multiple instances of a Trusted OS, then the UUID can be
-        shared by all instances.
-      - The TEE driver in the HLOS can use the UUID with the
-        SPCI_PARTITION_INFO_GET interface to determine the:
-
-         - Number of Trusted OSs
-         - The partition ID of each instance of the Trusted OS
 
 - id
    - value type: <u32>
@@ -75,9 +65,6 @@
       - 0x0: EL1
       - 0x1: S_EL0
       - 0x2: S_EL1
-      - 0x3: EL2
-      - 0x4: Supervisor mode
-      - 0x5: Secure User mode
 
 - execution-state [mandatory]
    - value type: <u32>
@@ -104,7 +91,7 @@
 
       - 0x0: 4k
       - 0x1: 16k
-      - 0x2: 32k
+      - 0x2: 64k
 
 - boot-order
    - value type: <u32>
@@ -116,7 +103,7 @@
    - value type: "memory-regions" node
    - Specific "memory-regions" nodes that describe the RX/TX buffers expected
      by the partition.
-     The "compatible" must be the string "arm,spci-manifest-rx_tx-buffer".
+     The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
 
 - messaging-method [mandatory]
    - value type: <u32>
@@ -146,7 +133,7 @@
 - gp-register-num
    - value type: <u32>
    - Presence of this field indicates that the partition expects the
-     spci_init_info structure to be passed in via the specified general purpose
+     ffa_init_info structure to be passed in via the specified general purpose
      register.
      The field specifies the general purpose register number but not its width.
      The width is derived from the partition's execution state, as specified in
@@ -159,12 +146,12 @@
    - List of <u32> tuples, identifying the IDs this partition is acting as
      proxy for.
 
-memory-regions
+Memory Regions
 --------------
 
 - compatible [mandatory]
    - value type: <string>
-   - Must be the string "arm,spci-manifest-memory-regions".
+   - Must be the string "arm,ffa-manifest-memory-regions".
 
 - description
    - value type: <string>
@@ -177,26 +164,30 @@
 
 - attributes [mandatory]
    - value type: <u32>
-   - ?? TO DEFINE
+   - Mapping modes: ORed to get required permission
+
+      - 0x1: Read
+      - 0x2: Write
+      - 0x4: Execute
 
 - base-address
    - value type: <u64>
    - Base address of the region. The address must be aligned to the translation
      granule size.
      The address given may be a Physical Address (PA), Virtual Address (VA), or
-     Intermediate Physical Address (IPA). Refer to the SPCI specification for
+     Intermediate Physical Address (IPA). Refer to the FFA specification for
      more information on the restrictions around the address type.
      If the base address is omitted then the partition manager must map a memory
      region of the specified size into the partition's translation regime and
      then communicate the region properties (including the base address chosen
      by the partition manager) to the partition.
 
-device-regions
+Device Regions
 --------------
 
 - compatible [mandatory]
    - value type: <string>
-   - Must be the string "arm,spci-manifest-device-regions".
+   - Must be the string "arm,ffa-manifest-device-regions".
 
 - description
    - value type: <string>
@@ -213,7 +204,11 @@
 
 - attributes [mandatory]
    - value type: <u32>
-   - ?? TO DEFINE
+   - Mapping modes: ORed to get required permission
+
+     - 0x1: Read
+     - 0x2: Write
+     - 0x4: Execute
 
 - smmu-id
    - value type: <u32>
@@ -222,19 +217,18 @@
      upstream of. If the field is omitted then it is assumed that the device is
      not upstream of any SMMU.
 
-- stream-ids [mandatory]
+- stream-ids
    - value type: <prop-encoded-array>
    - A list of (id, mem-manage) pair, where:
 
       - id: A unique <u32> value amongst all devices assigned to the partition.
-      - mem-manage: A <u32> value used in memory management operations.
 
 - interrupts [mandatory]
    - value type: <prop-encoded-array>
    - A list of (id, attributes) pair describing the device interrupts, where:
 
       - id: The <u32> interrupt IDs.
-      - attributes: A ?? TO DEFINE value,
+      - attributes: A <u32> value,
         containing the attributes for each interrupt ID:
 
          - Interrupt type: SPI, PPI, SGI
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 1a53e22..6913e66 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -619,11 +619,13 @@
 The TBBR CoT
 ~~~~~~~~~~~~
 
-The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
-an array of pointers to image descriptors and it is registered in the framework
-using the macro ``REGISTER_COT(cot_desc)``, where ``cot_desc`` must be the name
-of the array (passing a pointer or any other type of indirection will cause the
-registration process to fail).
+CoT specific to BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_bl1.c``
+and ``drivers/auth/tbbr/tbbr_cot_bl2.c`` respectively. The common CoT used across
+BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_common.c``.
+This CoT consists of an array of pointers to image descriptors and it is
+registered in the framework using the macro ``REGISTER_COT(cot_desc)``, where
+``cot_desc`` must be the name of the array (passing a pointer or any other
+type of indirection will cause the registration process to fail).
 
 The number of images participating in the boot process depends on the CoT.
 There is, however, a minimum set of images that are mandatory in TF-A and thus
@@ -702,7 +704,7 @@
    address/size to store the parameter. The CoT is responsible for allocating
    the required memory to store the parameters. This pointer may be NULL.
 
-In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters
+In the ``tbbr_cot*.c`` file, a set of buffers are allocated to store the parameters
 extracted from the certificates. In the case of the TBBR CoT, these parameters
 are hashes and public keys. In DER format, an RSA-4096 public key requires 550
 bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 90fe83f..c863079 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -645,6 +645,11 @@
    configuration device tree, instead of static structure in the code base.
    This is currently an experimental feature.
 
+-  ``SDEI_IN_FCONF``: This flag determines whether to configure SDEI setup in
+   runtime using firmware configuration framework. The platform specific SDEI
+   shared and private events configuration is retrieved from device tree rather
+   than static C structures at compile time. This is currently an experimental
+   feature and is only supported if SDEI_SUPPORT build flag is enabled.
 
 -  ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
    This feature creates a library of functions to be placed in ROM and thus
@@ -673,6 +678,29 @@
    default value of this flag is ``no``. Note this option must be enabled only
    for ARM architecture greater than Armv8.5-A.
 
+-  ``ERRATA_SPECULATIVE_AT``: This flag enables/disables page table walk during
+   context restore as speculative AT instructions using an out-of-context
+   translation regime could cause subsequent requests to generate an incorrect
+   translation.
+   System registers are not updated during context save, hence this workaround
+   need not be applied in the context save path.
+
+   This boolean option enables errata for all below CPUs.
+
+   +---------+--------------+
+   | Errata  |      CPU     |
+   +=========+==============+
+   | 1165522 |  Cortex-A76  |
+   +---------+--------------+
+   | 1319367 |  Cortex-A72  |
+   +---------+--------------+
+   | 1319537 |  Cortex-A57  |
+   +---------+--------------+
+   | 1530923 |  Cortex-A55  |
+   +---------+--------------+
+   | 1530924 |  Cortex-A53  |
+   +---------+--------------+
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 2d17f12..b7a93e4 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1890,6 +1890,21 @@
 of the system counter, which is retrieved from the first entry in the frequency
 modes table.
 
+Function : plat_arm_set_twedel_scr_el3() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint32_t
+
+This function is used in v8.6+ systems to set the WFE trap delay value in
+SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this
+feature is not enabled.  The only hook provided is to set the TWED fields in
+SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust
+the WFE trap delays in lower ELs and these fields should be set by the
+appropriate EL2 or EL1 code depending on the platform configuration.
+
 #define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1941,23 +1956,27 @@
 Functions
 .........
 
-Function: int plat_sdei_validate_entry_point(uintptr_t ep) [optional]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Function: int plat_sdei_validate_entry_point() [optional]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
-  Argument: uintptr_t
+  Argument: uintptr_t ep, unsigned int client_mode
   Return: int
 
+This function validates the entry point address of the event handler provided by
+the client for both event registration and *Complete and Resume* |SDEI| calls.
+The function ensures that the address is valid in the client translation regime.
+
-This function validates the address of client entry points provided for both
-event registration and *Complete and Resume* |SDEI| calls. The function
-takes one argument, which is the address of the handler the |SDEI| client
-requested to register. The function must return ``0`` for successful validation,
-or ``-1`` upon failure.
+The second argument is the exception level that the client is executing in. It
+can be Non-Secure EL1 or Non-Secure EL2.
+
+The function must return ``0`` for successful validation, or ``-1`` upon failure.
 
 The default implementation always returns ``0``. On Arm platforms, this function
-is implemented to translate the entry point to physical address, and further to
-ensure that the address is located in Non-secure DRAM.
+translates the entry point address within the client translation regime and
+further ensures that the resulting physical address is located in Non-secure
+DRAM.
 
 Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional]
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 4dda1dc..d33155b 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -14,6 +14,7 @@
 .. |EHF| replace:: :term:`EHF`
 .. |FCONF| replace:: :term:`FCONF`
 .. |FDT| replace:: :term:`FDT`
+.. |FFA| replace:: :term:`FFA`
 .. |FIP| replace:: :term:`FIP`
 .. |FVP| replace:: :term:`FVP`
 .. |FWU| replace:: :term:`FWU`
@@ -44,7 +45,6 @@
 .. |SMCCC| replace:: :term:`SMCCC`
 .. |SoC| replace:: :term:`SoC`
 .. |SP| replace:: :term:`SP`
-.. |SPCI| replace:: :term:`SPCI`
 .. |SPD| replace:: :term:`SPD`
 .. |SPM| replace:: :term:`SPM`
 .. |SSBS| replace:: :term:`SSBS`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 3da30b0..e087079 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -57,6 +57,9 @@
    FDT
       Flattened Device Tree
 
+   FFA
+      Firmware Framework for A-class processors
+
    FIP
       Firmware Image Package
 
@@ -107,6 +110,9 @@
    PMF
       Performance Measurement Framework
 
+   PSA
+      Platform Security Architecture
+
    PSCI
       Power State Coordination Interface
 
@@ -149,9 +155,6 @@
    SP
       Secure Partition
 
-   SPCI
-      Secure Partition Client Interface
-
    SPD
       Secure Payload Dispatcher
 
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
index e26f75e..1afe475 100644
--- a/docs/plat/arm/index.rst
+++ b/docs/plat/arm/index.rst
@@ -8,6 +8,7 @@
    juno/index
    fvp/index
    fvp-ve/index
+   tc0/index
    arm-build-options
 
 This chapter holds documentation related to Arm's development platforms,
diff --git a/docs/plat/arm/tc0/index.rst b/docs/plat/arm/tc0/index.rst
new file mode 100644
index 0000000..34d1f13
--- /dev/null
+++ b/docs/plat/arm/tc0/index.rst
@@ -0,0 +1,50 @@
+TC0 Total Compute Platform
+==========================
+
+Some of the features of TC0 platform referenced in TF-A include:
+
+- A `System Control Processor <https://github.com/ARM-software/SCP-firmware>`_
+  to abstract power and system management tasks away from application
+  processors. The RAM firmware for SCP is included in the TF-A FIP and is
+  loaded by AP BL2 from FIP in flash to SRAM for copying by SCP (SCP has access
+  to AP SRAM).
+- GICv4
+- Trusted Board Boot
+- SCMI
+- MHUv2
+
+Boot Sequence
+-------------
+
+The execution begins from SCP_BL1. SCP_BL1 powers up the AP which starts
+executing AP_BL1 and then executes AP_BL2 which loads the SCP_BL2 from
+FIP to SRAM. The SCP has access to AP SRAM. The address and size of SCP_BL2
+is communicated to SCP using SDS. SCP copies SCP_BL2 from SRAM to its own
+RAM and starts executing it. The AP then continues executing the rest of TF-A
+stages including BL31 runtime stage and hands off executing to
+Non-secure world (u-boot).
+
+Build Procedure (TF-A only)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-  Obtain arm `toolchain <https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads>`_.
+   Set the CROSS_COMPILE environment variable to point to the toolchain folder.
+
+-  Build TF-A:
+
+   .. code:: shell
+
+      make PLAT=tc0 BL33=<path_to_uboot.bin> \
+      SCP_BL2=<path_to_scp_ramfw.bin>  all fip
+
+   Enable TBBR by adding the following options to the make command:
+
+   .. code:: shell
+
+      MBEDTLS_DIR=<path_to_mbedtls_directory>  \
+      TRUSTED_BOARD_BOOT=1 \
+      GENERATE_COT=1 \
+      ARM_ROTPK_LOCATION=devel_rsa  \
+      ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/plat/imx8m.rst b/docs/plat/imx8m.rst
index 8acd13c..ba087a2 100644
--- a/docs/plat/imx8m.rst
+++ b/docs/plat/imx8m.rst
@@ -32,6 +32,7 @@
 
    Target_SoC should be "imx8mq" for i.MX8MQ SoC.
    Target_SoC should be "imx8mm" for i.MX8MM SoC.
+   Target_SoC should be "imx8mn" for i.MX8MN SoC.
 
 Deploy TF-A Images
 ~~~~~~~~~~~~~~~~~~
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index 68c494b..7886cf4 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -4,8 +4,8 @@
 Getting Started
 ---------------
 
--  Make sure you have a Github account and you are logged on
-   `developer.trustedfirmware.org`_.
+-  Make sure you have a Github account and you are logged on both
+   `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_.
 -  Create an `issue`_ for your work if one does not already exist. This gives
    everyone visibility of whether others are working on something similar.
 
@@ -55,9 +55,9 @@
       where XXXX is the year of first contribution (if different to YYYY) and
       YYYY is the year of most recent contribution. <OWNER> is your name or
       your company name.
-   -  If you are submitting new files that you intend to be the technical
-      sub-maintainer for (for example, a new platform port), then also update
-      the :ref:`maintainers` file.
+   -  If you are submitting new files that you intend to be the code owner for
+      (for example, a new platform port), then also update the
+      :ref:`code owners` file.
    -  For topics with multiple commits, you should make all documentation
       changes (and nothing else) in the last commit of the series. Otherwise,
       include the documentation changes within the single commit.
@@ -91,8 +91,10 @@
    targeting the ``integration`` branch.
 
    -  The changes will then undergo further review and testing by the
-      :ref:`maintainers`. Any review comments will be made directly on your
-      patch. This may require you to do some rework.
+      :ref:`code owners` and :ref:`maintainers`. Any review comments will be
+      made directly on your patch. This may require you to do some rework. For
+      controversial changes, the discussion might be moved to the `TF-A mailing
+      list`_ to involve more of the community.
 
    Refer to the `Gerrit Uploading Changes documentation`_ for more details.
 
@@ -102,12 +104,12 @@
       ``integration`` branch.
    -  If the changes are not based on a sufficiently-recent commit, or if they
       cannot be automatically rebased, then the :ref:`maintainers` may rebase it
-      on the ``master`` branch or ask you to do so.
+      on the ``integration`` branch or ask you to do so.
    -  After final integration testing, the changes will make their way into the
-      ``master`` branch. If a problem is found during integration, the merge
-      commit will be removed from the ``integration`` branch and the
-      :ref:`maintainers` will ask you to create a new patch set to resolve the
-      problem.
+      ``master`` branch. If a problem is found during integration, the
+      :ref:`maintainers` will request your help to solve the issue. They may
+      revert your patches and ask you to resubmit a reworked version of them or
+      they may ask you to provide a fix-up patch.
 
 Binary Components
 -----------------
@@ -131,12 +133,14 @@
 *Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
+.. _review.trustedfirmware.org: https://review.trustedfirmware.org
 .. _issue: https://developer.trustedfirmware.org/project/board/1/
 .. _Trusted Firmware-A: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
 .. _Git guidelines: http://git-scm.com/book/ch5-2.html
 .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
 .. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
 .. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
-.. _TF-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
+.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io
 .. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
 .. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
+.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
diff --git a/docs/process/faq.rst b/docs/process/faq.rst
index 2c36584..daab198 100644
--- a/docs/process/faq.rst
+++ b/docs/process/faq.rst
@@ -70,12 +70,10 @@
 All the comments from ``ci-bot-user`` are associated with Continuous Integration
 infrastructure. The links published on the comment are not currently accessible,
 but would be after the CI has been transitioned to `trustedfirmware.org`_.
-Please refer to https://github.com/ARM-software/tf-issues/issues/681 for more
-details on the timelines.
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
 
 .. _Gerrit Upload Patch Set documentation: https://review.trustedfirmware.org/Documentation/intro-user.html#upload-patch-set
 .. _Gerrit Replace Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html#push_replace
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
index eb0b020..8aca2be 100644
--- a/drivers/auth/dualroot/cot.c
+++ b/drivers/auth/dualroot/cot.c
@@ -13,44 +13,6 @@
 #include <tools_share/dualroot_oid.h>
 
 /*
- * TODO: Remove dependency on mbedTLS. The chain of trust should be agnostic of
- * the specific cryptographic library in use.
-*/
-/*
- * Maximum key and hash sizes (in DER format).
- *
- * Both RSA and ECDSA keys may be used at the same time. In this case, the key
- * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
- * ones for all key sizes we support, they impose the minimum size of these
- * buffers.
- */
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE == 1024
-#define PK_DER_LEN			162
-#elif TF_MBEDTLS_KEY_SIZE == 2048
-#define PK_DER_LEN			294
-#elif TF_MBEDTLS_KEY_SIZE == 3072
-#define PK_DER_LEN			422
-#elif TF_MBEDTLS_KEY_SIZE == 4096
-#define PK_DER_LEN			550
-#else
-#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
-#endif
-#else /* Only using ECDSA keys. */
-#define PK_DER_LEN			91
-#endif
-
-#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
-#define HASH_DER_LEN			51
-#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384
-#define HASH_DER_LEN			67
-#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512
-#define HASH_DER_LEN			83
-#else
-#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
-#endif
-
-/*
  * Allocate static buffers to store the authentication parameters extracted from
  * the certificates.
  */
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
new file mode 100644
index 0000000..f3bb376
--- /dev/null
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <platform_def.h>
+#include <drivers/auth/mbedtls/mbedtls_config.h>
+
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/tbbr_cot_common.h>
+#if USE_TBBR_DEFS
+#include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
+static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FWU_HASH_OID);
+
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
+			}
+		}
+	}
+};
+
+/*
+ * FWU auth descriptor.
+ */
+static const auth_img_desc_t fwu_cert = {
+	.img_id = FWU_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_bl2u_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &bl2u_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &ns_bl2u_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+/*
+ * SCP_BL2U
+ */
+static const auth_img_desc_t scp_bl2u_image = {
+	.img_id = SCP_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_bl2u_hash
+			}
+		}
+	}
+};
+/*
+ * BL2U
+ */
+static const auth_img_desc_t bl2u_image = {
+	.img_id = BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &bl2u_hash
+			}
+		}
+	}
+};
+/*
+ * NS_BL2U
+ */
+static const auth_img_desc_t ns_bl2u_image = {
+	.img_id = NS_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &ns_bl2u_hash
+				}
+			}
+		}
+};
+/*
+ * TB_FW_CONFIG
+ */
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+/*
+ * TBBR Chain of trust definition
+ */
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FWU_CERT_ID]				=	&fwu_cert,
+	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
+	[BL2U_IMAGE_ID]				=	&bl2u_image,
+	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
+};
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
similarity index 66%
rename from drivers/auth/tbbr/tbbr_cot.c
rename to drivers/auth/tbbr/tbbr_cot_bl2.c
index 6f00b18..c47bf1a 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -10,60 +10,13 @@
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 
 #include <drivers/auth/auth_mod.h>
+#include <drivers/auth/tbbr_cot_common.h>
 #if USE_TBBR_DEFS
 #include <tools_share/tbbr_oid.h>
 #else
 #include <platform_oid.h>
 #endif
 
-
-/*
- * Maximum key and hash sizes (in DER format).
- *
- * Both RSA and ECDSA keys may be used at the same time. In this case, the key
- * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
- * ones for all key sizes we support, they impose the minimum size of these
- * buffers.
- */
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE == 1024
-#define PK_DER_LEN			162
-#elif TF_MBEDTLS_KEY_SIZE == 2048
-#define PK_DER_LEN			294
-#elif TF_MBEDTLS_KEY_SIZE == 3072
-#define PK_DER_LEN			422
-#elif TF_MBEDTLS_KEY_SIZE == 4096
-#define PK_DER_LEN			550
-#else
-#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
-#endif
-#else /* Only using ECDSA keys. */
-#define PK_DER_LEN			91
-#endif
-
-#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
-#define HASH_DER_LEN			51
-#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384
-#define HASH_DER_LEN			67
-#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512
-#define HASH_DER_LEN			83
-#else
-#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
-#endif
-
-/*
- * The platform must allocate buffers to store the authentication parameters
- * extracted from the certificates. In this case, because of the way the CoT is
- * established, we can reuse some of the buffers on different stages
- */
-
-static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char hw_config_hash_buf[HASH_DER_LEN];
-static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
-
-#ifdef IMAGE_BL2
 static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
@@ -74,40 +27,7 @@
 static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
-#endif
-
-/*
- * Parameter type descriptors
- */
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-
-static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, 0);
-static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG, 0);
-static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG_ALG, 0);
-static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_RAW_DATA, 0);
-
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
-#ifdef IMAGE_BL1
-static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FWU_HASH_OID);
-#endif /* IMAGE_BL1 */
 
-#ifdef IMAGE_BL2
 static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
@@ -141,107 +61,6 @@
 static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
 
-#endif /* IMAGE_BL2 */
-
-
-	/*
-	 * BL2
-	 */
-static const auth_img_desc_t trusted_boot_fw_cert = {
-	.img_id = TRUSTED_BOOT_FW_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tb_fw_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tb_fw_config_hash,
-			.data = {
-				.ptr = (void *)tb_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &hw_config_hash,
-			.data = {
-				.ptr = (void *)hw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-	};
-#ifdef IMAGE_BL1
-static const auth_img_desc_t bl2_image = {
-	.img_id = BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-/* HW Config */
-static const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
-/* TB FW Config */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t tb_fw_config = {
-	.img_id = TB_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_config_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-#ifdef IMAGE_BL2
 /*
  * Trusted key certificate
  */
@@ -716,119 +535,9 @@
 		}
 	}
 };
-#else  /* IMAGE_BL2 */
-/*
- * FWU auth descriptor.
- */
-static const auth_img_desc_t fwu_cert = {
-	.img_id = FWU_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_bl2u_hash,
-			.data = {
-				.ptr = (void *)scp_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &bl2u_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &ns_bl2u_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-/*
- * SCP_BL2U
- */
-static const auth_img_desc_t scp_bl2u_image = {
-	.img_id = SCP_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &scp_bl2u_hash
-			}
-		}
-	}
-};
-/*
- * BL2U
- */
-static const auth_img_desc_t bl2u_image = {
-	.img_id = BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &bl2u_hash
-			}
-		}
-	}
-};
-/*
- * NS_BL2U
- */
-static const auth_img_desc_t ns_bl2u_image = {
-	.img_id = NS_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &ns_bl2u_hash
-				}
-			}
-		}
-	};
-#endif /* IMAGE_BL2 */
-/*
- * TBBR Chain of trust definition
- */
 
-#ifdef IMAGE_BL1
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
-	[BL2_IMAGE_ID]				=	&bl2_image,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
-	[FWU_CERT_ID]				=	&fwu_cert,
-	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
-	[BL2U_IMAGE_ID]				=	&bl2u_image,
-	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
-};
-#else /* IMAGE_BL2 */
-static const auth_img_desc_t * const cot_desc[] = {
-	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
 	[HW_CONFIG_ID]				=	&hw_config,
 	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
 	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
@@ -849,7 +558,6 @@
 	[BL33_IMAGE_ID]				=	&bl33_image,
 	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
 };
-#endif
 
 /* Register the CoT in the authentication module */
 REGISTER_COT(cot_desc);
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
new file mode 100644
index 0000000..0a4b75e
--- /dev/null
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <platform_def.h>
+#include <drivers/auth/mbedtls/mbedtls_config.h>
+
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/tbbr_cot_common.h>
+#if USE_TBBR_DEFS
+#include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
+/*
+ * The platform must allocate buffers to store the authentication parameters
+ * extracted from the certificates. In this case, because of the way the CoT is
+ * established, we can reuse some of the buffers on different stages
+ */
+
+unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+unsigned char hw_config_hash_buf[HASH_DER_LEN];
+unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+/*
+ * common Parameter type descriptors across BL1 and BL2
+ */
+auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_PUB_KEY, 0);
+auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_SIG, 0);
+auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_SIG_ALG, 0);
+auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_RAW_DATA, 0);
+
+/* common hash used across BL1 and BL2 */
+auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+	AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
+
+/* trusted_boot_fw_cert */
+const auth_img_desc_t trusted_boot_fw_cert = {
+	.img_id = TRUSTED_BOOT_FW_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &hw_config_hash,
+			.data = {
+				.ptr = (void *)hw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+/* HW Config */
+const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 540c66a..2f4dcad 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -106,10 +106,62 @@
 	_MCUS_SEL,
 	_USBPHY_SEL,
 	_USBO_SEL,
+	_MPU_SEL,
+	_PER_SEL,
+	_RTC_SEL,
 	_PARENT_SEL_NB,
 	_UNKNOWN_SEL = 0xff,
 };
 
+/* State the parent clock ID straight related to a clock */
+static const uint8_t parent_id_clock_id[_PARENT_NB] = {
+	[_HSE] = CK_HSE,
+	[_HSI] = CK_HSI,
+	[_CSI] = CK_CSI,
+	[_LSE] = CK_LSE,
+	[_LSI] = CK_LSI,
+	[_I2S_CKIN] = _UNKNOWN_ID,
+	[_USB_PHY_48] = _UNKNOWN_ID,
+	[_HSI_KER] = CK_HSI,
+	[_HSE_KER] = CK_HSE,
+	[_HSE_KER_DIV2] = CK_HSE_DIV2,
+	[_CSI_KER] = CK_CSI,
+	[_PLL1_P] = PLL1_P,
+	[_PLL1_Q] = PLL1_Q,
+	[_PLL1_R] = PLL1_R,
+	[_PLL2_P] = PLL2_P,
+	[_PLL2_Q] = PLL2_Q,
+	[_PLL2_R] = PLL2_R,
+	[_PLL3_P] = PLL3_P,
+	[_PLL3_Q] = PLL3_Q,
+	[_PLL3_R] = PLL3_R,
+	[_PLL4_P] = PLL4_P,
+	[_PLL4_Q] = PLL4_Q,
+	[_PLL4_R] = PLL4_R,
+	[_ACLK] = CK_AXI,
+	[_PCLK1] = CK_AXI,
+	[_PCLK2] = CK_AXI,
+	[_PCLK3] = CK_AXI,
+	[_PCLK4] = CK_AXI,
+	[_PCLK5] = CK_AXI,
+	[_CK_PER] = CK_PER,
+	[_CK_MPU] = CK_MPU,
+	[_CK_MCU] = CK_MCU,
+};
+
+static unsigned int clock_id2parent_id(unsigned long id)
+{
+	unsigned int n;
+
+	for (n = 0U; n < ARRAY_SIZE(parent_id_clock_id); n++) {
+		if (parent_id_clock_id[n] == id) {
+			return n;
+		}
+	}
+
+	return _UNKNOWN_ID;
+}
+
 enum stm32mp1_pll_id {
 	_PLL1,
 	_PLL2,
@@ -259,7 +311,8 @@
 	[_ ## _label ## _SEL] = {				\
 		.offset = _rcc_selr,				\
 		.src = _rcc_selr ## _ ## _label ## SRC_SHIFT,	\
-		.msk = _rcc_selr ## _ ## _label ## SRC_MASK,	\
+		.msk = (_rcc_selr ## _ ## _label ## SRC_MASK) >> \
+		       (_rcc_selr ## _ ## _label ## SRC_SHIFT), \
 		.parent = (_parents),				\
 		.nb_parent = ARRAY_SIZE(_parents)		\
 	}
@@ -281,19 +334,6 @@
 		.refclk[3] = (p4),			\
 	}
 
-static const uint8_t stm32mp1_clks[][2] = {
-	{ CK_PER, _CK_PER },
-	{ CK_MPU, _CK_MPU },
-	{ CK_AXI, _ACLK },
-	{ CK_MCU, _CK_MCU },
-	{ CK_HSE, _HSE },
-	{ CK_CSI, _CSI },
-	{ CK_LSI, _LSI },
-	{ CK_LSE, _LSE },
-	{ CK_HSI, _HSI },
-	{ CK_HSE_DIV2, _HSE_KER_DIV2 },
-};
-
 #define NB_GATES	ARRAY_SIZE(stm32mp1_clk_gate)
 
 static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
@@ -369,6 +409,7 @@
 	_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
 	_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
 
+	_CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL),
 	_CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
 };
 
@@ -440,6 +481,18 @@
 	_PLL4_R, _USB_PHY_48
 };
 
+static const uint8_t mpu_parents[] = {
+	_HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */
+};
+
+static const uint8_t per_parents[] = {
+	_HSI, _HSE, _CSI,
+};
+
+static const uint8_t rtc_parents[] = {
+	_UNKNOWN_ID, _LSE, _LSI, _HSE
+};
+
 static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
 	_CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents),
 	_CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents),
@@ -448,6 +501,9 @@
 	_CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents),
 	_CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents),
 	_CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents),
+	_CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents),
+	_CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents),
+	_CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents),
 	_CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents),
 	_CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents),
 	_CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents),
@@ -618,16 +674,16 @@
 static int stm32mp1_clk_get_parent(unsigned long id)
 {
 	const struct stm32mp1_clk_sel *sel;
-	uint32_t j, p_sel;
+	uint32_t p_sel;
 	int i;
 	enum stm32mp1_parent_id p;
 	enum stm32mp1_parent_sel s;
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
-	for (j = 0U; j < ARRAY_SIZE(stm32mp1_clks); j++) {
-		if (stm32mp1_clks[j][0] == id) {
-			return (int)stm32mp1_clks[j][1];
-		}
+	/* Few non gateable clock have a static parent ID, find them */
+	i = (int)clock_id2parent_id(id);
+	if (i != _UNKNOWN_ID) {
+		return i;
 	}
 
 	i = stm32mp1_clk_get_gated_id(id);
@@ -649,7 +705,8 @@
 	}
 
 	sel = clk_sel_ref(s);
-	p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src;
+	p_sel = (mmio_read_32(rcc_base + sel->offset) &
+		 (sel->msk << sel->src)) >> sel->src;
 	if (p_sel < sel->nb_parent) {
 		return (int)sel->parent[p_sel];
 	}
@@ -931,27 +988,27 @@
 {
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
+	VERBOSE("Enable clock %u\n", gate->index);
+
 	if (gate->set_clr != 0U) {
 		mmio_write_32(rcc_base + gate->offset, BIT(gate->bit));
 	} else {
 		mmio_setbits_32(rcc_base + gate->offset, BIT(gate->bit));
 	}
-
-	VERBOSE("Clock %d has been enabled", gate->index);
 }
 
 static void __clk_disable(struct stm32mp1_clk_gate const *gate)
 {
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
+	VERBOSE("Disable clock %u\n", gate->index);
+
 	if (gate->set_clr != 0U) {
 		mmio_write_32(rcc_base + gate->offset + RCC_MP_ENCLRR_OFFSET,
 			      BIT(gate->bit));
 	} else {
 		mmio_clrbits_32(rcc_base + gate->offset, BIT(gate->bit));
 	}
-
-	VERBOSE("Clock %d has been disabled", gate->index);
 }
 
 static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate)
@@ -972,12 +1029,41 @@
 	return gate_refcounts[i];
 }
 
+/* Oscillators and PLLs are not gated at runtime */
+static bool clock_is_always_on(unsigned long id)
+{
+	switch (id) {
+	case CK_HSE:
+	case CK_CSI:
+	case CK_LSI:
+	case CK_LSE:
+	case CK_HSI:
+	case CK_HSE_DIV2:
+	case PLL1_Q:
+	case PLL1_R:
+	case PLL2_P:
+	case PLL2_Q:
+	case PLL2_R:
+	case PLL3_P:
+	case PLL3_Q:
+	case PLL3_R:
+		return true;
+	default:
+		return false;
+	}
+}
+
 void __stm32mp1_clk_enable(unsigned long id, bool secure)
 {
 	const struct stm32mp1_clk_gate *gate;
-	int i = stm32mp1_clk_get_gated_id(id);
+	int i;
 	unsigned int *refcnt;
 
+	if (clock_is_always_on(id)) {
+		return;
+	}
+
+	i = stm32mp1_clk_get_gated_id(id);
 	if (i < 0) {
 		ERROR("Clock %d can't be enabled\n", (uint32_t)id);
 		panic();
@@ -998,9 +1084,14 @@
 void __stm32mp1_clk_disable(unsigned long id, bool secure)
 {
 	const struct stm32mp1_clk_gate *gate;
-	int i = stm32mp1_clk_get_gated_id(id);
+	int i;
 	unsigned int *refcnt;
 
+	if (clock_is_always_on(id)) {
+		return;
+	}
+
+	i = stm32mp1_clk_get_gated_id(id);
 	if (i < 0) {
 		ERROR("Clock %d can't be disabled\n", (uint32_t)id);
 		panic();
@@ -1030,8 +1121,13 @@
 
 bool stm32mp_clk_is_enabled(unsigned long id)
 {
-	int i = stm32mp1_clk_get_gated_id(id);
+	int i;
 
+	if (clock_is_always_on(id)) {
+		return true;
+	}
+
+	i = stm32mp1_clk_get_gated_id(id);
 	if (i < 0) {
 		panic();
 	}
@@ -1913,6 +2009,23 @@
 
 static void sync_earlyboot_clocks_state(void)
 {
+	unsigned int idx;
+	const unsigned long secure_enable[] = {
+		AXIDCG,
+		BSEC,
+		DDRC1, DDRC1LP,
+		DDRC2, DDRC2LP,
+		DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP,
+		DDRPHYC, DDRPHYCLP,
+		TZC1, TZC2,
+		TZPC,
+		STGEN_K,
+	};
+
+	for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) {
+		stm32mp_clk_enable(secure_enable[idx]);
+	}
+
 	if (!stm32mp_is_single_core()) {
 		stm32mp1_clk_enable_secure(RTCAPB);
 	}
diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts
index fcef927..591ec58 100644
--- a/fdts/fvp-base-gicv2-psci-aarch32.dts
+++ b/fdts/fvp-base-gicv2-psci-aarch32.dts
@@ -4,8 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	AFF
+#define	REG_32
+
+#include "fvp-defs.dtsi"
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -42,37 +49,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-
-			cluster1 {
-				core0 {
-					cpu = <&CPU4>;
-				};
-				core1 {
-					cpu = <&CPU5>;
-				};
-				core2 {
-					cpu = <&CPU6>;
-				};
-				core3 {
-					cpu = <&CPU7>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -96,77 +73,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU4:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x100>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU5:cpu@101 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x101>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU6:cpu@102 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x102>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU7:cpu@103 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x103>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts
index 1e0a81c..4b3942e 100644
--- a/fdts/fvp-base-gicv2-psci.dts
+++ b/fdts/fvp-base-gicv2-psci.dts
@@ -4,8 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	AFF
+
+#include "fvp-defs.dtsi"
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -42,37 +48,7 @@
 		#address-cells = <2>;
 		#size-cells = <0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-
-			cluster1 {
-				core0 {
-					cpu = <&CPU4>;
-				};
-				core1 {
-					cpu = <&CPU5>;
-				};
-				core2 {
-					cpu = <&CPU6>;
-				};
-				core3 {
-					cpu = <&CPU7>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -96,77 +72,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU4:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x100>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU5:cpu@101 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x101>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU6:cpu@102 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x102>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU7:cpu@103 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x103>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-1t.dts b/fdts/fvp-base-gicv3-psci-1t.dts
index 3c82f7b..c5e0424 100644
--- a/fdts/fvp-base-gicv3-psci-1t.dts
+++ b/fdts/fvp-base-gicv3-psci-1t.dts
@@ -4,38 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/dts-v1/;
-
-#include "fvp-base-gicv3-psci-common.dtsi"
-
-&CPU0 {
-	reg = <0x0 0x0>;
-};
-
-&CPU1 {
-	reg = <0x0 0x100>;
-};
+/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
 
-&CPU2 {
-	reg = <0x0 0x200>;
-};
-
-&CPU3 {
-	reg = <0x0 0x300>;
-};
-
-&CPU4 {
-	reg = <0x0 0x10000>;
-};
-
-&CPU5 {
-	reg = <0x0 0x10100>;
-};
+/dts-v1/;
 
-&CPU6 {
-	reg = <0x0 0x10200>;
-};
+#define	AFF	00
 
-&CPU7 {
-	reg = <0x0 0x10300>;
-};
+#include "fvp-defs.dtsi"
+#include "fvp-base-gicv3-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
index d1d3348..a31c703 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
+++ b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
@@ -4,38 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/dts-v1/;
-
-#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
-
-&CPU0 {
-	reg = <0x0>;
-};
-
-&CPU1 {
-	reg = <0x100>;
-};
+/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
 
-&CPU2 {
-	reg = <0x200>;
-};
-
-&CPU3 {
-	reg = <0x300>;
-};
-
-&CPU4 {
-	reg = <0x10000>;
-};
-
-&CPU5 {
-	reg = <0x10100>;
-};
+/dts-v1/;
 
-&CPU6 {
-	reg = <0x10200>;
-};
+#define	AFF	00
+#define	REG_32
 
-&CPU7 {
-	reg = <0x10300>;
-};
+#include "fvp-defs.dtsi"
+#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
index a28a4a5..1a1bd12 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
@@ -40,37 +40,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-
-			cluster1 {
-				core0 {
-					cpu = <&CPU4>;
-				};
-				core1 {
-					cpu = <&CPU5>;
-				};
-				core2 {
-					cpu = <&CPU6>;
-				};
-				core3 {
-					cpu = <&CPU7>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -94,77 +64,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU4:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x100>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU5:cpu@101 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x101>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU6:cpu@102 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x102>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU7:cpu@103 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x103>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dts b/fdts/fvp-base-gicv3-psci-aarch32.dts
index 513014b..971b2e4 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32.dts
+++ b/fdts/fvp-base-gicv3-psci-aarch32.dts
@@ -4,6 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	REG_32
+#define	AFF
+
+#include "fvp-defs.dtsi"
 #include "fvp-base-gicv3-psci-aarch32-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi
index fb73f60..0deb8a2 100644
--- a/fdts/fvp-base-gicv3-psci-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-common.dtsi
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <services/sdei_flags.h>
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -35,42 +37,36 @@
 		sys_reset = <0x84000009>;
 		max-pwr-lvl = <2>;
 	};
+
+#if SDEI_IN_FCONF
+	firmware {
+		sdei {
+			compatible = "arm,sdei-1.0";
+			method = "smc";
+			private_event_count = <3>;
+			shared_event_count = <3>;
+			/*
+			 * Each event descriptor has typically 3 fields:
+			 * 1. Event number
+			 * 2. Interrupt number the event is bound to or
+			 *    if event is dynamic, specified as SDEI_DYN_IRQ
+			 * 3. Bit map of event flags
+			 */
+			private_events =	<1000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<1001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<1002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
+			shared_events =		<2000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
+		};
+	};
+#endif /* SDEI_IN_FCONF */
 
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
 
-		CPU_MAP:cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-
-			cluster1 {
-				core0 {
-					cpu = <&CPU4>;
-				};
-				core1 {
-					cpu = <&CPU5>;
-				};
-				core2 {
-					cpu = <&CPU6>;
-				};
-				core3 {
-					cpu = <&CPU7>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -94,77 +90,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU4:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x100>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU5:cpu@101 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x101>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU6:cpu@102 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x102>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU7:cpu@103 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x103>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
index 6e63b43..bda4b8d 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -4,185 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/dts-v1/;
-
-#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
-
-&CPU_MAP {
-	/delete-node/ cluster0;
-
-	cluster0 {
-		core0 {
-			thread0 {
-				cpu = <&CPU0>;
-			};
-			thread1 {
-				cpu = <&CPU1>;
-			};
-		};
-		core1 {
-			thread0 {
-				cpu = <&CPU2>;
-			};
-			thread1 {
-				cpu = <&CPU3>;
-			};
-		};
-		core2 {
-			thread0 {
-				cpu = <&CPU4>;
-			};
-			thread1 {
-				cpu = <&CPU5>;
-			};
-		};
-		core3 {
-			thread0 {
-				cpu = <&CPU6>;
-			};
-			thread1 {
-				cpu = <&CPU7>;
-			};
-		};
-		core4 {
-			thread0 {
-				cpu = <&CPU8>;
-			};
-			thread1 {
-				cpu = <&CPU9>;
-			};
-		};
-		core5 {
-			thread0 {
-				cpu = <&CPU10>;
-			};
-			thread1 {
-				cpu = <&CPU11>;
-			};
-		};
-		core6 {
-			thread0 {
-				cpu = <&CPU12>;
-			};
-			thread1 {
-				cpu = <&CPU13>;
-			};
-		};
-		core7 {
-			thread0 {
-				cpu = <&CPU14>;
-			};
-			thread1 {
-				cpu = <&CPU15>;
-			};
-		};
-	};
-};
-
-/ {
-	cpus {
-		CPU0:cpu@0 {
-			reg = <0x0 0x0>;
-		};
-
-		CPU1:cpu@1 {
-			reg = <0x0 0x1>;
-		};
-
-		CPU2:cpu@2 {
-			reg = <0x0 0x100>;
-		};
-
-		CPU3:cpu@3 {
-			reg = <0x0 0x101>;
-		};
-
-		CPU4:cpu@100 {
-			reg = <0x0 0x200>;
-		};
+/* DynamIQ configuration: 1 cluster with up to 8 CPUs with 2 threads per each */
 
-		CPU5:cpu@101 {
-			reg = <0x0 0x201>;
-		};
+/* Set default value if not passed from platform's makefile */
+#ifdef	FVP_MAX_PE_PER_CPU
+#define	PE_PER_CPU		FVP_MAX_PE_PER_CPU
+#else
+#define	PE_PER_CPU		2
+#endif
 
-		CPU6:cpu@102 {
-			reg = <0x0 0x300>;
-		};
-
-		CPU7:cpu@103 {
-			reg = <0x0 0x301>;
-		};
-
-		CPU8:cpu@200 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x400>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU9:cpu@201 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x401>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU10:cpu@202 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x500>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU11:cpu@203 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x501>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU12:cpu@300 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x600>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU13:cpu@301 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x601>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU14:cpu@302 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x700>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+/dts-v1/;
 
-		CPU15:cpu@303 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x701>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-	};
-};
+#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
index 4bed36f..42a439f 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
@@ -6,38 +6,5 @@
 
 /dts-v1/;
 
+#include "fvp-defs-dynamiq.dtsi"
 #include "fvp-base-gicv3-psci-common.dtsi"
-
-/* DynamIQ based designs have upto 8 CPUs in each cluster */
-
-&CPU_MAP {
-	/delete-node/ cluster0;
-	/delete-node/ cluster1;
-
-	cluster0 {
-		core0 {
-			cpu = <&CPU0>;
-		};
-		core1 {
-			cpu = <&CPU1>;
-		};
-		core2 {
-			cpu = <&CPU2>;
-		};
-		core3 {
-			cpu = <&CPU3>;
-		};
-		core4 {
-			cpu = <&CPU4>;
-		};
-		core5 {
-			cpu = <&CPU5>;
-		};
-		core6 {
-			cpu = <&CPU6>;
-		};
-		core7 {
-			cpu = <&CPU7>;
-		};
-	};
-};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts
index b8b0445..b693f75 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts
@@ -4,38 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/dts-v1/;
-
-#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
-
-&CPU0 {
-	reg = <0x0 0x0>;
-};
-
-&CPU1 {
-	reg = <0x0 0x100>;
-};
+/* DynamIQ configuration: 1 cluster with up to 8 CPUs */
 
-&CPU2 {
-	reg = <0x0 0x200>;
-};
+/* Set default value if not passed from platform's makefile */
+#ifdef	FVP_MAX_PE_PER_CPU
+#define	PE_PER_CPU		FVP_MAX_PE_PER_CPU
+#else
+#define	PE_PER_CPU		1
+#endif
 
-&CPU3 {
-	reg = <0x0 0x300>;
-};
-
-&CPU4 {
-	reg = <0x0 0x400>;
-};
-
-&CPU5 {
-	reg = <0x0 0x500>;
-};
-
-&CPU6 {
-	reg = <0x0 0x600>;
-};
+/dts-v1/;
 
-&CPU7 {
-	reg = <0x0 0x700>;
-};
+#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts
index 65fa4b0..eb99472 100644
--- a/fdts/fvp-base-gicv3-psci.dts
+++ b/fdts/fvp-base-gicv3-psci.dts
@@ -4,6 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	AFF
+
+#include "fvp-defs.dtsi"
 #include "fvp-base-gicv3-psci-common.dtsi"
diff --git a/fdts/fvp-defs-dynamiq.dtsi b/fdts/fvp-defs-dynamiq.dtsi
new file mode 100644
index 0000000..3659cd3
--- /dev/null
+++ b/fdts/fvp-defs-dynamiq.dtsi
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef	FVP_DEFS_DYNAMIQ_DTSI
+#define	FVP_DEFS_DYNAMIQ_DTSI
+
+/* Set default topology values if not passed from platform's makefile */
+#ifdef	FVP_CLUSTER_COUNT
+#define	CLUSTER_COUNT		FVP_CLUSTER_COUNT
+#else
+#define	CLUSTER_COUNT		1
+#endif
+
+#ifdef FVP_MAX_CPUS_PER_CLUSTER
+#define	CPUS_PER_CLUSTER	FVP_MAX_CPUS_PER_CLUSTER
+#else
+#define	CPUS_PER_CLUSTER	8
+#endif
+
+#define CONCAT(x, y)	x##y
+#define CONC(x, y)	CONCAT(x, y)
+
+/*
+ * n - CPU number
+ * r - MPID
+ */
+#define	CPU(n, r)			\
+	CPU##n:cpu@r## {		\
+	device_type = "cpu";		\
+	compatible = "arm,armv8";	\
+	reg = <0x0 0x##r>;		\
+	enable-method = "psci";		\
+	cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;	\
+	next-level-cache = <&L2_0>;	\
+	};
+
+#if (PE_PER_CPU == 2)
+#define THREAD(n)		\
+	thread##n {		\
+		cpu = <&CONC(CPU, __COUNTER__)>;	\
+	};
+
+#define	CORE(n)			\
+	core##n {		\
+		THREAD(0)	\
+		THREAD(1)	\
+	};
+
+#else	/* PE_PER_CPU == 1 */
+#define	CORE(n)			\
+	core##n {		\
+		cpu = <&CPU##n>;\
+	};
+#endif	/* PE_PER_CORE */
+
+#if (CPUS_PER_CLUSTER == 1)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 2)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 3)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 4)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)	\
+	CPU(3, 300)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)	\
+	CPU(6, 300)	\
+	CPU(7, 301)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+		CORE(3)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 5)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)	\
+	CPU(3, 300)	\
+	CPU(4, 400)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)	\
+	CPU(6, 300)	\
+	CPU(7, 301)	\
+	CPU(8, 400)	\
+	CPU(9, 401)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+		CORE(3)	\
+		CORE(4)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 6)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)	\
+	CPU(3, 300)	\
+	CPU(4, 400)	\
+	CPU(5, 500)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)	\
+	CPU(6, 300)	\
+	CPU(7, 301)	\
+	CPU(8, 400)	\
+	CPU(9, 401)	\
+	CPU(10, 500)	\
+	CPU(11, 501)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+		CORE(3)	\
+		CORE(4)	\
+		CORE(5)	\
+	};
+
+#elif (CPUS_PER_CLUSTER == 7)
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)	\
+	CPU(3, 300)	\
+	CPU(4, 400)	\
+	CPU(5, 500)	\
+	CPU(6, 600)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)	\
+	CPU(6, 300)	\
+	CPU(7, 301)	\
+	CPU(8, 400)	\
+	CPU(9, 401)	\
+	CPU(10, 500)	\
+	CPU(11, 501)	\
+	CPU(12, 600)	\
+	CPU(13, 601)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+		CORE(3)	\
+		CORE(4)	\
+		CORE(5)	\
+		CORE(6)	\
+	};
+
+#else
+#if (PE_PER_CPU == 1)
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 100)	\
+	CPU(2, 200)	\
+	CPU(3, 300)	\
+	CPU(4, 400)	\
+	CPU(5, 500)	\
+	CPU(6, 600)	\
+	CPU(7, 700)
+#else
+#define	CPUS		\
+	CPU(0, 0)	\
+	CPU(1, 1)	\
+	CPU(2, 100)	\
+	CPU(3, 101)	\
+	CPU(4, 200)	\
+	CPU(5, 201)	\
+	CPU(6, 300)	\
+	CPU(7, 301)	\
+	CPU(8, 400)	\
+	CPU(9, 401)	\
+	CPU(10, 500)	\
+	CPU(11, 501)	\
+	CPU(12, 600)	\
+	CPU(13, 601)	\
+	CPU(14, 700)	\
+	CPU(15, 701)
+#endif
+#define	CLUSTER(n)	\
+	cluster##n {	\
+		CORE(0)	\
+		CORE(1)	\
+		CORE(2)	\
+		CORE(3)	\
+		CORE(4)	\
+		CORE(5)	\
+		CORE(6)	\
+		CORE(7)	\
+	};
+#endif	/* CPUS_PER_CLUSTER */
+
+#define	CPU_MAP			\
+	cpu-map {		\
+		CLUSTER(0)	\
+	};
+
+#endif	/* FVP_DEFS_DYNAMIQ_DTSI */
diff --git a/fdts/fvp-defs.dtsi b/fdts/fvp-defs.dtsi
new file mode 100644
index 0000000..1ffe65a
--- /dev/null
+++ b/fdts/fvp-defs.dtsi
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef	FVP_DEFS_DTSI
+#define	FVP_DEFS_DTSI
+
+/* Set default topology values if not passed from platform's makefile */
+#ifndef	CLUSTER_COUNT
+#ifdef	FVP_CLUSTER_COUNT
+#define	CLUSTER_COUNT		FVP_CLUSTER_COUNT
+#else
+#define	CLUSTER_COUNT		2
+#endif
+#endif	/* CLUSTER_COUNT */
+
+#ifndef CPUS_PER_CLUSTER
+#ifdef FVP_MAX_CPUS_PER_CLUSTER
+#define	CPUS_PER_CLUSTER	FVP_MAX_CPUS_PER_CLUSTER
+#else
+#define	CPUS_PER_CLUSTER	4
+#endif
+#endif	/* CPUS_PER_CLUSTER */
+
+/* Get platform's topology */
+#define	CPUS_COUNT		(CLUSTER_COUNT * CPUS_PER_CLUSTER)
+
+#define CONCAT(x, y)	x##y
+#define CONC(x, y)	CONCAT(x, y)
+
+/* CPU's cluster */
+#define	CLS(n)	(n / CPUS_PER_CLUSTER)
+
+/* CPU's position in cluster */
+#define	POS(n)	(n % CPUS_PER_CLUSTER)
+
+#define	ADR(n, c, p)	\
+	CPU##n:cpu@CONC(c, CONC(p, AFF)) {
+
+#define	PRE			\
+	device_type = "cpu";	\
+	compatible = "arm,armv8";
+
+#ifdef	REG_32
+/* 32-bit address */
+#define	REG(c, p)	\
+	reg = <CONC(0x, CONC(c, CONC(p, AFF)))>;
+#else
+/* 64-bit address */
+#define	REG(c, p)	\
+	reg = <0x0 CONC(0x, CONC(c, CONC(p, AFF)))>;
+#endif	/* REG_32 */
+
+#define	POST				\
+	enable-method = "psci";		\
+	cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;	\
+	next-level-cache = <&L2_0>;	\
+	};
+
+#ifdef	REG_32
+#define	CPU_0		\
+	CPU0:cpu@0 {	\
+	PRE		\
+	reg = <0x0>;	\
+	POST
+#else
+#define	CPU_0		\
+	CPU0:cpu@0 {	\
+	PRE		\
+	reg = <0x0 0x0>;\
+	POST
+#endif	/* REG_32 */
+
+/*
+ * n - CPU number
+ */
+#define	CPU(n, c, p)	\
+	ADR(n, c, p)	\
+	PRE		\
+	REG(c, p)	\
+	POST
+
+/* 2 CPUs */
+#if (CPUS_COUNT > 1)
+#if (CLS(1) == 0)
+#define c1
+#define	p1	1
+#else
+#define	c1	10
+#define p1	0
+#endif
+
+#define	CPU_1	CPU(1, c1, p1)	/* CPU1: 0.1; 1.0 */
+
+/* 3 CPUs */
+#if (CPUS_COUNT > 2)
+#if (CLS(2) == 0)
+#define c2
+#define p2	2
+#elif (CLS(2) == 1)
+#define	c2	10
+#define p2	0
+#else
+#define	c2	20
+#define p2	0
+#endif
+
+#define	CPU_2	CPU(2, c2, p2)	/* CPU2: 0.2; 1.0; 2.0 */
+
+/* 4 CPUs */
+#if (CPUS_COUNT > 3)
+#if (CLS(3) == 0)
+#define c3
+#elif (CLS(3) == 1)
+#define	c3	10
+#else
+#define	c3	30
+#endif
+
+#if (POS(3) == 0)
+#define p3	0
+#elif (POS(3) == 1)
+#define	p3	1
+#else
+#define	p3	3
+#endif
+
+#define	CPU_3	CPU(3, c3, p3)	/* CPU3: 0.3; 1.0; 1.1; 3.0 */
+
+/* 6 CPUs */
+#if (CPUS_COUNT > 4)
+#if (CLS(4) == 1)
+#define	c4	10
+#else
+#define	c4	20
+#endif
+
+#if (POS(4) == 0)
+#define p4	0
+#else
+#define	p4	1
+#endif
+
+#if (CLS(5) == 1)
+#define	c5	10
+#else
+#define	c5	20
+#endif
+
+#if (POS(5) == 1)
+#define	p5	1
+#else
+#define	p5	2
+#endif
+
+#define	CPU_4	CPU(4, c4, p4)	/* CPU4: 1.0; 1.1; 2.0 */
+#define	CPU_5	CPU(5, c5, p5)	/* CPU5: 1.1; 1.2; 2.1 */
+
+/* 8 CPUs */
+#if (CPUS_COUNT > 6)
+#if (CLS(6) == 1)
+#define	c6	10
+#define	p6	2
+#elif (CLS(6) == 2)
+#define	c6	20
+#define	p6	0
+#else
+#define	c6	30
+#define	p6	0
+#endif
+
+#if (CLS(7) == 1)
+#define	c7	10
+#define	p7	3
+#elif (CLS(7) == 2)
+#define	c7	20
+#define	p7	1
+#else
+#define	c7	30
+#define	p7	1
+#endif
+
+#define	CPU_6	CPU(6, c6, p6)	/* CPU6: 1.2; 2.0; 3.0 */
+#define	CPU_7	CPU(7, c7, p7)	/* CPU7: 1.3; 2.1; 3.1 */
+
+/* 9 CPUs */
+#if (CPUS_COUNT > 8)
+#if (POS(8) == 0)
+#define	p8	0
+#else
+#define	p8	2
+#endif
+
+#define	CPU_8	CPU(8, 20, p8)	/* CPU8: 2.0; 2.2 */
+
+/* 12 CPUs */
+#if (CPUS_COUNT > 9)
+#if (CLS(9) == 2)
+#define	c9	20
+#define	p9	1
+#else
+#define	c9	30
+#define	p9	0
+#endif
+
+#if (CLS(10) == 2)
+#define	c10	20
+#define	p10	2
+#else
+#define	c10	30
+#define	p10	1
+#endif
+
+#if (CLS(11) == 2)
+#define	c11	20
+#define	p11	3
+#else
+#define	c11	30
+#define	p11	2
+#endif
+
+#define	CPU_9	CPU(9, c9, p9)		/* CPU9:  2.1; 3.0 */
+#define	CPU_10	CPU(10, c10, p10)	/* CPU10: 2.2; 3.1 */
+#define	CPU_11	CPU(11, c11, p11)	/* CPU11: 2.3; 3.2 */
+
+/* 16 CPUs */
+#if (CPUS_COUNT > 12)
+#define	CPU_12	CPU(12, 30, 0)		/* CPU12: 3.0 */
+#define	CPU_13	CPU(13, 30, 1)		/* CPU13: 3.1 */
+#define	CPU_14	CPU(14, 30, 2)		/* CPU14: 3.2 */
+#define	CPU_15	CPU(15, 30, 3)		/* CPU15: 3.3 */
+#endif	/* > 12 */
+#endif	/* > 9 */
+#endif	/* > 8 */
+#endif	/* > 6 */
+#endif	/* > 4 */
+#endif	/* > 3 */
+#endif	/* > 2 */
+#endif	/* > 1 */
+
+#if (CPUS_COUNT == 1)
+#define	CPUS	\
+	CPU_0
+
+#elif (CPUS_COUNT == 2)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1
+
+#elif (CPUS_COUNT == 3)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2
+
+#elif (CPUS_COUNT == 4)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3
+
+#elif (CPUS_COUNT == 6)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3	\
+	CPU_4	\
+	CPU_5
+
+#elif (CPUS_COUNT == 8)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3	\
+	CPU_4	\
+	CPU_5	\
+	CPU_6	\
+	CPU_7
+
+#elif (CPUS_COUNT == 9)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3	\
+	CPU_4	\
+	CPU_5	\
+	CPU_6	\
+	CPU_7	\
+	CPU_8
+
+#elif (CPUS_COUNT == 12)
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3	\
+	CPU_4	\
+	CPU_5	\
+	CPU_6	\
+	CPU_7	\
+	CPU_8	\
+	CPU_9	\
+	CPU_10	\
+	CPU_11
+
+#else
+#define	CPUS	\
+	CPU_0	\
+	CPU_1	\
+	CPU_2	\
+	CPU_3	\
+	CPU_4	\
+	CPU_5	\
+	CPU_6	\
+	CPU_7	\
+	CPU_8	\
+	CPU_9	\
+	CPU_10	\
+	CPU_11	\
+	CPU_12	\
+	CPU_13	\
+	CPU_14	\
+	CPU_15
+#endif	/* CPUS_COUNT */
+
+#define	CORE(n)		\
+	core##n {	\
+		cpu = <&CONC(CPU, __COUNTER__)>;	\
+	};
+
+/* Max 4 CPUs per cluster */
+#if (CPUS_PER_CLUSTER == 1)
+#define	CLUSTER(n)		\
+	cluster##n {		\
+		CORE(0)		\
+	};
+#elif (CPUS_PER_CLUSTER == 2)
+#define	CLUSTER(n)		\
+	cluster##n {		\
+		CORE(0)		\
+		CORE(1)		\
+	};
+
+#elif (CPUS_PER_CLUSTER == 3)
+#define	CLUSTER(n)		\
+	cluster##n {		\
+		CORE(0)		\
+		CORE(1)		\
+		CORE(2)		\
+	};
+
+#else
+#define	CLUSTER(n)		\
+	cluster##n {		\
+		CORE(0)		\
+		CORE(1)		\
+		CORE(2)		\
+		CORE(3)		\
+	};
+#endif	/* CPUS_PER_CLUSTER */
+
+/* Max 4 clusters */
+#if (CLUSTER_COUNT == 1)
+#define	CPU_MAP			\
+	cpu-map {		\
+		CLUSTER(0)	\
+	};
+
+#elif (CLUSTER_COUNT == 2)
+#define	CPU_MAP			\
+	cpu-map {		\
+		CLUSTER(0)	\
+		CLUSTER(1)	\
+	};
+
+#elif (CLUSTER_COUNT == 3)
+#define	CPU_MAP			\
+	cpu-map {		\
+		CLUSTER(0)	\
+		CLUSTER(1)	\
+		CLUSTER(2)	\
+	};
+
+#else
+#define	CPU_MAP			\
+	cpu-map {		\
+		CLUSTER(0)	\
+		CLUSTER(1)	\
+		CLUSTER(2)	\
+		CLUSTER(3)	\
+	};
+#endif	/* CLUSTER_COUNT */
+
+#endif	/* FVP_DEFS_DTSI */
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 3a204cb..95a800e 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -4,8 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: 1 cluster with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	AFF
+#define	CLUSTER_COUNT	1
+
+#include "fvp-defs.dtsi"
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -42,22 +49,7 @@
 		#address-cells = <2>;
 		#size-cells = <0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -81,41 +73,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index d85305a..c295dc1 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -4,8 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+/* Configuration: 1 cluster with up to 4 CPUs */
+
 /dts-v1/;
 
+#define	AFF
+#define	CLUSTER_COUNT	1
+
+#include "fvp-defs.dtsi"
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -42,22 +49,7 @@
 		#address-cells = <2>;
 		#size-cells = <0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-			};
-		};
+		CPU_MAP
 
 		idle-states {
 			entry-method = "arm,psci";
@@ -81,41 +73,7 @@
 			};
 		};
 
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU1:cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x1>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU2:cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x2>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3:cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x3>;
-			enable-method = "psci";
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			next-level-cache = <&L2_0>;
-		};
+		CPUS
 
 		L2_0: l2-cache0 {
 			compatible = "cache";
diff --git a/fdts/tc0.dts b/fdts/tc0.dts
new file mode 100644
index 0000000..e736e49
--- /dev/null
+++ b/fdts/tc0.dts
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,tc0";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &soc_uart0;
+	};
+
+	chosen {
+		stdout-path = "soc_uart0:115200n8";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 0>;
+		};
+
+		CPU1:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x100>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 0>;
+		};
+
+		CPU2:cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x200>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 0>;
+		};
+
+		CPU3:cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x300>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 0>;
+		};
+
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x80000000>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+	};
+
+	sram: sram@6000000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x06000000 0x0 0x8000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x0 0x06000000 0x8000>;
+
+		cpu_scp_scmi_mem: scp-shmem@0 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x80>;
+		};
+	};
+
+	mbox_db_rx: mhu@45010000 {
+		compatible = "arm,mhuv2","arm,primecell";
+		reg = <0x0 0x45010000 0x0 0x1000>;
+		clocks = <&soc_refclk100mhz>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <1>;
+		interrupts = <0 316 4>;
+		interrupt-names = "mhu_rx";
+		mhu-protocol = "doorbell";
+	};
+
+	mbox_db_tx: mhu@45000000 {
+		compatible = "arm,mhuv2","arm,primecell";
+		reg = <0x0 0x45000000 0x0 0x1000>;
+		clocks = <&soc_refclk100mhz>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <1>;
+		interrupt-names = "mhu_tx";
+		mhu-protocol = "doorbell";
+	};
+
+	scmi {
+		compatible = "arm,scmi";
+		method = "mailbox-doorbell";
+		mbox-names = "tx", "rx";
+		mboxes = <&mbox_db_tx 0 &mbox_db_rx 0>;
+		shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi_dvfs: protocol@13 {
+			reg = <0x13>;
+			#clock-cells = <1>;
+		};
+
+		scmi_clk: protocol@14 {
+			reg = <0x14>;
+			#clock-cells = <1>;
+		};
+	};
+
+	gic: interrupt-controller@2c010000 {
+		compatible = "arm,gic-600", "arm,gic-v3";
+		#address-cells = <2>;
+		#interrupt-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+		interrupt-controller;
+		reg = <0x0 0x30000000 0 0x10000>, /* GICD */
+		      <0x0 0x30140000 0 0x200000>; /* GICR */
+		interrupts = <0x1 0x9 0x4>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <0x1 13 0x8>,
+			     <0x1 14 0x8>,
+			     <0x1 11 0x8>,
+			     <0x1 10 0x8>;
+	};
+
+	soc_refclk100mhz: refclk100mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <100000000>;
+		clock-output-names = "apb_pclk";
+	};
+
+	soc_refclk60mhz: refclk60mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <60000000>;
+		clock-output-names = "iofpga_clk";
+	};
+
+	soc_uartclk:  uartclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+		clock-output-names = "uartclk";
+	};
+
+	soc_uart0: uart@7ff80000 {
+		compatible = "arm,pl011", "arm,primecell";
+		reg = <0x0 0x7ff80000 0x0 0x1000>;
+		interrupts = <0x0 116 0x4>;
+		clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
+		clock-names = "uartclk", "apb_pclk";
+		status = "okay";
+	};
+
+	vencoder {
+		compatible = "drm,virtual-encoder";
+
+		port {
+			vencoder_in: endpoint {
+				remote-endpoint = <&hdlcd_out>;
+			};
+		};
+
+		display-timings {
+			panel-timing {
+				clock-frequency = <25175000>;
+				hactive = <640>;
+				vactive = <480>;
+				hfront-porch = <16>;
+				hback-porch = <48>;
+				hsync-len = <96>;
+				vfront-porch = <10>;
+				vback-porch = <33>;
+				vsync-len = <2>;
+			};
+		};
+
+	};
+
+	hdlcd: hdlcd@7ff60000 {
+		compatible = "arm,hdlcd";
+		reg = <0x0 0x7ff60000 0x0 0x1000>;
+		interrupts = <0x0 117 0x4>;
+		clocks = <&fake_hdlcd_clk>;
+		clock-names = "pxlclk";
+		status = "ok";
+
+		port {
+			hdlcd_out: endpoint {
+				remote-endpoint = <&vencoder_in>;
+			};
+		};
+	};
+
+	fake_hdlcd_clk: fake-hdlcd-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25175000>;
+		clock-output-names = "pxlclk";
+	};
+
+	ethernet@18000000 {
+		compatible = "smsc,lan91c111";
+		reg = <0x0 0x18000000 0x0 0x10000>;
+		interrupts = <0 109 4>;
+	};
+
+	kmi@1c060000 {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 0x001c060000 0x0 0x1000>;
+		interrupts = <0 197 4>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	kmi@1c070000 {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 0x001c070000 0x0 0x1000>;
+		interrupts = <0 103 4>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	bp_clock24mhz: clock24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "bp:clock24mhz";
+	};
+
+	virtio_block@1c130000 {
+		compatible = "virtio,mmio";
+		reg = <0x0 0x1c130000 0x0 0x200>;
+		interrupts = <0 204 4>;
+	};
+
+	dp0: display@2cc00000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "arm,mali-d71";
+		reg = <0 0x2cc00000 0 0x20000>;
+		interrupts = <0 69 4>;
+		interrupt-names = "DPU";
+		clocks = <&scmi_clk 0>;
+		clock-names = "aclk";
+		status = "disabled";
+		pl0: pipeline@0 {
+			reg = <0>;
+			clocks = <&scmi_clk 1>;
+			clock-names = "pxclk";
+			pl_id = <0>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					dp_pl0_out0: endpoint {
+						remote-endpoint = <&vencoder_in>;
+					};
+				};
+			};
+		};
+
+		pl1: pipeline@1 {
+			reg = <1>;
+			clocks = <&scmi_clk 2>;
+			clock-names = "pxclk";
+			pl_id = <1>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+			};
+		};
+	};
+};
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e45a594..9d4ad3b 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -226,6 +226,12 @@
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
 
+/* ID_AA64MMFR1_EL1 definitions */
+#define ID_AA64MMFR1_EL1_TWED_SHIFT		U(32)
+#define ID_AA64MMFR1_EL1_TWED_MASK		ULL(0xf)
+#define ID_AA64MMFR1_EL1_TWED_SUPPORTED		ULL(0x1)
+#define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED	ULL(0x0)
+
 /* ID_AA64MMFR2_EL1 definitions */
 #define ID_AA64MMFR2_EL1		S3_0_C0_C7_2
 
@@ -253,6 +259,9 @@
 #define MTE_IMPLEMENTED_EL0	ULL(1)	/* MTE is only implemented at EL0 */
 #define MTE_IMPLEMENTED_ELX	ULL(2)	/* MTE is implemented at all ELs */
 
+#define ID_AA64PFR1_MPAM_FRAC_SHIFT	ULL(16)
+#define ID_AA64PFR1_MPAM_FRAC_MASK	ULL(0xf)
+
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
 #define ID_PFR1_VIRTEXT_MASK	U(0xf)
@@ -312,6 +321,9 @@
 
 /* SCR definitions */
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
+#define SCR_TWEDEL_SHIFT	U(30)
+#define SCR_TWEDEL_MASK		ULL(0xf)
+#define SCR_TWEDEn_BIT		(UL(1) << 29)
 #define SCR_ATA_BIT		(U(1) << 26)
 #define SCR_FIEN_BIT		(U(1) << 21)
 #define SCR_EEL2_BIT		(U(1) << 18)
@@ -381,6 +393,7 @@
 /* HCR definitions */
 #define HCR_API_BIT		(ULL(1) << 41)
 #define HCR_APK_BIT		(ULL(1) << 40)
+#define HCR_E2H_BIT		(ULL(1) << 34)
 #define HCR_TGE_BIT		(ULL(1) << 27)
 #define HCR_RW_SHIFT		U(31)
 #define HCR_RW_BIT		(ULL(1) << HCR_RW_SHIFT)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 0491f48..321485a 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,4 +52,33 @@
 		ID_AA64PFR1_EL1_MTE_MASK);
 }
 
+static inline bool is_armv8_4_sel2_present(void)
+{
+	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
+		ID_AA64PFR0_SEL2_MASK) == 1ULL;
+}
+
+static inline bool is_armv8_6_twed_present(void)
+{
+	return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
+		ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
+}
+
+/*
+ * Return MPAM version:
+ *
+ * 0x00: None Armv8.0 or later
+ * 0x01: v0.1 Armv8.4 or later
+ * 0x10: v1.0 Armv8.2 or later
+ * 0x11: v1.1 Armv8.4 or later
+ *
+ */
+static inline unsigned int get_mpam_version(void)
+{
+	return (unsigned int)((((read_id_aa64pfr0_el1() >>
+		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
+				((read_id_aa64pfr1_el1() >>
+		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 9cd1ae5..09059ca 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -358,6 +358,7 @@
 DEFINE_SYSREG_READ_FUNC(midr_el1)
 DEFINE_SYSREG_READ_FUNC(mpidr_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
 
 DEFINE_SYSREG_RW_FUNCS(scr_el3)
 DEFINE_SYSREG_RW_FUNCS(hcr_el2)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 156b18a..0708de6 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <lib/xlat_tables/xlat_tables_defs.h>
 
 	/*
 	 * Helper macro to initialise EL3 registers we care about.
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 97fed72..208e3d6 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -101,12 +101,14 @@
 		__DATA_END__ = .;			\
 	}
 
+#if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
 #define STACK_SECTION					\
 	stacks (NOLOAD) : {				\
 		__STACKS_START__ = .;			\
 		*(tzfw_normal_stacks)			\
 		__STACKS_END__ = .;			\
 	}
+#endif
 
 /*
  * If BL doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 382651e..1d8da18 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -34,4 +34,7 @@
 			      uintptr_t *base, size_t *size);
 int fdt_get_stdout_node_offset(const void *dtb);
 
+uint64_t fdtw_translate_address(const void *dtb, int bus_node,
+				uint64_t base_address);
+
 #endif /* FDT_WRAPPERS_H */
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 33350a0..c411146 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,4 +11,38 @@
 
 #define COT_MAX_VERIFIED_PARAMS		4
 
+/*
+ * Maximum key and hash sizes (in DER format).
+ *
+ * Both RSA and ECDSA keys may be used at the same time. In this case, the key
+ * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
+ * ones for all key sizes we support, they impose the minimum size of these
+ * buffers.
+ */
+#if TF_MBEDTLS_USE_RSA
+#if TF_MBEDTLS_KEY_SIZE == 1024
+#define PK_DER_LEN                      162
+#elif TF_MBEDTLS_KEY_SIZE == 2048
+#define PK_DER_LEN                      294
+#elif TF_MBEDTLS_KEY_SIZE == 3072
+#define PK_DER_LEN                      422
+#elif TF_MBEDTLS_KEY_SIZE == 4096
+#define PK_DER_LEN                      550
+#else
+#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
+#endif
+#else /* Only using ECDSA keys. */
+#define PK_DER_LEN                      91
+#endif
+
+#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
+#define HASH_DER_LEN                    51
+#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384
+#define HASH_DER_LEN                    67
+#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512
+#define HASH_DER_LEN                    83
+#else
+#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
+#endif
+
 #endif /* COT_DEF_H */
diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h
new file mode 100644
index 0000000..0ea5f65
--- /dev/null
+++ b/include/drivers/auth/tbbr_cot_common.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TBBR_COT_COMMON_H
+#define TBBR_COT_COMMON_H
+
+#include <drivers/auth/auth_mod.h>
+
+extern unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+extern unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+extern unsigned char hw_config_hash_buf[HASH_DER_LEN];
+extern unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+extern unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+extern auth_param_type_desc_t trusted_nv_ctr;
+extern auth_param_type_desc_t subject_pk;
+extern auth_param_type_desc_t sig;
+extern auth_param_type_desc_t sig_alg;
+extern auth_param_type_desc_t raw_data;
+
+extern auth_param_type_desc_t tb_fw_hash;
+extern auth_param_type_desc_t tb_fw_config_hash;
+extern auth_param_type_desc_t hw_config_hash;
+
+extern const auth_img_desc_t trusted_boot_fw_cert;
+extern const auth_img_desc_t hw_config;
+
+#endif /* TBBR_COT_COMMON_H */
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
index 4b4aac8..2ffc3b2 100644
--- a/include/drivers/st/stm32mp1_rcc.h
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -250,6 +250,8 @@
 #define RCC_MPCKSELR_HSE		0x00000001
 #define RCC_MPCKSELR_PLL		0x00000002
 #define RCC_MPCKSELR_PLL_MPUDIV		0x00000003
+#define RCC_MPCKSELR_MPUSRC_MASK	GENMASK(1, 0)
+#define RCC_MPCKSELR_MPUSRC_SHIFT	0
 
 /* Values of RCC_ASSCKSELR register */
 #define RCC_ASSCKSELR_HSI		0x00000000
@@ -266,6 +268,8 @@
 #define RCC_CPERCKSELR_HSI		0x00000000
 #define RCC_CPERCKSELR_CSI		0x00000001
 #define RCC_CPERCKSELR_HSE		0x00000002
+#define RCC_CPERCKSELR_PERSRC_MASK	GENMASK(1, 0)
+#define RCC_CPERCKSELR_PERSRC_SHIFT	0
 
 /* Used for most of DIVR register: max div for RTC */
 #define RCC_DIVR_DIV_MASK		GENMASK(5, 0)
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 0029658..90807ce 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -168,76 +168,75 @@
 #define CTX_ELR_EL2		U(0x58)
 #define CTX_ESR_EL2		U(0x60)
 #define CTX_FAR_EL2		U(0x68)
-#define CTX_FPEXC32_EL2		U(0x70)
-#define CTX_HACR_EL2		U(0x78)
-#define CTX_HCR_EL2		U(0x80)
-#define CTX_HPFAR_EL2		U(0x88)
-#define CTX_HSTR_EL2		U(0x90)
-#define CTX_ICC_SRE_EL2		U(0x98)
-#define CTX_ICH_HCR_EL2		U(0xa0)
-#define CTX_ICH_VMCR_EL2	U(0xa8)
-#define CTX_MAIR_EL2		U(0xb0)
-#define CTX_MDCR_EL2		U(0xb8)
-#define CTX_PMSCR_EL2		U(0xc0)
-#define CTX_SCTLR_EL2		U(0xc8)
-#define CTX_SPSR_EL2		U(0xd0)
-#define CTX_SP_EL2		U(0xd8)
-#define CTX_TCR_EL2		U(0xe0)
-#define CTX_TPIDR_EL2		U(0xe8)
-#define CTX_TTBR0_EL2		U(0xf0)
-#define CTX_VBAR_EL2		U(0xf8)
-#define CTX_VMPIDR_EL2		U(0x100)
-#define CTX_VPIDR_EL2		U(0x108)
-#define CTX_VTCR_EL2		U(0x110)
-#define CTX_VTTBR_EL2		U(0x118)
+#define CTX_HACR_EL2		U(0x70)
+#define CTX_HCR_EL2		U(0x78)
+#define CTX_HPFAR_EL2		U(0x80)
+#define CTX_HSTR_EL2		U(0x88)
+#define CTX_ICC_SRE_EL2		U(0x90)
+#define CTX_ICH_HCR_EL2		U(0x98)
+#define CTX_ICH_VMCR_EL2	U(0xa0)
+#define CTX_MAIR_EL2		U(0xa8)
+#define CTX_MDCR_EL2		U(0xb0)
+#define CTX_PMSCR_EL2		U(0xb8)
+#define CTX_SCTLR_EL2		U(0xc0)
+#define CTX_SPSR_EL2		U(0xc8)
+#define CTX_SP_EL2		U(0xd0)
+#define CTX_TCR_EL2		U(0xd8)
+#define CTX_TPIDR_EL2		U(0xe0)
+#define CTX_TTBR0_EL2		U(0xe8)
+#define CTX_VBAR_EL2		U(0xf0)
+#define CTX_VMPIDR_EL2		U(0xf8)
+#define CTX_VPIDR_EL2		U(0x100)
+#define CTX_VTCR_EL2		U(0x108)
+#define CTX_VTTBR_EL2		U(0x110)
 
 // Only if MTE registers in use
-#define CTX_TFSR_EL2		U(0x120)
+#define CTX_TFSR_EL2		U(0x118)
 
 // Only if ENABLE_MPAM_FOR_LOWER_ELS==1
-#define CTX_MPAM2_EL2		U(0x128)
-#define CTX_MPAMHCR_EL2		U(0x130)
-#define CTX_MPAMVPM0_EL2	U(0x138)
-#define CTX_MPAMVPM1_EL2	U(0x140)
-#define CTX_MPAMVPM2_EL2	U(0x148)
-#define CTX_MPAMVPM3_EL2	U(0x150)
-#define CTX_MPAMVPM4_EL2	U(0x158)
-#define CTX_MPAMVPM5_EL2	U(0x160)
-#define CTX_MPAMVPM6_EL2	U(0x168)
-#define CTX_MPAMVPM7_EL2	U(0x170)
-#define CTX_MPAMVPMV_EL2	U(0x178)
+#define CTX_MPAM2_EL2		U(0x120)
+#define CTX_MPAMHCR_EL2		U(0x128)
+#define CTX_MPAMVPM0_EL2	U(0x130)
+#define CTX_MPAMVPM1_EL2	U(0x138)
+#define CTX_MPAMVPM2_EL2	U(0x140)
+#define CTX_MPAMVPM3_EL2	U(0x148)
+#define CTX_MPAMVPM4_EL2	U(0x150)
+#define CTX_MPAMVPM5_EL2	U(0x158)
+#define CTX_MPAMVPM6_EL2	U(0x160)
+#define CTX_MPAMVPM7_EL2	U(0x168)
+#define CTX_MPAMVPMV_EL2	U(0x170)
 
 // Starting with Armv8.6
-#define CTX_HAFGRTR_EL2		U(0x180)
-#define CTX_HDFGRTR_EL2		U(0x188)
-#define CTX_HDFGWTR_EL2		U(0x190)
-#define CTX_HFGITR_EL2		U(0x198)
-#define CTX_HFGRTR_EL2		U(0x1a0)
-#define CTX_HFGWTR_EL2		U(0x1a8)
-#define CTX_CNTPOFF_EL2		U(0x1b0)
+#define CTX_HAFGRTR_EL2		U(0x178)
+#define CTX_HDFGRTR_EL2		U(0x180)
+#define CTX_HDFGWTR_EL2		U(0x188)
+#define CTX_HFGITR_EL2		U(0x190)
+#define CTX_HFGRTR_EL2		U(0x198)
+#define CTX_HFGWTR_EL2		U(0x1a0)
+#define CTX_CNTPOFF_EL2		U(0x1a8)
 
 // Starting with Armv8.4
-#define CTX_CNTHPS_CTL_EL2	U(0x1b8)
-#define CTX_CNTHPS_CVAL_EL2	U(0x1c0)
-#define CTX_CNTHPS_TVAL_EL2	U(0x1c8)
-#define CTX_CNTHVS_CTL_EL2	U(0x1d0)
-#define CTX_CNTHVS_CVAL_EL2	U(0x1d8)
-#define CTX_CNTHVS_TVAL_EL2	U(0x1e0)
-#define CTX_CNTHV_CTL_EL2	U(0x1e8)
-#define CTX_CNTHV_CVAL_EL2	U(0x1f0)
-#define CTX_CNTHV_TVAL_EL2	U(0x1f8)
-#define CTX_CONTEXTIDR_EL2	U(0x200)
-#define CTX_SDER32_EL2		U(0x208)
-#define CTX_TTBR1_EL2		U(0x210)
-#define CTX_VDISR_EL2		U(0x218)
-#define CTX_VNCR_EL2		U(0x220)
-#define CTX_VSESR_EL2		U(0x228)
-#define CTX_VSTCR_EL2		U(0x230)
-#define CTX_VSTTBR_EL2		U(0x238)
-#define CTX_TRFCR_EL2		U(0x240)
+#define CTX_CNTHPS_CTL_EL2	U(0x1b0)
+#define CTX_CNTHPS_CVAL_EL2	U(0x1b8)
+#define CTX_CNTHPS_TVAL_EL2	U(0x1c0)
+#define CTX_CNTHVS_CTL_EL2	U(0x1c8)
+#define CTX_CNTHVS_CVAL_EL2	U(0x1d0)
+#define CTX_CNTHVS_TVAL_EL2	U(0x1d8)
+#define CTX_CNTHV_CTL_EL2	U(0x1e0)
+#define CTX_CNTHV_CVAL_EL2	U(0x1e8)
+#define CTX_CNTHV_TVAL_EL2	U(0x1f0)
+#define CTX_CONTEXTIDR_EL2	U(0x1f8)
+#define CTX_SDER32_EL2		U(0x200)
+#define CTX_TTBR1_EL2		U(0x208)
+#define CTX_VDISR_EL2		U(0x210)
+#define CTX_VNCR_EL2		U(0x218)
+#define CTX_VSESR_EL2		U(0x220)
+#define CTX_VSTCR_EL2		U(0x228)
+#define CTX_VSTTBR_EL2		U(0x230)
+#define CTX_TRFCR_EL2		U(0x238)
 
 // Starting with Armv8.5
-#define CTX_SCXTNUM_EL2		U(0x248)
+#define CTX_SCXTNUM_EL2		U(0x240)
 /* Align to the next 16 byte boundary */
 #define CTX_EL2_SYSREGS_END	U(0x250)
 
diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h
new file mode 100644
index 0000000..eac4aa3
--- /dev/null
+++ b/include/lib/extensions/twed.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TWED_H
+#define TWED_H
+
+#include <stdint.h>
+
+#define TWED_DISABLED U(0xFFFFFFFF)
+
+uint32_t plat_arm_set_twedel_scr_el3(void);
+
+#endif /* TWEDE_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 7c852e1..89f7c61 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -565,6 +565,13 @@
 /* SGI used for SDEI signalling */
 #define ARM_SDEI_SGI			ARM_IRQ_SEC_SGI_0
 
+#if SDEI_IN_FCONF
+/* ARM SDEI dynamic private event max count */
+#define ARM_SDEI_DP_EVENT_MAX_CNT	3
+
+/* ARM SDEI dynamic shared event max count */
+#define ARM_SDEI_DS_EVENT_MAX_CNT	3
+#else
 /* ARM SDEI dynamic private event numbers */
 #define ARM_SDEI_DP_EVENT_0		1000
 #define ARM_SDEI_DP_EVENT_1		1001
@@ -585,5 +592,6 @@
 	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
 	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
 	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+#endif /* SDEI_IN_FCONF */
 
 #endif /* ARM_DEF_H */
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index b5bf473..03976f3 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,11 +12,7 @@
             . = . + PLATFORM_STACK_SIZE;
             . = ALIGN(PAGE_SIZE);
             __INIT_CODE_START__ = .;
-            /*
-             * Exclude PSCI initialization functions to ensure the init section
-             * does not become larger than the overlaid stack region
-             */
-            *(EXCLUDE_FILE (*psci_setup.o).text.init*)
+	    *(*text.init*);
             __INIT_CODE_UNALIGNED__ = .;
             .  = ALIGN(PAGE_SIZE);
             __INIT_CODE_END__ = .;
@@ -32,4 +28,41 @@
 
 }
 
+#undef	MIN
+#define	ABS		ABSOLUTE
+#define	COUNT		PLATFORM_CORE_COUNT
+#define	ALIGN_MASK	~(CACHE_WRITEBACK_GRANULE - 1)
+
+#define PRIMARY_STACK							\
+	__STACKS_START__ = .;						\
+	*(tzfw_normal_stacks)						\
+	OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__));		\
+	/* Offset sign */						\
+	SIGN = ABS(OFFSET) & (1 << 63);					\
+	/* Offset mask */						\
+	MASK = ABS(SIGN >> 63) - 1;					\
+	. +=  ABS(OFFSET) & ABS(MASK);					\
+	__STACKS_END__ = .;						\
+	/* Total stack size */						\
+	SIZE = ABS(. - __STACKS_START__);				\
+	/* Maximum primary CPU stack */					\
+	STACK = ABS(__STACKS_START__ + SIZE / COUNT) & ALIGN_MASK;	\
+	/* Primary CPU stack */						\
+	__PRIMARY_STACK__ = MIN(STACK, ABS(__INIT_CODE_START__));
+
+#if (COUNT > 1)
+#define	SECONDARY_STACK					\
+	/* Size of the secondary CPUs' stack */		\
+	REST = ABS(__STACKS_END__ - __PRIMARY_STACK__);	\
+	/* Secondary per-CPU stack size */		\
+	__STACK_SIZE__ = ABS(REST / (COUNT - 1));
+#else
+#define	SECONDARY_STACK
+#endif
+
+#define STACK_SECTION		\
+	stacks (NOLOAD) : {	\
+		PRIMARY_STACK	\
+		SECONDARY_STACK	\
+	}
 #endif /* ARM_RECLAIM_INIT_LD_S */
diff --git a/include/plat/arm/common/fconf_sdei_getter.h b/include/plat/arm/common/fconf_sdei_getter.h
new file mode 100644
index 0000000..e0a97a6
--- /dev/null
+++ b/include/plat/arm/common/fconf_sdei_getter.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_SDEI_GETTER_H
+#define FCONF_SDEI_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+#include <platform_def.h>
+
+#define sdei__dyn_config_getter(id)	sdei_dyn_config.id
+
+struct sdei_dyn_config_t {
+	uint32_t private_ev_cnt;
+	int32_t private_ev_nums[PLAT_SDEI_DP_EVENT_MAX_CNT];
+	unsigned int private_ev_intrs[PLAT_SDEI_DP_EVENT_MAX_CNT];
+	unsigned int private_ev_flags[PLAT_SDEI_DP_EVENT_MAX_CNT];
+	uint32_t shared_ev_cnt;
+	int32_t shared_ev_nums[PLAT_SDEI_DS_EVENT_MAX_CNT];
+	unsigned int shared_ev_intrs[PLAT_SDEI_DS_EVENT_MAX_CNT];
+	unsigned int shared_ev_flags[PLAT_SDEI_DS_EVENT_MAX_CNT];
+};
+
+int fconf_populate_sdei_dyn_config(uintptr_t config);
+
+extern struct sdei_dyn_config_t sdei_dyn_config;
+
+#endif /* FCONF_SDEI_GETTER_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index e4431d2..720c259 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -132,6 +132,7 @@
 
 /* SDEI platform functions */
 #if SDEI_SUPPORT
+void plat_sdei_setup(void);
 int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode);
 void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr);
 #endif
@@ -289,9 +290,8 @@
 int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
 				 void **rd_base, size_t *rd_size);
 #if defined(SPD_spmd)
-int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
-				const void *ptr,
-				size_t size);
+int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
+				const void *pm_addr);
 #endif
 /*******************************************************************************
  * Mandatory BL image load functions(may be overridden).
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
new file mode 100644
index 0000000..fe32175
--- /dev/null
+++ b/include/services/ffa_svc.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FFA_SVC_H
+#define FFA_SVC_H
+
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/* FFA error codes. */
+#define FFA_ERROR_NOT_SUPPORTED	-1
+#define FFA_ERROR_INVALID_PARAMETER	-2
+#define FFA_ERROR_NO_MEMORY		-3
+#define FFA_ERROR_BUSY			-4
+#define FFA_ERROR_INTERRUPTED		-5
+#define FFA_ERROR_DENIED		-6
+#define FFA_ERROR_RETRY		-7
+
+/* The macros below are used to identify FFA calls from the SMC function ID */
+#define FFA_FNUM_MIN_VALUE	U(0x60)
+#define FFA_FNUM_MAX_VALUE	U(0x7f)
+#define is_ffa_fid(fid) __extension__ ({		\
+	__typeof__(fid) _fid = (fid);			\
+	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
+	 (GET_SMC_NUM(_fid) <= FFA_FNUM_MAX_VALUE)); })
+
+/* FFA_VERSION helpers */
+#define FFA_VERSION_MAJOR		U(1)
+#define FFA_VERSION_MAJOR_SHIFT	16
+#define FFA_VERSION_MAJOR_MASK		U(0x7FFF)
+#define FFA_VERSION_MINOR		U(0)
+#define FFA_VERSION_MINOR_SHIFT	0
+#define FFA_VERSION_MINOR_MASK		U(0xFFFF)
+
+#define MAKE_FFA_VERSION(major, minor) \
+	((((major) & FFA_VERSION_MAJOR_MASK) <<  FFA_VERSION_MAJOR_SHIFT) | \
+	 (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT))
+#define FFA_VERSION_COMPILED		MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \
+							  FFA_VERSION_MINOR)
+
+/* FFA_MSG_SEND helpers */
+#define FFA_MSG_SEND_ATTRS_BLK_SHIFT	U(0)
+#define FFA_MSG_SEND_ATTRS_BLK_MASK	U(0x1)
+#define FFA_MSG_SEND_ATTRS_BLK		U(0)
+#define FFA_MSG_SEND_ATTRS_BLK_NOT	U(1)
+#define FFA_MSG_SEND_ATTRS(blk)		\
+	(((blk) & FFA_MSG_SEND_ATTRS_BLK_MASK) \
+	<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
+
+/* Get FFA fastcall std FID from function number */
+#define FFA_FID(smc_cc, func_num)			\
+		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) |	\
+		 ((smc_cc) << FUNCID_CC_SHIFT) |	\
+		 (OEN_STD_START << FUNCID_OEN_SHIFT) |	\
+		 ((func_num) << FUNCID_NUM_SHIFT))
+
+/* FFA function numbers */
+#define FFA_FNUM_ERROR			U(0x60)
+#define FFA_FNUM_SUCCESS		U(0x61)
+#define FFA_FNUM_INTERRUPT		U(0x62)
+#define FFA_FNUM_VERSION		U(0x63)
+#define FFA_FNUM_FEATURES		U(0x64)
+#define FFA_FNUM_RX_RELEASE		U(0x65)
+#define FFA_FNUM_RXTX_MAP		U(0x66)
+#define FFA_FNUM_RXTX_UNMAP		U(0x67)
+#define FFA_FNUM_PARTITION_INFO_GET	U(0x68)
+#define FFA_FNUM_ID_GET		U(0x69)
+#define FFA_FNUM_MSG_POLL		U(0x6A)
+#define FFA_FNUM_MSG_WAIT		U(0x6B)
+#define FFA_FNUM_MSG_YIELD		U(0x6C)
+#define FFA_FNUM_MSG_RUN		U(0x6D)
+#define FFA_FNUM_MSG_SEND		U(0x6E)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ	U(0x6F)
+#define FFA_FNUM_MSG_SEND_DIRECT_RESP	U(0x70)
+#define FFA_FNUM_MEM_DONATE		U(0x71)
+#define FFA_FNUM_MEM_LEND		U(0x72)
+#define FFA_FNUM_MEM_SHARE		U(0x73)
+#define FFA_FNUM_MEM_RETRIEVE_REQ	U(0x74)
+#define FFA_FNUM_MEM_RETRIEVE_RESP	U(0x75)
+#define FFA_FNUM_MEM_RELINQUISH	U(0x76)
+#define FFA_FNUM_MEM_RECLAIM		U(0x77)
+
+/* FFA SMC32 FIDs */
+#define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
+#define FFA_SUCCESS_SMC32	FFA_FID(SMC_32, FFA_FNUM_SUCCESS)
+#define FFA_INTERRUPT		FFA_FID(SMC_32, FFA_FNUM_INTERRUPT)
+#define FFA_VERSION		FFA_FID(SMC_32, FFA_FNUM_VERSION)
+#define FFA_FEATURES		FFA_FID(SMC_32, FFA_FNUM_FEATURES)
+#define FFA_RX_RELEASE		FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
+#define FFA_RXTX_MAP_SMC32	FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
+#define FFA_RXTX_UNMAP		FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
+#define FFA_PARTITION_INFO_GET	FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
+#define FFA_ID_GET		FFA_FID(SMC_32, FFA_FNUM_ID_GET)
+#define FFA_MSG_POLL		FFA_FID(SMC_32, FFA_FNUM_MSG_POLL)
+#define FFA_MSG_WAIT		FFA_FID(SMC_32, FFA_FNUM_MSG_WAIT)
+#define FFA_MSG_YIELD		FFA_FID(SMC_32, FFA_FNUM_MSG_YIELD)
+#define FFA_MSG_RUN		FFA_FID(SMC_32, FFA_FNUM_MSG_RUN)
+#define FFA_MSG_SEND		FFA_FID(SMC_32, FFA_FNUM_MSG_SEND)
+#define FFA_MSG_SEND_DIRECT_REQ_SMC32 \
+	FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_REQ)
+#define FFA_MSG_SEND_DIRECT_RESP_SMC32	\
+	FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_RESP)
+#define FFA_MEM_DONATE_SMC32	FFA_FID(SMC_32, FFA_FNUM_MEM_DONATE)
+#define FFA_MEM_LEND_SMC32	FFA_FID(SMC_32, FFA_FNUM_MEM_LEND)
+#define FFA_MEM_SHARE_SMC32	FFA_FID(SMC_32, FFA_FNUM_MEM_SHARE)
+#define FFA_MEM_RETRIEVE_REQ_SMC32 \
+	FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_REQ)
+#define FFA_MEM_RETRIEVE_RESP	FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP)
+#define FFA_MEM_RELINQUISH	FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH)
+#define FFA_MEM_RECLAIM	FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM)
+
+/* FFA SMC64 FIDs */
+#define FFA_SUCCESS_SMC64	FFA_FID(SMC_64, FFA_FNUM_SUCCESS)
+#define FFA_RXTX_MAP_SMC64	FFA_FID(SMC_64, FFA_FNUM_RXTX_MAP)
+#define FFA_MSG_SEND_DIRECT_REQ_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ)
+#define FFA_MSG_SEND_DIRECT_RESP_SMC64	\
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP)
+#define FFA_MEM_DONATE_SMC64	FFA_FID(SMC_64, FFA_FNUM_MEM_DONATE)
+#define FFA_MEM_LEND_SMC64	FFA_FID(SMC_64, FFA_FNUM_MEM_LEND)
+#define FFA_MEM_SHARE_SMC64	FFA_FID(SMC_64, FFA_FNUM_MEM_SHARE)
+#define FFA_MEM_RETRIEVE_REQ_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_MEM_RETRIEVE_REQ)
+
+/*
+ * Reserve a special value for traffic targeted to the Hypervisor or SPM.
+ */
+#define FFA_TARGET_INFO_MBZ		U(0x0)
+
+/*
+ * Reserve a special value for MBZ parameters.
+ */
+#define FFA_PARAM_MBZ			U(0x0)
+
+#endif /* FFA_SVC_H */
diff --git a/include/services/sdei.h b/include/services/sdei.h
index ae8c7e4..063ed6f 100644
--- a/include/services/sdei.h
+++ b/include/services/sdei.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <lib/spinlock.h>
 #include <lib/utils_def.h>
+#include <services/sdei_flags.h>
 
 /* Range 0xC4000020 - 0xC400003F reserved for SDE 64bit smc calls */
 #define SDEI_VERSION				0xC4000020U
@@ -41,50 +42,6 @@
 #define SDEI_EV_HANDLED		0U
 #define SDEI_EV_FAILED		1U
 
-/* Internal: SDEI flag bit positions */
-#define SDEI_MAPF_DYNAMIC_SHIFT_	1U
-#define SDEI_MAPF_BOUND_SHIFT_		2U
-#define SDEI_MAPF_SIGNALABLE_SHIFT_	3U
-#define SDEI_MAPF_PRIVATE_SHIFT_	4U
-#define SDEI_MAPF_CRITICAL_SHIFT_	5U
-#define SDEI_MAPF_EXPLICIT_SHIFT_	6U
-
-/* SDEI event 0 */
-#define SDEI_EVENT_0	0
-
-/* Placeholder interrupt for dynamic mapping */
-#define SDEI_DYN_IRQ	0U
-
-/* SDEI flags */
-
-/*
- * These flags determine whether or not an event can be associated with an
- * interrupt. Static events are permanently associated with an interrupt, and
- * can't be changed at runtime.  Association of dynamic events with interrupts
- * can be changed at run time using the SDEI_INTERRUPT_BIND and
- * SDEI_INTERRUPT_RELEASE calls.
- *
- * SDEI_MAPF_DYNAMIC only indicates run time configurability, where as
- * SDEI_MAPF_BOUND indicates interrupt association. For example:
- *
- *  - Calling SDEI_INTERRUPT_BIND on a dynamic event will have both
- *    SDEI_MAPF_DYNAMIC and SDEI_MAPF_BOUND set.
- *
- *  - Statically-bound events will always have SDEI_MAPF_BOUND set, and neither
- *    SDEI_INTERRUPT_BIND nor SDEI_INTERRUPT_RELEASE can be called on them.
- *
- * See also the is_map_bound() macro.
- */
-#define SDEI_MAPF_DYNAMIC	BIT(SDEI_MAPF_DYNAMIC_SHIFT_)
-#define SDEI_MAPF_BOUND		BIT(SDEI_MAPF_BOUND_SHIFT_)
-#define SDEI_MAPF_EXPLICIT	BIT(SDEI_MAPF_EXPLICIT_SHIFT_)
-
-#define SDEI_MAPF_SIGNALABLE	BIT(SDEI_MAPF_SIGNALABLE_SHIFT_)
-#define SDEI_MAPF_PRIVATE	BIT(SDEI_MAPF_PRIVATE_SHIFT_)
-
-#define SDEI_MAPF_NORMAL	0
-#define SDEI_MAPF_CRITICAL	BIT(SDEI_MAPF_CRITICAL_SHIFT_)
-
 /* Indices of private and shared mappings */
 #define SDEI_MAP_IDX_PRIV_	0U
 #define SDEI_MAP_IDX_SHRD_	1U
diff --git a/include/services/sdei_flags.h b/include/services/sdei_flags.h
new file mode 100644
index 0000000..d1308f8
--- /dev/null
+++ b/include/services/sdei_flags.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDEI_FLAGS_H
+#define SDEI_FLAGS_H
+
+#include <lib/utils_def.h>
+
+/* Internal: SDEI flag bit positions */
+#define SDEI_MAPF_DYNAMIC_SHIFT_	1U
+#define SDEI_MAPF_BOUND_SHIFT_		2U
+#define SDEI_MAPF_SIGNALABLE_SHIFT_	3U
+#define SDEI_MAPF_PRIVATE_SHIFT_	4U
+#define SDEI_MAPF_CRITICAL_SHIFT_	5U
+#define SDEI_MAPF_EXPLICIT_SHIFT_	6U
+
+/* SDEI event 0 */
+#define SDEI_EVENT_0	0
+
+/* Placeholder interrupt for dynamic mapping */
+#define SDEI_DYN_IRQ	0U
+
+/* SDEI flags */
+
+/*
+ * These flags determine whether or not an event can be associated with an
+ * interrupt. Static events are permanently associated with an interrupt, and
+ * can't be changed at runtime.  Association of dynamic events with interrupts
+ * can be changed at run time using the SDEI_INTERRUPT_BIND and
+ * SDEI_INTERRUPT_RELEASE calls.
+ *
+ * SDEI_MAPF_DYNAMIC only indicates run time configurability, where as
+ * SDEI_MAPF_BOUND indicates interrupt association. For example:
+ *
+ *  - Calling SDEI_INTERRUPT_BIND on a dynamic event will have both
+ *    SDEI_MAPF_DYNAMIC and SDEI_MAPF_BOUND set.
+ *
+ *  - Statically-bound events will always have SDEI_MAPF_BOUND set, and neither
+ *    SDEI_INTERRUPT_BIND nor SDEI_INTERRUPT_RELEASE can be called on them.
+ *
+ * See also the is_map_bound() macro.
+ */
+#define SDEI_MAPF_DYNAMIC	BIT(SDEI_MAPF_DYNAMIC_SHIFT_)
+#define SDEI_MAPF_BOUND		BIT(SDEI_MAPF_BOUND_SHIFT_)
+#define SDEI_MAPF_EXPLICIT	BIT(SDEI_MAPF_EXPLICIT_SHIFT_)
+
+#define SDEI_MAPF_SIGNALABLE	BIT(SDEI_MAPF_SIGNALABLE_SHIFT_)
+#define SDEI_MAPF_PRIVATE	BIT(SDEI_MAPF_PRIVATE_SHIFT_)
+
+#define SDEI_MAPF_NORMAL	0
+#define SDEI_MAPF_CRITICAL	BIT(SDEI_MAPF_CRITICAL_SHIFT_)
+
+#endif /* SDEI_FLAGS_H */
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
deleted file mode 100644
index 49ba408..0000000
--- a/include/services/spci_svc.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPCI_SVC_H
-#define SPCI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-#include <tools_share/uuid.h>
-
-/* SPCI error codes. */
-#define SPCI_ERROR_NOT_SUPPORTED	-1
-#define SPCI_ERROR_INVALID_PARAMETER	-2
-#define SPCI_ERROR_NO_MEMORY		-3
-#define SPCI_ERROR_BUSY			-4
-#define SPCI_ERROR_INTERRUPTED		-5
-#define SPCI_ERROR_DENIED		-6
-#define SPCI_ERROR_RETRY		-7
-
-/* The macros below are used to identify SPCI calls from the SMC function ID */
-#define SPCI_FNUM_MIN_VALUE	U(0x60)
-#define SPCI_FNUM_MAX_VALUE	U(0x7f)
-#define is_spci_fid(fid) __extension__ ({		\
-	__typeof__(fid) _fid = (fid);			\
-	((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) &&	\
-	 (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); })
-
-/* SPCI_VERSION helpers */
-#define SPCI_VERSION_MAJOR		U(0)
-#define SPCI_VERSION_MAJOR_SHIFT	16
-#define SPCI_VERSION_MAJOR_MASK		U(0x7FFF)
-#define SPCI_VERSION_MINOR		U(9)
-#define SPCI_VERSION_MINOR_SHIFT	0
-#define SPCI_VERSION_MINOR_MASK		U(0xFFFF)
-
-#define MAKE_SPCI_VERSION(major, minor) \
-	((((major) & SPCI_VERSION_MAJOR_MASK) <<  SPCI_VERSION_MAJOR_SHIFT) | \
-	 (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT))
-#define SPCI_VERSION_COMPILED		MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \
-							  SPCI_VERSION_MINOR)
-
-/* SPCI_MSG_SEND helpers */
-#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT	U(0)
-#define SPCI_MSG_SEND_ATTRS_BLK_MASK	U(0x1)
-#define SPCI_MSG_SEND_ATTRS_BLK		U(0)
-#define SPCI_MSG_SEND_ATTRS_BLK_NOT	U(1)
-#define SPCI_MSG_SEND_ATTRS(blk)		\
-	(((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \
-	<< SPCI_MSG_SEND_ATTRS_BLK_SHIFT)
-
-/* Get SPCI fastcall std FID from function number */
-#define SPCI_FID(smc_cc, func_num)			\
-		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) |	\
-		 ((smc_cc) << FUNCID_CC_SHIFT) |	\
-		 (OEN_STD_START << FUNCID_OEN_SHIFT) |	\
-		 ((func_num) << FUNCID_NUM_SHIFT))
-
-/* SPCI function numbers */
-#define SPCI_FNUM_ERROR			U(0x60)
-#define SPCI_FNUM_SUCCESS		U(0x61)
-#define SPCI_FNUM_INTERRUPT		U(0x62)
-#define SPCI_FNUM_VERSION		U(0x63)
-#define SPCI_FNUM_FEATURES		U(0x64)
-#define SPCI_FNUM_RX_RELEASE		U(0x65)
-#define SPCI_FNUM_RXTX_MAP		U(0x66)
-#define SPCI_FNUM_RXTX_UNMAP		U(0x67)
-#define SPCI_FNUM_PARTITION_INFO_GET	U(0x68)
-#define SPCI_FNUM_ID_GET		U(0x69)
-#define SPCI_FNUM_MSG_POLL		U(0x6A)
-#define SPCI_FNUM_MSG_WAIT		U(0x6B)
-#define SPCI_FNUM_MSG_YIELD		U(0x6C)
-#define SPCI_FNUM_MSG_RUN		U(0x6D)
-#define SPCI_FNUM_MSG_SEND		U(0x6E)
-#define SPCI_FNUM_MSG_SEND_DIRECT_REQ	U(0x6F)
-#define SPCI_FNUM_MSG_SEND_DIRECT_RESP	U(0x70)
-#define SPCI_FNUM_MEM_DONATE		U(0x71)
-#define SPCI_FNUM_MEM_LEND		U(0x72)
-#define SPCI_FNUM_MEM_SHARE		U(0x73)
-#define SPCI_FNUM_MEM_RETRIEVE_REQ	U(0x74)
-#define SPCI_FNUM_MEM_RETRIEVE_RESP	U(0x75)
-#define SPCI_FNUM_MEM_RELINQUISH	U(0x76)
-#define SPCI_FNUM_MEM_RECLAIM		U(0x77)
-
-/* SPCI SMC32 FIDs */
-#define SPCI_ERROR		SPCI_FID(SMC_32, SPCI_FNUM_ERROR)
-#define SPCI_SUCCESS_SMC32	SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS)
-#define SPCI_INTERRUPT		SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT)
-#define SPCI_VERSION		SPCI_FID(SMC_32, SPCI_FNUM_VERSION)
-#define SPCI_FEATURES		SPCI_FID(SMC_32, SPCI_FNUM_FEATURES)
-#define SPCI_RX_RELEASE		SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE)
-#define SPCI_RXTX_MAP_SMC32	SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP)
-#define SPCI_RXTX_UNMAP		SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP)
-#define SPCI_PARTITION_INFO_GET	SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET)
-#define SPCI_ID_GET		SPCI_FID(SMC_32, SPCI_FNUM_ID_GET)
-#define SPCI_MSG_POLL		SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL)
-#define SPCI_MSG_WAIT		SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT)
-#define SPCI_MSG_YIELD		SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD)
-#define SPCI_MSG_RUN		SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN)
-#define SPCI_MSG_SEND		SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND)
-#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \
-	SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
-#define SPCI_MSG_SEND_DIRECT_RESP_SMC32	\
-	SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
-#define SPCI_MEM_DONATE_SMC32	SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE)
-#define SPCI_MEM_LEND_SMC32	SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND)
-#define SPCI_MEM_SHARE_SMC32	SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE)
-#define SPCI_MEM_RETRIEVE_REQ_SMC32 \
-	SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ)
-#define SPCI_MEM_RETRIEVE_RESP	SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP)
-#define SPCI_MEM_RELINQUISH	SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH)
-#define SPCI_MEM_RECLAIM	SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM)
-
-/* SPCI SMC64 FIDs */
-#define SPCI_SUCCESS_SMC64	SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS)
-#define SPCI_RXTX_MAP_SMC64	SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP)
-#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \
-	SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
-#define SPCI_MSG_SEND_DIRECT_RESP_SMC64	\
-	SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
-#define SPCI_MEM_DONATE_SMC64	SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE)
-#define SPCI_MEM_LEND_SMC64	SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND)
-#define SPCI_MEM_SHARE_SMC64	SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE)
-#define SPCI_MEM_RETRIEVE_REQ_SMC64 \
-	SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ)
-
-/*
- * Reserve a special value for traffic targeted to the Hypervisor or SPM.
- */
-#define SPCI_TARGET_INFO_MBZ		U(0x0)
-
-/*
- * Reserve a special value for MBZ parameters.
- */
-#define SPCI_PARAM_MBZ			U(0x0)
-
-#endif /* SPCI_SVC_H */
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
index 71e6cfb..64ecce0 100644
--- a/include/services/spm_core_manifest.h
+++ b/include/services/spm_core_manifest.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SPMC_MANIFEST_H
-#define SPMC_MANIFEST_H
+#ifndef SPM_CORE_MANIFEST_H
+#define SPM_CORE_MANIFEST_H
 
 #include <stdint.h>
 
@@ -15,7 +15,7 @@
 
 typedef struct spm_core_manifest_sect_attribute {
 	/*
-	 * SPCI version (mandatory).
+	 * FFA version (mandatory).
 	 */
 	uint32_t major_version;
 	uint32_t minor_version;
@@ -28,18 +28,18 @@
 	uint32_t exec_state;
 
 	/*
-	 * Address of binary image containing SPM core in bytes (optional).
+	 * Address of binary image containing SPM Core (optional).
 	 */
 	uint64_t load_address;
 
 	/*
 	 * Offset from the base of the partition's binary image to the entry
-	 * point of the partition.
+	 * point of the partition (optional).
 	 */
 	uint64_t entrypoint;
 
 	/*
-	 * Size of binary image containing SPM core in bytes (mandatory).
+	 * Size of binary image containing SPM Core in bytes (mandatory).
 	 */
 	uint32_t binary_size;
 
@@ -48,6 +48,6 @@
 	 */
 	uint16_t spmc_id;
 
-} spmc_manifest_sect_attribute_t;
+} spmc_manifest_attribute_t;
 
-#endif /* SPMC_MANIFEST_H */
+#endif /* SPM_CORE_MANIFEST_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index a766dcf..1e7e6aa 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -8,7 +8,7 @@
 #define SPMD_SVC_H
 
 #ifndef __ASSEMBLER__
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
 #include <stdint.h>
 
 int spmd_setup(void);
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 221f33e..1568ef0 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -71,53 +71,52 @@
 	mrs	x15, far_el2
 	stp	x14, x15, [x0, #CTX_ESR_EL2]
 
-	mrs	x16, fpexc32_el2
-	mrs	x17, hacr_el2
-	stp	x16, x17, [x0, #CTX_FPEXC32_EL2]
+	mrs	x16, hacr_el2
+	mrs	x17, hcr_el2
+	stp	x16, x17, [x0, #CTX_HACR_EL2]
 
-	mrs	x9, hcr_el2
-	mrs	x10, hpfar_el2
-	stp	x9, x10, [x0, #CTX_HCR_EL2]
+	mrs	x9, hpfar_el2
+	mrs	x10, hstr_el2
+	stp	x9, x10, [x0, #CTX_HPFAR_EL2]
 
-	mrs	x11, hstr_el2
-	mrs	x12, ICC_SRE_EL2
-	stp	x11, x12, [x0, #CTX_HSTR_EL2]
+	mrs	x11, ICC_SRE_EL2
+	mrs	x12, ICH_HCR_EL2
+	stp	x11, x12, [x0, #CTX_ICC_SRE_EL2]
 
-	mrs	x13, ICH_HCR_EL2
-	mrs	x14, ICH_VMCR_EL2
-	stp	x13, x14, [x0, #CTX_ICH_HCR_EL2]
+	mrs	x13, ICH_VMCR_EL2
+	mrs	x14, mair_el2
+	stp	x13, x14, [x0, #CTX_ICH_VMCR_EL2]
 
-	mrs	x15, mair_el2
-	mrs	x16, mdcr_el2
-	stp	x15, x16, [x0, #CTX_MAIR_EL2]
+	mrs	x15, mdcr_el2
+	mrs	x16, PMSCR_EL2
+	stp	x15, x16, [x0, #CTX_MDCR_EL2]
 
-	mrs	x17, PMSCR_EL2
-	mrs	x9, sctlr_el2
-	stp	x17, x9, [x0, #CTX_PMSCR_EL2]
+	mrs	x17, sctlr_el2
+	mrs	x9, spsr_el2
+	stp	x17, x9, [x0, #CTX_SCTLR_EL2]
 
-	mrs	x10, spsr_el2
-	mrs	x11, sp_el2
-	stp	x10, x11, [x0, #CTX_SPSR_EL2]
+	mrs	x10, sp_el2
+	mrs	x11, tcr_el2
+	stp	x10, x11, [x0, #CTX_SP_EL2]
 
-	mrs	x12, tcr_el2
-	mrs	x13, tpidr_el2
-	stp	x12, x13, [x0, #CTX_TCR_EL2]
+	mrs	x12, tpidr_el2
+	mrs	x13, ttbr0_el2
+	stp	x12, x13, [x0, #CTX_TPIDR_EL2]
 
-	mrs	x14, ttbr0_el2
-	mrs	x15, vbar_el2
-	stp	x14, x15, [x0, #CTX_TTBR0_EL2]
+	mrs	x14, vbar_el2
+	mrs	x15, vmpidr_el2
+	stp	x14, x15, [x0, #CTX_VBAR_EL2]
 
-	mrs	x16, vmpidr_el2
-	mrs	x17, vpidr_el2
-	stp	x16, x17, [x0, #CTX_VMPIDR_EL2]
+	mrs	x16, vpidr_el2
+	mrs	x17, vtcr_el2
+	stp	x16, x17, [x0, #CTX_VPIDR_EL2]
 
-	mrs	x9, vtcr_el2
-	mrs	x10, vttbr_el2
-	stp	x9, x10, [x0, #CTX_VTCR_EL2]
+	mrs	x9, vttbr_el2
+	str	x9, [x0, #CTX_VTTBR_EL2]
 
 #if CTX_INCLUDE_MTE_REGS
-	mrs	x11, TFSR_EL2
-	str	x11, [x0, #CTX_TFSR_EL2]
+	mrs	x10, TFSR_EL2
+	str	x10, [x0, #CTX_TFSR_EL2]
 #endif
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
@@ -234,6 +233,21 @@
  */
 func el2_sysregs_context_restore
 
+#if ERRATA_SPECULATIVE_AT
+/* Clear EPD0 and EPD1 bit and M bit to disable PTW */
+	mrs	x9, hcr_el2
+	tst	x9, #HCR_E2H_BIT
+	bne	1f
+	mrs	x9, tcr_el2
+	orr	x9, x9, #TCR_EPD0_BIT
+	orr	x9, x9, #TCR_EPD1_BIT
+	msr	tcr_el2, x9
+1:	mrs	x9, sctlr_el2
+	bic	x9, x9, #SCTLR_M_BIT
+	msr	sctlr_el2, x9
+	isb
+#endif
+
 	ldp	x9, x10, [x0, #CTX_ACTLR_EL2]
 	msr	actlr_el2, x9
 	msr	afsr0_el2, x10
@@ -262,53 +276,48 @@
 	msr	esr_el2, x14
 	msr	far_el2, x15
 
-	ldp	x16, x17, [x0, #CTX_FPEXC32_EL2]
-	msr	fpexc32_el2, x16
-	msr	hacr_el2, x17
+	ldp	x16, x17, [x0, #CTX_HACR_EL2]
+	msr	hacr_el2, x16
+	msr	hcr_el2, x17
 
-	ldp	x9, x10, [x0, #CTX_HCR_EL2]
-	msr	hcr_el2, x9
-	msr	hpfar_el2, x10
+	ldp	x9, x10, [x0, #CTX_HPFAR_EL2]
+	msr	hpfar_el2, x9
+	msr	hstr_el2, x10
 
-	ldp	x11, x12, [x0, #CTX_HSTR_EL2]
-	msr	hstr_el2, x11
-	msr	ICC_SRE_EL2, x12
+	ldp	x11, x12, [x0, #CTX_ICC_SRE_EL2]
+	msr	ICC_SRE_EL2, x11
+	msr	ICH_HCR_EL2, x12
 
-	ldp	x13, x14, [x0, #CTX_ICH_HCR_EL2]
-	msr	ICH_HCR_EL2, x13
-	msr	ICH_VMCR_EL2, x14
+	ldp	x13, x14, [x0, #CTX_ICH_VMCR_EL2]
+	msr	ICH_VMCR_EL2, x13
+	msr	mair_el2, x14
 
-	ldp	x15, x16, [x0, #CTX_MAIR_EL2]
-	msr	mair_el2, x15
-	msr	mdcr_el2, x16
+	ldp	x15, x16, [x0, #CTX_MDCR_EL2]
+	msr	mdcr_el2, x15
+	msr	PMSCR_EL2, x16
 
-	ldp	x17, x9, [x0, #CTX_PMSCR_EL2]
-	msr	PMSCR_EL2, x17
-	msr	sctlr_el2, x9
-
-	ldp	x10, x11, [x0, #CTX_SPSR_EL2]
-	msr	spsr_el2, x10
-	msr	sp_el2, x11
+	ldp	x17, x9, [x0, #CTX_SPSR_EL2]
+	msr	spsr_el2, x17
+	msr	sp_el2, x9
 
-	ldp	x12, x13, [x0, #CTX_TCR_EL2]
-	msr	tcr_el2, x12
-	msr	tpidr_el2, x13
+	ldp	x10, x11, [x0, #CTX_TPIDR_EL2]
+	msr	tpidr_el2, x10
+	msr	ttbr0_el2, x11
 
-	ldp	x14, x15, [x0, #CTX_TTBR0_EL2]
-	msr	ttbr0_el2, x14
-	msr	vbar_el2, x15
+	ldp	x12, x13, [x0, #CTX_VBAR_EL2]
+	msr	vbar_el2, x12
+	msr	vmpidr_el2, x13
 
-	ldp	x16, x17, [x0, #CTX_VMPIDR_EL2]
-	msr	vmpidr_el2, x16
-	msr	vpidr_el2, x17
+	ldp	x14, x15, [x0, #CTX_VPIDR_EL2]
+	msr	vpidr_el2, x14
+	msr	vtcr_el2, x15
 
-	ldp	x9, x10, [x0, #CTX_VTCR_EL2]
-	msr	vtcr_el2, x9
-	msr	vttbr_el2, x10
+	ldr	x16, [x0, #CTX_VTTBR_EL2]
+	msr	vttbr_el2, x16
 
 #if CTX_INCLUDE_MTE_REGS
-	ldr	x11, [x0, #CTX_TFSR_EL2]
-	msr	TFSR_EL2, x11
+	ldr	x17, [x0, #CTX_TFSR_EL2]
+	msr	TFSR_EL2, x17
 #endif
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
@@ -404,6 +413,19 @@
 	msr	scxtnum_el2, x9
 #endif
 
+#if ERRATA_SPECULATIVE_AT
+/*
+ * Make sure all registers are stored successfully except
+ * SCTLR_EL2 and TCR_EL2
+ */
+	isb
+#endif
+
+	ldr	x9, [x0, #CTX_SCTLR_EL2]
+	msr	sctlr_el2, x9
+	ldr	x9, [x0, #CTX_TCR_EL2]
+	msr	tcr_el2, x9
+
 	ret
 endfunc el2_sysregs_context_restore
 
@@ -515,12 +537,22 @@
  */
 func el1_sysregs_context_restore
 
+#if ERRATA_SPECULATIVE_AT
+	mrs	x9, tcr_el1
+	orr	x9, x9, #TCR_EPD0_BIT
+	orr	x9, x9, #TCR_EPD1_BIT
+	msr	tcr_el1, x9
+	mrs	x9, sctlr_el1
+	bic	x9, x9, #SCTLR_M_BIT
+	msr	sctlr_el1, x9
+	isb
+#endif
+
 	ldp	x9, x10, [x0, #CTX_SPSR_EL1]
 	msr	spsr_el1, x9
 	msr	elr_el1, x10
 
-	ldp	x15, x16, [x0, #CTX_SCTLR_EL1]
-	msr	sctlr_el1, x15
+	ldr	x16, [x0, #CTX_ACTLR_EL1]
 	msr	actlr_el1, x16
 
 	ldp	x17, x9, [x0, #CTX_CPACR_EL1]
@@ -539,9 +571,8 @@
 	msr	mair_el1, x14
 	msr	amair_el1, x15
 
-	ldp	x16, x17, [x0, #CTX_TCR_EL1]
-	msr	tcr_el1, x16
-	msr	tpidr_el1, x17
+	ldr	x16,[x0, #CTX_TPIDR_EL1]
+	msr	tpidr_el1, x16
 
 	ldp	x9, x10, [x0, #CTX_TPIDR_EL0]
 	msr	tpidr_el0, x9
@@ -597,6 +628,19 @@
 	msr	GCR_EL1, x14
 #endif
 
+#if ERRATA_SPECULATIVE_AT
+/*
+ * Make sure all registers are stored successfully except
+ * SCTLR_EL1 and TCR_EL1
+ */
+	isb
+#endif
+
+	ldr	x9, [x0, #CTX_SCTLR_EL1]
+	msr	sctlr_el1, x9
+	ldr	x9, [x0, #CTX_TCR_EL1]
+	msr	tcr_el1, x9
+
 	/* No explict ISB required here as ERET covers it */
 	ret
 endfunc el1_sysregs_context_restore
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 0314a85..64a2d7b 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -22,6 +22,7 @@
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
+#include <lib/extensions/twed.h>
 #include <lib/utils.h>
 
 
@@ -229,6 +230,24 @@
 	sctlr_elx |= SCTLR_IESB_BIT;
 #endif
 
+	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
+	if (is_armv8_6_twed_present()) {
+		uint32_t delay = plat_arm_set_twedel_scr_el3();
+
+		if (delay != TWED_DISABLED) {
+			/* Make sure delay value fits */
+			assert((delay & ~SCR_TWEDEL_MASK) == 0U);
+
+			/* Set delay in SCR_EL3 */
+			scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+			scr_el3 |= ((delay & SCR_TWEDEL_MASK)
+					<< SCR_TWEDEL_SHIFT);
+
+			/* Enable WFE delay */
+			scr_el3 |= SCR_TWEDEn_BIT;
+		}
+	}
+
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
 	 * and other EL2 registers are set up by cm_prepare_ns_entry() as they
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index e794f01..65601dd 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,20 +7,16 @@
 #include <stdbool.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/extensions/mpam.h>
 
-bool mpam_supported(void)
-{
-	uint64_t features = read_id_aa64dfr0_el1() >> ID_AA64PFR0_MPAM_SHIFT;
-
-	return ((features & ID_AA64PFR0_MPAM_MASK) != 0U);
-}
-
 void mpam_enable(bool el2_unused)
 {
-	if (!mpam_supported())
+	/* Check if MPAM is implemented */
+	if (get_mpam_version() == 0U) {
 		return;
+	}
 
 	/*
 	 * Enable MPAM, and disable trapping to EL3 when lower ELs access their
@@ -34,10 +30,11 @@
 	 * If EL2 is implemented and used, enable trapping to EL2.
 	 */
 	if (el2_unused) {
-		write_mpam2_el2(0);
+		write_mpam2_el2(0ULL);
 
-		if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U)
-			write_mpamhcr_el2(0);
+		if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
+			write_mpamhcr_el2(0ULL);
+		}
 	} else {
 		write_mpam2_el2(MPAM2_EL2_TRAPMPAM0EL1 |
 				MPAM2_EL2_TRAPMPAM1EL1);
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 590a800..e5880d2 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -223,7 +223,10 @@
 USE_DEBUGFS			:= 0
 
 # Build option to fconf based io
-ARM_IO_IN_DTB		:= 0
+ARM_IO_IN_DTB			:= 0
+
+# Build option to support SDEI through fconf
+SDEI_IN_FCONF			:=0
 
 # Build option to choose whether Trusted Firmware uses library at ROM
 USE_ROMLIB			:= 0
@@ -293,3 +296,6 @@
 # than Armv8.5-A
 # By default it is set to "no"
 SUPPORT_STACK_MEMTAG		:= no
+
+# Select workaround for AT speculative behaviour.
+ERRATA_SPECULATIVE_AT           := 0
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index f1d9b93..8172a6e 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -13,6 +13,9 @@
 
 struct gicv3_config_t gicv3_config;
 struct hw_topology_t soc_topology;
+struct uart_serial_config_t uart_serial_config;
+
+#define ILLEGAL_ADDR	ULL(~0)
 
 int fconf_populate_gicv3_config(uintptr_t config)
 {
@@ -147,7 +150,8 @@
 			return -1;
 		}
 
-		INFO("CLUSTER ID: %d cpu-count: %d\n", cluster_count, cpus_per_cluster[cluster_count]);
+		VERBOSE("CLUSTER ID: %d cpu-count: %d\n", cluster_count,
+					cpus_per_cluster[cluster_count]);
 
 		/* Find the maximum number of cpus in any cluster */
 		max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]);
@@ -167,8 +171,98 @@
 	soc_topology.cluster_cpu_count = max_cpu_per_cluster;
 	soc_topology.plat_cpu_count = total_cpu_count;
 
+	return 0;
+}
+
+int fconf_populate_uart_config(uintptr_t config)
+{
+	int uart_node, node, err;
+	uintptr_t addr;
+	const char *path;
+	uint32_t phandle;
+	uint64_t translated_addr;
+
+	/* Necessary to work with libfdt APIs */
+	const void *hw_config_dtb = (const void *)config;
+
+	/*
+	 * uart child node is indirectly referenced through its path which is
+	 * specified in the `serial1` property of the "aliases" node.
+	 * Note that TF-A boot console is mapped to serial0 while runtime
+	 * console is mapped to serial1.
+	 */
+
+	path = fdt_get_alias(hw_config_dtb, "serial1");
+	if (path == NULL) {
+		ERROR("FCONF: Could not read serial1 property in aliases node\n");
+		return -1;
+	}
+
+	/* Find the offset of the uart serial node */
+	uart_node = fdt_path_offset(hw_config_dtb, path);
+	if (uart_node < 0) {
+		ERROR("FCONF: Failed to locate uart serial node using its path\n");
+		return -1;
+	}
+
+	/* uart serial node has its offset and size of address in reg property */
+	err = fdt_get_reg_props_by_index(hw_config_dtb, uart_node, 0, &addr,
+						NULL);
+	if (err < 0) {
+		ERROR("FCONF: Failed to read reg property of '%s' node\n",
+			"uart serial");
+		return err;
+	}
+	VERBOSE("FCONF: UART node address: %lx\n", addr);
+
+	/*
+	 * Perform address translation of local device address to CPU address
+	 * domain.
+	 */
+	translated_addr = fdtw_translate_address(hw_config_dtb,
+						 uart_node, (uint64_t)addr);
+	if (translated_addr == ILLEGAL_ADDR) {
+		ERROR("FCONF: failed to translate UART node base address");
+		return -1;
+	}
+
+	uart_serial_config.uart_base = translated_addr;
+
+	VERBOSE("FCONF: UART serial device base address: %llx\n",
+		uart_serial_config.uart_base);
+
+	/*
+	 * The phandle of the DT node which captures the clock info of uart
+	 * serial node is specified in the "clocks" property.
+	 */
+	err = fdt_read_uint32(hw_config_dtb, uart_node, "clocks", &phandle);
+	if (err < 0) {
+		ERROR("FCONF: Could not read clocks property in uart serial node\n");
+		return err;
+	}
+
+	node = fdt_node_offset_by_phandle(hw_config_dtb, phandle);
+	if (node < 0) {
+		ERROR("FCONF: Failed to locate clk node using its path\n");
+		return node;
+	}
+
+	/*
+	 * Retrieve clock frequency. We assume clock provider generates a fixed
+	 * clock.
+	 */
+	err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency",
+				&uart_serial_config.uart_clk);
+	if (err < 0) {
+		ERROR("FCONF: Could not read clock-frequency property in clk node\n");
+		return err;
+	}
+
+	VERBOSE("FCONF: UART serial device clk frequency: %x\n",
+		uart_serial_config.uart_clk);
 	return 0;
 }
 
 FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index ebfbe17..a1c9094 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -6,12 +6,14 @@
 /dts-v1/;
 
 / {
-	compatible = "arm,spci-core-manifest-1.0";
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
 
 	attribute {
 		spmc_id = <0x8000>;
-		maj_ver = <0x0>;
-		min_ver = <0x9>;
+		maj_ver = <0x1>;
+		min_ver = <0x0>;
 		exec_state = <0x0>;
 		load_address = <0x0 0x6000000>;
 		entrypoint = <0x0 0x6000000>;
@@ -25,12 +27,12 @@
 	hypervisor {
 		compatible = "hafnium,hafnium";
 		vm1 {
-			is_spci_partition;
+			is_ffa_partition;
 			debug_name = "cactus-primary";
 			load_address = <0x7000000>;
 		};
 		vm2 {
-			is_spci_partition;
+			is_ffa_partition;
 			debug_name = "cactus-secondary";
 			load_address = <0x7100000>;
 			vcpu_count = <2>;
@@ -62,6 +64,6 @@
 
 	memory@60000000 {
 		device_type = "memory";
-		reg = <0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
 	};
 };
diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c
new file mode 100644
index 0000000..928b47b
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_console.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <fconf_hw_config_getter.h>
+#include <plat/arm/common/plat_arm.h>
+
+static console_t fvp_runtime_console;
+
+/* Initialize the runtime console */
+void arm_console_runtime_init(void)
+{
+	uintptr_t uart_base;
+	uint32_t uart_clk;
+
+	/*
+	 * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
+	 * BL2_AT_EL3 systems.
+	 */
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+	uart_base = PLAT_ARM_RUN_UART_BASE;
+	uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ;
+#else
+	uart_base = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+					uart_base);
+	uart_clk = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+					uart_clk);
+#endif
+
+	int rc = console_pl011_register(uart_base, uart_clk,
+					ARM_CONSOLE_BAUDRATE,
+					&fvp_runtime_console);
+
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(&fvp_runtime_console, CONSOLE_FLAG_RUNTIME);
+}
+
+void arm_console_runtime_end(void)
+{
+	(void)console_flush();
+	(void)console_unregister(&fvp_runtime_console);
+}
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
new file mode 100644
index 0000000..a3ee8ef
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <fconf_hw_config_getter.h>
+#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+/* Default GICR base address to be used for GICR probe. */
+static uint64_t fvp_gicr_base_addrs[2] = { 0U };
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs;
+
+static const interrupt_prop_t fvp_interrupt_props[] = {
+	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ *   - No CPUs implemented in the system use affinity level 3.
+ */
+static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr)
+{
+	u_register_t temp_mpidr = mpidr;
+
+	temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+	return plat_arm_calc_core_pos(temp_mpidr);
+}
+
+
+static gicv3_driver_data_t fvp_gic_data = {
+	.interrupt_props = fvp_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = fvp_rdistif_base_addrs,
+	.mpidr_to_core_pos = fvp_gicv3_mpidr_hash
+};
+
+void plat_arm_gic_driver_init(void)
+{
+	/* Get GICD and GICR base addressed through FCONF APIs */
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+	(defined(__aarch64__) && defined(IMAGE_BL31))
+	fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
+							       gicv3_config,
+							       gicd_base);
+	fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config,
+						    gicr_base);
+#else
+	fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE;
+	fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE;
+#endif
+
+	/*
+	 * The GICv3 driver is initialized in EL3 and does not need
+	 * to be initialized again in SEL1. This is because the S-EL1
+	 * can use GIC system registers to manage interrupts and does
+	 * not need GIC interface base addresses to be configured.
+	 */
+
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+	(defined(__aarch64__) && defined(IMAGE_BL31))
+	gicv3_driver_init(&fvp_gic_data);
+	if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) {
+		ERROR("No GICR base frame found for Primary CPU\n");
+		panic();
+	}
+#endif
+}
+
+/******************************************************************************
+ * Function to iterate over all GICR frames and discover the corresponding
+ * per-cpu redistributor frame as well as initialize the corresponding
+ * interface in GICv3.
+ *****************************************************************************/
+void plat_arm_gic_pcpu_init(void)
+{
+	int result;
+	const uint64_t *plat_gicr_frames = fvp_gicr_frames;
+
+	do {
+		result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+		/* If the probe is successful, no need to proceed further */
+		if (result == 0)
+			break;
+
+		plat_gicr_frames++;
+	} while (*plat_gicr_frames != 0U);
+
+	if (result == -1) {
+		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
+		panic();
+	}
+	gicv3_rdistif_init(plat_my_core_pos());
+}
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index a9e569e..b53e00a 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -14,9 +14,11 @@
 
 #define hw_config__topology_getter(prop) soc_topology.prop
 
+#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
+
 struct gicv3_config_t {
-	uintptr_t gicd_base;
-	uintptr_t gicr_base;
+	uint64_t gicd_base;
+	uint64_t gicr_base;
 };
 
 struct hw_topology_t {
@@ -26,10 +28,17 @@
 	uint32_t plat_max_pwr_level;
 };
 
+struct uart_serial_config_t {
+	uint64_t uart_base;
+	uint32_t uart_clk;
+};
+
 int fconf_populate_gicv3_config(uintptr_t config);
 int fconf_populate_topology(uintptr_t config);
+int fconf_populate_uart_config(uintptr_t config);
 
 extern struct gicv3_config_t gicv3_config;
 extern struct hw_topology_t soc_topology;
+extern struct uart_serial_config_t uart_serial_config;
 
 #endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 1ed3074..62ede9a 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -264,8 +264,13 @@
 
 #define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
 
+#if SDEI_IN_FCONF
+#define PLAT_SDEI_DP_EVENT_MAX_CNT	ARM_SDEI_DP_EVENT_MAX_CNT
+#define PLAT_SDEI_DS_EVENT_MAX_CNT	ARM_SDEI_DS_EVENT_MAX_CNT
+#else
 #define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
 #define PLAT_ARM_SHARED_SDEI_EVENTS	ARM_SDEI_SHARED_EVENTS
+#endif
 
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 213a974..b72bdab 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -16,6 +16,7 @@
 
 rom     rom_lib_init
 fdt     fdt_getprop
+fdt     fdt_get_property
 fdt     fdt_getprop_namelen
 fdt     fdt_setprop_inplace
 fdt     fdt_check_header
@@ -31,6 +32,9 @@
 fdt     fdt_parent_offset
 fdt     fdt_stringlist_search
 fdt     fdt_get_alias_namelen
+fdt     fdt_get_name
+fdt     fdt_get_alias
+fdt     fdt_node_offset_by_phandle
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
 mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 04cebca..33531f3 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -65,6 +65,10 @@
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c
 
+	ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
+		FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
+	endif
+
 else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2)
 
 # No GICv4 extension
@@ -201,6 +205,7 @@
 				drivers/cfi/v2m/v2m_flash.c			\
 				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/fvp_bl31_setup.c		\
+				plat/arm/board/fvp/fvp_console.c		\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 36bf441..ba6ceec 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -10,6 +10,7 @@
 				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/aarch32/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_pm.c			\
+				plat/arm/board/fvp/fvp_console.c		\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c	\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 09017ac..20ed2c7 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -16,6 +16,7 @@
 
 rom     rom_lib_init
 fdt     fdt_getprop
+fdt     fdt_get_property
 fdt     fdt_getprop_namelen
 fdt     fdt_setprop_inplace
 fdt     fdt_check_header
@@ -28,6 +29,9 @@
 fdt     fdt_get_alias_namelen
 fdt     fdt_path_offset
 fdt     fdt_path_offset_namelen
+fdt     fdt_get_name
+fdt     fdt_get_alias
+fdt     fdt_node_offset_by_phandle
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
 mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
new file mode 100644
index 0000000..8d7faf8
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		/* tb_fw_config is temporarily contained in this dtb */
+		tb_fw-config {
+			load-address = <0x0 0x2001010>;
+			max-size = <0x200>;
+			id = <TB_FW_CONFIG_ID>;
+		};
+
+		hw-config {
+			load-address = <0x0 0x83000000>;
+			max-size = <0x01000000>;
+			id = <HW_CONFIG_ID>;
+		};
+	};
+
+	tb_fw-config {
+		compatible = "arm,tb_fw";
+
+		/* Disable authentication for development */
+		disable_auth = <0x0>;
+		/*
+		 * The following two entries are placeholders for Mbed TLS
+		 * heap information. The default values don't matter since
+		 * they will be overwritten by BL1.
+		 * In case of having shared Mbed TLS heap between BL1 and BL2,
+		 * BL1 will populate these two properties with the respective
+		 * info about the shared heap. This info will be available for
+		 * BL2 in order to locate and re-use the heap.
+		 */
+		mbedtls_heap_addr = <0x0 0x0>;
+		mbedtls_heap_size = <0x0>;
+	};
+};
diff --git a/plat/arm/board/tc0/include/plat_macros.S b/plat/arm/board/tc0/include/plat_macros.S
new file mode 100644
index 0000000..6006fa5
--- /dev/null
+++ b/plat/arm/board/tc0/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+	.macro plat_crash_print_regs
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h
new file mode 100644
index 0000000..56c71c1
--- /dev/null
+++ b/plat/arm/board/tc0/include/platform_def.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_CORE_COUNT		4
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLAT_ARM_MMAP_ENTRIES		9
+#  define MAX_XLAT_TABLES		7
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	7
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		8
+#  define MAX_XLAT_TABLES		8
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		8
+# define MAX_XLAT_TABLES		5
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES		11
+# define MAX_XLAT_TABLES		7
+#else
+# define PLAT_ARM_MMAP_ENTRIES		12
+# define MAX_XLAT_TABLES		6
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE	0xC000
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0x1000
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0xe000
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL2_SIZE		0x1E000
+#else
+# define PLAT_ARM_MAX_BL2_SIZE		0x11000
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW
+ */
+#define PLAT_ARM_MAX_BL31_SIZE		0x3B000
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		0x1000
+# else
+#  define PLATFORM_STACK_SIZE		0x440
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		0x1000
+# else
+#  define PLATFORM_STACK_SIZE		0x400
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		0x400
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		0x500
+# else
+#  define PLATFORM_STACK_SIZE		0x400
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		0x440
+#endif
+
+
+#define TC0_DEVICE_BASE			0x21000000
+#define TC0_DEVICE_SIZE			0x5f000000
+
+// TC0_MAP_DEVICE covers different peripherals
+// available to the platform
+#define TC0_MAP_DEVICE	MAP_REGION_FLAT(		\
+					TC0_DEVICE_BASE,	\
+					TC0_DEVICE_SIZE,	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define TC0_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+						V2M_FLASH0_SIZE,	\
+						MT_DEVICE | MT_RO | MT_SECURE)
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	0
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	0x0
+#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000	/* 512KB */
+
+#define PLAT_ARM_NSRAM_BASE		0x06000000
+#define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
+
+#define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
+					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
+
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	1
+
+#define PLAT_ARM_CLUSTER_COUNT		U(1)
+#define PLAT_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLAT_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 36)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x30140000)
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x14000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x14000
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc0/include/tc0_helpers.S b/plat/arm/board/tc0/include/tc0_helpers.S
new file mode 100644
index 0000000..90623a2
--- /dev/null
+++ b/plat/arm/board/tc0/include/tc0_helpers.S
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cpu_macros.S>
+
+	.globl	plat_arm_calc_core_pos
+	.globl	plat_reset_handler
+
+	/* ---------------------------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Function to calculate the core position on TC0.
+	 *
+	 * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) +
+	 * (CPUId * PLAT_MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
+	 */
+func plat_arm_calc_core_pos
+	/*
+	 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+	 * look as if in a multi-threaded implementation.
+	 */
+	tst	x0, #MPIDR_MT_MASK
+	lsl	x3, x0, #MPIDR_AFFINITY_BITS
+	csel	x3, x3, x0, eq
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov	x4, #PLAT_MAX_CPUS_PER_CLUSTER
+	madd	x1, x2, x4, x1
+	mov	x5, #PLAT_MAX_PE_PER_CPU
+	madd	x0, x1, x5, x0
+	ret
+endfunc plat_arm_calc_core_pos
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the CPU MIDR and disable power down bit for
+	 * that CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	ret
+endfunc plat_reset_handler
diff --git a/plat/arm/board/tc0/include/tc0_plat.h b/plat/arm/board/tc0/include/tc0_plat.h
new file mode 100644
index 0000000..f0cb431
--- /dev/null
+++ b/plat/arm/board/tc0/include/tc0_plat.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef tc0_bl31_common_platform_setup_PLAT_H
+#define tc0_bl31_common_platform_setup_PLAT_H
+
+void tc0_bl31_common_platform_setup(void);
+
+#endif /* tc0_bl31_common_platform_setup_PLAT_H */
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
new file mode 100644
index 0000000..265826f
--- /dev/null
+++ b/plat/arm/board/tc0/platform.mk
@@ -0,0 +1,97 @@
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CSS_LOAD_SCP_IMAGES	:=	1
+
+CSS_USE_SCMI_SDS_DRIVER	:=	1
+
+RAS_EXTENSION		:=	0
+
+SDEI_SUPPORT		:=	0
+
+EL3_EXCEPTION_HANDLING	:=	0
+
+HANDLE_EA_EL3_FIRST	:=	0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+GIC_ENABLE_V4_EXTN	:=      1
+
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+ENT_GIC_SOURCES		:=	${GICV3_SOURCES}		\
+				plat/common/plat_gicv3.c	\
+				plat/arm/common/arm_gicv3.c
+
+override NEED_BL2U	:=	no
+
+override ARM_PLAT_MT	:=	1
+
+TC0_BASE	=	plat/arm/board/tc0
+
+PLAT_INCLUDES		+=	-I${TC0_BASE}/include/
+
+TC0_CPU_SOURCES	:=	lib/cpus/aarch64/cortex_matterhorn.S
+
+INTERCONNECT_SOURCES	:=	${TC0_BASE}/tc0_interconnect.c
+
+PLAT_BL_COMMON_SOURCES	+=	${TC0_BASE}/tc0_plat.c	\
+				${TC0_BASE}/include/tc0_helpers.S
+
+BL1_SOURCES		+=	${INTERCONNECT_SOURCES}	\
+				${TC0_CPU_SOURCES}	\
+				${TC0_BASE}/tc0_trusted_boot.c	\
+				${TC0_BASE}/tc0_err.c	\
+				drivers/arm/sbsa/sbsa.c
+
+
+BL2_SOURCES		+=	${TC0_BASE}/tc0_security.c	\
+				${TC0_BASE}/tc0_err.c		\
+				${TC0_BASE}/tc0_trusted_boot.c		\
+				lib/utils/mem_region.c			\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
+				${TC0_CPU_SOURCES}	\
+				${ENT_GIC_SOURCES}			\
+				${TC0_BASE}/tc0_bl31_setup.c	\
+				${TC0_BASE}/tc0_topology.c	\
+				drivers/cfi/v2m/v2m_flash.c		\
+				lib/utils/mem_region.c			\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES		+=	${TC0_BASE}/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+
+#Device tree
+TC0_HW_CONFIG_DTS	:=	fdts/tc0.dts
+TC0_HW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+FDT_SOURCES		+=	${TC0_HW_CONFIG_DTS}
+$(eval TC0_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC0_HW_CONFIG_DTS)))
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config))
+
+override CTX_INCLUDE_AARCH32_REGS	:= 0
+
+override CTX_INCLUDE_PAUTH_REGS	:= 1
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/tc0/tc0_bl31_setup.c b/plat/arm/board/tc0/tc0_bl31_setup.c
new file mode 100644
index 0000000..b91b11c
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_bl31_setup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+#include <tc0_plat.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+static scmi_channel_plat_info_t tc0_scmi_plat_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	}
+};
+
+void bl31_platform_setup(void)
+{
+	tc0_bl31_common_platform_setup();
+}
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+{
+
+	return &tc0_scmi_plat_info[channel_id];
+
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
+
+void tc0_bl31_common_platform_setup(void)
+{
+	arm_bl31_platform_setup();
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+	return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c
new file mode 100644
index 0000000..4fc0505
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * tc0 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/tc0/tc0_interconnect.c b/plat/arm/board/tc0/tc0_interconnect.c
new file mode 100644
index 0000000..e2fc4e1
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_interconnect.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * For Total Compute we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void __init plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c
new file mode 100644
index 0000000..b1ec39b
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_plat.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <plat/common/platform.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/ccn.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+#include <services/spm_mm_partition.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	TC0_FLASH0_RO,
+	TC0_MAP_DEVICE,
+	{0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	TC0_FLASH0_RO,
+	TC0_MAP_DEVICE,
+	ARM_MAP_NS_DRAM1,
+#if ARM_BL31_IN_DRAM
+	ARM_MAP_BL31_SEC_DRAM,
+#endif
+#if SPM_MM
+	ARM_SP_IMAGE_MMAP,
+#endif
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+	ARM_MAP_BL1_RW,
+#endif
+	{0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_IOFPGA,
+	TC0_MAP_DEVICE,
+#if SPM_MM
+	ARM_SPM_BUF_EL3_MMAP,
+#endif
+	{0}
+};
+
+#if SPM_MM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+	PLAT_ARM_SECURE_MAP_DEVICE,
+	ARM_SP_IMAGE_MMAP,
+	ARM_SP_IMAGE_NS_BUF_MMAP,
+	ARM_SP_CPER_BUF_MMAP,
+	ARM_SP_IMAGE_RW_MMAP,
+	ARM_SPM_BUF_EL0_MMAP,
+	{0}
+};
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+#endif
+
+ARM_CASSERT_MMAP
+
+#if SPM_MM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static spm_mm_mp_info_t sp_mp_info[] = {
+	[0] = {0x81000000, 0},
+	[1] = {0x81000100, 0},
+	[2] = {0x81000200, 0},
+	[3] = {0x81000300, 0},
+	[4] = {0x81010000, 0},
+	[5] = {0x81010100, 0},
+	[6] = {0x81010200, 0},
+	[7] = {0x81010300, 0},
+};
+
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
+	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
+	.h.version           = VERSION_1,
+	.h.size              = sizeof(spm_mm_boot_info_t),
+	.h.attr              = 0,
+	.sp_mem_base         = ARM_SP_IMAGE_BASE,
+	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
+	.sp_image_base       = ARM_SP_IMAGE_BASE,
+	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
+	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
+	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
+	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
+	.sp_image_size       = ARM_SP_IMAGE_SIZE,
+	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
+	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
+	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
+	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+	.num_cpus            = PLATFORM_CORE_COUNT,
+	.mp_info             = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+	return plat_arm_secure_partition_mmap;
+}
+
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
+		void *cookie)
+{
+	return &plat_arm_secure_partition_boot_info;
+}
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c
new file mode 100644
index 0000000..6aa38c8
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/tc0/tc0_topology.c b/plat/arm/board/tc0/tc0_topology.c
new file mode 100644
index 0000000..5478fbc
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_topology.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char tc0_pd_tree_desc[] = {
+	PLAT_ARM_CLUSTER_COUNT,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return tc0_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+};
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return PLAT_MAX_CPUS_PER_CLUSTER;
+}
+
+#if ARM_PLAT_MT
+/******************************************************************************
+ * Return the number of PE's supported by the CPU.
+ *****************************************************************************/
+unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
+{
+	return PLAT_MAX_PE_PER_CPU;
+}
+#endif
diff --git a/plat/arm/board/tc0/tc0_trusted_boot.c b/plat/arm/board/tc0/tc0_trusted_boot.c
new file mode 100644
index 0000000..614f7e2
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c
index 493134b..3c74a46 100644
--- a/plat/arm/common/aarch64/arm_sdei.c
+++ b/plat/arm/common/aarch64/arm_sdei.c
@@ -1,16 +1,51 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 /* SDEI configuration for ARM platforms */
 
-#include <platform_def.h>
-
 #include <bl31/ehf.h>
+#include <common/debug.h>
 #include <services/sdei.h>
 
+#if SDEI_IN_FCONF
+#include <plat/arm/common/fconf_sdei_getter.h>
+#endif
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+
+#if SDEI_IN_FCONF
+/* Private event mappings */
+static sdei_ev_map_t arm_sdei_private[PLAT_SDEI_DP_EVENT_MAX_CNT + 1] = { 0 };
+
+/* Shared event mappings */
+static sdei_ev_map_t arm_sdei_shared[PLAT_SDEI_DS_EVENT_MAX_CNT] = { 0 };
+
+void plat_sdei_setup(void)
+{
+	uint32_t i;
+
+	arm_sdei_private[0] = (sdei_ev_map_t)SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI);
+
+	for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_cnt); i++) {
+		arm_sdei_private[i + 1] = (sdei_ev_map_t)SDEI_PRIVATE_EVENT(
+			FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_nums[i]),
+			FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_intrs[i]),
+			FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_flags[i]));
+	}
+
+	for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) {
+		arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \
+			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]),
+			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]),
+			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i]));
+	}
+	INFO("FCONF: SDEI platform setup\n");
+}
+#else
 /* Private event mappings */
 static sdei_ev_map_t arm_sdei_private[] = {
 	PLAT_ARM_PRIVATE_SDEI_EVENTS
@@ -21,5 +56,11 @@
 	PLAT_ARM_SHARED_SDEI_EVENTS
 };
 
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+#endif /* SDEI_IN_FCONF */
+
 /* Export ARM SDEI events */
 REGISTER_SDEI_MAP(arm_sdei_private, arm_sdei_shared);
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 3b0c39d..a92bf25 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -263,6 +263,9 @@
 
 ifeq (${SDEI_SUPPORT},1)
 BL31_SOURCES		+=	plat/arm/common/aarch64/arm_sdei.c
+ifeq (${SDEI_IN_FCONF},1)
+BL31_SOURCES		+=	plat/arm/common/fconf/fconf_sdei_getter.c
+endif
 endif
 
 # RAS sources
@@ -294,7 +297,9 @@
 
     # Include the selected chain of trust sources.
     ifeq (${COT},tbbr)
-        AUTH_SOURCES	+=	drivers/auth/tbbr/tbbr_cot.c
+        AUTH_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
+	BL1_SOURCES     +=      drivers/auth/tbbr/tbbr_cot_bl1.c
+	BL2_SOURCES     +=      drivers/auth/tbbr/tbbr_cot_bl2.c
     else ifeq (${COT},dualroot)
         AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
     else
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 0cac5d9..c2281c4 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -13,6 +13,9 @@
 #include <drivers/console.h>
 #include <plat/arm/common/plat_arm.h>
 
+#pragma weak arm_console_runtime_init
+#pragma weak arm_console_runtime_end
+
 /*******************************************************************************
  * Functions that set up the console
  ******************************************************************************/
diff --git a/plat/arm/common/fconf/fconf_sdei_getter.c b/plat/arm/common/fconf/fconf_sdei_getter.c
new file mode 100644
index 0000000..c26e316
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_sdei_getter.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <plat/arm/common/fconf_sdei_getter.h>
+
+#define PRIVATE_EVENT_NUM(i) private_events[3 * (i)]
+#define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1]
+#define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2]
+
+#define SHARED_EVENT_NUM(i) shared_events[3 * (i)]
+#define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1]
+#define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2]
+
+struct sdei_dyn_config_t sdei_dyn_config;
+
+int fconf_populate_sdei_dyn_config(uintptr_t config)
+{
+	uint32_t i;
+	int node, err;
+	uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3];
+	uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3];
+
+	const void *dtb = (void *)config;
+
+	/* Check that the node offset points to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0");
+	if (node < 0) {
+		ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n");
+		return node;
+	}
+
+	/* Read number of private mappings */
+	err = fdt_read_uint32(dtb, node, "private_event_count",
+				&sdei_dyn_config.private_ev_cnt);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'private_event_count': %u\n",
+				sdei_dyn_config.private_ev_cnt);
+		return err;
+	}
+
+	/* Check if the value is in range */
+	if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) {
+		ERROR("FCONF: Invalid value for 'private_event_count': %u\n",
+				sdei_dyn_config.private_ev_cnt);
+		return -1;
+	}
+
+	/* Read private mappings */
+	err = fdt_read_uint32_array(dtb, node, "private_events",
+				sdei_dyn_config.private_ev_cnt * 3, private_events);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'private_events': %d\n", err);
+		return err;
+	}
+
+	/* Move data to fconf struct */
+	for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) {
+		sdei_dyn_config.private_ev_nums[i]  = PRIVATE_EVENT_NUM(i);
+		sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i);
+		sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i);
+	}
+
+	/* Read number of shared mappings */
+	err = fdt_read_uint32(dtb, node, "shared_event_count",
+				&sdei_dyn_config.shared_ev_cnt);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'shared_event_count'\n");
+		return err;
+	}
+
+	/* Check if the value is in range */
+	if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) {
+		ERROR("FCONF: Invalid value for 'shared_event_count': %u\n",
+				sdei_dyn_config.shared_ev_cnt);
+		return -1;
+	}
+
+	/* Read shared mappings */
+	err = fdt_read_uint32_array(dtb, node, "shared_events",
+				sdei_dyn_config.shared_ev_cnt * 3, shared_events);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err);
+		return err;
+	}
+
+	/* Move data to fconf struct */
+	for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) {
+		sdei_dyn_config.shared_ev_nums[i]  = SHARED_EVENT_NUM(i);
+		sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i);
+		sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i);
+	}
+
+	return 0;
+}
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config);
diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk
index 1795ce7..808a107 100644
--- a/plat/brcm/board/common/board_common.mk
+++ b/plat/brcm/board/common/board_common.mk
@@ -213,7 +213,8 @@
 AUTH_SOURCES	+= 	drivers/auth/auth_mod.c \
 			drivers/auth/crypto_mod.c \
 			drivers/auth/img_parser_mod.c \
-			drivers/auth/tbbr/tbbr_cot.c
+			drivers/auth/tbbr/tbbr_cot_common.c \
+			drivers/auth/tbbr/tbbr_cot_bl2.c
 
 BL2_SOURCES	+=	${AUTH_SOURCES}
 
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 63871d9..b8a4d01 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -11,6 +11,7 @@
 #if RAS_EXTENSION
 #include <lib/extensions/ras.h>
 #endif
+#include <lib/extensions/twed.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
@@ -20,6 +21,7 @@
  * platforms but may also be overridden by a platform if required.
  */
 #pragma weak bl31_plat_runtime_setup
+#pragma weak plat_arm_set_twedel_scr_el3
 
 #if SDEI_SUPPORT
 #pragma weak plat_sdei_handle_masked_trigger
@@ -100,3 +102,16 @@
 #endif
 	panic();
 }
+
+/*******************************************************************************
+ * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
+ * is a weak function definition so can be overridden depending on the
+ * requirements of a platform.  The only hook provided is for the TWED fields
+ * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
+ * configured as needed in lower exception levels.
+ ******************************************************************************/
+
+uint32_t plat_arm_set_twedel_scr_el3(void)
+{
+	return TWED_DISABLED;
+}
diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S
index f9780e8..e2d71da 100644
--- a/plat/common/aarch64/platform_mp_stack.S
+++ b/plat/common/aarch64/platform_mp_stack.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,9 +32,41 @@
 	 * -----------------------------------------------------
 	 */
 func plat_get_my_stack
-	mov	x10, x30 // lr
+#if (defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
+#if (PLATFORM_CORE_COUNT == 1)
+	/* Single CPU */
+	adrp	x0, __PRIMARY_STACK__
+	add	x0, x0, :lo12:__PRIMARY_STACK__
+	ret
+#else
+	mov	x10, x30
+	bl	plat_my_core_pos
+	cbnz	x0, 2f
+
+	/* Primary CPU */
+	adrp	x0, __PRIMARY_STACK__
+	add	x0, x0, :lo12:__PRIMARY_STACK__
+	ret	x10
+
+	/* Secondary CPU */
+2:	sub	x0, x0, #(PLATFORM_CORE_COUNT - 1)
+	adrp	x1, __STACKS_END__
+	adrp	x2, __STACK_SIZE__
+	add	x1, x1, :lo12:__STACKS_END__
+	add	x2, x2, :lo12:__STACK_SIZE__
+
+	madd	x0, x0, x2, x1
+	bic	x0, x0, #(CACHE_WRITEBACK_GRANULE - 1)
+	ret	x10
+#endif
+	.word	platform_normal_stacks
+
+#else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */
+	mov	x10, x30
 	get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
 	ret	x10
+
+#endif /* IMAGE_BL31 && RECLAIM_INIT_CODE */
 endfunc plat_get_my_stack
 
 	/* -----------------------------------------------------
@@ -45,14 +77,14 @@
 	 * -----------------------------------------------------
 	 */
 func plat_set_my_stack
-	mov	x9, x30 // lr
+	mov	x9, x30
 	bl 	plat_get_my_stack
 	mov	sp, x0
 	ret	x9
 endfunc plat_set_my_stack
 
 	/* -----------------------------------------------------
-	 * Per-cpu stacks in normal memory. Each cpu gets a
+	 * Per-CPU stacks in normal memory. Each CPU gets a
 	 * stack of PLATFORM_STACK_SIZE bytes.
 	 * -----------------------------------------------------
 	 */
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index 8330356..455b980 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -5,65 +5,79 @@
  */
 
 #include <assert.h>
+#include <errno.h>
 #include <string.h>
 #include <libfdt.h>
 
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
-#include <errno.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <platform_def.h>
 #include <services/spm_core_manifest.h>
 
+#define ATTRIBUTE_ROOT_NODE_STR "attribute"
+
 /*******************************************************************************
- * Attribute section handler
+ * SPMC attribute node parser
  ******************************************************************************/
-static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
+static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
 				    const void *fdt,
 				    int node)
 {
 	uint32_t val32;
-	int rc = 0;
+	int rc;
 
-	assert(attr && fdt);
+	assert((attr != NULL) && (fdt != NULL));
 
 	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
-	if (rc) {
-		ERROR("Missing SPCI major version in SPM core manifest.\n");
-		return -ENOENT;
+	if (rc != 0) {
+		ERROR("Missing FFA %s version in SPM Core manifest.\n",
+			"major");
+		return rc;
 	}
 
 	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
-	if (rc) {
-		ERROR("Missing SPCI minor version in SPM core manifest.\n");
-		return -ENOENT;
+	if (rc != 0) {
+		ERROR("Missing FFA %s version in SPM Core manifest.\n",
+			"minor");
+		return rc;
 	}
 
 	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
-	if (rc) {
+	if (rc != 0) {
 		ERROR("Missing SPMC ID in manifest.\n");
-		return -ENOENT;
+		return rc;
 	}
-	attr->spmc_id = val32;
+
+	attr->spmc_id = val32 & 0xffff;
 
 	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
-	if (rc)
-		NOTICE("Execution state not specified in SPM core manifest.\n");
+	if (rc != 0) {
+		NOTICE("%s not specified in SPM Core manifest.\n",
+			"Execution state");
+	}
 
 	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
-	if (rc)
-		NOTICE("Binary size not specified in SPM core manifest.\n");
+	if (rc != 0) {
+		NOTICE("%s not specified in SPM Core manifest.\n",
+			"Binary size");
+	}
 
 	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
-	if (rc)
-		NOTICE("Load address not specified in SPM core manifest.\n");
+	if (rc != 0) {
+		NOTICE("%s not specified in SPM Core manifest.\n",
+			"Load address");
+	}
 
 	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
-	if (rc)
-		NOTICE("Entrypoint not specified in SPM core manifest.\n");
+	if (rc != 0) {
+		NOTICE("%s not specified in SPM Core manifest.\n",
+			"Entry point");
+	}
 
-	VERBOSE("SPM core manifest attribute section:\n");
-	VERBOSE("  version: %x.%x\n", attr->major_version, attr->minor_version);
-	VERBOSE("  spmc_id: %x\n", attr->spmc_id);
+	VERBOSE("SPM Core manifest attribute section:\n");
+	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
+	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
 	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
 	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
@@ -74,53 +88,98 @@
 /*******************************************************************************
  * Root node handler
  ******************************************************************************/
-static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
-				const void *fdt,
-				int root)
+static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
+			       const void *fdt,
+			       int root)
 {
 	int node;
-	char *str;
 
-	str = "attribute";
-	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
+	assert(manifest != NULL);
+
+	node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
+		sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
 	if (node < 0) {
-		ERROR("Root node doesn't contain subnode '%s'\n", str);
-		return -ENOENT;
+		ERROR("Root node doesn't contain subnode '%s'\n",
+			ATTRIBUTE_ROOT_NODE_STR);
+		return node;
 	}
 
 	return manifest_parse_attribute(manifest, fdt, node);
 }
 
 /*******************************************************************************
- * Platform handler to parse a SPM core manifest.
+ * Platform handler to parse a SPM Core manifest.
  ******************************************************************************/
-int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
-				const void *ptr,
-				size_t size)
+int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
+				const void *pm_addr)
 {
-	int rc;
-	int root_node;
+	int rc, unmap_ret;
+	uintptr_t pm_base, pm_base_align;
+	size_t mapped_size;
 
 	assert(manifest != NULL);
-	assert(ptr != NULL);
+	assert(pm_addr != NULL);
 
-	INFO("Reading SPM core manifest at address %p\n", ptr);
+	/*
+	 * Assume TOS_FW_CONFIG is not necessarily aligned to a page
+	 * boundary, thus calculate the remaining space between SPMC
+	 * manifest start address and upper page limit.
+	 *
+	 */
+	pm_base = (uintptr_t)pm_addr;
+	pm_base_align = page_align(pm_base, UP);
+	mapped_size = pm_base_align - pm_base;
 
-	rc = fdt_check_header(ptr);
-	if (rc != 0) {
-		ERROR("Wrong format for SPM core manifest (%d).\n", rc);
+	/* Check space within the page at least maps the FDT header */
+	if (mapped_size < sizeof(struct fdt_header)) {
+		ERROR("Error while mapping SPM Core manifest.\n");
 		return -EINVAL;
 	}
 
+	/* Map first SPMC manifest page in the SPMD translation regime */
+	pm_base_align = page_align(pm_base, DOWN);
+	rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
+				     pm_base_align,
+				     PAGE_SIZE,
+				     MT_RO_DATA);
+	if (rc != 0) {
+		ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
+		return rc;
+	}
+
+	rc = fdt_check_header(pm_addr);
+	if (rc != 0) {
+		ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
+		goto exit_unmap;
+	}
+
+	/* Check SPMC manifest fits within the upper mapped page boundary */
+	if (mapped_size < fdt_totalsize(pm_addr)) {
+		ERROR("SPM Core manifest too large.\n");
+		rc = -EINVAL;
+		goto exit_unmap;
+	}
+
+	VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr);
+
+	rc = fdt_node_offset_by_compatible(pm_addr, -1,
+				"arm,ffa-core-manifest-1.0");
+	if (rc < 0) {
+		ERROR("Unrecognized SPM Core manifest\n");
+		goto exit_unmap;
+	}
+
-	INFO("Reading SPM core manifest at address %p\n", ptr);
+	rc = manifest_parse_root(manifest, pm_addr, rc);
 
-	root_node = fdt_node_offset_by_compatible(ptr, -1,
-				"arm,spci-core-manifest-1.0");
-	if (root_node < 0) {
-		ERROR("Unrecognized SPM core manifest\n");
-		return -ENOENT;
+exit_unmap:
+	unmap_ret = mmap_remove_dynamic_region(pm_base_align, PAGE_SIZE);
+	if (unmap_ret != 0) {
+		ERROR("Error while unmapping SPM Core manifest (%d).\n",
+			unmap_ret);
+		if (rc == 0) {
+			rc = unmap_ret;
+		}
 	}
 
-	INFO("Reading SPM core manifest at address %p\n", ptr);
-	return manifest_parse_root(manifest, ptr, root_node);
+	return rc;
 }
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index fbf7432..18197cf 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -126,17 +126,19 @@
 AUTH_SOURCES		:=	drivers/auth/auth_mod.c			\
 				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
-				drivers/auth/tbbr/tbbr_cot.c
+				drivers/auth/tbbr/tbbr_cot_common.c
 
 BL1_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/hisilicon/hikey/hikey_tbbr.c	\
-				plat/hisilicon/hikey/hikey_rotpk.S
+				plat/hisilicon/hikey/hikey_rotpk.S	\
+				drivers/auth/tbbr/tbbr_cot_bl1.c
 
 BL2_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/hisilicon/hikey/hikey_tbbr.c	\
-				plat/hisilicon/hikey/hikey_rotpk.S
+				plat/hisilicon/hikey/hikey_rotpk.S	\
+				drivers/auth/tbbr/tbbr_cot_bl2.c
 
 ROT_KEY		=	$(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH		=	$(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 8ebabeb..fc2c209 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -118,17 +118,19 @@
 AUTH_SOURCES		:=	drivers/auth/auth_mod.c			\
 				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
-				drivers/auth/tbbr/tbbr_cot.c
+				drivers/auth/tbbr/tbbr_cot_common.c
 
 BL1_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/hisilicon/hikey960/hikey960_tbbr.c	\
-				plat/hisilicon/hikey960/hikey960_rotpk.S
+				plat/hisilicon/hikey960/hikey960_rotpk.S \
+				drivers/auth/tbbr/tbbr_cot_bl1.c
 
 BL2_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/hisilicon/hikey960/hikey960_tbbr.c	\
-				plat/hisilicon/hikey960/hikey960_rotpk.S
+				plat/hisilicon/hikey960/hikey960_rotpk.S \
+				drivers/auth/tbbr/tbbr_cot_bl2.c
 
 ROT_KEY		=	$(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH		=	$(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 849ddcd..3a95772 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -58,12 +58,13 @@
 AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
 			drivers/auth/crypto_mod.c		\
 			drivers/auth/img_parser_mod.c		\
-			drivers/auth/tbbr/tbbr_cot.c
+			drivers/auth/tbbr/tbbr_cot_common.c
 
 BL2_SOURCES		+=	${AUTH_SOURCES}					\
 				plat/common/tbbr/plat_tbbr.c			\
 				plat/imx/imx7/common/imx7_trusted_boot.c	\
-				plat/imx/imx7/common/imx7_rotpk.S
+				plat/imx/imx7/common/imx7_rotpk.S		\
+				drivers/auth/tbbr/tbbr_cot_bl2.c
 
 ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
new file mode 100644
index 0000000..37d4226
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/smccc.h>
+#include <services/std_svc.h>
+
+#include <gpc.h>
+#include <imx_sip_svc.h>
+#include <platform_def.h>
+
+#define CCGR(x)		(0x4000 + (x) * 0x10)
+
+void imx_gpc_init(void)
+{
+	unsigned int val;
+	int i;
+
+	/* mask all the wakeup irq by default */
+	for (i = 0; i < 4; i++) {
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
+	}
+
+	val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
+	/* use GIC wake_request to wakeup C0~C3 from LPM */
+	val |= CORE_WKUP_FROM_GIC;
+	/* clear the MASTER0 LPM handshake */
+	val &= ~MASTER0_LPM_HSK;
+	mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
+
+	/* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
+	mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
+		MASTER2_MAPPING));
+
+	/* set all mix/PU in A53 domain */
+	mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff);
+
+	/*
+	 * Set the CORE & SCU power up timing:
+	 * SW = 0x1, SW2ISO = 0x1;
+	 * the CPU CORE and SCU power up timming counter
+	 * is drived  by 32K OSC, each domain's power up
+	 * latency is (SW + SW2ISO) / 32768
+	 */
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401);
+	mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401);
+	mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
+		      (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT));
+
+	/* set DUMMY PDN/PUP ACK by default for A53 domain */
+	mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
+		      A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
+
+	/* clear DSM by default */
+	val = mmio_read_32(IMX_GPC_BASE + SLPCR);
+	val &= ~SLPCR_EN_DSM;
+	/* enable the fast wakeup wait mode */
+	val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+	/* clear the RBC */
+	val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
+	/* set the STBY_COUNT to 0x5, (128 * 30)us */
+	val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
+	val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
+	mmio_write_32(IMX_GPC_BASE + SLPCR, val);
+
+	/*
+	 * USB PHY power up needs to make sure RESET bit in SRC is clear,
+	 * otherwise, the PU power up bit in GPC will NOT self-cleared.
+	 * only need to do it once.
+	 */
+	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
+
+	/* enable all the power domain by default */
+	for (i = 0; i < 103; i++)
+		mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
+	mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485);
+}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
new file mode 100644
index 0000000..d4705ee
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/arm/tzc380.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <gpc.h>
+#include <imx_aipstz.h>
+#include <imx_uart.h>
+#include <imx_rdc.h>
+#include <imx8m_caam.h>
+#include <platform_def.h>
+#include <plat_imx8.h>
+
+static const mmap_region_t imx_mmap[] = {
+	GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0},
+};
+
+static const struct aipstz_cfg aipstz[] = {
+	{IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+	{IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+	{IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+	{IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+	{0},
+};
+
+static const struct imx_rdc_cfg rdc[] = {
+	/* Master domain assignment */
+	RDC_MDAn(0x1, DID1),
+
+	/* peripherals domain permission */
+
+	/* memory region */
+	RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff),
+	RDC_MEM_REGIONn(17, 0x0, 0x0, 0xff),
+	RDC_MEM_REGIONn(18, 0x0, 0x0, 0xff),
+
+	/* Sentinel */
+	{0},
+};
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* get SPSR for BL33 entry */
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned long mode;
+	uint32_t spsr;
+
+	/* figure out what mode we enter the non-secure world */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+static void bl31_tzc380_setup(void)
+{
+	unsigned int val;
+
+	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28);
+	if ((val & GPR_TZASC_EN) != GPR_TZASC_EN)
+		return;
+
+	tzc380_init(IMX_TZASC_BASE);
+
+	/*
+	 * Need to substact offset 0x40000000 from CPU address when
+	 * programming tzasc region for i.mx8mn.
+	 */
+
+	/* Enable 1G-5G S/NS RW */
+	tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) |
+		TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+		u_register_t arg2, u_register_t arg3)
+{
+	static console_t console;
+	int i;
+
+	/* Enable CSU NS access permission */
+	for (i = 0; i < 64; i++) {
+		mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff);
+	}
+
+	imx_aipstz_init(aipstz);
+
+	imx_rdc_init(rdc);
+
+	imx8m_caam_init();
+
+	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+		IMX_CONSOLE_BAUDRATE, &console);
+	/* This console is only used for boot stage */
+	console_set_scope(&console, CONSOLE_FLAG_BOOT);
+
+	/*
+	 * tell BL3-1 where the non-secure software image is located
+	 * and the entry state information.
+	 */
+	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#ifdef SPD_opteed
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+
+	/* Pass TEE base and size to bl33 */
+	bl33_image_ep_info.args.arg1 = BL32_BASE;
+	bl33_image_ep_info.args.arg2 = BL32_SIZE;
+#endif
+
+	bl31_tzc380_setup();
+}
+
+void bl31_plat_arch_setup(void)
+{
+	mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE),
+		MT_MEMORY | MT_RW | MT_SECURE);
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE),
+		MT_MEMORY | MT_RO | MT_SECURE);
+#if USE_COHERENT_MEM
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+		(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
+		MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+	mmap_add(imx_mmap);
+
+	init_xlat_tables();
+
+	enable_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+	generic_delay_timer_init();
+
+	/* select the CKIL source to 32K OSC */
+	mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	imx_gpc_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	if (type == NON_SECURE)
+		return &bl33_image_ep_info;
+	if (type == SECURE)
+		return &bl32_image_ep_info;
+
+	return NULL;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_psci.c b/plat/imx/imx8m/imx8mn/imx8mn_psci.c
new file mode 100644
index 0000000..f541fc1
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/imx8mn_psci.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <gpc.h>
+#include <imx8m_psci.h>
+#include <plat_imx8.h>
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+	.pwr_domain_on = imx_pwr_domain_on,
+	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
+	.pwr_domain_off = imx_pwr_domain_off,
+	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+	.validate_power_state = imx_validate_power_state,
+	.cpu_standby = imx_cpu_standby,
+	.pwr_domain_suspend = imx_domain_suspend,
+	.pwr_domain_suspend_finish = imx_domain_suspend_finish,
+	.pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi,
+	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+	.system_reset = imx_system_reset,
+	.system_off = imx_system_off,
+};
+
+/* export the platform specific psci ops */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	/* sec_entrypoint is used for warm reset */
+	imx_mailbox_init(sec_entrypoint);
+
+	*psci_ops = &imx_plat_psci_ops;
+
+	return 0;
+}
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
new file mode 100644
index 0000000..2444e66
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLATFORM_STACK_SIZE		0xB00
+#define CACHE_WRITEBACK_GRANULE		64
+
+#define PLAT_PRIMARY_CPU		U(0x0)
+#define PLATFORM_MAX_CPU_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	U(4)
+#define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define IMX_PWR_LVL0			MPIDR_AFFLVL0
+#define IMX_PWR_LVL1			MPIDR_AFFLVL1
+#define IMX_PWR_LVL2			MPIDR_AFFLVL2
+
+#define PWR_DOMAIN_AT_MAX_LVL		U(1)
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_OFF_STATE		U(4)
+#define PLAT_MAX_RET_STATE		U(2)
+
+#define PLAT_WAIT_RET_STATE		U(1)
+#define PLAT_STOP_OFF_STATE		U(3)
+
+#define BL31_BASE			U(0x960000)
+#define BL31_LIMIT			U(0x980000)
+
+/* non-secure uboot base */
+#define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+
+/* GICv3 base address */
+#define PLAT_GICD_BASE			U(0x38800000)
+#define PLAT_GICR_BASE			U(0x38880000)
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+
+#define MAX_XLAT_TABLES			8
+#define MAX_MMAP_REGIONS		16
+
+#define HAB_RVT_BASE			U(0x00000900) /* HAB_RVT for i.MX8MM */
+
+#define IMX_BOOT_UART_CLK_IN_HZ		24000000 /* Select 24MHz oscillator */
+#define PLAT_CRASH_UART_BASE		IMX_BOOT_UART_BASE
+#define PLAT_CRASH_UART_CLK_IN_HZ	24000000
+#define IMX_CONSOLE_BAUDRATE		115200
+
+#define IMX_AIPSTZ1			U(0x301f0000)
+#define IMX_AIPSTZ2			U(0x305f0000)
+#define IMX_AIPSTZ3			U(0x309f0000)
+#define IMX_AIPSTZ4			U(0x32df0000)
+
+#define IMX_AIPS_BASE			U(0x30000000)
+#define IMX_AIPS_SIZE			U(0xC00000)
+#define IMX_GPV_BASE			U(0x32000000)
+#define IMX_GPV_SIZE			U(0x800000)
+#define IMX_AIPS1_BASE			U(0x30200000)
+#define IMX_AIPS4_BASE			U(0x32c00000)
+#define IMX_ANAMIX_BASE			U(0x30360000)
+#define IMX_CCM_BASE			U(0x30380000)
+#define IMX_SRC_BASE			U(0x30390000)
+#define IMX_GPC_BASE			U(0x303a0000)
+#define IMX_RDC_BASE			U(0x303d0000)
+#define IMX_CSU_BASE			U(0x303e0000)
+#define IMX_WDOG_BASE			U(0x30280000)
+#define IMX_SNVS_BASE			U(0x30370000)
+#define IMX_NOC_BASE			U(0x32700000)
+#define IMX_TZASC_BASE			U(0x32F80000)
+#define IMX_IOMUX_GPR_BASE		U(0x30340000)
+#define IMX_CAAM_BASE			U(0x30900000)
+#define IMX_DDRC_BASE			U(0x3d400000)
+#define IMX_DDRPHY_BASE			U(0x3c000000)
+#define IMX_DDR_IPS_BASE		U(0x3d000000)
+#define IMX_DDR_IPS_SIZE		U(0x1800000)
+#define IMX_ROM_BASE			U(0x0)
+
+#define IMX_GIC_BASE			PLAT_GICD_BASE
+#define IMX_GIC_SIZE			U(0x200000)
+
+#define WDOG_WSR			U(0x2)
+#define WDOG_WCR_WDZST			BIT(0)
+#define WDOG_WCR_WDBG			BIT(1)
+#define WDOG_WCR_WDE			BIT(2)
+#define WDOG_WCR_WDT			BIT(3)
+#define WDOG_WCR_SRS			BIT(4)
+#define WDOG_WCR_WDA			BIT(5)
+#define WDOG_WCR_SRE			BIT(6)
+#define WDOG_WCR_WDW			BIT(7)
+
+#define SRC_A53RCR0			U(0x4)
+#define SRC_A53RCR1			U(0x8)
+#define SRC_OTG1PHY_SCR			U(0x20)
+#define SRC_GPR1_OFFSET			U(0x74)
+
+#define SNVS_LPCR			U(0x38)
+#define SNVS_LPCR_SRTC_ENV		BIT(0)
+#define SNVS_LPCR_DP_EN			BIT(5)
+#define SNVS_LPCR_TOP			BIT(6)
+
+#define IOMUXC_GPR10			U(0x28)
+#define GPR_TZASC_EN			BIT(0)
+#define GPR_TZASC_EN_LOCK		BIT(16)
+
+#define ANAMIX_MISC_CTL			U(0x124)
+#define DRAM_PLL_CTRL			(IMX_ANAMIX_BASE + 0x50)
+
+#define MAX_CSU_NUM			U(64)
+
+#define OCRAM_S_BASE			U(0x00180000)
+#define OCRAM_S_SIZE			U(0x8000)
+#define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
+#define SAVED_DRAM_TIMING_BASE		OCRAM_S_BASE
+
+#define COUNTER_FREQUENCY		8000000 /* 8MHz */
+
+#define IMX_WDOG_B_RESET
+
+#define GIC_MAP		MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW)
+#define AIPS_MAP	MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
+#define OCRAM_S_MAP	MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW) /* OCRAM_S */
+#define DDRC_MAP	MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
+
+#endif /* platform_def.h */
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
new file mode 100644
index 0000000..8c4ad1c
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -0,0 +1,56 @@
+#
+# Copyright 2019-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		:=	-Iplat/imx/common/include		\
+				-Iplat/imx/imx8m/include		\
+				-Iplat/imx/imx8m/imx8mn/include
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
+				plat/common/plat_gicv3.c		\
+				plat/common/plat_psci_common.c		\
+				plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+				plat/imx/imx8m/gpc_common.c			\
+				plat/imx/imx8m/imx_aipstz.c			\
+				plat/imx/imx8m/imx_rdc.c			\
+				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_psci_common.c		\
+				plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c	\
+				plat/imx/imx8m/imx8mn/imx8mn_psci.c		\
+				plat/imx/imx8m/imx8mn/gpc.c			\
+				plat/imx/common/imx8_topology.c			\
+				plat/imx/common/imx_sip_handler.c		\
+				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_uart_console.S		\
+				lib/cpus/aarch64/cortex_a53.S			\
+				drivers/arm/tzc/tzc380.c			\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				${IMX_GIC_SOURCES}				\
+				${XLAT_TABLES_LIB_SRCS}
+
+USE_COHERENT_MEM	:=	1
+RESET_TO_BL31		:=	1
+A53_DISABLE_NON_TEMPORAL_HINT := 0
+
+ERRATA_A53_835769	:=	1
+ERRATA_A53_843419	:=	1
+ERRATA_A53_855873	:=	1
+
+BL32_BASE		?=	0xbe000000
+$(eval $(call add_define,BL32_BASE))
+
+BL32_SIZE		?=	0x2000000
+$(eval $(call add_define,BL32_SIZE))
+
+IMX_BOOT_UART_BASE	?=	0x30890000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 139132c..6033b0d 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -39,6 +39,7 @@
 #define IRQ_SRC_C0			BIT(28)
 #define IRQ_SRC_C3			BIT(23)
 #define IRQ_SRC_C2			BIT(22)
+#define CORE_WKUP_FROM_GIC		(IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3)
 #define CPU_CLOCK_ON_LPM		BIT(14)
 #define A53_CLK_ON_LPM			BIT(14)
 #define MASTER0_LPM_HSK			BIT(6)
@@ -71,6 +72,10 @@
 #define MASTER1_MAPPING			BIT(1)
 #define MASTER2_MAPPING			BIT(2)
 
+#define TMR_TCD2_SHIFT			0
+#define TMC_TMR_SHIFT			10
+#define TRC1_TMC_SHIFT			20
+
 /* helper macro */
 #define A53_LPM_MASK	U(0xF)
 #define A53_LPM_WAIT	U(0x5)
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index c946a75..a86a315 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -27,8 +28,14 @@
 				${COMMON_DIR}/lib/debug/profiler.c		\
 				${COMMON_DIR}/tegra_bl31_setup.c		\
 				${COMMON_DIR}/tegra_delay_timer.c		\
+				${COMMON_DIR}/tegra_ehf.c			\
 				${COMMON_DIR}/tegra_fiq_glue.c			\
 				${COMMON_DIR}/tegra_io_storage.c		\
 				${COMMON_DIR}/tegra_platform.c			\
 				${COMMON_DIR}/tegra_pm.c			\
-				${COMMON_DIR}/tegra_sip_calls.c
+				${COMMON_DIR}/tegra_sip_calls.c			\
+				${COMMON_DIR}/tegra_sdei.c
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+BL31_SOURCES		+=	${COMMON_DIR}/tegra_stack_protector.c
+endif
diff --git a/plat/nvidia/tegra/common/tegra_ehf.c b/plat/nvidia/tegra/common/tegra_ehf.c
new file mode 100644
index 0000000..ea6e443
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_ehf.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+
+/*
+ * Enumeration of priority levels on Tegra platforms.
+ */
+ehf_pri_desc_t tegra_exceptions[] = {
+	/* Watchdog priority */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO),
+
+#if SDEI_SUPPORT
+	/* Critical priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+	/* Normal priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+#endif
+};
+
+/* Plug in Tegra exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(tegra_exceptions, ARRAY_SIZE(tegra_exceptions), PLAT_PRI_BITS);
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index bb5add8..5309d98 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -26,15 +26,6 @@
 /* Legacy FIQ used by earlier Tegra platforms */
 #define LEGACY_FIQ_PPI_WDT		28U
 
-/* Install priority level descriptors for each dispatcher */
-ehf_pri_desc_t plat_exceptions[] = {
-	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO),
-};
-
-/* Expose priority descriptors to Exception Handling Framework */
-EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions),
-	PLAT_PRI_BITS);
-
 /*******************************************************************************
  * Static variables
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index c1e4209..e4338b9 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -259,3 +260,29 @@
 {
 	return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
 }
+
+/*
+ * This function returns soc version which mainly consist of below fields
+ *
+ *  soc_version[30:24] = JEP-106 continuation code for the SiP
+ *  soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
+ *  soc_version[0:15]  = chip identification
+ */
+int32_t plat_get_soc_version(void)
+{
+	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
+	uint32_t manfid = (JEDEC_NVIDIA_BKID << 24) | (JEDEC_NVIDIA_MFID << 16);
+
+	return (int32_t)(manfid | (chip_id & 0xFFFF));
+}
+
+/*
+ * This function returns soc revision in below format
+ *
+ *   soc_revision[8:15] = major version number
+ *   soc_revision[0:7]  = minor version number
+ */
+int32_t plat_get_soc_revision(void)
+{
+	return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor());
+}
diff --git a/plat/nvidia/tegra/common/tegra_sdei.c b/plat/nvidia/tegra/common/tegra_sdei.c
new file mode 100644
index 0000000..9241b81
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_sdei.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for Tegra platforms */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+
+/* Private event mappings */
+static sdei_ev_map_t tegra_sdei_private[] = {
+	/* Event 0 definition */
+	SDEI_DEFINE_EVENT_0(TEGRA_SDEI_SGI_PRIVATE),
+
+	/* Dynamic private events */
+	SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+	SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+	SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+
+	/* General purpose explicit events */
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_0, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_1, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_2, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_3, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_4, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_5, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_6, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_7, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_8, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_9, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_10, SDEI_MAPF_CRITICAL),
+	SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_11, SDEI_MAPF_CRITICAL)
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t tegra_sdei_shared[] = {
+	/* Dynamic shared events */
+	SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+	SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+	SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+};
+
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+
+/* Export Tegra SDEI events */
+REGISTER_SDEI_MAP(tegra_sdei_private, tegra_sdei_shared);
diff --git a/plat/nvidia/tegra/common/tegra_stack_protector.c b/plat/nvidia/tegra/common/tegra_stack_protector.c
new file mode 100644
index 0000000..f6c459a
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_stack_protector.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	u_register_t seed;
+
+	/*
+	 * Ideally, a random number should be returned instead. As the
+	 * platform does not have any random number generator, this is
+	 * better than nothing, but not really secure.
+	 */
+	seed = mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET);
+	seed <<= 32;
+	seed |= mmio_read_32(TEGRA_TMRUS_BASE);
+
+	return seed ^ read_cntpct_el0();
+}
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 6bfad23..678b15c 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -87,9 +87,43 @@
 #define MAX_IO_HANDLES			U(0)
 
 /*******************************************************************************
+ * Platforms macros to support SDEI
+ ******************************************************************************/
+#define TEGRA_SDEI_SGI_PRIVATE		U(8)
+
+/*******************************************************************************
  * Platform macros to support exception handling framework
  ******************************************************************************/
 #define PLAT_PRI_BITS			U(3)
+#define PLAT_SDEI_CRITICAL_PRI		U(0x20)
+#define PLAT_SDEI_NORMAL_PRI		U(0x30)
 #define PLAT_TEGRA_WDT_PRIO		U(0x40)
 
+/*******************************************************************************
+ * SDEI events
+ ******************************************************************************/
+/* SDEI dynamic private event numbers */
+#define TEGRA_SDEI_DP_EVENT_0		U(100)
+#define TEGRA_SDEI_DP_EVENT_1		U(101)
+#define TEGRA_SDEI_DP_EVENT_2		U(102)
+
+/* SDEI dynamic shared event numbers */
+#define TEGRA_SDEI_DS_EVENT_0		U(200)
+#define TEGRA_SDEI_DS_EVENT_1		U(201)
+#define TEGRA_SDEI_DS_EVENT_2		U(202)
+
+/* SDEI explicit events */
+#define TEGRA_SDEI_EP_EVENT_0		U(300)
+#define TEGRA_SDEI_EP_EVENT_1		U(301)
+#define TEGRA_SDEI_EP_EVENT_2		U(302)
+#define TEGRA_SDEI_EP_EVENT_3		U(303)
+#define TEGRA_SDEI_EP_EVENT_4		U(304)
+#define TEGRA_SDEI_EP_EVENT_5		U(305)
+#define TEGRA_SDEI_EP_EVENT_6		U(306)
+#define TEGRA_SDEI_EP_EVENT_7		U(307)
+#define TEGRA_SDEI_EP_EVENT_8		U(308)
+#define TEGRA_SDEI_EP_EVENT_9		U(309)
+#define TEGRA_SDEI_EP_EVENT_10		U(310)
+#define TEGRA_SDEI_EP_EVENT_11		U(311)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index d83ce48..7dfa4d0 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,6 +31,12 @@
 #define TEGRA_CHIPID_TEGRA21		U(0x21)
 #define TEGRA_CHIPID_TEGRA18		U(0x18)
 
+/*******************************************************************************
+ * JEDEC Standard Manufacturer's Identification Code and Bank ID
+ ******************************************************************************/
+#define JEDEC_NVIDIA_MFID		U(0x6B)
+#define JEDEC_NVIDIA_BKID		U(3)
+
 #ifndef __ASSEMBLER__
 
 /*
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index e03e1f3..3d61f06 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -49,6 +49,12 @@
 # Flag to allow relocation of BL32 image to TZDRAM during boot
 RELOCATE_BL32_IMAGE		?= 0
 
+# Enable stack protection
+ENABLE_STACK_PROTECTOR		:=	strong
+
+# Enable SDEI
+SDEI_SUPPORT			:= 1
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
@@ -63,6 +69,7 @@
 
 # override with necessary libc files for the Tegra platform
 override LIBC_SRCS :=	$(addprefix lib/libc/,		\
+			aarch64/setjmp.S		\
 			assert.c			\
 			memcpy.c			\
 			memmove.c			\
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 1c7c25d..c216b5d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -214,6 +214,8 @@
 
 /* Secure IRQs for Tegra186 */
 static const interrupt_prop_t tegra186_interrupt_props[] = {
+	INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index ce5815b..e226372 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -73,19 +73,16 @@
 	switch (state_id) {
 	case PSTATE_ID_CORE_IDLE:
 
+		if (psci_get_pstate_type(power_state) != PSTATE_TYPE_STANDBY) {
+			ret = PSCI_E_INVALID_PARAMS;
+			break;
+		}
+
 		/* Core idle request */
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
 		req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN;
 		break;
 
-	case PSTATE_ID_CORE_POWERDN:
-
-		/* Core powerdown request */
-		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
-		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
-
-		break;
-
 	default:
 		ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
 		ret = PSCI_E_INVALID_PARAMS;
@@ -117,7 +114,7 @@
 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	const plat_local_state_t *pwr_domain_state;
-	uint8_t stateid_afflvl0, stateid_afflvl2;
+	uint8_t stateid_afflvl2;
 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	uint64_t mc_ctx_base;
 	uint32_t val;
@@ -128,25 +125,14 @@
 		.system_state_force = 1U,
 		.update_wake_mask = 1U,
 	};
-	uint32_t cpu = plat_my_core_pos();
 	int32_t ret = 0;
 
 	/* get the state ID */
 	pwr_domain_state = target_state->pwr_domain_state;
-	stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
-		TEGRA194_STATE_ID_MASK;
 	stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA194_STATE_ID_MASK;
 
-	if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
-
-		/* Enter CPU powerdown */
-		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
-					  (uint64_t)TEGRA_NVG_CORE_C7,
-					  t19x_percpu_data[cpu].wake_time,
-					  0U);
-
-	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
 		/* save 'Secure Boot' Processor Feature Config Register */
 		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
@@ -187,8 +173,6 @@
 
 		/* set system suspend state for house-keeping */
 		tegra194_set_system_suspend_entry();
-	} else {
-		; /* do nothing */
 	}
 
 	return PSCI_E_SUCCESS;
@@ -226,15 +210,6 @@
 	plat_local_state_t target = states[core_pos];
 	mce_cstate_info_t cstate_info = { 0 };
 
-	/* CPU suspend */
-	if (target == PSTATE_ID_CORE_POWERDN) {
-
-		/* Program default wake mask */
-		cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK;
-		cstate_info.update_wake_mask = 1;
-		mce_update_cstate_info(&cstate_info);
-	}
-
 	/* CPU off */
 	if (target == PLAT_MAX_OFF_STATE) {
 
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index f90a69e..5d6c60b 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -275,6 +275,8 @@
 
 /* Secure IRQs for Tegra194 */
 static const interrupt_prop_t tegra194_interrupt_props[] = {
+	INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index 930eeac..f2b267b 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -179,6 +179,8 @@
 
 /* Secure IRQs for Tegra186 */
 static const interrupt_prop_t tegra210_interrupt_props[] = {
+	INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, PLAT_TEGRA_WDT_PRIO,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 1bf4e08..9441437 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -59,18 +59,20 @@
     AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
 				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
-				drivers/auth/tbbr/tbbr_cot.c
+				drivers/auth/tbbr/tbbr_cot_common.c
 
     BL1_SOURCES		+=	${AUTH_SOURCES}				\
 				bl1/tbbr/tbbr_img_desc.c		\
 				plat/common/tbbr/plat_tbbr.c		\
 				${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c	     	\
-				$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S
+				$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S	\
+				drivers/auth/tbbr/tbbr_cot_bl1.c
 
     BL2_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c	     	\
-				$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S
+				$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S	\
+				drivers/auth/tbbr/tbbr_cot_bl2.c
 
     ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
     ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index bcfc34e..4d627b8 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -185,18 +185,20 @@
     AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
 				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
-				drivers/auth/tbbr/tbbr_cot.c
+				drivers/auth/tbbr/tbbr_cot_common.c
 
     BL1_SOURCES		+=	${AUTH_SOURCES}				\
 				bl1/tbbr/tbbr_img_desc.c		\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/rpi/common/rpi3_trusted_boot.c    	\
-				plat/rpi/common/rpi3_rotpk.S
+				plat/rpi/common/rpi3_rotpk.S		\
+				drivers/auth/tbbr/tbbr_cot_bl1.c
 
     BL2_SOURCES		+=	${AUTH_SOURCES}				\
 				plat/common/tbbr/plat_tbbr.c		\
 				plat/rpi/common/rpi3_trusted_boot.c    	\
-				plat/rpi/common/rpi3_rotpk.S
+				plat/rpi/common/rpi3_rotpk.S		\
+				drivers/auth/tbbr/tbbr_cot_bl2.c
 
     ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
     ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 2c0ed92..6edd181 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -92,7 +92,8 @@
 BL2_SOURCES		+=	drivers/auth/auth_mod.c			\
 				drivers/auth/crypto_mod.c		\
 				drivers/auth/img_parser_mod.c		\
-				drivers/auth/tbbr/tbbr_cot.c		\
+				drivers/auth/tbbr/tbbr_cot_common.c	\
+				drivers/auth/tbbr/tbbr_cot_bl2.c	\
 				plat/common/tbbr/plat_tbbr.c		\
 				$(PLAT_PATH)/uniphier_rotpk.S		\
 				$(PLAT_PATH)/uniphier_tbbr.c
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 27ddab0..feeb4a7 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -61,6 +61,9 @@
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
 
+/* Return node offset for target GPIO bank ID @bank or a FDT error code */
+int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank);
+
 /* Print CPU information */
 void stm32mp_print_cpuinfo(void);
 
diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h
index e79551a..44ad820 100644
--- a/plat/st/common/include/stm32mp_dt.h
+++ b/plat/st/common/include/stm32mp_dt.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved
  * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -39,5 +40,6 @@
 uint32_t dt_get_pwr_vdd_voltage(void);
 uintptr_t dt_get_syscfg_base(void);
 const char *dt_get_board_model(void);
+int fdt_get_gpio_bank_pin_count(unsigned int bank);
 
 #endif /* STM32MP_DT_H */
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 9af1564..48a747c 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -97,28 +97,6 @@
 	return (read_sctlr() & c_m_bits) == c_m_bits;
 }
 
-uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
-{
-	if (bank == GPIO_BANK_Z) {
-		return GPIOZ_BASE;
-	}
-
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
-
-	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
-}
-
-uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
-{
-	if (bank == GPIO_BANK_Z) {
-		return 0;
-	}
-
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
-
-	return bank * GPIO_BANK_OFFSET;
-}
-
 int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer)
 {
 	uint32_t i;
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 155f784..4b8b2db 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -393,3 +393,51 @@
 
 	return (const char *)fdt_getprop(fdt, node, "model", NULL);
 }
+
+/*******************************************************************************
+ * This function gets the pin count for a GPIO bank based from the FDT.
+ * It also checks node consistency.
+ ******************************************************************************/
+int fdt_get_gpio_bank_pin_count(unsigned int bank)
+{
+	int pinctrl_node;
+	int node;
+	uint32_t bank_offset;
+
+	pinctrl_node = stm32_get_gpio_bank_pinctrl_node(fdt, bank);
+	if (pinctrl_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	bank_offset = stm32_get_gpio_bank_offset(bank);
+
+	fdt_for_each_subnode(node, fdt, pinctrl_node) {
+		const fdt32_t *cuint;
+
+		if (fdt_getprop(fdt, node, "gpio-controller", NULL) == NULL) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, node, "reg", NULL);
+		if (cuint == NULL) {
+			continue;
+		}
+
+		if (fdt32_to_cpu(*cuint) != bank_offset) {
+			continue;
+		}
+
+		if (fdt_get_status(node) == DT_DISABLED) {
+			return 0;
+		}
+
+		cuint = fdt_getprop(fdt, node, "ngpios", NULL);
+		if (cuint == NULL) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		return (int)fdt32_to_cpu(*cuint);
+	}
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index ac45195..779228d 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -76,6 +76,28 @@
 	enable_mmu_svc_mon(0);
 }
 
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return GPIOZ_BASE;
+	}
+
+	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+
+	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return 0;
+	}
+
+	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+
+	return bank * GPIO_BANK_OFFSET;
+}
+
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
 {
 	if (bank == GPIO_BANK_Z) {
@@ -87,6 +109,28 @@
 	return GPIOA + (bank - GPIO_BANK_A);
 }
 
+int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
+{
+	switch (bank) {
+	case GPIO_BANK_A:
+	case GPIO_BANK_B:
+	case GPIO_BANK_C:
+	case GPIO_BANK_D:
+	case GPIO_BANK_E:
+	case GPIO_BANK_F:
+	case GPIO_BANK_G:
+	case GPIO_BANK_H:
+	case GPIO_BANK_I:
+	case GPIO_BANK_J:
+	case GPIO_BANK_K:
+		return fdt_path_offset(fdt, "/soc/pin-controller");
+	case GPIO_BANK_Z:
+		return fdt_path_offset(fdt, "/soc/pin-controller-z");
+	default:
+		panic();
+	}
+}
+
 static int get_part_number(uint32_t *part_nb)
 {
 	uint32_t part_number;
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 0424177..dba5e07 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -226,6 +226,7 @@
 /* SDEI dispatcher initialisation */
 void sdei_init(void)
 {
+	plat_sdei_setup();
 	sdei_class_init(SDEI_CRITICAL);
 	sdei_class_init(SDEI_NORMAL);
 
@@ -328,8 +329,11 @@
 }
 
 /* Register handler and argument for an SDEI event */
-static int64_t sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
-		uint64_t flags, uint64_t mpidr)
+static int64_t sdei_event_register(int ev_num,
+				uint64_t ep,
+				uint64_t arg,
+				uint64_t flags,
+				uint64_t mpidr)
 {
 	int ret;
 	unsigned int routing;
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index a3e1a2d..a818037 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include <arch_helpers.h>
+#include <arch/aarch64/arch_features.h>
 #include <bl31/bl31.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -16,11 +17,10 @@
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
 #include <services/spmd_svc.h>
 #include <smccc_helpers.h>
 #include "spmd_private.h"
@@ -28,12 +28,12 @@
 /*******************************************************************************
  * SPM Core context information.
  ******************************************************************************/
-spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
 
 /*******************************************************************************
  * SPM Core attribute information read from its manifest.
  ******************************************************************************/
-static spmc_manifest_sect_attribute_t spmc_attrs;
+static spmc_manifest_attribute_t spmc_attrs;
 
 /*******************************************************************************
  * SPM Core entry point information. Discovered on the primary core and reused
@@ -42,18 +42,33 @@
 static entry_point_info_t *spmc_ep_info;
 
 /*******************************************************************************
+ * SPM Core context on current CPU get helper.
+ ******************************************************************************/
+spmd_spm_core_context_t *spmd_get_context(void)
+{
+	unsigned int linear_id = plat_my_core_pos();
+
+	return &spm_core_context[linear_id];
+}
+
+/*******************************************************************************
  * Static function declaration.
  ******************************************************************************/
-static int32_t	spmd_init(void);
-static int	spmd_spmc_init(void *rd_base, size_t rd_size);
-static uint64_t	spmd_spci_error_return(void *handle, int error_code);
-static uint64_t	spmd_smc_forward(uint32_t smc_fid, bool secure_origin,
-				 uint64_t x1, uint64_t x2, uint64_t x3,
-				 uint64_t x4, void *handle);
+static int32_t spmd_init(void);
+static int spmd_spmc_init(void *pm_addr);
+static uint64_t spmd_ffa_error_return(void *handle,
+				       int error_code);
+static uint64_t spmd_smc_forward(uint32_t smc_fid,
+				 bool secure_origin,
+				 uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *handle);
 
 /*******************************************************************************
- * This function takes an SP context pointer and performs a synchronous entry
- * into it.
+ * This function takes an SPMC context pointer and performs a synchronous
+ * SPMC entry.
  ******************************************************************************/
 uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
 {
@@ -83,14 +98,14 @@
 }
 
 /*******************************************************************************
- * This function returns to the place where spm_sp_synchronous_entry() was
+ * This function returns to the place where spmd_spm_core_sync_entry() was
  * called originally.
  ******************************************************************************/
 __dead2 void spmd_spm_core_sync_exit(uint64_t rc)
 {
-	spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+	spmd_spm_core_context_t *ctx = spmd_get_context();
 
-	/* Get context of the SP in use by this CPU. */
+	/* Get current CPU context from SPMC context */
 	assert(cm_get_context(SECURE) == &(ctx->cpu_ctx));
 
 	/*
@@ -104,110 +119,99 @@
 }
 
 /*******************************************************************************
- * Jump to the SPM core for the first time.
+ * Jump to the SPM Core for the first time.
  ******************************************************************************/
 static int32_t spmd_init(void)
 {
-	uint64_t rc = 0;
-	spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+	uint64_t rc;
 
-	INFO("SPM Core init start.\n");
+	VERBOSE("SPM Core init start.\n");
 	ctx->state = SPMC_STATE_RESET;
 
 	rc = spmd_spm_core_sync_entry(ctx);
-	if (rc) {
+	if (rc != 0ULL) {
 		ERROR("SPMC initialisation failed 0x%llx\n", rc);
-		panic();
+		return 0;
 	}
 
 	ctx->state = SPMC_STATE_IDLE;
-	INFO("SPM Core init end.\n");
+	VERBOSE("SPM Core init end.\n");
 
 	return 1;
 }
 
 /*******************************************************************************
- * Load SPMC manifest, init SPMC.
+ * Loads SPMC manifest and inits SPMC.
  ******************************************************************************/
-static int spmd_spmc_init(void *rd_base, size_t rd_size)
+static int spmd_spmc_init(void *pm_addr)
 {
-	int rc;
+	spmd_spm_core_context_t *spm_ctx = spmd_get_context();
 	uint32_t ep_attr;
-	unsigned int linear_id = plat_my_core_pos();
-	spmd_spm_core_context_t *spm_ctx = &spm_core_context[linear_id];
+	int rc;
 
-	/* Load the SPM core manifest */
-	rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size);
+	/* Load the SPM Core manifest */
+	rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
 	if (rc != 0) {
-		WARN("No or invalid SPM core manifest image provided by BL2 "
-		     "boot loader. ");
-		return 1;
+		WARN("No or invalid SPM Core manifest image provided by BL2\n");
+		return rc;
 	}
 
 	/*
-	 * Ensure that the SPM core version is compatible with the SPM
-	 * dispatcher version
+	 * Ensure that the SPM Core version is compatible with the SPM
+	 * Dispatcher version.
 	 */
-	if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) ||
-	    (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) {
-		WARN("Unsupported SPCI version (%x.%x) specified in SPM core "
-		     "manifest image provided by BL2 boot loader.\n",
+	if ((spmc_attrs.major_version != FFA_VERSION_MAJOR) ||
+	    (spmc_attrs.minor_version > FFA_VERSION_MINOR)) {
+		WARN("Unsupported FFA version (%u.%u)\n",
 		     spmc_attrs.major_version, spmc_attrs.minor_version);
-		return 1;
+		return -EINVAL;
 	}
 
-	INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version,
+	VERBOSE("FFA version (%u.%u)\n", spmc_attrs.major_version,
 	     spmc_attrs.minor_version);
 
-	INFO("SPM core run time EL%x.\n",
+	VERBOSE("SPM Core run time EL%x.\n",
 	     SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1);
 
 	/* Validate the SPMC ID, Ensure high bit is set */
-	if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) &
-			SPMC_SECURE_ID_MASK) {
-		WARN("Invalid ID (0x%x) for SPMC.\n",
-		     spmc_attrs.spmc_id);
-		return 1;
+	if (((spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) &
+			SPMC_SECURE_ID_MASK) == 0U) {
+		WARN("Invalid ID (0x%x) for SPMC.\n", spmc_attrs.spmc_id);
+		return -EINVAL;
 	}
 
-	INFO("SPMC ID %x.\n", spmc_attrs.spmc_id);
-
-	/* Validate the SPM core execution state */
+	/* Validate the SPM Core execution state */
 	if ((spmc_attrs.exec_state != MODE_RW_64) &&
 	    (spmc_attrs.exec_state != MODE_RW_32)) {
-		WARN("Unsupported SPM core execution state %x specified in "
-		     "manifest image provided by BL2 boot loader.\n",
+		WARN("Unsupported %s%x.\n", "SPM Core execution state 0x",
 		     spmc_attrs.exec_state);
-		return 1;
+		return -EINVAL;
 	}
 
-	INFO("SPM core execution state %x.\n", spmc_attrs.exec_state);
+	VERBOSE("%s%x.\n", "SPM Core execution state 0x",
+		spmc_attrs.exec_state);
 
 #if SPMD_SPM_AT_SEL2
 	/* Ensure manifest has not requested AArch32 state in S-EL2 */
 	if (spmc_attrs.exec_state == MODE_RW_32) {
 		WARN("AArch32 state at S-EL2 is not supported.\n");
-		return 1;
+		return -EINVAL;
 	}
 
 	/*
 	 * Check if S-EL2 is supported on this system if S-EL2
 	 * is required for SPM
 	 */
-	uint64_t sel2 = read_id_aa64pfr0_el1();
-
-	sel2 >>= ID_AA64PFR0_SEL2_SHIFT;
-	sel2 &= ID_AA64PFR0_SEL2_MASK;
-
-	if (!sel2) {
-		WARN("SPM core run time S-EL2 is not supported.");
-		return 1;
+	if (!is_armv8_4_sel2_present()) {
+		WARN("SPM Core run time S-EL2 is not supported.\n");
+		return -EINVAL;
 	}
 #endif /* SPMD_SPM_AT_SEL2 */
 
 	/* Initialise an entrypoint to set up the CPU context */
 	ep_attr = SECURE | EP_ST_ENABLE;
-	if (read_sctlr_el3() & SCTLR_EE_BIT) {
+	if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0ULL) {
 		ep_attr |= EP_EE_BIG;
 	}
 
@@ -215,8 +219,8 @@
 	assert(spmc_ep_info->pc == BL32_BASE);
 
 	/*
-	 * Populate SPSR for SPM core based upon validated parameters from the
-	 * manifest
+	 * Populate SPSR for SPM Core based upon validated parameters from the
+	 * manifest.
 	 */
 	if (spmc_attrs.exec_state == MODE_RW_32) {
 		spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
@@ -236,99 +240,66 @@
 					     DISABLE_ALL_EXCEPTIONS);
 	}
 
-	/* Initialise SPM core context with this entry point information */
+	/* Initialise SPM Core context with this entry point information */
 	cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info);
 
 	/* Reuse PSCI affinity states to mark this SPMC context as off */
 	spm_ctx->state = AFF_STATE_OFF;
 
-	INFO("SPM core setup done.\n");
+	INFO("SPM Core setup done.\n");
 
-	/* Register init function for deferred init.  */
+	/* Register init function for deferred init. */
 	bl31_register_bl32_init(&spmd_init);
 
 	return 0;
 }
 
 /*******************************************************************************
- * Initialize context of SPM core.
+ * Initialize context of SPM Core.
  ******************************************************************************/
 int spmd_setup(void)
 {
+	void *spmc_manifest;
 	int rc;
-	void *rd_base;
-	size_t rd_size;
-	uintptr_t rd_base_align;
-	uintptr_t rd_size_align;
 
 	spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-	if (!spmc_ep_info) {
-		WARN("No SPM core image provided by BL2 boot loader, Booting "
-		     "device without SP initialization. SMC`s destined for SPM "
-		     "core will return SMC_UNK\n");
-		return 1;
+	if (spmc_ep_info == NULL) {
+		WARN("No SPM Core image provided by BL2 boot loader.\n");
+		return -EINVAL;
 	}
 
 	/* Under no circumstances will this parameter be 0 */
-	assert(spmc_ep_info->pc != 0U);
+	assert(spmc_ep_info->pc != 0ULL);
 
 	/*
 	 * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will
-	 * be used as a manifest for the SPM core at the next lower EL/mode.
+	 * be used as a manifest for the SPM Core at the next lower EL/mode.
 	 */
-	if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) {
-		ERROR("Invalid or absent SPM core manifest\n");
-		panic();
-	}
-
-	/* Obtain whereabouts of SPM core manifest */
-	rd_base = (void *) spmc_ep_info->args.arg0;
-	rd_size = spmc_ep_info->args.arg2;
-
-	rd_base_align = page_align((uintptr_t) rd_base, DOWN);
-	rd_size_align = page_align((uintptr_t) rd_size, UP);
-
-	/* Map the manifest in the SPMD translation regime first */
-	VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align);
-	VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align);
-	rc = mmap_add_dynamic_region((unsigned long long) rd_base_align,
-				     (uintptr_t) rd_base_align,
-				     rd_size_align,
-				     MT_RO_DATA);
-	if (rc != 0) {
-		ERROR("Error while mapping SPM core manifest (%d).\n", rc);
-		panic();
+	spmc_manifest = (void *)spmc_ep_info->args.arg0;
+	if (spmc_manifest == NULL) {
+		ERROR("Invalid or absent SPM Core manifest.\n");
+		return -EINVAL;
 	}
 
 	/* Load manifest, init SPMC */
-	rc = spmd_spmc_init(rd_base, rd_size);
+	rc = spmd_spmc_init(spmc_manifest);
 	if (rc != 0) {
-		int mmap_rc;
-
-		WARN("Booting device without SPM initialization. "
-		     "SPCI SMCs destined for SPM core will return "
-		     "ENOTSUPPORTED\n");
-
-		mmap_rc = mmap_remove_dynamic_region(rd_base_align,
-						     rd_size_align);
-		if (mmap_rc != 0) {
-			ERROR("Error while unmapping SPM core manifest (%d).\n",
-			      mmap_rc);
-			panic();
-		}
-
-		return rc;
+		WARN("Booting device without SPM initialization.\n");
 	}
 
-	return 0;
+	return rc;
 }
 
 /*******************************************************************************
  * Forward SMC to the other security state
  ******************************************************************************/
-static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin,
-				 uint64_t x1, uint64_t x2, uint64_t x3,
-				 uint64_t x4, void *handle)
+static uint64_t spmd_smc_forward(uint32_t smc_fid,
+				 bool secure_origin,
+				 uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *handle)
 {
 	uint32_t secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
 	uint32_t secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
@@ -353,42 +324,46 @@
 }
 
 /*******************************************************************************
- * Return SPCI_ERROR with specified error code
+ * Return FFA_ERROR with specified error code
  ******************************************************************************/
-static uint64_t spmd_spci_error_return(void *handle, int error_code)
+static uint64_t spmd_ffa_error_return(void *handle, int error_code)
 {
-	SMC_RET8(handle, SPCI_ERROR,
-		 SPCI_TARGET_INFO_MBZ, error_code,
-		 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-		 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+	SMC_RET8(handle, FFA_ERROR,
+		 FFA_TARGET_INFO_MBZ, error_code,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ);
 }
 
 /*******************************************************************************
- * This function handles all SMCs in the range reserved for SPCI. Each call is
+ * This function handles all SMCs in the range reserved for FFA. Each call is
  * either forwarded to the other security state or handled by the SPM dispatcher
  ******************************************************************************/
-uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-			  uint64_t x3, uint64_t x4, void *cookie, void *handle,
+uint64_t spmd_smc_handler(uint32_t smc_fid,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
 			  uint64_t flags)
 {
-	spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+	spmd_spm_core_context_t *ctx = spmd_get_context();
 	bool secure_origin;
 	int32_t ret;
 
 	/* Determine which security state this SMC originated from */
 	secure_origin = is_caller_secure(flags);
 
-	INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
-	     "0x%llx, 0x%llx, 0x%llx\n",
+	INFO("SPM: 0x%x 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n",
 	     smc_fid, x1, x2, x3, x4, SMC_GET_GP(handle, CTX_GPREG_X5),
 	     SMC_GET_GP(handle, CTX_GPREG_X6),
 	     SMC_GET_GP(handle, CTX_GPREG_X7));
 
 	switch (smc_fid) {
-	case SPCI_ERROR:
+	case FFA_ERROR:
 		/*
 		 * Check if this is the first invocation of this interface on
-		 * this CPU. If so, then indicate that the SPM core initialised
+		 * this CPU. If so, then indicate that the SPM Core initialised
 		 * unsuccessfully.
 		 */
 		if (secure_origin && (ctx->state == SPMC_STATE_RESET)) {
@@ -399,105 +374,105 @@
 					x1, x2, x3, x4, handle);
 		break; /* not reached */
 
-	case SPCI_VERSION:
+	case FFA_VERSION:
 		/*
 		 * TODO: This is an optimization that the version information
-		 * provided by the SPM core manifest is returned by the SPM
+		 * provided by the SPM Core manifest is returned by the SPM
 		 * dispatcher. It might be a better idea to simply forward this
-		 * call to the SPM core and wash our hands completely.
+		 * call to the SPM Core and wash our hands completely.
 		 */
-		ret = MAKE_SPCI_VERSION(spmc_attrs.major_version,
+		ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
 					spmc_attrs.minor_version);
-		SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret,
-			 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-			 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+		SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret,
+			 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+			 FFA_PARAM_MBZ, FFA_PARAM_MBZ);
 		break; /* not reached */
 
-	case SPCI_FEATURES:
+	case FFA_FEATURES:
 		/*
 		 * This is an optional interface. Do the minimal checks and
-		 * forward to SPM core which will handle it if implemented.
+		 * forward to SPM Core which will handle it if implemented.
 		 */
 
 		/*
-		 * Check if x1 holds a valid SPCI fid. This is an
+		 * Check if x1 holds a valid FFA fid. This is an
 		 * optimization.
 		 */
-		if (!is_spci_fid(x1)) {
-			return spmd_spci_error_return(handle,
-						      SPCI_ERROR_NOT_SUPPORTED);
+		if (!is_ffa_fid(x1)) {
+			return spmd_ffa_error_return(handle,
+						      FFA_ERROR_NOT_SUPPORTED);
 		}
 
-		/* Forward SMC from Normal world to the SPM core */
+		/* Forward SMC from Normal world to the SPM Core */
 		if (!secure_origin) {
 			return spmd_smc_forward(smc_fid, secure_origin,
 						x1, x2, x3, x4, handle);
-		} else {
-			/*
-			 * Return success if call was from secure world i.e. all
-			 * SPCI functions are supported. This is essentially a
-			 * nop.
-			 */
-			SMC_RET8(handle, SPCI_SUCCESS_SMC32, x1, x2, x3, x4,
-				 SMC_GET_GP(handle, CTX_GPREG_X5),
-				 SMC_GET_GP(handle, CTX_GPREG_X6),
-				 SMC_GET_GP(handle, CTX_GPREG_X7));
 		}
 
+		/*
+		 * Return success if call was from secure world i.e. all
+		 * FFA functions are supported. This is essentially a
+		 * nop.
+		 */
+		SMC_RET8(handle, FFA_SUCCESS_SMC32, x1, x2, x3, x4,
+			 SMC_GET_GP(handle, CTX_GPREG_X5),
+			 SMC_GET_GP(handle, CTX_GPREG_X6),
+			 SMC_GET_GP(handle, CTX_GPREG_X7));
+
 		break; /* not reached */
 
-	case SPCI_ID_GET:
+	case FFA_ID_GET:
 		/*
-		 * Returns the ID of the calling SPCI component.
-		*/
+		 * Returns the ID of the calling FFA component.
+		 */
 		if (!secure_origin) {
-			SMC_RET8(handle, SPCI_SUCCESS_SMC32,
-				 SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID,
-				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-				 SPCI_PARAM_MBZ);
-		} else {
-			SMC_RET8(handle, SPCI_SUCCESS_SMC32,
-				 SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
-				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
-				 SPCI_PARAM_MBZ);
+			SMC_RET8(handle, FFA_SUCCESS_SMC32,
+				 FFA_TARGET_INFO_MBZ, FFA_NS_ENDPOINT_ID,
+				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+				 FFA_PARAM_MBZ);
 		}
 
+		SMC_RET8(handle, FFA_SUCCESS_SMC32,
+			 FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
+			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+			 FFA_PARAM_MBZ);
+
 		break; /* not reached */
 
-	case SPCI_RX_RELEASE:
-	case SPCI_RXTX_MAP_SMC32:
-	case SPCI_RXTX_MAP_SMC64:
-	case SPCI_RXTX_UNMAP:
-	case SPCI_MSG_RUN:
+	case FFA_RX_RELEASE:
+	case FFA_RXTX_MAP_SMC32:
+	case FFA_RXTX_MAP_SMC64:
+	case FFA_RXTX_UNMAP:
+	case FFA_MSG_RUN:
 		/* This interface must be invoked only by the Normal world */
 		if (secure_origin) {
-			return spmd_spci_error_return(handle,
-						      SPCI_ERROR_NOT_SUPPORTED);
+			return spmd_ffa_error_return(handle,
+						      FFA_ERROR_NOT_SUPPORTED);
 		}
 
 		/* Fall through to forward the call to the other world */
 
-	case SPCI_PARTITION_INFO_GET:
-	case SPCI_MSG_SEND:
-	case SPCI_MSG_SEND_DIRECT_REQ_SMC32:
-	case SPCI_MSG_SEND_DIRECT_REQ_SMC64:
-	case SPCI_MSG_SEND_DIRECT_RESP_SMC32:
-	case SPCI_MSG_SEND_DIRECT_RESP_SMC64:
-	case SPCI_MEM_DONATE_SMC32:
-	case SPCI_MEM_DONATE_SMC64:
-	case SPCI_MEM_LEND_SMC32:
-	case SPCI_MEM_LEND_SMC64:
-	case SPCI_MEM_SHARE_SMC32:
-	case SPCI_MEM_SHARE_SMC64:
-	case SPCI_MEM_RETRIEVE_REQ_SMC32:
-	case SPCI_MEM_RETRIEVE_REQ_SMC64:
-	case SPCI_MEM_RETRIEVE_RESP:
-	case SPCI_MEM_RELINQUISH:
-	case SPCI_MEM_RECLAIM:
-	case SPCI_SUCCESS_SMC32:
-	case SPCI_SUCCESS_SMC64:
+	case FFA_PARTITION_INFO_GET:
+	case FFA_MSG_SEND:
+	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+	case FFA_MEM_DONATE_SMC32:
+	case FFA_MEM_DONATE_SMC64:
+	case FFA_MEM_LEND_SMC32:
+	case FFA_MEM_LEND_SMC64:
+	case FFA_MEM_SHARE_SMC32:
+	case FFA_MEM_SHARE_SMC64:
+	case FFA_MEM_RETRIEVE_REQ_SMC32:
+	case FFA_MEM_RETRIEVE_REQ_SMC64:
+	case FFA_MEM_RETRIEVE_RESP:
+	case FFA_MEM_RELINQUISH:
+	case FFA_MEM_RECLAIM:
+	case FFA_SUCCESS_SMC32:
+	case FFA_SUCCESS_SMC64:
 		/*
 		 * TODO: Assume that no requests originate from EL3 at the
 		 * moment. This will change if a SP service is required in
@@ -509,11 +484,11 @@
 					x1, x2, x3, x4, handle);
 		break; /* not reached */
 
-	case SPCI_MSG_WAIT:
+	case FFA_MSG_WAIT:
 		/*
 		 * Check if this is the first invocation of this interface on
 		 * this CPU from the Secure world. If so, then indicate that the
-		 * SPM core initialised successfully.
+		 * SPM Core initialised successfully.
 		 */
 		if (secure_origin && (ctx->state == SPMC_STATE_RESET)) {
 			spmd_spm_core_sync_exit(0);
@@ -521,11 +496,11 @@
 
 		/* Fall through to forward the call to the other world */
 
-	case SPCI_MSG_YIELD:
+	case FFA_MSG_YIELD:
 		/* This interface must be invoked only by the Secure world */
 		if (!secure_origin) {
-			return spmd_spci_error_return(handle,
-						      SPCI_ERROR_NOT_SUPPORTED);
+			return spmd_ffa_error_return(handle,
+						      FFA_ERROR_NOT_SUPPORTED);
 		}
 
 		return spmd_smc_forward(smc_fid, secure_origin,
@@ -534,6 +509,6 @@
 
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
-		return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED);
+		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
 	}
 }
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 0ad35c7..4946309 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -30,15 +30,9 @@
 #define SPMD_C_RT_CTX_ENTRIES		(SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
 
 #ifndef __ASSEMBLER__
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
 #include <stdint.h>
 
-/*
- * Convert a function no. in a FID to a bit position. All function nos. are
- * between 0 and 0x1f
- */
-#define SPCI_FNO_TO_BIT_POS(_fid)	(1 << ((_fid) & U(0x1f)))
-
 typedef enum spmc_state {
 	SPMC_STATE_RESET = 0,
 	SPMC_STATE_IDLE
@@ -55,26 +49,15 @@
 } spmd_spm_core_context_t;
 
 /*
- * Reserve ID for NS physical SPCI Endpoint.
+ * Reserve ID for NS physical FFA Endpoint.
  */
-#define SPCI_NS_ENDPOINT_ID		U(0)
+#define FFA_NS_ENDPOINT_ID		U(0)
 
-/* Mask and shift to check valid secure SPCI Endpoint ID. */
-#define SPMC_SECURE_ID_MASK		0x1
-#define SPMC_SECURE_ID_SHIFT		15
+/* Mask and shift to check valid secure FFA Endpoint ID. */
+#define SPMC_SECURE_ID_MASK		U(1)
+#define SPMC_SECURE_ID_SHIFT		U(15)
 
-/*
- * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of
- * SPCI calls from lower ELs.
- *
- * next_smc_bit_map: Per-cpu bit map of SMCs from each world that are expected
- *                   next.
- */
-typedef struct spmd_spci_context {
-	uint32_t next_smc_bit_map[2];
-} spmd_spci_context_t;
-
-/* Functions used to enter/exit a Secure Partition synchronously */
+/* Functions used to enter/exit SPMC synchronously */
 uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
 __dead2 void spmd_spm_core_sync_exit(uint64_t rc);
 
@@ -82,6 +65,9 @@
 uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx);
 void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret);
 
+/* SPMC context on current CPU get helper */
+spmd_spm_core_context_t *spmd_get_context(void);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_PRIVATE_H */
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 895fd29..cdd17bc 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -123,10 +123,10 @@
 
 #if defined(SPD_spmd)
 	/*
-	 * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM
+	 * Dispatch FFA calls to the FFA SMC handler implemented by the SPM
 	 * dispatcher and return its return value
 	 */
-	if (is_spci_fid(smc_fid)) {
+	if (is_ffa_fid(smc_fid)) {
 		return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 					handle, flags);
 	}