Merge "plat: marvell: ap807: implement workaround for errata-id 3033912" into integration
diff --git a/Makefile b/Makefile
index f4589d9..a9a4d90 100644
--- a/Makefile
+++ b/Makefile
@@ -855,70 +855,77 @@
 # Build options checks
 ################################################################################
 
-$(eval $(call assert_boolean,ALLOW_RO_XLAT_TABLES))
-$(eval $(call assert_boolean,COLD_BOOT_SINGLE_CPU))
-$(eval $(call assert_boolean,CREATE_KEYS))
-$(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS))
-$(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
-$(eval $(call assert_boolean,CTX_INCLUDE_PAUTH_REGS))
-$(eval $(call assert_boolean,CTX_INCLUDE_MTE_REGS))
-$(eval $(call assert_boolean,CTX_INCLUDE_EL2_REGS))
-$(eval $(call assert_boolean,DEBUG))
-$(eval $(call assert_boolean,DYN_DISABLE_AUTH))
-$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
-$(eval $(call assert_boolean,ENABLE_AMU))
-$(eval $(call assert_boolean,ENABLE_ASSERTIONS))
-$(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS))
-$(eval $(call assert_boolean,ENABLE_PIE))
-$(eval $(call assert_boolean,ENABLE_PMF))
-$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
-$(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
-$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call assert_boolean,ENABLE_SVE_FOR_NS))
-$(eval $(call assert_boolean,ERROR_DEPRECATED))
-$(eval $(call assert_boolean,FAULT_INJECTION_SUPPORT))
-$(eval $(call assert_boolean,GENERATE_COT))
-$(eval $(call assert_boolean,GICV2_G0_FOR_EL3))
-$(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST))
-$(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
-$(eval $(call assert_boolean,INVERTED_MEMMAP))
-$(eval $(call assert_boolean,MEASURED_BOOT))
-$(eval $(call assert_boolean,NS_TIMER_SWITCH))
-$(eval $(call assert_boolean,OVERRIDE_LIBC))
-$(eval $(call assert_boolean,PL011_GENERIC_UART))
-$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS))
-$(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID))
-$(eval $(call assert_boolean,RAS_EXTENSION))
-$(eval $(call assert_boolean,RESET_TO_BL31))
-$(eval $(call assert_boolean,SAVE_KEYS))
-$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
-$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION))
-$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
-$(eval $(call assert_boolean,SPM_MM))
-$(eval $(call assert_boolean,SPMD_SPM_AT_SEL2))
-$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
-$(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,SEC_INT_DESC_IN_FCONF))
-$(eval $(call assert_boolean,USE_ROMLIB))
-$(eval $(call assert_boolean,USE_TBBR_DEFS))
-$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call assert_boolean,BL2_AT_EL3))
-$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
-$(eval $(call assert_boolean,BL2_INV_DCACHE))
-$(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_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS))
-$(eval $(call assert_boolean,COT_DESC_IN_DTB))
+$(eval $(call assert_booleans,\
+    $(sort \
+        ALLOW_RO_XLAT_TABLES \
+        COLD_BOOT_SINGLE_CPU \
+        CREATE_KEYS \
+        CTX_INCLUDE_AARCH32_REGS \
+        CTX_INCLUDE_FPREGS \
+        CTX_INCLUDE_PAUTH_REGS \
+        CTX_INCLUDE_MTE_REGS \
+        CTX_INCLUDE_EL2_REGS \
+        DEBUG \
+        DYN_DISABLE_AUTH \
+        EL3_EXCEPTION_HANDLING \
+        ENABLE_AMU \
+        ENABLE_ASSERTIONS \
+        ENABLE_MPAM_FOR_LOWER_ELS \
+        ENABLE_PIE \
+        ENABLE_PMF \
+        ENABLE_PSCI_STAT \
+        ENABLE_RUNTIME_INSTRUMENTATION \
+        ENABLE_SPE_FOR_LOWER_ELS \
+        ENABLE_SVE_FOR_NS \
+        ERROR_DEPRECATED \
+        FAULT_INJECTION_SUPPORT \
+        GENERATE_COT \
+        GICV2_G0_FOR_EL3 \
+        HANDLE_EA_EL3_FIRST \
+        HW_ASSISTED_COHERENCY \
+        INVERTED_MEMMAP \
+        MEASURED_BOOT \
+        NS_TIMER_SWITCH \
+        OVERRIDE_LIBC \
+        PL011_GENERIC_UART \
+        PROGRAMMABLE_RESET_ADDRESS \
+        PSCI_EXTENDED_STATE_ID \
+        RAS_EXTENSION \
+        RESET_TO_BL31 \
+        SAVE_KEYS \
+        SEPARATE_CODE_AND_RODATA \
+        SEPARATE_NOBITS_REGION \
+        SPIN_ON_BL1_EXIT \
+        SPM_MM \
+        SPMD_SPM_AT_SEL2 \
+        TRUSTED_BOARD_BOOT \
+        USE_COHERENT_MEM \
+        USE_DEBUGFS \
+        ARM_IO_IN_DTB \
+        SDEI_IN_FCONF \
+        SEC_INT_DESC_IN_FCONF \
+        USE_ROMLIB \
+        USE_TBBR_DEFS \
+        WARMBOOT_ENABLE_DCACHE_EARLY \
+        BL2_AT_EL3 \
+        BL2_IN_XIP_MEM \
+        BL2_INV_DCACHE \
+        USE_SPINLOCK_CAS \
+        ENCRYPT_BL31 \
+        ENCRYPT_BL32 \
+        ERRATA_SPECULATIVE_AT \
+        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        COT_DESC_IN_DTB \
+        USE_SP804_TIMER \
+)))
 
-$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
-$(eval $(call assert_numeric,ARM_ARCH_MINOR))
-$(eval $(call assert_numeric,BRANCH_PROTECTION))
-$(eval $(call assert_numeric,FW_ENC_STATUS))
+$(eval $(call assert_numerics,\
+    $(sort \
+        ARM_ARCH_MAJOR \
+        ARM_ARCH_MINOR \
+        BRANCH_PROTECTION \
+        FW_ENC_STATUS \
+)))
 
 ifdef KEY_SIZE
         $(eval $(call assert_numeric,KEY_SIZE))
@@ -934,67 +941,71 @@
 # platform to overwrite the default options
 ################################################################################
 
-$(eval $(call add_define,ALLOW_RO_XLAT_TABLES))
-$(eval $(call add_define,ARM_ARCH_MAJOR))
-$(eval $(call add_define,ARM_ARCH_MINOR))
-$(eval $(call add_define,COLD_BOOT_SINGLE_CPU))
-$(eval $(call add_define,CTX_INCLUDE_AARCH32_REGS))
-$(eval $(call add_define,CTX_INCLUDE_FPREGS))
-$(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS))
-$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
-$(eval $(call add_define,CTX_INCLUDE_MTE_REGS))
-$(eval $(call add_define,CTX_INCLUDE_EL2_REGS))
-$(eval $(call add_define,DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT}))
-$(eval $(call add_define,ENABLE_AMU))
-$(eval $(call add_define,ENABLE_ASSERTIONS))
-$(eval $(call add_define,ENABLE_BTI))
-$(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS))
-$(eval $(call add_define,ENABLE_PAUTH))
-$(eval $(call add_define,ENABLE_PIE))
-$(eval $(call add_define,ENABLE_PMF))
-$(eval $(call add_define,ENABLE_PSCI_STAT))
-$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
-$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call add_define,ENABLE_SVE_FOR_NS))
-$(eval $(call add_define,ENCRYPT_BL31))
-$(eval $(call add_define,ENCRYPT_BL32))
-$(eval $(call add_define,ERROR_DEPRECATED))
-$(eval $(call add_define,FAULT_INJECTION_SUPPORT))
-$(eval $(call add_define,GICV2_G0_FOR_EL3))
-$(eval $(call add_define,HANDLE_EA_EL3_FIRST))
-$(eval $(call add_define,HW_ASSISTED_COHERENCY))
-$(eval $(call add_define,LOG_LEVEL))
-$(eval $(call add_define,MEASURED_BOOT))
-$(eval $(call add_define,NS_TIMER_SWITCH))
-$(eval $(call add_define,PL011_GENERIC_UART))
-$(eval $(call add_define,PLAT_${PLAT}))
-$(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS))
-$(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
-$(eval $(call add_define,RAS_EXTENSION))
-$(eval $(call add_define,RESET_TO_BL31))
-$(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
-$(eval $(call add_define,SEPARATE_NOBITS_REGION))
-$(eval $(call add_define,RECLAIM_INIT_CODE))
-$(eval $(call add_define,SPD_${SPD}))
-$(eval $(call add_define,SPIN_ON_BL1_EXIT))
-$(eval $(call add_define,SPM_MM))
-$(eval $(call add_define,SPMD_SPM_AT_SEL2))
-$(eval $(call add_define,TRUSTED_BOARD_BOOT))
-$(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,SEC_INT_DESC_IN_FCONF))
-$(eval $(call add_define,USE_ROMLIB))
-$(eval $(call add_define,USE_TBBR_DEFS))
-$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call add_define,BL2_AT_EL3))
-$(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))
-$(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS))
-$(eval $(call add_define,COT_DESC_IN_DTB))
+$(eval $(call add_defines,\
+    $(sort \
+        ALLOW_RO_XLAT_TABLES \
+        ARM_ARCH_MAJOR \
+        ARM_ARCH_MINOR \
+        COLD_BOOT_SINGLE_CPU \
+        CTX_INCLUDE_AARCH32_REGS \
+        CTX_INCLUDE_FPREGS \
+        CTX_INCLUDE_PAUTH_REGS \
+        EL3_EXCEPTION_HANDLING \
+        CTX_INCLUDE_MTE_REGS \
+        CTX_INCLUDE_EL2_REGS \
+        DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
+        ENABLE_AMU \
+        ENABLE_ASSERTIONS \
+        ENABLE_BTI \
+        ENABLE_MPAM_FOR_LOWER_ELS \
+        ENABLE_PAUTH \
+        ENABLE_PIE \
+        ENABLE_PMF \
+        ENABLE_PSCI_STAT \
+        ENABLE_RUNTIME_INSTRUMENTATION \
+        ENABLE_SPE_FOR_LOWER_ELS \
+        ENABLE_SVE_FOR_NS \
+        ENCRYPT_BL31 \
+        ENCRYPT_BL32 \
+        ERROR_DEPRECATED \
+        FAULT_INJECTION_SUPPORT \
+        GICV2_G0_FOR_EL3 \
+        HANDLE_EA_EL3_FIRST \
+        HW_ASSISTED_COHERENCY \
+        LOG_LEVEL \
+        MEASURED_BOOT \
+        NS_TIMER_SWITCH \
+        PL011_GENERIC_UART \
+        PLAT_${PLAT} \
+        PROGRAMMABLE_RESET_ADDRESS \
+        PSCI_EXTENDED_STATE_ID \
+        RAS_EXTENSION \
+        RESET_TO_BL31 \
+        SEPARATE_CODE_AND_RODATA \
+        SEPARATE_NOBITS_REGION \
+        RECLAIM_INIT_CODE \
+        SPD_${SPD} \
+        SPIN_ON_BL1_EXIT \
+        SPM_MM \
+        SPMD_SPM_AT_SEL2 \
+        TRUSTED_BOARD_BOOT \
+        USE_COHERENT_MEM \
+        USE_DEBUGFS \
+        ARM_IO_IN_DTB \
+        SDEI_IN_FCONF \
+        SEC_INT_DESC_IN_FCONF \
+        USE_ROMLIB \
+        USE_TBBR_DEFS \
+        WARMBOOT_ENABLE_DCACHE_EARLY \
+        BL2_AT_EL3 \
+        BL2_IN_XIP_MEM \
+        BL2_INV_DCACHE \
+        USE_SPINLOCK_CAS \
+        ERRATA_SPECULATIVE_AT \
+        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        COT_DESC_IN_DTB \
+        USE_SP804_TIMER \
+)))
 
 ifeq (${SANITIZE_UB},trap)
         $(eval $(call add_define,MONITOR_TRAPS))
@@ -1135,7 +1146,7 @@
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
 $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
-	${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT)
+	${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT}
 sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk
 	${Q}$(SPTOOL) $(SPTOOL_ARGS)
 	@${ECHO_BLANK_LINE}
@@ -1155,7 +1166,13 @@
 clean:
 	@echo "  CLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
+ifdef UNIX_MK
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+else
+# Clear the MAKEFLAGS as we do not want
+# to pass the gnumake flags to nmake.
+	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
+endif
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
 	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
@@ -1164,7 +1181,13 @@
 	@echo "  REALCLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
 	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
+ifdef UNIX_MK
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+else
+# Clear the MAKEFLAGS as we do not want
+# to pass the gnumake flags to nmake.
+	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
+endif
 	${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
@@ -1207,7 +1230,7 @@
 
 .PHONY: ${CRTTOOL}
 ${CRTTOOL}:
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${CRTTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -1250,12 +1273,21 @@
 
 .PHONY: ${FIPTOOL}
 ${FIPTOOL}:
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${FIPTOOLPATH}
+	@${ECHO_BLANK_LINE}
+	@echo "Building $@"
+ifdef UNIX_MK
+	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} --no-print-directory -C ${FIPTOOLPATH}
+else
+# Clear the MAKEFLAGS as we do not want
+# to pass the gnumake flags to nmake.
+	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
+endif
+	@${ECHO_BLANK_LINE}
 
 sptool: ${SPTOOL}
 .PHONY: ${SPTOOL}
 ${SPTOOL}:
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${SPTOOLPATH}
+	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH}
 
 .PHONY: libraries
 romlib.bin: libraries
@@ -1273,7 +1305,7 @@
 
 .PHONY: ${ENCTOOL}
 ${ENCTOOL}:
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${ENCTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c
index fec513d..87e367c 100644
--- a/bl1/aarch64/bl1_context_mgmt.c
+++ b/bl1/aarch64/bl1_context_mgmt.c
@@ -14,12 +14,6 @@
 
 #include "../bl1_private.h"
 
-/*
- * Following array will be used for context management.
- * There are 2 instances, for the Secure and Non-Secure contexts.
- */
-static cpu_context_t bl1_cpu_context[2];
-
 /* Following contains the cpu context pointers. */
 static void *bl1_cpu_context_ptr[2];
 
@@ -42,6 +36,13 @@
  ******************************************************************************/
 void bl1_prepare_next_image(unsigned int image_id)
 {
+
+	/*
+	 * Following array will be used for context management.
+	 * There are 2 instances, for the Secure and Non-Secure contexts.
+	 */
+	static cpu_context_t bl1_cpu_context[2];
+
 	unsigned int security_state, mode = MODE_EL1;
 	image_desc_t *desc;
 	entry_point_info_t *next_bl_ep;
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 1479a96..fd60232 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -24,11 +24,6 @@
 
 #include "bl1_private.h"
 
-/* BL1 Service UUID */
-DEFINE_SVC_UUID2(bl1_svc_uid,
-	U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75,
-	0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a);
-
 static void bl1_load_bl2(void);
 
 #if ENABLE_PAUTH
@@ -234,6 +229,11 @@
 	void *handle,
 	unsigned int flags)
 {
+	/* BL1 Service UUID */
+	DEFINE_SVC_UUID2(bl1_svc_uid,
+		U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75,
+		0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a);
+
 
 #if TRUSTED_BOARD_BOOT
 	/*
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 5b37388..bfe13f3 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -12,6 +12,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/runtime_svc.h>
 #include <context.h>
+#include <el3_common_macros.S>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/smccc.h>
 
@@ -285,21 +286,25 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch64
 end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch64
 end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
+	apply_at_speculative_wa
 	msr	daifclr, #DAIF_ABT_BIT
 	b	enter_lower_el_async_ea
 end_vector_entry serror_aarch64
@@ -315,21 +320,25 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch32
 end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
+	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch32
 end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
+	apply_at_speculative_wa
 	msr	daifclr, #DAIF_ABT_BIT
 	b	enter_lower_el_async_ea
 end_vector_entry serror_aarch32
@@ -455,6 +464,8 @@
 	b	el3_exit
 
 smc_prohibited:
+	restore_ptw_el1_sys_regs
+	ldp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	mov	x0, #SMC_UNK
 	exception_return
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 0948e94..735d1fc 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -89,10 +89,16 @@
 CRASH_REPORTING		:=	$(DEBUG)
 endif
 
-$(eval $(call assert_boolean,CRASH_REPORTING))
-$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
-$(eval $(call assert_boolean,SDEI_SUPPORT))
+$(eval $(call assert_booleans,\
+    $(sort \
+	CRASH_REPORTING \
+	EL3_EXCEPTION_HANDLING \
+	SDEI_SUPPORT \
+)))
 
-$(eval $(call add_define,CRASH_REPORTING))
-$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
-$(eval $(call add_define,SDEI_SUPPORT))
+$(eval $(call add_defines,\
+    $(sort \
+        CRASH_REPORTING \
+        EL3_EXCEPTION_HANDLING \
+        SDEI_SUPPORT \
+)))
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index ef57500..a07c066 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -70,7 +70,7 @@
 	} else if (el == 2U) {
 		ats1e2r(addr);
 	} else {
-		ats1e1r(addr);
+		AT(ats1e1r, addr);
 	}
 
 	isb();
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index d518eb2..980e60d 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,15 +14,20 @@
  * that.
  */
 
+#include <errno.h>
+#include <stdio.h>
 #include <string.h>
 
 #include <libfdt.h>
 
+#include <arch.h>
 #include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/console.h>
 #include <lib/psci/psci.h>
+#include <plat/common/platform.h>
 
-#include <common/fdt_fixup.h>
 
 static int append_psci_compatible(void *fdt, int offs, const char *str)
 {
@@ -210,3 +215,165 @@
 
 	return 0;
 }
+
+/*******************************************************************************
+ * fdt_add_cpu()	Add a new CPU node to the DT
+ * @dtb:		Pointer to the device tree blob in memory
+ * @parent:		Offset of the parent node
+ * @mpidr:		MPIDR for the current CPU
+ *
+ * Create and add a new cpu node to a DTB.
+ *
+ * Return the offset of the new node or a negative value in case of error
+ ******************************************************************************/
+
+static int fdt_add_cpu(void *dtb, int parent, u_register_t mpidr)
+{
+	int cpu_offs;
+	int err;
+	char snode_name[15];
+	uint64_t reg_prop;
+
+	reg_prop = mpidr & MPID_MASK & ~MPIDR_MT_MASK;
+
+	snprintf(snode_name, sizeof(snode_name), "cpu@%x",
+					(unsigned int)reg_prop);
+
+	cpu_offs = fdt_add_subnode(dtb, parent, snode_name);
+	if (cpu_offs < 0) {
+		ERROR ("FDT: add subnode \"%s\" failed: %i\n",
+							snode_name, cpu_offs);
+		return cpu_offs;
+	}
+
+	err = fdt_setprop_string(dtb, cpu_offs, "compatible", "arm,armv8");
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"compatible", cpu_offs);
+		return err;
+	}
+
+	err = fdt_setprop_u64(dtb, cpu_offs, "reg", reg_prop);
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"reg", cpu_offs);
+		return err;
+	}
+
+	err = fdt_setprop_string(dtb, cpu_offs, "device_type", "cpu");
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"device_type", cpu_offs);
+		return err;
+	}
+
+	err = fdt_setprop_string(dtb, cpu_offs, "enable-method", "psci");
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"enable-method", cpu_offs);
+		return err;
+	}
+
+	return cpu_offs;
+}
+
+/******************************************************************************
+ * fdt_add_cpus_node() - Add the cpus node to the DTB
+ * @dtb:		pointer to the device tree blob in memory
+ * @afflv0:		Maximum number of threads per core (affinity level 0).
+ * @afflv1:		Maximum number of CPUs per cluster (affinity level 1).
+ * @afflv2:		Maximum number of clusters (affinity level 2).
+ *
+ * Iterate over all the possible MPIDs given the maximum affinity levels and
+ * add a cpus node to the DTB with all the valid CPUs on the system.
+ * If there is already a /cpus node, exit gracefully
+ *
+ * A system with two CPUs would generate a node equivalent or similar to:
+ *
+ *	cpus {
+ *		#address-cells = <2>;
+ *		#size-cells = <0>;
+ *
+ *		cpu0: cpu@0 {
+ *			compatible = "arm,armv8";
+ *			reg = <0x0 0x0>;
+ *			device_type = "cpu";
+ *			enable-method = "psci";
+ *		};
+ *		cpu1: cpu@10000 {
+ *			compatible = "arm,armv8";
+ *			reg = <0x0 0x100>;
+ *			device_type = "cpu";
+ *			enable-method = "psci";
+ *		};
+ *	};
+ *
+ * Full documentation about the CPU bindings can be found at:
+ * https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpus.txt
+ *
+ * Return the offset of the node or a negative value on error.
+ ******************************************************************************/
+
+int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
+		      unsigned int afflv1, unsigned int afflv2)
+{
+	int offs;
+	int err;
+	unsigned int i, j, k;
+	u_register_t mpidr;
+	int cpuid;
+
+	if (fdt_path_offset(dtb, "/cpus") >= 0) {
+		return -EEXIST;
+	}
+
+	offs = fdt_add_subnode(dtb, 0, "cpus");
+	if (offs < 0) {
+		ERROR ("FDT: add subnode \"cpus\" node to parent node failed");
+		return offs;
+	}
+
+	err = fdt_setprop_u32(dtb, offs, "#address-cells", 2);
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"#address-cells", offs);
+		return err;
+	}
+
+	err = fdt_setprop_u32(dtb, offs, "#size-cells", 0);
+	if (err < 0) {
+		ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n",
+			"#size-cells", offs);
+		return err;
+	}
+
+	/*
+	 * Populate the node with the CPUs.
+	 * As libfdt prepends subnodes within a node, reverse the index count
+	 * so the CPU nodes would be better ordered.
+	 */
+	for (i = afflv2; i > 0U; i--) {
+		for (j = afflv1; j > 0U; j--) {
+			for (k = afflv0; k > 0U; k--) {
+				mpidr = ((i - 1) << MPIDR_AFF2_SHIFT) |
+					((j - 1) << MPIDR_AFF1_SHIFT) |
+					((k - 1) << MPIDR_AFF0_SHIFT) |
+					(read_mpidr_el1() & MPIDR_MT_MASK);
+
+				cpuid = plat_core_pos_by_mpidr(mpidr);
+				if (cpuid >= 0) {
+					/* Valid MPID found */
+					err = fdt_add_cpu(dtb, offs, mpidr);
+					if (err < 0) {
+						ERROR ("FDT: %s 0x%08x\n",
+							"error adding CPU",
+							(uint32_t)mpidr);
+						return err;
+					}
+				}
+			}
+		}
+	}
+
+	return offs;
+}
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 9cb25ef..4440a37 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -24,12 +24,21 @@
 
 You can see a `summary of all the lists`_ on the TrustedFirmware.org website.
 
+Open Tech Forum Call
+^^^^^^^^^^^^^^^^^^^^
+
+Every other week, we organize a call with all interested TF-A contributors.
+Anyone is welcome to join. This is an opportunity to discuss any technical
+topic within the community. More details can be found `here`_.
+
+.. _here: https://www.trustedfirmware.org/meetings/tf-a-technical-forum/
+
 Issue Tracker
 ^^^^^^^^^^^^^
 
-Specific issues may be raised using the `issue tracker`_ on the
-TrustedFirmware.org website. Using this tracker makes it easy for the
-maintainers to prioritise and respond to your ticket.
+Bug reports may be filed on the `issue tracker`_ on the TrustedFirmware.org
+website. Using this tracker gives everyone visibility of the known issues in
+TF-A.
 
 Arm Licensees
 ^^^^^^^^^^^^^
@@ -44,4 +53,4 @@
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index a628704..ab2d3f9 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -64,8 +64,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
 :G: `javieralso-arm`_
-:M: Jack Bond-Preston <Jack.Bond-Preston@arm.com>
-:G: `jackbondpreston-arm`_
+:M: Chris Kay <chris.kay@arm.com>
+:G: `CJkay`_
 :F: /
 
 Software Delegated Exception Interface (SDEI)
@@ -523,8 +523,7 @@
 
 UniPhier platform port
 ^^^^^^^^^^^^^^^^^^^^^^
-:M: Masahiro Yamada <yamada.masahiro@socionext.com>
-:G: `masahir0y`_
+:M: Orphan
 :F: docs/plat/socionext-uniphier.rst
 :F: plat/socionext/uniphier/
 
@@ -648,6 +647,6 @@
 .. _madhukar-Arm: https://github.com/madhukar-Arm
 .. _john-powell-arm: https://github.com/john-powell-arm
 .. _raghuncstate: https://github.com/raghuncstate
-.. _jackbondpreston-arm: https://github.com/jackbondpreston-arm
+.. _CJKay: https://github.com/cjkay
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst
index 46915db..4f8c8b7 100644
--- a/docs/components/cot-binding.rst
+++ b/docs/components/cot-binding.rst
@@ -279,6 +279,10 @@
                     Description: Contains various non-volatile counters present in the platform.
 
             PROPERTIES
+                - id
+                    Usage: Required for every nv-counter with unique id.
+
+                    Value type: <u32>
 
                 - reg
                     Usage:
@@ -301,21 +305,21 @@
 
 .. code:: c
 
-   non-volatile-counters {
+   non_volatile_counters: non_volatile_counters {
         compatible = "arm, non-volatile-counter";
         #address-cells = <1>;
         #size-cells = <0>;
 
-        counters {
-            trusted-nv-counter: trusted_nv_counter {
-                reg = <TFW_NVCTR_BASE>;
-                oid = TRUSTED_FW_NVCOUNTER_OID;
-            };
-            non_trusted_nv_counter: non_trusted_nv_counter {
-                reg = <NTFW_CTR_BASE>;
-                oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+        trusted-nv-counter: trusted_nv_counter {
+           id  = <TRUSTED_NV_CTR_ID>;
+           reg = <TFW_NVCTR_BASE>;
+           oid = TRUSTED_FW_NVCOUNTER_OID;
+        };
 
-            };
+        non_trusted_nv_counter: non_trusted_nv_counter {
+           id  = <NON_TRUSTED_NV_CTR_ID>;
+           reg = <NTFW_CTR_BASE>;
+           oid = NON_TRUSTED_FW_NVCOUNTER_OID;
         };
    };
 
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index c58cd08..9a65e64 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -283,18 +283,25 @@
 paths to the SP binary image and associated DTS partition manifest file.
 The latter is going through the dtc compiler to generate the dtb fed into
 the SP package.
+This file also specifies the owner of the SP, which is an optional field and
+identifies the signing domain in case of dualroot CoT.
+The possible owner of an SP could either be Silicon Provider or Platform, and
+the corresponding "owner" field value could either be "SiP" or "Plat".
+In absence of "owner" field, it defaults to "SiP".
 
 .. code:: shell
 
     {
         "tee1" : {
             "image": "tee1.bin",
-             "pm": "tee1.dts"
+             "pm": "tee1.dts",
+             "owner": "SiP"
         },
 
         "tee2" : {
             "image": "tee2.bin",
-            "pm": "tee2.dts"
+            "pm": "tee2.dts",
+            "owner": "Plat"
         }
     }
 
@@ -376,8 +383,9 @@
 The multiple-signing domain feature (in current state dual signing domain) allows
 the use of two root keys namely S-ROTPK and NS-ROTPK (see `[8]`_):
 
--  SPMC(BL32), SPMC manifest, SPs may be signed by the SiP using the S-ROTPK.
+-  SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK.
 -  BL33 may be signed by the OEM using NS-ROTPK.
+-  An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK).
 
 Longer term multiple signing domain will allow additional signing keys, e.g.
 if SPs originate from different parties.
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 6b6c639..3c0e30f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -127,6 +127,9 @@
    Earlier revisions of the CPU have other errata which require the same
    workaround in software, so they should be covered anyway.
 
+-  ``ERRATA_A53_1530924``: This applies errata 1530924 workaround to all
+   revisions of Cortex-A53 CPU.
+
 For Cortex-A55, the following errata build flags are defined :
 
 -  ``ERRATA_A55_768277``: This applies errata 768277 workaround to Cortex-A55
@@ -147,6 +150,9 @@
 -  ``ERRATA_A55_1221012``: This applies errata 1221012 workaround to Cortex-A55
    CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
 
+-  ``ERRATA_A55_1530923``: This applies errata 1530923 workaround to all
+   revisions of Cortex-A55 CPU.
+
 For Cortex-A57, the following errata build flags are defined :
 
 -  ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57
@@ -182,12 +188,17 @@
 -  ``ERRATA_A57_859972``: This applies errata 859972 workaround to Cortex-A57
    CPU. This needs to be enabled only for revision <= r1p3 of the CPU.
 
+-  ``ERRATA_A57_1319537``: This applies errata 1319537 workaround to all
+   revisions of Cortex-A57 CPU.
 
 For Cortex-A72, the following errata build flags are defined :
 
 -  ``ERRATA_A72_859971``: This applies errata 859971 workaround to Cortex-A72
    CPU. This needs to be enabled only for revision <= r0p3 of the CPU.
 
+-  ``ERRATA_A72_1319367``: This applies errata 1319367 workaround to all
+   revisions of Cortex-A72 CPU.
+
 For Cortex-A73, the following errata build flags are defined :
 
 -  ``ERRATA_A73_852427``: This applies errata 852427 workaround to Cortex-A73
@@ -233,6 +244,11 @@
 -  ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76
    CPU. This needs to be enabled only for revision <= r4p0 of the CPU.
 
+-  ``ERRATA_A76_1165522``: This applies errata 1165522 workaround to all
+   revisions of Cortex-A76 CPU. This errata is fixed in r3p0 but due to
+   limitation of errata framework this errata is applied to all revisions
+   of Cortex-A76 CPU.
+
 For Cortex-A77, the following errata build flags are defined :
 
 -  ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77
@@ -278,6 +294,9 @@
 -  ``ERRATA_N1_1542419``: This applies errata 1542419 workaround to Neoverse-N1
    CPU. This needs to be enabled only for revisions r3p0 - r4p0 of the CPU.
 
+-  ``ERRATA_N1_1868343``: This applies errata 1868343 workaround to Neoverse-N1
+   CPU. This needs to be enabled only for revision <= r4p0 of the CPU.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index a357d58..c12e73f 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -369,7 +369,7 @@
 
 For AArch64, BL2 performs the minimal architectural initialization required
 for subsequent stages of TF-A and normal world software. EL1 and EL0 are given
-access to Floating Point and Advanced SIMD registers by clearing the
+access to Floating Point and Advanced SIMD registers by setting the
 ``CPACR.FPEN`` bits.
 
 For AArch32, the minimal architectural initialization required for subsequent
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 0acc886..b4fe404 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -694,28 +694,36 @@
    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.
+-  ``ERRATA_SPECULATIVE_AT``: This flag determines whether to enable ``AT``
+   speculative errata workaround or not. It accepts 2 values: ``1`` and ``0``.
+   The default value of this flag is ``0``.
+
+   ``AT`` speculative errata workaround disables stage1 page table walk for
+   lower ELs (EL1 and EL0) in EL3 so that ``AT`` speculative fetch at any point
+   produces either the correct result or failure without TLB allocation.
 
    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  |
-   +---------+--------------+
+   +---------+--------------+-------------------------+
+   | Errata  |      CPU     |     Workaround Define   |
+   +=========+==============+=========================+
+   | 1165522 |  Cortex-A76  |  ``ERRATA_A76_1165522`` |
+   +---------+--------------+-------------------------+
+   | 1319367 |  Cortex-A72  |  ``ERRATA_A72_1319367`` |
+   +---------+--------------+-------------------------+
+   | 1319537 |  Cortex-A57  |  ``ERRATA_A57_1319537`` |
+   +---------+--------------+-------------------------+
+   | 1530923 |  Cortex-A55  |  ``ERRATA_A55_1530923`` |
+   +---------+--------------+-------------------------+
+   | 1530924 |  Cortex-A53  |  ``ERRATA_A53_1530924`` |
+   +---------+--------------+-------------------------+
+
+   .. note::
+      This option is enabled by build only if platform sets any of above defines
+      mentioned in ’Workaround Define' column in the table.
+      If this option is enabled for the EL3 software then EL2 software also must
+      implement this workaround due to the behaviour of the errata mentioned
+      in new SDEN document which will get published soon.
 
 - ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR
   bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs.
@@ -725,6 +733,10 @@
   path on the host machine which is used to build certificate generation and
   firmware encryption tool.
 
+- ``USE_SP804_TIMER``: Use the SP804 timer instead of the Generic Timer for
+  functions that wait for an arbitrary time length (udelay and mdelay). The
+  default value is 0.
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 6b8bbc6..f331616 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -562,21 +562,14 @@
    doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't
    defined, it defaults to ``LOG_LEVEL``.
 
-If the platform port uses the Activity Monitor Unit, the following constants
+If the platform port uses the Activity Monitor Unit, the following constant
 may be defined:
 
 -  **PLAT_AMU_GROUP1_COUNTERS_MASK**
    This mask reflects the set of group counters that should be enabled.  The
    maximum number of group 1 counters supported by AMUv1 is 16 so the mask
    can be at most 0xffff. If the platform does not define this mask, no group 1
-   counters are enabled. If the platform defines this mask, the following
-   constant needs to also be defined.
-
--  **PLAT_AMU_GROUP1_NR_COUNTERS**
-   This value is used to allocate an array to save and restore the counters
-   specified by ``PLAT_AMU_GROUP1_COUNTERS_MASK`` on CPU suspend.
-   This value should be equal to the highest bit position set in the
-   mask, plus 1.  The maximum number of group 1 counters in AMUv1 is 16.
+   counters are enabled.
 
 File : plat_macros.S [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/glossary.rst b/docs/glossary.rst
index e087079..08add3a 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -18,6 +18,9 @@
    API
       Application Programming Interface
 
+   AT
+      Address Translation
+
    BTI
       Branch Target Identification. An Armv8.5 extension providing additional
       control flow integrity around indirect branches and their targets.
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 745e31f..e3bf42a 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -123,10 +123,6 @@
    -  ``FVP_GICV2`` : The GICv2 only driver is selected
    -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
 
--  ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer
-   for functions that wait for an arbitrary time length (udelay and mdelay).
-   The default value is 0.
-
 -  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
    to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
    details on HW_CONFIG. By default, this is initialized to a sensible DTS
diff --git a/docs/plat/qemu-sbsa.rst b/docs/plat/qemu-sbsa.rst
index 51fe414..bc82ae5 100644
--- a/docs/plat/qemu-sbsa.rst
+++ b/docs/plat/qemu-sbsa.rst
@@ -19,7 +19,6 @@
 Current limitations:
 
 -  Only cold boot is supported
--  No instructions for how to load a BL32 (Secure Payload)
 
 To build TF-A:
 
@@ -27,9 +26,18 @@
 
     git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa
     cd tfa
-    export CROSS_COMPILE=aarch64-linux-gnu-
+    export CROSS_COMPILE=aarch64-none-elf-
     make PLAT=qemu_sbsa all fip
 
+To build TF-A with BL32 and SPM enabled(StandaloneMM as a Secure Payload):
+
+::
+
+    git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa
+    cd tfa
+    export CROSS_COMPILE=aarch64-none-elf-
+    make PLAT=qemu_sbsa BL32=../STANDALONE_MM.fd SPM_MM=1 EL3_EXCEPTION_HANDLING=1 all fip
+
 Images will be placed at build/qemu_sbsa/release (bl1.bin and fip.bin).
 Need to copy them into top directory for EDK2 compilation.
 
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index f7d53a9..ef319e4 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -19,6 +19,7 @@
 
 Use of the EditorConfig file is suggested but is not required.
 
+.. _automatic-compliance-checking:
 
 Automatic Compliance Checking
 -----------------------------
@@ -95,10 +96,13 @@
 be compiled into debug builds and all statements with a log level
 ``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
 overridden from the command line or by the platform makefile (although it may be
-necessary to clean the build directory first). For example, to enable
-``VERBOSE`` logging on FVP:
+necessary to clean the build directory first).
 
-``make PLAT=fvp LOG_LEVEL=50 all``
+For example, to enable ``VERBOSE`` logging on FVP:
+
+.. code:: shell
+
+  make PLAT=fvp LOG_LEVEL=50 all
 
 Use const data where possible
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -438,6 +442,25 @@
 
 These guidelines should be updated if additional types are needed.
 
+Favor C language over assembly language
+---------------------------------------
+
+Generally, prefer code written in C over assembly. Assembly code is less
+portable, harder to understand, maintain and audit security wise. Also, static
+analysis tools generally don't analyze assembly code.
+
+There are, however, legitimate uses of assembly language. These include:
+
+  - Early boot code executed before the C runtime environment is setup.
+
+  - Exception handling code.
+
+  - Low-level code where the exact sequence of instructions executed on the CPU
+    matters, such as CPU reset sequences.
+
+  - Low-level code where specific system-level instructions must be used, such
+    as cache maintenance operations.
+
 --------------
 
 *Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index 7886cf4..0b3b848 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -6,15 +6,20 @@
 
 -  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.
 
-   -  If you intend to include Third Party IP in your contribution, please
-      raise a separate `issue`_ for this and ensure that the changes that
-      include Third Party IP are made on a separate topic branch.
+-  If you plan to contribute a major piece of work, it is usually a good idea to
+   start a discussion around it on the mailing list. This gives everyone
+   visibility of what is coming up, you might learn that somebody else is
+   already working on something similar or the community might be able to
+   provide some early input to help shaping the design of the feature.
+
+   If you intend to include Third Party IP in your contribution, please mention
+   it explicitly in the email thread and ensure that the changes that include
+   Third Party IP are made in a separate patch (or patch series).
 
 -  Clone `Trusted Firmware-A`_ on your own machine as described in
    :ref:`prerequisites_get_source`.
+
 -  Create a local topic branch based on the `Trusted Firmware-A`_ ``master``
    branch.
 
@@ -23,88 +28,165 @@
 
 -  Make commits of logical units. See these general `Git guidelines`_ for
    contributing to a project.
--  Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`.
-
-   -  Use the checkpatch.pl script provided with the Linux source tree. A
-      Makefile target is provided for convenience.
 
 -  Keep the commits on topic. If you need to fix another bug or make another
-   enhancement, please create a separate `issue`_ and address it on a separate
-   topic branch.
+   enhancement, please address it on a separate topic branch.
+
+-  Split the patch in manageable units. Small patches are usually easier to
+   review so this will speed up the review process.
+
 -  Avoid long commit series. If you do have a long series, consider whether
    some commits should be squashed together or addressed in a separate topic.
--  Make sure your commit messages are in the proper format. If a commit fixes
-   an `issue`_, include a reference.
--  Where appropriate, please update the documentation.
+
+-  Ensure that each commit in the series has at least one ``Signed-off-by:``
+   line, using your real name and email address. The names in the
+   ``Signed-off-by:`` and ``Commit:`` lines must match. By adding this line the
+   contributor certifies the contribution is made under the terms of the
+   :download:`Developer Certificate of Origin <../../dco.txt>`.
+
+   There might be multiple ``Signed-off-by:`` lines, depending on the history
+   of the patch.
+
+   More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
 
-   -  Consider whether the :ref:`Porting Guide`,
-      :ref:`Firmware Design` document or other in-source documentation needs
-      updating.
-   -  Ensure that each changed file has the correct copyright and license
-      information. Files that entirely consist of contributions to this
-      project should have a copyright notice and BSD-3-Clause SPDX license
-      identifier of the form as shown in :ref:`license`. Files that contain
-      changes to imported Third Party IP files should retain their original
-      copyright and license notices. For significant contributions you may
-      add your own copyright notice in following format:
+-  Ensure that each commit also has a unique ``Change-Id:`` line. If you have
+   cloned the repository with the "`Clone with commit-msg hook`" clone method
+   (following the :ref:`Prerequisites` document), this should already be the
+   case.
 
-      ::
+   More details may be found in the `Gerrit Change-Ids documentation`_.
+
+-  Write informative and comprehensive commit messages. A good commit message
+   provides all the background information needed for reviewers to understand
+   the intent and rationale of the patch. This information is also useful for
+   future reference.
 
-          Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
+   For example:
 
-      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.
+   -  What does the patch do?
+   -  What motivated it?
+   -  What impact does it have?
+   -  How was it tested?
+   -  Have alternatives been considered? Why did you choose this approach over
+      another one?
+   -  If it fixes an `issue`_, include a reference.
+
+-  Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`.
+
+   -  Use the checkpatch.pl script provided with the Linux source tree. A
+      Makefile target is provided for convenience, see :ref:`this
+      section<automatic-compliance-checking>` for more details.
+
+-  Where appropriate, please update the documentation.
+
+   -  Consider whether the :ref:`Porting Guide`, :ref:`Firmware Design` document
+      or other in-source documentation needs updating.
+
    -  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.
+
+   -  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.
+
+-  Ensure that each changed file has the correct copyright and license
+   information. Files that entirely consist of contributions to this project
+   should have a copyright notice and BSD-3-Clause SPDX license identifier of
+   the form as shown in :ref:`license`. Files that contain changes to imported
+   Third Party IP files should retain their original copyright and license
+   notices.
+
+   For significant contributions you may add your own copyright notice in the
+   following format:
+
+   ::
+
+       Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
+
+   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.
+
+-  Ensure that each patch in the patch series compiles in all supported
+   configurations. Patches which do not compile will not be merged.
 
 -  Please test your changes. As a minimum, ensure that Linux boots on the
    Foundation FVP. See :ref:`Arm Fixed Virtual Platforms (FVP)` for more
    information. For more extensive testing, consider running the `TF-A Tests`_
    against your patches.
 
+-  Ensure that all CI automated tests pass. Failures should be fixed. They might
+   block a patch, depending on how critical they are.
+
 Submitting Changes
 ------------------
 
--  Ensure that each commit in the series has at least one ``Signed-off-by:``
-   line, using your real name and email address. The names in the
-   ``Signed-off-by:`` and ``Author:`` lines must match. If anyone else
-   contributes to the commit, they must also add their own ``Signed-off-by:``
-   line. By adding this line the contributor certifies the contribution is made
-   under the terms of the
-   :download:`Developer Certificate of Origin <../../dco.txt>`.
+-  Submit your changes for review at https://review.trustedfirmware.org
+   targeting the ``integration`` branch.
 
-   More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
+-  Add reviewers for your patch:
 
--  Ensure that each commit also has a unique ``Change-Id:`` line. If you have
-   cloned the repository with the "`Clone with commit-msg hook`" clone method
-   (following the :ref:`Prerequisites` document), this should already be the
-   case.
+   -  At least one code owner for each module modified by the patch. See the list
+      of modules and their :ref:`code owners`.
 
-   More details may be found in the `Gerrit Change-Ids documentation`_.
+   -  At least one maintainer. See the list of :ref:`maintainers`.
 
--  Submit your changes for review at https://review.trustedfirmware.org
-   targeting the ``integration`` branch.
+   -  If some module has no code owner, try to identify a suitable (non-code
+      owner) reviewer. Running ``git blame`` on the module's source code can
+      help, as it shows who has been working the most recently on this area of
+      the code.
+
+      Alternatively, if it is impractical to identify such a reviewer, you might
+      send an email to the `TF-A mailing list`_ to broadcast your review request
+      to the community.
+
+   Note that self-reviewing a patch is prohibited, even if the patch author is
+   the only code owner of a module modified by the patch. Getting a second pair
+   of eyes on the code is essential to keep up with the quality standards the
+   project aspires to.
 
-   -  The changes will then undergo further review and testing by the
-      :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.
+-  The changes will then undergo further review by the designated people. 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.
 
+-  The patch submission rules are the following. For a patch to be approved
+   and merged in the tree, it must get:
+
+   -  One ``Code-Owner-Review+1`` for each of the modules modified by the patch.
+   -  A ``Maintainer-Review+1``.
+
+   In the case where a code owner could not be found for a given module,
+   ``Code-Owner-Review+1`` is substituted by ``Code-Review+1``.
+
+   In addition to these various code review labels, the patch must also get a
+   ``Verified+1``. This is usually set by the Continuous Integration (CI) bot
+   when all automated tests passed on the patch. Sometimes, some of these
+   automated tests may fail for reasons unrelated to the patch. In this case,
+   the maintainers might (after analysis of the failures) override the CI bot
+   score to certify that the patch has been correctly tested.
+
+   In the event where the CI system lacks proper tests for a patch, the patch
+   author or a reviewer might agree to perform additional manual tests
+   in their review and the reviewer incorporates the review of the additional
+   testing in the ``Code-Review+1`` or ``Code-Owner-Review+1`` as applicable to
+   attest that the patch works as expected. Where possible additional tests should
+   be added to the CI system as a follow up task. For example, for a
+   platform-dependent patch where the said platform is not available in the CI
+   system's board farm.
+
 -  When the changes are accepted, the :ref:`maintainers` will integrate them.
 
    -  Typically, the :ref:`maintainers` will merge the changes into the
       ``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 ``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
       :ref:`maintainers` will request your help to solve the issue. They may
diff --git a/docs/process/security.rst b/docs/process/security.rst
index 516eb98..a3b9971 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -20,13 +20,15 @@
 Although we try to keep TF-A secure, we can only do so with the help of the
 community of developers and security researchers.
 
-If you think you have found a security vulnerability, please **do not** report
-it in the `issue tracker`_. Instead, please follow the `TrustedFirmware.org
-security incident process`_. One of the goals of this process is to ensure
-providers of products that use TF-A have a chance to consider the implications
-of the vulnerability and its remedy before it is made public. As such, please
-follow the disclosure plan outlined in the process. We do our best to respond
-and fix any issues quickly.
+.. warning::
+   If you think you have found a security vulnerability, please **do not**
+   report it in the `issue tracker`_ or on the `mailing list`_. Instead, please
+   follow the `TrustedFirmware.org security incident process`_.
+
+One of the goals of this process is to ensure providers of products that use
+TF-A have a chance to consider the implications of the vulnerability and its
+remedy before it is made public. As such, please follow the disclosure plan
+outlined in the process. We do our best to respond and fix any issues quickly.
 
 Afterwards, we encourage you to write-up your findings about the TF-A source
 code.
@@ -69,6 +71,7 @@
 +-----------+------------------------------------------------------------------+
 
 .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
+.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
 
 .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
 .. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)`
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index 13437fe..e98b16f 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -105,6 +105,25 @@
 	return false;
 }
 
+static bool board_uses_usb0_host_mode(const void *fdt)
+{
+	int node, length;
+	const char *prop;
+
+	node = fdt_node_offset_by_compatible(fdt, -1,
+					     "allwinner,sun8i-a33-musb");
+	if (node < 0) {
+		return false;
+	}
+
+	prop = fdt_getprop(fdt, node, "dr_mode", &length);
+	if (!prop) {
+		return false;
+	}
+
+	return !strncmp(prop, "host", length);
+}
+
 void axp_setup_regulators(const void *fdt)
 {
 	int node;
@@ -121,7 +140,8 @@
 	}
 
 	/* This applies to AXP803 only. */
-	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL) &&
+	    board_uses_usb0_host_mode(fdt)) {
 		axp_clrbits(0x8f, BIT(4));
 		axp_setbits(0x30, BIT(2));
 		INFO("PMIC: Enabling DRIVEVBUS\n");
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
index 68f3d46..e1e47bc 100644
--- a/drivers/auth/dualroot/cot.c
+++ b/drivers/auth/dualroot/cot.c
@@ -743,29 +743,60 @@
 				.ptr = (void *)sp_pkg_hash_buf[3],
 				.len = (unsigned int)HASH_DER_LEN
 			}
+		}
+	}
+};
+
+DEFINE_SIP_SP_PKG(1);
+DEFINE_SIP_SP_PKG(2);
+DEFINE_SIP_SP_PKG(3);
+DEFINE_SIP_SP_PKG(4);
+
+static const auth_img_desc_t plat_sp_content_cert = {
+	.img_id = PLAT_SP_CONTENT_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 = &prot_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
 		},
-		[4] = {
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
 			.type_desc = &sp_pkg5_hash,
 			.data = {
 				.ptr = (void *)sp_pkg_hash_buf[4],
 				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		[5] = {
+		[1] = {
 			.type_desc = &sp_pkg6_hash,
 			.data = {
 				.ptr = (void *)sp_pkg_hash_buf[5],
 				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		[6] = {
+		[2] = {
 			.type_desc = &sp_pkg7_hash,
 			.data = {
 				.ptr = (void *)sp_pkg_hash_buf[6],
 				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		[7] = {
+		[3] = {
 			.type_desc = &sp_pkg8_hash,
 			.data = {
 				.ptr = (void *)sp_pkg_hash_buf[7],
@@ -775,14 +806,10 @@
 	}
 };
 
-DEFINE_SIP_SP_PKG(1);
-DEFINE_SIP_SP_PKG(2);
-DEFINE_SIP_SP_PKG(3);
-DEFINE_SIP_SP_PKG(4);
-DEFINE_SIP_SP_PKG(5);
-DEFINE_SIP_SP_PKG(6);
-DEFINE_SIP_SP_PKG(7);
-DEFINE_SIP_SP_PKG(8);
+DEFINE_PLAT_SP_PKG(5);
+DEFINE_PLAT_SP_PKG(6);
+DEFINE_PLAT_SP_PKG(7);
+DEFINE_PLAT_SP_PKG(8);
 #endif /* SPD_spmd */
 
 #else  /* IMAGE_BL2 */
@@ -915,6 +942,7 @@
 	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
 #if defined(SPD_spmd)
 	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
+	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
 	[SP_PKG1_ID]				=	&sp_pkg1,
 	[SP_PKG2_ID]				=	&sp_pkg2,
 	[SP_PKG3_ID]				=	&sp_pkg3,
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 94f2f59..8454105 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -98,10 +98,13 @@
 endif
 
 # Needs to be set to drive mbed TLS configuration correctly
-$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
-$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE))
-$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
-$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM))
+$(eval $(call add_defines,\
+    $(sort \
+        TF_MBEDTLS_KEY_ALG_ID \
+        TF_MBEDTLS_KEY_SIZE \
+        TF_MBEDTLS_HASH_ALG_ID \
+        TF_MBEDTLS_USE_AES_GCM \
+)))
 
 $(eval $(call MAKE_LIB,mbedtls))
 
diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk
index fc005d5..b7aa48b 100644
--- a/drivers/measured_boot/measured_boot.mk
+++ b/drivers/measured_boot/measured_boot.mk
@@ -25,10 +25,13 @@
 EVENT_LOG_SIZE			:= 1024
 
 # Set definitions for mbed TLS library and Measured Boot driver
-$(eval $(call add_define,MBEDTLS_MD_ID))
-$(eval $(call add_define,TPM_ALG_ID))
-$(eval $(call add_define,TCG_DIGEST_SIZE))
-$(eval $(call add_define,EVENT_LOG_SIZE))
+$(eval $(call add_defines,\
+    $(sort \
+        MBEDTLS_MD_ID \
+        TPM_ALG_ID \
+        TCG_DIGEST_SIZE \
+        EVENT_LOG_SIZE \
+)))
 
 ifeq (${HASH_ALG}, sha256)
 ifneq (${TPM_HASH_ALG}, sha256)
diff --git a/fdts/corstone700_fpga.dts b/fdts/corstone700_fpga.dts
index 814d6a8..1ac0d4b 100644
--- a/fdts/corstone700_fpga.dts
+++ b/fdts/corstone700_fpga.dts
@@ -20,6 +20,13 @@
 		reg-io-width = <2>;
 		smsc,irq-push-pull;
 	};
+
+	usb: usb@4020000 {
+		compatible = "nxp,usb-isp1763";
+		reg = <0x40200000 0x100000>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+	};
 };
 
 &refclk {
diff --git a/fdts/cot_descriptors.dtsi b/fdts/cot_descriptors.dtsi
index 9308e17..411bae6 100644
--- a/fdts/cot_descriptors.dtsi
+++ b/fdts/cot_descriptors.dtsi
@@ -6,6 +6,7 @@
 
 #include <tools_share/tbbr_oid.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
 
 cot {
 	manifests {
@@ -301,18 +302,19 @@
 	};
 };
 
-non-volatile-counters {
+non_volatile_counters: non_volatile_counters {
 	compatible = "arm, non-volatile-counter";
 
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	counters {
-		trusted_nv_counter: trusted_nv_counter {
-			oid = TRUSTED_FW_NVCOUNTER_OID;
-		};
-		non_trusted_nv_counter: non_trusted_nv_counter {
-			oid = NON_TRUSTED_FW_NVCOUNTER_OID;
-		};
+	trusted_nv_counter: trusted_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_counter: non_trusted_nv_counter {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
 };
diff --git a/fdts/n1sdp-multi-chip.dts b/fdts/n1sdp-multi-chip.dts
index b58d9d8..8932dfc 100644
--- a/fdts/n1sdp-multi-chip.dts
+++ b/fdts/n1sdp-multi-chip.dts
@@ -53,6 +53,42 @@
 				    <0 1 20>,
 				    <1 1 10>;
 	};
+
+	smmu_slave_pcie: iommu@4004f400000 {
+		compatible = "arm,smmu-v3";
+		reg = <0x400 0x4f400000 0 0x40000>;
+		interrupts = <GIC_SPI 715 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 716 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 717 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "eventq", "cmdq-sync", "gerror";
+		msi-parent = <&its2_slave 0>;
+		#iommu-cells = <1>;
+		dma-coherent;
+	};
+
+	pcie_slave_ctlr: pcie@40070000000 {
+		compatible = "arm,n1sdp-pcie";
+		device_type = "pci";
+		reg = <0x400 0x70000000 0 0x1200000>;
+		bus-range = <0 0xff>;
+		linux,pci-domain = <2>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		dma-coherent;
+		ranges = <0x01000000 0x00 0x00000000 0x400 0x75200000 0x00 0x00010000>,
+			 <0x02000000 0x00 0x71200000 0x400 0x71200000 0x00 0x04000000>,
+			 <0x42000000 0x09 0x00000000 0x409 0x00000000 0x20 0x00000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &gic 0 0 0 649 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 2 &gic 0 0 0 650 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 3 &gic 0 0 0 651 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 4 &gic 0 0 0 652 IRQ_TYPE_LEVEL_HIGH>;
+		msi-map = <0 &its_slave_pcie 0 0x10000>;
+		iommu-map = <0 &smmu_slave_pcie 0 0x10000>;
+		status = "okay";
+	};
+
 };
 
 &gic {
@@ -60,4 +96,18 @@
 	reg =   <0x0 0x30000000 0 0x10000>,	/* GICD */
 		<0x0 0x300c0000 0 0x80000>,	/* GICR */
 		<0x400 0x300c0000 0 0x80000>;	/* GICR */
+
+	its2_slave: its@40030060000 {
+		compatible = "arm,gic-v3-its";
+		msi-controller;
+		#msi-cells = <1>;
+		reg = <0x400 0x30060000 0x0 0x20000>;
+	};
+
+	its_slave_pcie: its@400300a0000 {
+		compatible = "arm,gic-v3-its";
+		msi-controller;
+		#msi-cells = <1>;
+		reg = <0x400 0x300a0000 0x0 0x20000>;
+	};
 };
diff --git a/fdts/tc0.dts b/fdts/tc0.dts
index e736e49..ac097cd 100644
--- a/fdts/tc0.dts
+++ b/fdts/tc0.dts
@@ -41,12 +41,38 @@
 			};
 		};
 
+		/*
+		 * The timings below are just to demonstrate working cpuidle.
+		 * These values may be inaccurate.
+		 */
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x0010000>;
+				local-timer-stop;
+				entry-latency-us = <300>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2000>;
+			};
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x1010000>;
+				local-timer-stop;
+				entry-latency-us = <400>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2500>;
+			};
+		};
+
 		CPU0:cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,armv8";
 			reg = <0x0>;
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 		};
 
 		CPU1:cpu@100 {
@@ -55,6 +81,7 @@
 			reg = <0x100>;
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 		};
 
 		CPU2:cpu@200 {
@@ -63,6 +90,7 @@
 			reg = <0x200>;
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 		};
 
 		CPU3:cpu@300 {
@@ -71,6 +99,7 @@
 			reg = <0x300>;
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 		};
 
 	};
@@ -195,7 +224,7 @@
 
 		port {
 			vencoder_in: endpoint {
-				remote-endpoint = <&hdlcd_out>;
+				remote-endpoint = <&dp_pl0_out0>;
 			};
 		};
 
@@ -221,7 +250,7 @@
 		interrupts = <0x0 117 0x4>;
 		clocks = <&fake_hdlcd_clk>;
 		clock-names = "pxlclk";
-		status = "ok";
+		status = "disabled";
 
 		port {
 			hdlcd_out: endpoint {
@@ -272,6 +301,35 @@
 		interrupts = <0 204 4>;
 	};
 
+	sysreg: sysreg@1c010000 {
+		compatible = "arm,vexpress-sysreg";
+		reg = <0x0 0x001c010000 0x0 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	fixed_3v3: v2m-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	mmci@1c050000 {
+		compatible = "arm,pl180", "arm,primecell";
+		reg = <0x0 0x001c050000 0x0 0x1000>;
+		interrupts = <0 107 0x4>,
+			     <0 108 0x4>;
+		cd-gpios = <&sysreg 0 0>;
+		wp-gpios = <&sysreg 1 0>;
+		bus-width = <8>;
+		max-frequency = <12000000>;
+		vmmc-supply = <&fixed_3v3>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "mclk", "apb_pclk";
+	};
+
 	dp0: display@2cc00000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -281,7 +339,6 @@
 		interrupt-names = "DPU";
 		clocks = <&scmi_clk 0>;
 		clock-names = "aclk";
-		status = "disabled";
 		pl0: pipeline@0 {
 			reg = <0>;
 			clocks = <&scmi_clk 1>;
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index a11d55e..1032e13 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -701,6 +701,16 @@
 #define AMEVTYPER1E	p15, 0, c13, c15, 6
 #define AMEVTYPER1F	p15, 0, c13, c15, 7
 
+/* AMCFGR definitions */
+#define AMCFGR_NCG_SHIFT	U(28)
+#define AMCFGR_NCG_MASK		U(0xf)
+#define AMCFGR_N_SHIFT		U(0)
+#define AMCFGR_N_MASK		U(0xff)
+
+/* AMCGCR definitions */
+#define AMCGCR_CG1NC_SHIFT	U(8)
+#define AMCGCR_CG1NC_MASK	U(0xff)
+
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index eed56e2..94cf7ea 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -300,11 +300,16 @@
 DEFINE_COPROCR_RW_FUNCS(nmrr, NMRR)
 DEFINE_COPROCR_RW_FUNCS(dacr, DACR)
 
+/* Coproc registers for 32bit AMU support */
+DEFINE_COPROCR_READ_FUNC(amcfgr, AMCFGR)
+DEFINE_COPROCR_READ_FUNC(amcgcr, AMCGCR)
+
 DEFINE_COPROCR_RW_FUNCS(amcntenset0, AMCNTENSET0)
 DEFINE_COPROCR_RW_FUNCS(amcntenset1, AMCNTENSET1)
 DEFINE_COPROCR_RW_FUNCS(amcntenclr0, AMCNTENCLR0)
 DEFINE_COPROCR_RW_FUNCS(amcntenclr1, AMCNTENCLR1)
 
+/* Coproc registers for 64bit AMU support */
 DEFINE_COPROCR_RW_FUNCS_64(amevcntr00, AMEVCNTR00)
 DEFINE_COPROCR_RW_FUNCS_64(amevcntr01, AMEVCNTR01)
 DEFINE_COPROCR_RW_FUNCS_64(amevcntr02, AMEVCNTR02)
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 90569c3..ebe1a24 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -898,9 +898,14 @@
 #define AMEVTYPER1E_EL0		S3_3_C13_C15_6
 #define AMEVTYPER1F_EL0		S3_3_C13_C15_7
 
+/* AMCFGR_EL0 definitions */
+#define AMCFGR_EL0_NCG_SHIFT	U(28)
+#define AMCFGR_EL0_NCG_MASK	U(0xf)
+#define AMCFGR_EL0_N_SHIFT	U(0)
+#define AMCFGR_EL0_N_MASK	U(0xff)
+
 /* AMCGCR_EL0 definitions */
 #define AMCGCR_EL0_CG1NC_SHIFT	U(8)
-#define AMCGCR_EL0_CG1NC_LENGTH	U(8)
 #define AMCGCR_EL0_CG1NC_MASK	U(0xff)
 
 /* MPAM register definitions */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 09059ca..1f2f4a9 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -482,7 +482,8 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
 
-DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0)
+DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
+DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
@@ -589,4 +590,24 @@
 #define read_clusterpwrdn()	read_clusterpwrdn_el1()
 #define write_clusterpwrdn(_v)	write_clusterpwrdn_el1(_v)
 
+#if ERRATA_SPECULATIVE_AT
+/*
+ * Assuming SCTLR.M bit is already enabled
+ * 1. Enable page table walk by clearing TCR_EL1.EPDx bits
+ * 2. Execute AT instruction for lower EL1/0
+ * 3. Disable page table walk by setting TCR_EL1.EPDx bits
+ */
+#define AT(_at_inst, _va)	\
+{	\
+	assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL);	\
+	write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT));	\
+	isb();	\
+	_at_inst(_va);	\
+	write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT));	\
+	isb();	\
+}
+#else
+#define AT(_at_inst, _va)	_at_inst(_va);
+#endif
+
 #endif /* ARCH_HELPERS_H */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 0708de6..17a4efa 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -9,6 +9,7 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <context.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 	/*
@@ -443,4 +444,42 @@
 #endif
 	.endm
 
+	.macro	apply_at_speculative_wa
+#if ERRATA_SPECULATIVE_AT
+	/*
+	 * Explicitly save x30 so as to free up a register and to enable
+	 * branching and also, save x29 which will be used in the called
+	 * function
+	 */
+	stp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	bl	save_and_update_ptw_el1_sys_regs
+	ldp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+#endif
+	.endm
+
+	.macro	restore_ptw_el1_sys_regs
+#if ERRATA_SPECULATIVE_AT
+	/* -----------------------------------------------------------
+	 * In case of ERRATA_SPECULATIVE_AT, must follow below order
+	 * to ensure that page table walk is not enabled until
+	 * restoration of all EL1 system registers. TCR_EL1 register
+	 * should be updated at the end which restores previous page
+	 * table walk setting of stage1 i.e.(TCR_EL1.EPDx) bits. ISB
+	 * ensures that CPU does below steps in order.
+	 *
+	 * 1. Ensure all other system registers are written before
+	 *    updating SCTLR_EL1 using ISB.
+	 * 2. Restore SCTLR_EL1 register.
+	 * 3. Ensure SCTLR_EL1 written successfully using ISB.
+	 * 4. Restore TCR_EL1 register.
+	 * -----------------------------------------------------------
+	 */
+	isb
+	ldp	x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+	msr	sctlr_el1, x28
+	isb
+	msr	tcr_el1, x29
+#endif
+	.endm
+
 #endif /* EL3_COMMON_MACROS_S */
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
index e6447f2..21d3ae7 100644
--- a/include/bl1/bl1.h
+++ b/include/bl1/bl1.h
@@ -26,8 +26,8 @@
 /*
  * BL1 SMC version
  */
-#define BL1_SMC_MAJOR_VER		0x0
-#define BL1_SMC_MINOR_VER		0x1
+#define BL1_SMC_MAJOR_VER		UL(0x0)
+#define BL1_SMC_MINOR_VER		UL(0x1)
 
 /*
  * Defines for FWU SMC function ids.
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 0248de9..29d8b3a 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,5 +11,7 @@
 int dt_add_psci_cpu_enable_methods(void *fdt);
 int fdt_add_reserved_memory(void *dtb, const char *node_name,
 			    uintptr_t base, size_t size);
+int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
+		      unsigned int afflv1, unsigned int afflv2);
 
 #endif /* FDT_FIXUP_H */
diff --git a/include/common/nv_cntr_ids.h b/include/common/nv_cntr_ids.h
new file mode 100644
index 0000000..a15c431
--- /dev/null
+++ b/include/common/nv_cntr_ids.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define	TRUSTED_NV_CTR_ID	U(0)
+#define	NON_TRUSTED_NV_CTR_ID	U(1)
+#define	MAX_NV_CTR_IDS		U(2)
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index b29b135..bd125e6 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -11,16 +11,17 @@
 
 #if defined(SPD_spmd)
 #define SIP_SP_CONTENT_CERT_ID		MAX_IMAGE_IDS
-#define SP_PKG1_ID			(MAX_IMAGE_IDS + 1)
-#define SP_PKG2_ID			(MAX_IMAGE_IDS + 2)
-#define SP_PKG3_ID			(MAX_IMAGE_IDS + 3)
-#define SP_PKG4_ID			(MAX_IMAGE_IDS + 4)
-#define SP_PKG5_ID			(MAX_IMAGE_IDS + 5)
-#define SP_PKG6_ID			(MAX_IMAGE_IDS + 6)
-#define SP_PKG7_ID			(MAX_IMAGE_IDS + 7)
-#define SP_PKG8_ID			(MAX_IMAGE_IDS + 8)
+#define PLAT_SP_CONTENT_CERT_ID		(MAX_IMAGE_IDS + 1)
+#define SP_PKG1_ID			(MAX_IMAGE_IDS + 2)
+#define SP_PKG2_ID			(MAX_IMAGE_IDS + 3)
+#define SP_PKG3_ID			(MAX_IMAGE_IDS + 4)
+#define SP_PKG4_ID			(MAX_IMAGE_IDS + 5)
+#define SP_PKG5_ID			(MAX_IMAGE_IDS + 6)
+#define SP_PKG6_ID			(MAX_IMAGE_IDS + 7)
+#define SP_PKG7_ID			(MAX_IMAGE_IDS + 8)
+#define SP_PKG8_ID			(MAX_IMAGE_IDS + 9)
 #define MAX_SP_IDS			U(8)
-#define MAX_NUMBER_IDS			(MAX_IMAGE_IDS + MAX_SP_IDS + U(1))
+#define MAX_NUMBER_IDS			(MAX_IMAGE_IDS + MAX_SP_IDS + U(2))
 #else
 #define MAX_NUMBER_IDS			MAX_IMAGE_IDS
 #endif
diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index 504e539..d1fd52c 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -21,7 +21,18 @@
  */
 #define IMG_FLAG_AUTHENTICATED		(1 << 0)
 
-
+#if COT_DESC_IN_DTB && !IMAGE_BL1
+/*
+ * Authentication image descriptor
+ */
+typedef struct auth_img_desc_s {
+	unsigned int img_id;
+	img_type_t img_type;
+	const struct auth_img_desc_s *parent;
+	auth_method_desc_t *img_auth_methods;
+	auth_param_desc_t *authenticated_data;
+} auth_img_desc_t;
+#else
 /*
  * Authentication image descriptor
  */
@@ -32,6 +43,7 @@
 	const auth_method_desc_t *const img_auth_methods;
 	const auth_param_desc_t *const authenticated_data;
 } auth_img_desc_t;
+#endif /* COT_DESC_IN_DTB && !IMAGE_BL1 */
 
 /* Public functions */
 void auth_mod_init(void);
@@ -51,11 +63,15 @@
 extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 #if defined(SPD_spmd)
-#define DEFINE_SIP_SP_PKG(n) \
+
+#define DEFINE_SIP_SP_PKG(n)		DEFINE_SP_PKG(n, sip_sp_content_cert)
+#define DEFINE_PLAT_SP_PKG(n)		DEFINE_SP_PKG(n, plat_sp_content_cert)
+
+#define DEFINE_SP_PKG(n, cert) \
 	static const auth_img_desc_t sp_pkg##n = { \
 		.img_id = SP_PKG##n##_ID, \
 		.img_type = IMG_RAW, \
-		.parent = &sip_sp_content_cert, \
+		.parent = &cert, \
 		.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { \
 			[0] = { \
 				.type = AUTH_METHOD_HASH, \
@@ -66,6 +82,7 @@
 			} \
 		} \
 	}
+
 #endif
 
 #endif /* TRUSTED_BOARD_BOOT */
diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h
index b98abdf..24b6a87 100644
--- a/include/lib/cpus/aarch64/denver.h
+++ b/include/lib/cpus/aarch64/denver.h
@@ -13,6 +13,11 @@
 #define DENVER_MIDR_PN2			U(0x4E0F0020)
 #define DENVER_MIDR_PN3			U(0x4E0F0030)
 #define DENVER_MIDR_PN4			U(0x4E0F0040)
+#define DENVER_MIDR_PN5			U(0x4E0F0050)
+#define DENVER_MIDR_PN6			U(0x4E0F0060)
+#define DENVER_MIDR_PN7			U(0x4E0F0070)
+#define DENVER_MIDR_PN8			U(0x4E0F0080)
+#define DENVER_MIDR_PN9			U(0x4E0F0090)
 
 /* Implementer code in the MIDR register */
 #define DENVER_IMPL			U(0x4E)
diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h
index b50befa..9998b93 100644
--- a/include/lib/cpus/aarch64/neoverse_n1.h
+++ b/include/lib/cpus/aarch64/neoverse_n1.h
@@ -64,4 +64,12 @@
 #define CPUPOR_EL3	S3_6_C15_C8_2
 #define CPUPMR_EL3	S3_6_C15_C8_3
 
+/******************************************************************************
+ * CPU Configuration register definitions.
+ *****************************************************************************/
+#define CPUCFR_EL1	S3_0_C15_C0_0
+
+/* SCU bit of CPU Configuration Register, EL1 */
+#define SCU_SHIFT	U(2)
+
 #endif /* NEOVERSE_N1_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 90807ce..3490414 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -72,7 +72,7 @@
 #define CTX_SPSR_EL1		U(0x0)
 #define CTX_ELR_EL1		U(0x8)
 #define CTX_SCTLR_EL1		U(0x10)
-#define CTX_ACTLR_EL1		U(0x18)
+#define CTX_TCR_EL1		U(0x18)
 #define CTX_CPACR_EL1		U(0x20)
 #define CTX_CSSELR_EL1		U(0x28)
 #define CTX_SP_EL1		U(0x30)
@@ -81,7 +81,7 @@
 #define CTX_TTBR1_EL1		U(0x48)
 #define CTX_MAIR_EL1		U(0x50)
 #define CTX_AMAIR_EL1		U(0x58)
-#define CTX_TCR_EL1		U(0x60)
+#define CTX_ACTLR_EL1		U(0x60)
 #define CTX_TPIDR_EL1		U(0x68)
 #define CTX_TPIDR_EL0		U(0x70)
 #define CTX_TPIDRRO_EL0		U(0x78)
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index 99ecfcc..dcbdd5a 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.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
  */
@@ -10,13 +10,14 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include <platform_def.h>
-
 #include <lib/cassert.h>
 #include <lib/utils_def.h>
 
+#include <platform_def.h>
+
 /* All group 0 counters */
 #define AMU_GROUP0_COUNTERS_MASK	U(0xf)
+#define AMU_GROUP0_NR_COUNTERS		U(4)
 
 #ifdef PLAT_AMU_GROUP1_COUNTERS_MASK
 #define AMU_GROUP1_COUNTERS_MASK	PLAT_AMU_GROUP1_COUNTERS_MASK
@@ -24,25 +25,67 @@
 #define AMU_GROUP1_COUNTERS_MASK	U(0)
 #endif
 
-#ifdef PLAT_AMU_GROUP1_NR_COUNTERS
-#define AMU_GROUP1_NR_COUNTERS		PLAT_AMU_GROUP1_NR_COUNTERS
+/* Calculate number of group 1 counters */
+#if (AMU_GROUP1_COUNTERS_MASK	& (1 << 15))
+#define	AMU_GROUP1_NR_COUNTERS		16U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 14))
+#define	AMU_GROUP1_NR_COUNTERS		15U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 13))
+#define	AMU_GROUP1_NR_COUNTERS		14U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 12))
+#define	AMU_GROUP1_NR_COUNTERS		13U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 11))
+#define	AMU_GROUP1_NR_COUNTERS		12U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 10))
+#define	AMU_GROUP1_NR_COUNTERS		11U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 9))
+#define	AMU_GROUP1_NR_COUNTERS		10U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 8))
+#define	AMU_GROUP1_NR_COUNTERS		9U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 7))
+#define	AMU_GROUP1_NR_COUNTERS		8U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 6))
+#define	AMU_GROUP1_NR_COUNTERS		7U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 5))
+#define	AMU_GROUP1_NR_COUNTERS		6U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 4))
+#define	AMU_GROUP1_NR_COUNTERS		5U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 3))
+#define	AMU_GROUP1_NR_COUNTERS		4U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 2))
+#define	AMU_GROUP1_NR_COUNTERS		3U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 1))
+#define	AMU_GROUP1_NR_COUNTERS		2U
+#elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 0))
+#define	AMU_GROUP1_NR_COUNTERS		1U
 #else
-#define AMU_GROUP1_NR_COUNTERS		U(0)
+#define	AMU_GROUP1_NR_COUNTERS		0U
 #endif
 
 CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask);
-CASSERT(AMU_GROUP1_NR_COUNTERS <= 16, invalid_amu_group1_nr_counters);
+
+struct amu_ctx {
+	uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS];
+
+#if AMU_GROUP1_NR_COUNTERS
+	uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS];
+#endif
+};
 
 bool amu_supported(void);
 void amu_enable(bool el2_unused);
 
 /* Group 0 configuration helpers */
-uint64_t amu_group0_cnt_read(int idx);
-void amu_group0_cnt_write(int idx, uint64_t val);
+uint64_t amu_group0_cnt_read(unsigned int idx);
+void amu_group0_cnt_write(unsigned int idx, uint64_t val);
+
+#if AMU_GROUP1_NR_COUNTERS
+bool amu_group1_supported(void);
 
 /* Group 1 configuration helpers */
-uint64_t amu_group1_cnt_read(int idx);
-void amu_group1_cnt_write(int idx, uint64_t val);
-void amu_group1_set_evtype(int idx, unsigned int val);
+uint64_t amu_group1_cnt_read(unsigned int idx);
+void amu_group1_cnt_write(unsigned int idx, uint64_t val);
+void amu_group1_set_evtype(unsigned int idx, unsigned int val);
+#endif
 
 #endif /* AMU_H */
diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h
index ab4e6aa..30ce59d 100644
--- a/include/lib/extensions/amu_private.h
+++ b/include/lib/extensions/amu_private.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,11 +9,11 @@
 
 #include <stdint.h>
 
-uint64_t amu_group0_cnt_read_internal(int idx);
-void amu_group0_cnt_write_internal(int idx, uint64_t val);
+uint64_t amu_group0_cnt_read_internal(unsigned int idx);
+void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val);
 
-uint64_t amu_group1_cnt_read_internal(int idx);
-void amu_group1_cnt_write_internal(int idx, uint64_t val);
-void amu_group1_set_evtype_internal(int idx, unsigned int val);
+uint64_t amu_group1_cnt_read_internal(unsigned int idx);
+void amu_group1_cnt_write_internal(unsigned int idx, uint64_t val);
+void amu_group1_set_evtype_internal(unsigned int idx, unsigned int val);
 
 #endif /* AMU_PRIVATE_H */
diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h
index 2d9e655..ba13683 100644
--- a/include/lib/libc/stdio.h
+++ b/include/lib/libc/stdio.h
@@ -22,6 +22,7 @@
 
 #ifdef STDARG_H
 int vprintf(const char *fmt, va_list args);
+int vsnprintf(char *s, size_t n, const char *fmt, va_list args);
 #endif
 
 int putchar(int c);
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 71774b0..91cbafb 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2020, ARM Limited and Contributors.
  * All rights reserved.
  */
 
@@ -26,5 +26,6 @@
 size_t strnlen(const char *s, size_t maxlen);
 char *strrchr(const char *p, int ch);
 size_t strlcpy(char * dst, const char * src, size_t dsize);
+size_t strlcat(char * dst, const char * src, size_t dsize);
 
 #endif /* STRING_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 76c1a8d..1ac45ad 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -89,6 +89,8 @@
 void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
 void psci_prepare_next_non_secure_ctx(
 			  entry_point_info_t *next_image_info);
+int psci_stop_other_cores(unsigned int wait_ms,
+			  void (*stop_func)(u_register_t mpidr));
 #endif /* __ASSEMBLER__ */
 
 #endif /* PSCI_LIB_H */
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 26509ae..366f056 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -122,7 +122,8 @@
  */
 #define DEFINE_SVC_UUID2(_name, _tl, _tm, _th, _cl, _ch,		\
 		_n0, _n1, _n2, _n3, _n4, _n5)				\
-	CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK, invalid_svc_uuid);\
+	CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK,			\
+		invalid_svc_uuid_##_name);				\
 	static const uuid_t _name = {					\
 		{((_tl) >> 24) & 0xFF,					\
 		 ((_tl) >> 16) & 0xFF,					\
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 293e7ce..c018643 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -568,7 +568,7 @@
 #define PLAT_SDEI_NORMAL_PRI		0x70
 
 /* ARM platforms use 3 upper bits of secure interrupt priority */
-#define ARM_PRI_BITS			3
+#define PLAT_PRI_BITS			3
 
 /* SGI used for SDEI signalling */
 #define ARM_SDEI_SGI			ARM_IRQ_SEC_SGI_0
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 03976f3..e4d4f12 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -13,8 +13,6 @@
             . = ALIGN(PAGE_SIZE);
             __INIT_CODE_START__ = .;
 	    *(*text.init*);
-            __INIT_CODE_UNALIGNED__ = .;
-            .  = ALIGN(PAGE_SIZE);
             __INIT_CODE_END__ = .;
         } >RAM
 
@@ -42,6 +40,7 @@
 	/* Offset mask */						\
 	MASK = ABS(SIGN >> 63) - 1;					\
 	. +=  ABS(OFFSET) & ABS(MASK);					\
+	.  = ALIGN(PAGE_SIZE);						\
 	__STACKS_END__ = .;						\
 	/* Total stack size */						\
 	SIZE = ABS(. - __STACKS_START__);				\
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
index 236254b..c6315be 100644
--- a/include/plat/arm/common/fconf_arm_sp_getter.h
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -14,11 +14,13 @@
 #define arm__sp_getter(prop)	arm_sp.prop
 
 #define ARM_SP_MAX_SIZE		U(0x80000)
+#define ARM_SP_OWNER_NAME_LEN	U(8)
 
 struct arm_sp_t {
 	unsigned int		number_of_sp;
 	union uuid_helper_t	uuids[MAX_SP_IDS];
 	uintptr_t		load_addr[MAX_SP_IDS];
+	char			owner[MAX_SP_IDS][ARM_SP_OWNER_NAME_LEN];
 };
 
 int fconf_populate_arm_sp(uintptr_t config);
diff --git a/include/plat/arm/common/fconf_nv_cntr_getter.h b/include/plat/arm/common/fconf_nv_cntr_getter.h
new file mode 100644
index 0000000..80a6000
--- /dev/null
+++ b/include/plat/arm/common/fconf_nv_cntr_getter.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_NV_CNTR_GETTER_H
+#define FCONF_NV_CNTR_GETTER_H
+
+#include <common/nv_cntr_ids.h>
+#include <lib/fconf/fconf.h>
+
+#define cot__nv_cntr_addr_getter(id)		nv_cntr_base_addr[id]
+
+extern uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
+
+#endif /* FCONF_NV_CNTR_GETTER_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 7285077..0513eab 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -138,4 +138,43 @@
  */
 #define FFA_PARAM_MBZ			U(0x0)
 
+/*
+ * Maximum FF-A endpoint id value
+ */
+#define FFA_ENDPOINT_ID_MAX			U(1 << 16)
+
+/*
+ * Mask for source and destination endpoint id in
+ * a direct message request/response.
+ */
+#define FFA_DIRECT_MSG_ENDPOINT_ID_MASK		U(0xffff)
+
+/*
+ * Bit shift for destination endpoint id in a direct message request/response.
+ */
+#define FFA_DIRECT_MSG_DESTINATION_SHIFT	U(0)
+
+/*
+ * Bit shift for source endpoint id in a direct message request/response.
+ */
+#define FFA_DIRECT_MSG_SOURCE_SHIFT		U(16)
+
+/******************************************************************************
+ * ffa_endpoint_destination
+ *****************************************************************************/
+static inline uint16_t ffa_endpoint_destination(unsigned int ep)
+{
+	return (ep >> FFA_DIRECT_MSG_DESTINATION_SHIFT) &
+		FFA_DIRECT_MSG_ENDPOINT_ID_MASK;
+}
+
+/******************************************************************************
+ * ffa_endpoint_source
+ *****************************************************************************/
+static inline uint16_t ffa_endpoint_source(unsigned int ep)
+{
+	return (ep >> FFA_DIRECT_MSG_SOURCE_SHIFT) &
+		FFA_DIRECT_MSG_ENDPOINT_ID_MASK;
+}
+
 #endif /* FFA_SVC_H */
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
index 64ecce0..453b21c 100644
--- a/include/services/spm_core_manifest.h
+++ b/include/services/spm_core_manifest.h
@@ -44,7 +44,7 @@
 	uint32_t binary_size;
 
 	/*
-	 * ID of the SPMD (mandatory)
+	 * ID of the SPMC (mandatory)
 	 */
 	uint16_t spmc_id;
 
diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h
index 7342c0c..bcde04f 100644
--- a/include/tools_share/firmware_image_package.h
+++ b/include/tools_share/firmware_image_package.h
@@ -66,6 +66,8 @@
 	{{0x8e,  0xc4, 0xc1, 0xf3}, {0x5d, 0x63}, {0xe4, 0x11}, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} }
 #define UUID_SIP_SECURE_PARTITION_CONTENT_CERT \
 	{{0x77,  0x6d, 0xfd, 0x44}, {0x86, 0x97}, {0x4c, 0x3b}, 0x91, 0xeb, {0xc1, 0x3e, 0x02, 0x5a, 0x2a, 0x6f} }
+#define UUID_PLAT_SECURE_PARTITION_CONTENT_CERT \
+	{{0xdd,  0xcb, 0xbf, 0x4a}, {0xca, 0xd6}, {0x11, 0xea}, 0x87, 0xd0, {0x02, 0x42, 0xac, 0x13, 0x00, 0x03} }
 /* Dynamic configs */
 #define UUID_HW_CONFIG \
 	{{0x08,  0xb8, 0xf1, 0xd9}, {0xc9, 0xcf}, {0x93, 0x49}, 0xa9, 0x62, {0x6f, 0xbc, 0x6b, 0x72, 0x65, 0xcc} }
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 37d87d3..c789f79 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -7,6 +7,8 @@
 #ifndef TBBR_OID_H
 #define TBBR_OID_H
 
+#define	MAX_OID_NAME_LEN	30
+
 /*
  * The following is a list of OID values defined and reserved by ARM, which
  * are used to define the extension fields of the certificate structure, as
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index b105de2..df11d86 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.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
  */
@@ -239,6 +239,20 @@
 	ret
 endfunc check_errata_843419
 
+	/* --------------------------------------------------
+	 * Errata workaround for Cortex A53 Errata #1530924.
+	 * This applies to all revisions of Cortex A53.
+	 * --------------------------------------------------
+	 */
+func check_errata_1530924
+#if ERRATA_A53_1530924
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_1530924
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A53.
 	 * Shall clobber: x0-x19
@@ -359,6 +373,7 @@
 	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
 	report_errata ERRATA_A53_843419, cortex_a53, 843419
 	report_errata ERRATA_A53_855873, cortex_a53, 855873
+	report_errata ERRATA_A53_1530924, cortex_a53, 1530924
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 8e13824..7838304 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.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
  */
@@ -222,6 +222,20 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_1221012
 
+	/* --------------------------------------------------
+	 * Errata workaround for Cortex A55 Errata #1530923.
+	 * This applies to all revisions of Cortex A55.
+	 * --------------------------------------------------
+	 */
+func check_errata_1530923
+#if ERRATA_A55_1530923
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_1530923
+
 func cortex_a55_reset_func
 	mov	x19, x30
 
@@ -306,6 +320,7 @@
 	report_errata ERRATA_A55_846532, cortex_a55, 846532
 	report_errata ERRATA_A55_903758, cortex_a55, 903758
 	report_errata ERRATA_A55_1221012, cortex_a55, 1221012
+	report_errata ERRATA_A55_1530923, cortex_a55, 1530923
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 3fee470..8ef0f92 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.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.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -396,6 +396,20 @@
 	ret
 endfunc check_errata_cve_2018_3639
 
+	/* --------------------------------------------------
+	 * Errata workaround for Cortex A57 Errata #1319537.
+	 * This applies to all revisions of Cortex A57.
+	 * --------------------------------------------------
+	 */
+func check_errata_1319537
+#if ERRATA_A57_1319537
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_1319537
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A57.
 	 * Shall clobber: x0-x19
@@ -613,6 +627,7 @@
 	report_errata ERRATA_A57_829520, cortex_a57, 829520
 	report_errata ERRATA_A57_833471, cortex_a57, 833471
 	report_errata ERRATA_A57_859972, cortex_a57, 859972
+	report_errata ERRATA_A57_1319537, cortex_a57, 1319537
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a57, cve_2017_5715
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a57, cve_2018_3639
 
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index 38b76b9..aff6072 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -119,6 +119,20 @@
 	ret
 endfunc check_errata_cve_2018_3639
 
+	/* --------------------------------------------------
+	 * Errata workaround for Cortex A72 Errata #1319367.
+	 * This applies to all revisions of Cortex A72.
+	 * --------------------------------------------------
+	 */
+func check_errata_1319367
+#if ERRATA_A72_1319367
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_1319367
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A72.
 	 * -------------------------------------------------
@@ -282,6 +296,7 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_A72_859971, cortex_a72, 859971
+	report_errata ERRATA_A72_1319367, cortex_a72, 1319367
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a72, cve_2017_5715
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a72, cve_2018_3639
 
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 10011f7..0895946 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -465,6 +465,23 @@
 	ret
 endfunc cortex_a76_disable_wa_cve_2018_3639
 
+	/* --------------------------------------------------------------
+	 * Errata Workaround for Cortex A76 Errata #1165522.
+	 * This applies only to revisions <= r3p0 of Cortex A76.
+	 * Due to the nature of the errata it is applied unconditionally
+	 * when built in, report it as applicable in this case
+	 * --------------------------------------------------------------
+	 */
+func check_errata_1165522
+#if ERRATA_A76_1165522
+	mov	x0, #ERRATA_APPLIES
+	ret
+#else
+	mov	x1, #0x30
+	b	cpu_rev_var_ls
+#endif
+endfunc check_errata_1165522
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A76.
 	 * Shall clobber: x0-x19
@@ -597,6 +614,7 @@
 	report_errata ERRATA_A76_1286807, cortex_a76, 1286807
 	report_errata ERRATA_A76_1791580, cortex_a76, 1791580
 	report_errata ERRATA_A76_1800710, cortex_a76, 1800710
+	report_errata ERRATA_A76_1165522, cortex_a76, 1165522
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
 	report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 808c7f8..da663be 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -78,6 +78,10 @@
 	mov	x1, #CPU_PWR_DWN_OPS
 	add	x1, x1, x2, lsl #3
 	ldr	x1, [x0, x1]
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif
 	br	x1
 endfunc prepare_cpu_pwr_dwn
 
@@ -171,6 +175,10 @@
 
 	/* Subtract the increment and offset to get the cpu-ops pointer */
 	sub	x0, x4, #(CPU_OPS_SIZE + CPU_MIDR)
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 error_exit:
 	ret
 endfunc get_cpu_ops_ptr
@@ -276,7 +284,15 @@
 	 * turn.
 	 */
 	mrs	x0, tpidr_el3
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x1, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x1, #CPU_ERRATA_FUNC]
 	cbz	x0, .Lnoprint
 
@@ -326,6 +342,10 @@
 	ASM_ASSERT(ne)
 #endif
 	ldr	x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x0, #CPU_EXTRA1_FUNC]
 	/*
 	 * If the reserved function pointer is NULL, this CPU
@@ -359,6 +379,10 @@
 	ASM_ASSERT(ne)
 #endif
 	ldr	x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x0, #CPU_EXTRA2_FUNC]
 	ret
 endfunc wa_cve_2018_3639_get_disable_ptr
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index c050b02..224ee26 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -27,8 +27,6 @@
 	 * table.
 	 * -------------------------------------------------
 	 */
-	.globl	workaround_bpflush_runtime_exceptions
-
 vector_base workaround_bpflush_runtime_exceptions
 
 	.macro	apply_workaround
@@ -163,13 +161,19 @@
 	 * ----------------------------------------------------
 	 */
 func denver_enable_dco
+	/* DCO is not supported on PN5 and later */
+	mrs	x1, midr_el1
+	mov_imm	x2, DENVER_MIDR_PN4
+	cmp	x1, x2
+	b.hi	1f
+
 	mov	x18, x30
 	bl	plat_my_core_pos
 	mov	x1, #1
 	lsl	x1, x1, x0
 	msr	s3_0_c15_c0_2, x1
 	mov	x30, x18
-	ret
+1:	ret
 endfunc denver_enable_dco
 
 	/* ----------------------------------------------------
@@ -177,10 +181,14 @@
 	 * ----------------------------------------------------
 	 */
 func denver_disable_dco
-
-	mov	x18, x30
+	/* DCO is not supported on PN5 and later */
+	mrs	x1, midr_el1
+	mov_imm	x2, DENVER_MIDR_PN4
+	cmp	x1, x2
+	b.hi	2f
 
 	/* turn off background work */
+	mov	x18, x30
 	bl	plat_my_core_pos
 	mov	x1, #1
 	lsl	x1, x1, x0
@@ -196,7 +204,7 @@
 	cbnz	x2, 1b
 
 	mov	x30, x18
-	ret
+2:	ret
 endfunc denver_disable_dco
 
 func check_errata_cve_2017_5715
@@ -355,37 +363,23 @@
 	ret
 endfunc denver_cpu_reg_dump
 
-declare_cpu_ops_wa denver, DENVER_MIDR_PN0, \
-	denver_reset_func, \
-	check_errata_cve_2017_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	denver_core_pwr_dwn, \
-	denver_cluster_pwr_dwn
-
-declare_cpu_ops_wa denver, DENVER_MIDR_PN1, \
-	denver_reset_func, \
-	check_errata_cve_2017_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	denver_core_pwr_dwn, \
-	denver_cluster_pwr_dwn
-
-declare_cpu_ops_wa denver, DENVER_MIDR_PN2, \
-	denver_reset_func, \
-	check_errata_cve_2017_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	denver_core_pwr_dwn, \
-	denver_cluster_pwr_dwn
-
-declare_cpu_ops_wa denver, DENVER_MIDR_PN3, \
-	denver_reset_func, \
-	check_errata_cve_2017_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	denver_core_pwr_dwn, \
-	denver_cluster_pwr_dwn
+/* macro to declare cpu_ops for Denver SKUs */
+.macro	denver_cpu_ops_wa midr
+	declare_cpu_ops_wa denver, \midr, \
+		denver_reset_func, \
+		check_errata_cve_2017_5715, \
+		CPU_NO_EXTRA2_FUNC, \
+		denver_core_pwr_dwn, \
+		denver_cluster_pwr_dwn
+.endm
 
-declare_cpu_ops_wa denver, DENVER_MIDR_PN4, \
-	denver_reset_func, \
-	check_errata_cve_2017_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	denver_core_pwr_dwn, \
-	denver_cluster_pwr_dwn
+denver_cpu_ops_wa DENVER_MIDR_PN0
+denver_cpu_ops_wa DENVER_MIDR_PN1
+denver_cpu_ops_wa DENVER_MIDR_PN2
+denver_cpu_ops_wa DENVER_MIDR_PN3
+denver_cpu_ops_wa DENVER_MIDR_PN4
+denver_cpu_ops_wa DENVER_MIDR_PN5
+denver_cpu_ops_wa DENVER_MIDR_PN6
+denver_cpu_ops_wa DENVER_MIDR_PN7
+denver_cpu_ops_wa DENVER_MIDR_PN8
+denver_cpu_ops_wa DENVER_MIDR_PN9
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 100ffaa..da052d5 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -72,18 +72,36 @@
 	 * This function is called from both assembly and C environment. So it
 	 * follows AAPCS.
 	 *
-	 * Clobbers: x0-x3
+	 * Clobbers: x0-x15
 	 * -----------------------------------------------------------------------
 	 */
 	.globl	check_errata_dsu_936184
 	.globl	errata_dsu_936184_wa
+	.weak	is_scu_present_in_dsu
+
+	/* --------------------------------------------------------------------
+	 * Default behaviour respresents SCU is always present with DSU.
+	 * CPUs can override this definition if required.
+	 *
+	 * Can clobber only: x0-x14
+	 * --------------------------------------------------------------------
+	 */
+func is_scu_present_in_dsu
+	mov	x0, #1
+	ret
+endfunc is_scu_present_in_dsu
 
 func check_errata_dsu_936184
-	mov	x2, #ERRATA_NOT_APPLIES
-	mov	x3, #ERRATA_APPLIES
+	mov	x15, x30
+	bl	is_scu_present_in_dsu
+	cmp	x0, xzr
+	/* Default error status */
+	mov	x0, #ERRATA_NOT_APPLIES
+
+	/* If SCU is not present, return without applying patch */
+	b.eq	1f
 
 	/* Erratum applies only if DSU has the ACP interface */
-	mov	x0, x2
 	mrs	x1, CLUSTERCFR_EL1
 	ubfx	x1, x1, #CLUSTERCFR_ACP_SHIFT, #1
 	cbz	x1, 1f
@@ -92,13 +110,13 @@
 	mrs	x1, CLUSTERIDR_EL1
 
 	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
-	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
+	ubfx	x2, x1, #CLUSTERIDR_REV_SHIFT,\
 			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
-	mov	x1, #(0x2 << CLUSTERIDR_VAR_SHIFT)
-	cmp	x0, x1
-	csel	x0, x2, x3, hs
+	cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT)
+	b.hs	1f
+	mov	x0, #ERRATA_APPLIES
 1:
-	ret
+	ret	x15
 endfunc check_errata_dsu_936184
 
 	/* --------------------------------------------------
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index d537ed6..03ee472 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -22,6 +22,19 @@
 #endif
 
 	.global neoverse_n1_errata_ic_trap_handler
+	.global is_scu_present_in_dsu
+
+/*
+ * Check DSU is configured with SCU and L3 unit
+ * 1-> SCU present
+ * 0-> SCU not present
+ */
+func is_scu_present_in_dsu
+	mrs	x0, CPUCFR_EL1
+	ubfx	x0, x0, #SCU_SHIFT, #1
+	eor	x0, x0, #1
+	ret
+endfunc is_scu_present_in_dsu
 
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Erratum 1043202.
@@ -375,6 +388,38 @@
 	b	cpu_rev_var_range
 endfunc check_errata_1542419
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Neoverse N1 Errata #1868343.
+	 * This applies to revision <= r4p0 of Neoverse N1.
+	 * This workaround is the same as the workaround for
+	 * errata 1262606 and 1275112 but applies to a wider
+	 * revision range.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_n1_1868343_wa
+	/*
+	 * Compare x0 against revision r4p0
+	 */
+	mov	x17, x30
+	bl	check_errata_1868343
+	cbz	x0, 1f
+	mrs	x1, NEOVERSE_N1_CPUACTLR_EL1
+	orr	x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
+	msr	NEOVERSE_N1_CPUACTLR_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_n1_1868343_wa
+
+func check_errata_1868343
+	/* Applies to everything <= r4p0 */
+	mov	x1, #0x40
+	b	cpu_rev_var_ls
+endfunc check_errata_1868343
+
 func neoverse_n1_reset_func
 	mov	x19, x30
 
@@ -449,6 +494,11 @@
 	bl	errata_n1_1542419_wa
 #endif
 
+#if ERRATA_N1_1868343
+	mov	x0, x18
+	bl	errata_n1_1868343_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -522,6 +572,7 @@
 	report_errata ERRATA_N1_1275112, neoverse_n1, 1275112
 	report_errata ERRATA_N1_1315703, neoverse_n1, 1315703
 	report_errata ERRATA_N1_1542419, neoverse_n1, 1542419
+	report_errata ERRATA_N1_1868343, neoverse_n1, 1868343
 	report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index e494375..7cd8ed9 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -130,6 +130,10 @@
 # of by the rich OS.
 ERRATA_A53_855873	?=0
 
+# Flag to apply erratum 1530924 workaround during reset. This erratum applies
+# to all revisions of Cortex A53 cpu.
+ERRATA_A53_1530924	?=0
+
 # Flag to apply erratum 768277 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A55 cpu.
 ERRATA_A55_768277	?=0
@@ -154,6 +158,10 @@
 # only to revision <= r1p0 of the Cortex A55 cpu.
 ERRATA_A55_1221012	?=0
 
+# Flag to apply erratum 1530923 workaround during reset. This erratum applies
+# to all revisions of Cortex A55 cpu.
+ERRATA_A55_1530923	?=0
+
 # Flag to apply erratum 806969 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
 ERRATA_A57_806969	?=0
@@ -198,10 +206,18 @@
 # only to revision <= r1p3 of the Cortex A57 cpu.
 ERRATA_A57_859972	?=0
 
+# Flag to apply erratum 1319537 workaround during reset. This erratum applies
+# to all revisions of Cortex A57 cpu.
+ERRATA_A57_1319537	?=0
+
 # Flag to apply erratum 855971 workaround during reset. This erratum applies
 # only to revision <= r0p3 of the Cortex A72 cpu.
 ERRATA_A72_859971	?=0
 
+# Flag to apply erratum 1319367 workaround during reset. This erratum applies
+# to all revisions of Cortex A72 cpu.
+ERRATA_A72_1319367	?=0
+
 # Flag to apply erratum 852427 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A73 cpu.
 ERRATA_A73_852427	?=0
@@ -258,6 +274,10 @@
 # only to revision <= r4p0 of the Cortex A76 cpu.
 ERRATA_A76_1800710	?=0
 
+# Flag to apply erratum 1165522 workaround during reset. This erratum applies
+# to all revisions of Cortex A76 cpu.
+ERRATA_A76_1165522	?=0
+
 # Flag to apply erratum 1800714 workaround during reset. This erratum applies
 # only to revision <= r1p1 of the Cortex A77 cpu.
 ERRATA_A77_1800714	?=0
@@ -314,6 +334,10 @@
 # to revisions r3p0 - r4p0 of the Neoverse N1 cpu.
 ERRATA_N1_1542419	?=0
 
+# Flag to apply erratum 1868343 workaround during reset. This erratum applies
+# to revision <= r4p0 of the Neoverse N1 cpu.
+ERRATA_N1_1868343	?=0
+
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
 ERRATA_DSU_798953	?=0
@@ -379,6 +403,10 @@
 $(eval $(call assert_boolean,ERRATA_A53_855873))
 $(eval $(call add_define,ERRATA_A53_855873))
 
+# Process ERRATA_A53_1530924 flag
+$(eval $(call assert_boolean,ERRATA_A53_1530924))
+$(eval $(call add_define,ERRATA_A53_1530924))
+
 # Process ERRATA_A55_768277 flag
 $(eval $(call assert_boolean,ERRATA_A55_768277))
 $(eval $(call add_define,ERRATA_A55_768277))
@@ -403,6 +431,10 @@
 $(eval $(call assert_boolean,ERRATA_A55_1221012))
 $(eval $(call add_define,ERRATA_A55_1221012))
 
+# Process ERRATA_A55_1530923 flag
+$(eval $(call assert_boolean,ERRATA_A55_1530923))
+$(eval $(call add_define,ERRATA_A55_1530923))
+
 # Process ERRATA_A57_806969 flag
 $(eval $(call assert_boolean,ERRATA_A57_806969))
 $(eval $(call add_define,ERRATA_A57_806969))
@@ -447,10 +479,18 @@
 $(eval $(call assert_boolean,ERRATA_A57_859972))
 $(eval $(call add_define,ERRATA_A57_859972))
 
+# Process ERRATA_A57_1319537 flag
+$(eval $(call assert_boolean,ERRATA_A57_1319537))
+$(eval $(call add_define,ERRATA_A57_1319537))
+
 # Process ERRATA_A72_859971 flag
 $(eval $(call assert_boolean,ERRATA_A72_859971))
 $(eval $(call add_define,ERRATA_A72_859971))
 
+# Process ERRATA_A72_1319367 flag
+$(eval $(call assert_boolean,ERRATA_A72_1319367))
+$(eval $(call add_define,ERRATA_A72_1319367))
+
 # Process ERRATA_A73_852427 flag
 $(eval $(call assert_boolean,ERRATA_A73_852427))
 $(eval $(call add_define,ERRATA_A73_852427))
@@ -507,6 +547,10 @@
 $(eval $(call assert_boolean,ERRATA_A76_1800710))
 $(eval $(call add_define,ERRATA_A76_1800710))
 
+# Process ERRATA_A76_1165522 flag
+$(eval $(call assert_boolean,ERRATA_A76_1165522))
+$(eval $(call add_define,ERRATA_A76_1165522))
+
 # Process ERRATA_A77_1800714 flag
 $(eval $(call assert_boolean,ERRATA_A77_1800714))
 $(eval $(call add_define,ERRATA_A77_1800714))
@@ -563,6 +607,10 @@
 $(eval $(call assert_boolean,ERRATA_N1_1542419))
 $(eval $(call add_define,ERRATA_N1_1542419))
 
+# Process ERRATA_N1_1868343 flag
+$(eval $(call assert_boolean,ERRATA_N1_1868343))
+$(eval $(call add_define,ERRATA_N1_1868343))
+
 # Process ERRATA_DSU_798953 flag
 $(eval $(call assert_boolean,ERRATA_DSU_798953))
 $(eval $(call add_define,ERRATA_DSU_798953))
@@ -580,3 +628,10 @@
 TF_CFLAGS_aarch64	+= -mfix-cortex-a53-835769
 TF_LDFLAGS_aarch64	+= --fix-cortex-a53-835769
 endif
+
+ifneq ($(filter 1,${ERRATA_A53_1530924} ${ERRATA_A55_1530923}	\
+	${ERRATA_A57_1319537} ${ERRATA_A72_1319367} ${ERRATA_A76_1165522}),)
+ERRATA_SPECULATIVE_AT	:= 1
+else
+ERRATA_SPECULATIVE_AT	:= 0
+endif
diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c
index b0ee39a..d8b83b7 100644
--- a/lib/debugfs/devfip.c
+++ b/lib/debugfs/devfip.c
@@ -76,7 +76,8 @@
 	{"fw.cfg",		UUID_FW_CONFIG},
 	{"rot-k.crt",		UUID_ROT_KEY_CERT},
 	{"nt-k.crt",		UUID_NON_TRUSTED_WORLD_KEY_CERT},
-	{"sip-sp.crt",		UUID_SIP_SECURE_PARTITION_CONTENT_CERT}
+	{"sip-sp.crt",		UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
+	{"plat-sp.crt",		UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}
 };
 
 /*******************************************************************************
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1568ef0..1cb527d 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -8,6 +8,7 @@
 #include <asm_macros.S>
 #include <assert_macros.S>
 #include <context.h>
+#include <el3_common_macros.S>
 
 #if CTX_INCLUDE_EL2_REGS
 	.global	el2_sysregs_context_save
@@ -22,6 +23,7 @@
 #endif
 	.global	save_gp_pmcr_pauth_regs
 	.global	restore_gp_pmcr_pauth_regs
+	.global save_and_update_ptw_el1_sys_regs
 	.global	el3_exit
 
 #if CTX_INCLUDE_EL2_REGS
@@ -233,21 +235,6 @@
  */
 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
@@ -296,136 +283,127 @@
 	msr	mdcr_el2, x15
 	msr	PMSCR_EL2, x16
 
-	ldp	x17, x9, [x0, #CTX_SPSR_EL2]
-	msr	spsr_el2, x17
-	msr	sp_el2, x9
+	ldp	x17, x9, [x0, #CTX_SCTLR_EL2]
+	msr	sctlr_el2, x17
+	msr	spsr_el2, x9
 
-	ldp	x10, x11, [x0, #CTX_TPIDR_EL2]
-	msr	tpidr_el2, x10
-	msr	ttbr0_el2, x11
+	ldp	x10, x11, [x0, #CTX_SP_EL2]
+	msr	sp_el2, x10
+	msr	tcr_el2, x11
 
-	ldp	x12, x13, [x0, #CTX_VBAR_EL2]
-	msr	vbar_el2, x12
-	msr	vmpidr_el2, x13
+	ldp	x12, x13, [x0, #CTX_TPIDR_EL2]
+	msr	tpidr_el2, x12
+	msr	ttbr0_el2, x13
 
-	ldp	x14, x15, [x0, #CTX_VPIDR_EL2]
-	msr	vpidr_el2, x14
-	msr	vtcr_el2, x15
+	ldp	x13, x14, [x0, #CTX_VBAR_EL2]
+	msr	vbar_el2, x13
+	msr	vmpidr_el2, x14
 
-	ldr	x16, [x0, #CTX_VTTBR_EL2]
-	msr	vttbr_el2, x16
+	ldp	x15, x16, [x0, #CTX_VPIDR_EL2]
+	msr	vpidr_el2, x15
+	msr	vtcr_el2, x16
+
+	ldr	x17, [x0, #CTX_VTTBR_EL2]
+	msr	vttbr_el2, x17
 
 #if CTX_INCLUDE_MTE_REGS
-	ldr	x17, [x0, #CTX_TFSR_EL2]
-	msr	TFSR_EL2, x17
+	ldr	x9, [x0, #CTX_TFSR_EL2]
+	msr	TFSR_EL2, x9
 #endif
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
-	ldp	x9, x10, [x0, #CTX_MPAM2_EL2]
-	msr	MPAM2_EL2, x9
-	msr	MPAMHCR_EL2, x10
+	ldp	x10, x11, [x0, #CTX_MPAM2_EL2]
+	msr	MPAM2_EL2, x10
+	msr	MPAMHCR_EL2, x11
 
-	ldp	x11, x12, [x0, #CTX_MPAMVPM0_EL2]
-	msr	MPAMVPM0_EL2, x11
-	msr	MPAMVPM1_EL2, x12
+	ldp	x12, x13, [x0, #CTX_MPAMVPM0_EL2]
+	msr	MPAMVPM0_EL2, x12
+	msr	MPAMVPM1_EL2, x13
 
-	ldp	x13, x14, [x0, #CTX_MPAMVPM2_EL2]
-	msr	MPAMVPM2_EL2, x13
-	msr	MPAMVPM3_EL2, x14
+	ldp	x14, x15, [x0, #CTX_MPAMVPM2_EL2]
+	msr	MPAMVPM2_EL2, x14
+	msr	MPAMVPM3_EL2, x15
 
-	ldp	x15, x16, [x0, #CTX_MPAMVPM4_EL2]
-	msr	MPAMVPM4_EL2, x15
-	msr	MPAMVPM5_EL2, x16
+	ldp	x16, x17, [x0, #CTX_MPAMVPM4_EL2]
+	msr	MPAMVPM4_EL2, x16
+	msr	MPAMVPM5_EL2, x17
 
-	ldp	x17, x9, [x0, #CTX_MPAMVPM6_EL2]
-	msr	MPAMVPM6_EL2, x17
-	msr	MPAMVPM7_EL2, x9
+	ldp	x9, x10, [x0, #CTX_MPAMVPM6_EL2]
+	msr	MPAMVPM6_EL2, x9
+	msr	MPAMVPM7_EL2, x10
 
-	ldr	x10, [x0, #CTX_MPAMVPMV_EL2]
-	msr	MPAMVPMV_EL2, x10
+	ldr	x11, [x0, #CTX_MPAMVPMV_EL2]
+	msr	MPAMVPMV_EL2, x11
 #endif
 
 #if ARM_ARCH_AT_LEAST(8, 6)
-	ldp	x11, x12, [x0, #CTX_HAFGRTR_EL2]
-	msr	HAFGRTR_EL2, x11
-	msr	HDFGRTR_EL2, x12
+	ldp	x12, x13, [x0, #CTX_HAFGRTR_EL2]
+	msr	HAFGRTR_EL2, x12
+	msr	HDFGRTR_EL2, x13
 
-	ldp	x13, x14, [x0, #CTX_HDFGWTR_EL2]
-	msr	HDFGWTR_EL2, x13
-	msr	HFGITR_EL2, x14
+	ldp	x14, x15, [x0, #CTX_HDFGWTR_EL2]
+	msr	HDFGWTR_EL2, x14
+	msr	HFGITR_EL2, x15
 
-	ldp	x15, x16, [x0, #CTX_HFGRTR_EL2]
-	msr	HFGRTR_EL2, x15
-	msr	HFGWTR_EL2, x16
+	ldp	x16, x17, [x0, #CTX_HFGRTR_EL2]
+	msr	HFGRTR_EL2, x16
+	msr	HFGWTR_EL2, x17
 
-	ldr	x17, [x0, #CTX_CNTPOFF_EL2]
-	msr	CNTPOFF_EL2, x17
+	ldr	x9, [x0, #CTX_CNTPOFF_EL2]
+	msr	CNTPOFF_EL2, x9
 #endif
 
 #if ARM_ARCH_AT_LEAST(8, 4)
-	ldp	x9, x10, [x0, #CTX_CNTHPS_CTL_EL2]
-	msr	cnthps_ctl_el2, x9
-	msr	cnthps_cval_el2, x10
+	ldp	x10, x11, [x0, #CTX_CNTHPS_CTL_EL2]
+	msr	cnthps_ctl_el2, x10
+	msr	cnthps_cval_el2, x11
 
-	ldp	x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2]
-	msr	cnthps_tval_el2, x11
-	msr	cnthvs_ctl_el2, x12
+	ldp	x12, x13, [x0, #CTX_CNTHPS_TVAL_EL2]
+	msr	cnthps_tval_el2, x12
+	msr	cnthvs_ctl_el2, x13
 
-	ldp	x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2]
-	msr	cnthvs_cval_el2, x13
-	msr	cnthvs_tval_el2, x14
+	ldp	x14, x15, [x0, #CTX_CNTHVS_CVAL_EL2]
+	msr	cnthvs_cval_el2, x14
+	msr	cnthvs_tval_el2, x15
 
-	ldp	x15, x16, [x0, #CTX_CNTHV_CTL_EL2]
-	msr	cnthv_ctl_el2, x15
-	msr	cnthv_cval_el2, x16
+	ldp	x16, x17, [x0, #CTX_CNTHV_CTL_EL2]
+	msr	cnthv_ctl_el2, x16
+	msr	cnthv_cval_el2, x17
 
-	ldp	x17, x9, [x0, #CTX_CNTHV_TVAL_EL2]
-	msr	cnthv_tval_el2, x17
-	msr	contextidr_el2, x9
+	ldp	x9, x10, [x0, #CTX_CNTHV_TVAL_EL2]
+	msr	cnthv_tval_el2, x9
+	msr	contextidr_el2, x10
 
-	ldr	x10, [x0, #CTX_SDER32_EL2]
-	msr	sder32_el2, x10
+	ldr	x11, [x0, #CTX_SDER32_EL2]
+	msr	sder32_el2, x11
 
-	ldr	x11, [x0, #CTX_TTBR1_EL2]
-	msr	ttbr1_el2, x11
+	ldr	x12, [x0, #CTX_TTBR1_EL2]
+	msr	ttbr1_el2, x12
 
-	ldr	x12, [x0, #CTX_VDISR_EL2]
-	msr	vdisr_el2, x12
+	ldr	x13, [x0, #CTX_VDISR_EL2]
+	msr	vdisr_el2, x13
 
-	ldr	x13, [x0, #CTX_VNCR_EL2]
-	msr	vncr_el2, x13
+	ldr	x14, [x0, #CTX_VNCR_EL2]
+	msr	vncr_el2, x14
 
-	ldr	x14, [x0, #CTX_VSESR_EL2]
-	msr	vsesr_el2, x14
+	ldr	x15, [x0, #CTX_VSESR_EL2]
+	msr	vsesr_el2, x15
 
-	ldr	x15, [x0, #CTX_VSTCR_EL2]
-	msr	vstcr_el2, x15
+	ldr	x16, [x0, #CTX_VSTCR_EL2]
+	msr	vstcr_el2, x16
 
-	ldr	x16, [x0, #CTX_VSTTBR_EL2]
-	msr	vsttbr_el2, x16
+	ldr	x17, [x0, #CTX_VSTTBR_EL2]
+	msr	vsttbr_el2, x17
 
-	ldr	x17, [x0, #CTX_TRFCR_EL2]
-	msr	TRFCR_EL2, x17
+	ldr	x9, [x0, #CTX_TRFCR_EL2]
+	msr	TRFCR_EL2, x9
 #endif
 
 #if ARM_ARCH_AT_LEAST(8, 5)
-	ldr	x9, [x0, #CTX_SCXTNUM_EL2]
-	msr	scxtnum_el2, x9
+	ldr	x10, [x0, #CTX_SCXTNUM_EL2]
+	msr	scxtnum_el2, x10
 #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
 
@@ -444,9 +422,11 @@
 	mrs	x10, elr_el1
 	stp	x9, x10, [x0, #CTX_SPSR_EL1]
 
+#if !ERRATA_SPECULATIVE_AT
 	mrs	x15, sctlr_el1
-	mrs	x16, actlr_el1
+	mrs	x16, tcr_el1
 	stp	x15, x16, [x0, #CTX_SCTLR_EL1]
+#endif
 
 	mrs	x17, cpacr_el1
 	mrs	x9, csselr_el1
@@ -464,9 +444,9 @@
 	mrs	x15, amair_el1
 	stp	x14, x15, [x0, #CTX_MAIR_EL1]
 
-	mrs	x16, tcr_el1
+	mrs	x16, actlr_el1
 	mrs	x17, tpidr_el1
-	stp	x16, x17, [x0, #CTX_TCR_EL1]
+	stp	x16, x17, [x0, #CTX_ACTLR_EL1]
 
 	mrs	x9, tpidr_el0
 	mrs	x10, tpidrro_el0
@@ -537,23 +517,15 @@
  */
 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
 
-	ldr	x16, [x0, #CTX_ACTLR_EL1]
-	msr	actlr_el1, x16
+#if !ERRATA_SPECULATIVE_AT
+	ldp	x15, x16, [x0, #CTX_SCTLR_EL1]
+	msr	sctlr_el1, x15
+	msr	tcr_el1, x16
+#endif
 
 	ldp	x17, x9, [x0, #CTX_CPACR_EL1]
 	msr	cpacr_el1, x17
@@ -571,8 +543,9 @@
 	msr	mair_el1, x14
 	msr	amair_el1, x15
 
-	ldr	x16,[x0, #CTX_TPIDR_EL1]
-	msr	tpidr_el1, x16
+	ldp 	x16, x17, [x0, #CTX_ACTLR_EL1]
+	msr	actlr_el1, x16
+	msr	tpidr_el1, x17
 
 	ldp	x9, x10, [x0, #CTX_TPIDR_EL0]
 	msr	tpidr_el0, x9
@@ -628,19 +601,6 @@
 	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
@@ -905,6 +865,48 @@
 	ret
 endfunc restore_gp_pmcr_pauth_regs
 
+/*
+ * In case of ERRATA_SPECULATIVE_AT, save SCTLR_EL1 and TCR_EL1
+ * registers and update EL1 registers to disable stage1 and stage2
+ * page table walk
+ */
+func save_and_update_ptw_el1_sys_regs
+	/* ----------------------------------------------------------
+	 * Save only sctlr_el1 and tcr_el1 registers
+	 * ----------------------------------------------------------
+	 */
+	mrs	x29, sctlr_el1
+	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1)]
+	mrs	x29, tcr_el1
+	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_TCR_EL1)]
+
+	/* ------------------------------------------------------------
+	 * Must follow below order in order to disable page table
+	 * walk for lower ELs (EL1 and EL0). First step ensures that
+	 * page table walk is disabled for stage1 and second step
+	 * ensures that page table walker should use TCR_EL1.EPDx
+	 * bits to perform address translation. ISB ensures that CPU
+	 * does these 2 steps in order.
+	 *
+	 * 1. Update TCR_EL1.EPDx bits to disable page table walk by
+	 *    stage1.
+	 * 2. Enable MMU bit to avoid identity mapping via stage2
+	 *    and force TCR_EL1.EPDx to be used by the page table
+	 *    walker.
+	 * ------------------------------------------------------------
+	 */
+	orr	x29, x29, #(TCR_EPD0_BIT)
+	orr	x29, x29, #(TCR_EPD1_BIT)
+	msr	tcr_el1, x29
+	isb
+	mrs	x29, sctlr_el1
+	orr	x29, x29, #SCTLR_M_BIT
+	msr	sctlr_el1, x29
+	isb
+
+	ret
+endfunc save_and_update_ptw_el1_sys_regs
+
 /* ------------------------------------------------------------------
  * This routine assumes that the SP_EL3 is pointing to a valid
  * context structure from where the gp regs and other special
@@ -949,6 +951,8 @@
 	blr	x17
 1:
 #endif
+	restore_ptw_el1_sys_regs
+
 	/* ----------------------------------------------------------
 	 * Restore general purpose (including x30), PMCR_EL0 and
 	 * ARMv8.3-PAuth registers.
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index f4a34bf..e5434eb 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -585,7 +585,7 @@
 	 * S-EL2 context if S-EL2 is enabled.
 	 */
 	if ((security_state == NON_SECURE) ||
-	    ((scr_el3 & SCR_EEL2_BIT) != 0U)) {
+	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
 		cpu_context_t *ctx;
 
 		ctx = cm_get_context(security_state);
@@ -607,7 +607,7 @@
 	 * S-EL2 context if S-EL2 is enabled.
 	 */
 	if ((security_state == NON_SECURE) ||
-	    ((scr_el3 & SCR_EEL2_BIT) != 0U)) {
+	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
 		cpu_context_t *ctx;
 
 		ctx = cm_get_context(security_state);
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index 82d2e18..0f75f07 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -1,39 +1,73 @@
 /*
- * 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
  */
 
+#include <assert.h>
 #include <stdbool.h>
 
 #include <arch.h>
 #include <arch_helpers.h>
+
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
 #include <lib/extensions/amu_private.h>
-#include <plat/common/platform.h>
 
-#define AMU_GROUP0_NR_COUNTERS	4
-
-struct amu_ctx {
-	uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS];
-	uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS];
-};
+#include <plat/common/platform.h>
 
 static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
 
+/* Check if AMUv1 for Armv8.4 or 8.6 is implemented */
 bool amu_supported(void)
 {
-	uint64_t features;
+	uint32_t features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT;
 
-	features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT;
-	return (features & ID_PFR0_AMU_MASK) == 1U;
+	features &= ID_PFR0_AMU_MASK;
+	return ((features == 1U) || (features == 2U));
 }
 
+#if AMU_GROUP1_NR_COUNTERS
+/* Check if group 1 counters is implemented */
+bool amu_group1_supported(void)
+{
+	uint32_t features = read_amcfgr() >> AMCFGR_NCG_SHIFT;
+
+	return (features & AMCFGR_NCG_MASK) == 1U;
+}
+#endif
+
+/*
+ * Enable counters. This function is meant to be invoked
+ * by the context management library before exiting from EL3.
+ */
 void amu_enable(bool el2_unused)
 {
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return;
+	}
+
+#if AMU_GROUP1_NR_COUNTERS
+	/* Check and set presence of group 1 counters */
+	if (!amu_group1_supported()) {
+		ERROR("AMU Counter Group 1 is not implemented\n");
+		panic();
+	}
+
+	/* Check number of group 1 counters */
+	uint32_t cnt_num = (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) &
+				AMCGCR_CG1NC_MASK;
+	VERBOSE("%s%u. %s%u\n",
+		"Number of AMU Group 1 Counters ", cnt_num,
+		"Requested number ", AMU_GROUP1_NR_COUNTERS);
+
+	if (cnt_num < AMU_GROUP1_NR_COUNTERS) {
+		ERROR("%s%u is less than %s%u\n",
+		"Number of AMU Group 1 Counters ", cnt_num,
+		"Requested number ", AMU_GROUP1_NR_COUNTERS);
+		panic();
+	}
+#endif
 
 	if (el2_unused) {
 		uint64_t v;
@@ -49,112 +83,156 @@
 	/* Enable group 0 counters */
 	write_amcntenset0(AMU_GROUP0_COUNTERS_MASK);
 
+#if AMU_GROUP1_NR_COUNTERS
 	/* Enable group 1 counters */
 	write_amcntenset1(AMU_GROUP1_COUNTERS_MASK);
+#endif
 }
 
 /* Read the group 0 counter identified by the given `idx`. */
-uint64_t amu_group0_cnt_read(int idx)
+uint64_t amu_group0_cnt_read(unsigned int idx)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
+	assert(idx < AMU_GROUP0_NR_COUNTERS);
 
 	return amu_group0_cnt_read_internal(idx);
 }
 
-/* Write the group 0 counter identified by the given `idx` with `val`. */
-void amu_group0_cnt_write(int idx, uint64_t val)
+/* Write the group 0 counter identified by the given `idx` with `val` */
+void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
+	assert(idx < AMU_GROUP0_NR_COUNTERS);
 
 	amu_group0_cnt_write_internal(idx, val);
 	isb();
 }
 
-/* Read the group 1 counter identified by the given `idx`. */
-uint64_t amu_group1_cnt_read(int idx)
+#if AMU_GROUP1_NR_COUNTERS
+/* Read the group 1 counter identified by the given `idx` */
+uint64_t amu_group1_cnt_read(unsigned  int idx)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	return amu_group1_cnt_read_internal(idx);
 }
 
-/* Write the group 1 counter identified by the given `idx` with `val`. */
-void amu_group1_cnt_write(int idx, uint64_t val)
+/* Write the group 1 counter identified by the given `idx` with `val` */
+void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	amu_group1_cnt_write_internal(idx, val);
 	isb();
 }
 
-void amu_group1_set_evtype(int idx, unsigned int val)
+/*
+ * Program the event type register for the given `idx` with
+ * the event number `val`
+ */
+void amu_group1_set_evtype(unsigned int idx, unsigned int val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	amu_group1_set_evtype_internal(idx, val);
 	isb();
 }
+#endif	/* AMU_GROUP1_NR_COUNTERS */
 
 static void *amu_context_save(const void *arg)
 {
-	struct amu_ctx *ctx;
-	int i;
+	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+	unsigned int i;
 
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return (void *)-1;
-
-	ctx = &amu_ctxs[plat_my_core_pos()];
+	}
 
-	/* Assert that group 0 counter configuration is what we expect */
-	assert(read_amcntenset0() == AMU_GROUP0_COUNTERS_MASK &&
-	       read_amcntenset1() == AMU_GROUP1_COUNTERS_MASK);
+#if AMU_GROUP1_NR_COUNTERS
+	if (!amu_group1_supported()) {
+		return (void *)-1;
+	}
+#endif
+	/* Assert that group 0/1 counter configuration is what we expect */
+	assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK);
 
+#if AMU_GROUP1_NR_COUNTERS
+	assert(read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK);
+#endif
 	/*
-	 * Disable group 0 counters to avoid other observers like SCP sampling
+	 * Disable group 0/1 counters to avoid other observers like SCP sampling
 	 * counter values from the future via the memory mapped view.
 	 */
 	write_amcntenclr0(AMU_GROUP0_COUNTERS_MASK);
+
+#if AMU_GROUP1_NR_COUNTERS
 	write_amcntenclr1(AMU_GROUP1_COUNTERS_MASK);
+#endif
 	isb();
 
-	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
+	/* Save all group 0 counters */
+	for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
 		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
-
-	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
-		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
+	}
 
+#if AMU_GROUP1_NR_COUNTERS
+	/* Save group 1 counters */
+	for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) {
+			ctx->group1_cnts[i] = amu_group1_cnt_read(i);
+		}
+	}
+#endif
 	return (void *)0;
 }
 
 static void *amu_context_restore(const void *arg)
 {
-	struct amu_ctx *ctx;
-	int i;
+	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+	unsigned int i;
 
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return (void *)-1;
-
-	ctx = &amu_ctxs[plat_my_core_pos()];
+	}
 
+#if AMU_GROUP1_NR_COUNTERS
+	if (!amu_group1_supported()) {
+		return (void *)-1;
+	}
+#endif
 	/* Counters were disabled in `amu_context_save()` */
-	assert((read_amcntenset0() == 0U) && (read_amcntenset1() == 0U));
+	assert(read_amcntenset0_el0() == 0U);
+
+#if AMU_GROUP1_NR_COUNTERS
+	assert(read_amcntenset1_el0() == 0U);
+#endif
 
-	/* Restore group 0 counters */
-	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
+	/* Restore all group 0 counters */
+	for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
 		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
-	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
-		amu_group1_cnt_write(i, ctx->group1_cnts[i]);
+	}
 
-	/* Enable group 0 counters */
+	/* Restore group 0 counter configuration */
 	write_amcntenset0(AMU_GROUP0_COUNTERS_MASK);
 
-	/* Enable group 1 counters */
+#if AMU_GROUP1_NR_COUNTERS
+	/* Restore group 1 counters */
+	for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) {
+			amu_group1_cnt_write(i, ctx->group1_cnts[i]);
+		}
+	}
+
+	/* Restore group 1 counter configuration */
 	write_amcntenset1(AMU_GROUP1_COUNTERS_MASK);
+#endif
+
 	return (void *)0;
 }
 
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index 85f7007..4997363 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.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
  */
@@ -9,38 +9,67 @@
 
 #include <arch.h>
 #include <arch_helpers.h>
+
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
 #include <lib/extensions/amu_private.h>
-#include <plat/common/platform.h>
 
-#define AMU_GROUP0_NR_COUNTERS	4
-
-struct amu_ctx {
-	uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS];
-	uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS];
-};
+#include <plat/common/platform.h>
 
 static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
 
+/* Check if AMUv1 for Armv8.4 or 8.6 is implemented */
 bool amu_supported(void)
 {
+	uint64_t features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT;
+
+	features &= ID_AA64PFR0_AMU_MASK;
+	return ((features == 1U) || (features == 2U));
+}
+
+#if AMU_GROUP1_NR_COUNTERS
+/* Check if group 1 counters is implemented */
+bool amu_group1_supported(void)
+{
-	uint64_t features;
+	uint64_t features = read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT;
 
-	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT;
-	return (features & ID_AA64PFR0_AMU_MASK) == 1U;
+	return (features & AMCFGR_EL0_NCG_MASK) == 1U;
 }
+#endif
 
 /*
- * Enable counters.  This function is meant to be invoked
+ * Enable counters. This function is meant to be invoked
  * by the context management library before exiting from EL3.
  */
 void amu_enable(bool el2_unused)
 {
 	uint64_t v;
 
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return;
+	}
+
+#if AMU_GROUP1_NR_COUNTERS
+	/* Check and set presence of group 1 counters */
+	if (!amu_group1_supported()) {
+		ERROR("AMU Counter Group 1 is not implemented\n");
+		panic();
+	}
+
+	/* Check number of group 1 counters */
+	uint64_t cnt_num = (read_amcgcr_el0() >> AMCGCR_EL0_CG1NC_SHIFT) &
+				AMCGCR_EL0_CG1NC_MASK;
+	VERBOSE("%s%llu. %s%u\n",
+		"Number of AMU Group 1 Counters ", cnt_num,
+		"Requested number ", AMU_GROUP1_NR_COUNTERS);
+
+	if (cnt_num < AMU_GROUP1_NR_COUNTERS) {
+		ERROR("%s%llu is less than %s%u\n",
+		"Number of AMU Group 1 Counters ", cnt_num,
+		"Requested number ", AMU_GROUP1_NR_COUNTERS);
+		panic();
+	}
+#endif
 
 	if (el2_unused) {
 		/*
@@ -62,43 +91,49 @@
 
 	/* Enable group 0 counters */
 	write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
+
+#if AMU_GROUP1_NR_COUNTERS
 	/* Enable group 1 counters */
 	write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK);
+#endif
 }
 
 /* Read the group 0 counter identified by the given `idx`. */
-uint64_t amu_group0_cnt_read(int idx)
+uint64_t amu_group0_cnt_read(unsigned int idx)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
+	assert(idx < AMU_GROUP0_NR_COUNTERS);
 
 	return amu_group0_cnt_read_internal(idx);
 }
 
-/* Write the group 0 counter identified by the given `idx` with `val`. */
-void amu_group0_cnt_write(int idx, uint64_t val)
+/* Write the group 0 counter identified by the given `idx` with `val` */
+void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
+	assert(idx < AMU_GROUP0_NR_COUNTERS);
 
 	amu_group0_cnt_write_internal(idx, val);
 	isb();
 }
 
-/* Read the group 1 counter identified by the given `idx`. */
-uint64_t amu_group1_cnt_read(int idx)
+#if AMU_GROUP1_NR_COUNTERS
+/* Read the group 1 counter identified by the given `idx` */
+uint64_t amu_group1_cnt_read(unsigned  int idx)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	return amu_group1_cnt_read_internal(idx);
 }
 
-/* Write the group 1 counter identified by the given `idx` with `val`. */
-void amu_group1_cnt_write(int idx, uint64_t val)
+/* Write the group 1 counter identified by the given `idx` with `val` */
+void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	amu_group1_cnt_write_internal(idx, val);
 	isb();
@@ -106,78 +141,106 @@
 
 /*
  * Program the event type register for the given `idx` with
- * the event number `val`.
+ * the event number `val`
  */
-void amu_group1_set_evtype(int idx, unsigned int val)
+void amu_group1_set_evtype(unsigned int idx, unsigned int val)
 {
 	assert(amu_supported());
-	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
+	assert(amu_group1_supported());
+	assert(idx < AMU_GROUP1_NR_COUNTERS);
 
 	amu_group1_set_evtype_internal(idx, val);
 	isb();
 }
+#endif	/* AMU_GROUP1_NR_COUNTERS */
 
 static void *amu_context_save(const void *arg)
 {
 	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
-	int i;
+	unsigned int i;
 
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return (void *)-1;
+	}
 
+#if AMU_GROUP1_NR_COUNTERS
+	if (!amu_group1_supported()) {
+		return (void *)-1;
+	}
+#endif
 	/* Assert that group 0/1 counter configuration is what we expect */
-	assert((read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK) &&
-	       (read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK));
+	assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK);
 
-	assert(((sizeof(int) * 8) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK))
-		<= AMU_GROUP1_NR_COUNTERS);
-
+#if AMU_GROUP1_NR_COUNTERS
+	assert(read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK);
+#endif
 	/*
 	 * Disable group 0/1 counters to avoid other observers like SCP sampling
 	 * counter values from the future via the memory mapped view.
 	 */
 	write_amcntenclr0_el0(AMU_GROUP0_COUNTERS_MASK);
+
+#if AMU_GROUP1_NR_COUNTERS
 	write_amcntenclr1_el0(AMU_GROUP1_COUNTERS_MASK);
+#endif
 	isb();
 
-	/* Save group 0 counters */
-	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
+	/* Save all group 0 counters */
+	for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
 		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
+	}
 
+#if AMU_GROUP1_NR_COUNTERS
 	/* Save group 1 counters */
-	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
-		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
-
+	for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) {
+			ctx->group1_cnts[i] = amu_group1_cnt_read(i);
+		}
+	}
+#endif
 	return (void *)0;
 }
 
 static void *amu_context_restore(const void *arg)
 {
 	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
-	int i;
+	unsigned int i;
 
-	if (!amu_supported())
+	if (!amu_supported()) {
 		return (void *)-1;
+	}
 
+#if AMU_GROUP1_NR_COUNTERS
+	if (!amu_group1_supported()) {
+		return (void *)-1;
+	}
+#endif
 	/* Counters were disabled in `amu_context_save()` */
-	assert((read_amcntenset0_el0() == 0U) && (read_amcntenset1_el0() == 0U));
+	assert(read_amcntenset0_el0() == 0U);
 
-	assert(((sizeof(int) * 8U) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK))
-		<= AMU_GROUP1_NR_COUNTERS);
+#if AMU_GROUP1_NR_COUNTERS
+	assert(read_amcntenset1_el0() == 0U);
+#endif
 
-	/* Restore group 0 counters */
-	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
-		if ((AMU_GROUP0_COUNTERS_MASK & (1U << i)) != 0U)
-			amu_group0_cnt_write(i, ctx->group0_cnts[i]);
+	/* Restore all group 0 counters */
+	for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
+	}
 
+	/* Restore group 0 counter configuration */
+	write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
+
+#if AMU_GROUP1_NR_COUNTERS
 	/* Restore group 1 counters */
-	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
-		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U)
+	for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) {
 			amu_group1_cnt_write(i, ctx->group1_cnts[i]);
+		}
+	}
 
-	/* Restore group 0/1 counter configuration */
-	write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
+	/* Restore group 1 counter configuration */
 	write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK);
+#endif
 
 	return (void *)0;
 }
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index 78876c6..f0d7342 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -25,7 +25,7 @@
 	uint64_t features;
 
 	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	return (features & ID_AA64DFR0_PMS_MASK) == 1U;
+	return (features & ID_AA64DFR0_PMS_MASK) > 0ULL;
 }
 
 void spe_enable(bool el2_unused)
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
new file mode 100644
index 0000000..adfa534
--- /dev/null
+++ b/lib/fconf/fconf_cot_getter.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+
+#include <common/fdt_wrappers.h>
+#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include <drivers/auth/auth_mod.h>
+#include <lib/fconf/fconf.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+
+#include <tools_share/tbbr_oid.h>
+
+/* static structures used during authentication process */
+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);
+
+/* pointers to an array of CoT descriptors */
+static const auth_img_desc_t *cot_desc[MAX_NUMBER_IDS];
+/* array of CoT descriptors */
+static auth_img_desc_t auth_img_descs[MAX_NUMBER_IDS];
+
+/* array of authentication methods structures */
+static auth_method_desc_t auth_methods[MAX_NUMBER_IDS * AUTH_METHOD_NUM];
+static OBJECT_POOL_ARRAY(auth_methods_pool, auth_methods);
+
+/* array of authentication params structures */
+static auth_param_desc_t auth_params[MAX_NUMBER_IDS * COT_MAX_VERIFIED_PARAMS];
+static OBJECT_POOL_ARRAY(auth_params_pool, auth_params);
+
+/* array of authentication param type structures */
+static auth_param_type_desc_t auth_param_type_descs[MAX_NUMBER_IDS];
+static OBJECT_POOL_ARRAY(auth_param_type_descs_pool, auth_param_type_descs);
+
+/*
+ * array of OIDs
+ * Object IDs are used to search hash, pk, counter values in certificate.
+ * As per binding we have below 2 combinations:
+ * 1. Certificates are validated using nv-cntr and pk
+ * 2. Raw images are authenticated using hash
+ * Hence in worst case, there are maximum 2 OIDs per image/certificate
+ */
+static unsigned char oids[(MAX_NUMBER_IDS * 2)][MAX_OID_NAME_LEN];
+static OBJECT_POOL_ARRAY(oid_pool, oids);
+
+/* An array of auth buffer which holds hashes and pk
+ * ToDo: Size decided with the current number of images and
+ * certificates which are available in CoT. Size of these buffers bound to
+ * increase in the future on the addition of images/certificates.
+ */
+static unsigned char hash_auth_bufs[20][HASH_DER_LEN];
+static OBJECT_POOL_ARRAY(hash_auth_buf_pool, hash_auth_bufs);
+static unsigned char pk_auth_bufs[12][PK_DER_LEN];
+static OBJECT_POOL_ARRAY(pk_auth_buf_pool, pk_auth_bufs);
+
+/*******************************************************************************
+ * update_parent_auth_data() - Update authentication data structure
+ * @auth_desc[in]:	Pointer to the auth image descriptor
+ * @type_desc[in]:	Pointer to authentication parameter
+ * @auth_buf_size[in]:	Buffer size to hold pk or hash
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int update_parent_auth_data(const auth_img_desc_t *auth_desc,
+				   auth_param_type_desc_t *type_desc,
+				   unsigned int auth_buf_size)
+{
+	unsigned int i;
+	auth_param_desc_t *auth_data = &auth_desc->authenticated_data[0];
+	unsigned char *auth_buf;
+
+	for (i = 0U; i < COT_MAX_VERIFIED_PARAMS; i++) {
+		if (auth_data[i].type_desc == type_desc) {
+			return 0;
+		}
+		if (auth_data[i].type_desc == NULL) {
+			break;
+		}
+	}
+
+	if (auth_buf_size == HASH_DER_LEN) {
+		auth_buf = pool_alloc(&hash_auth_buf_pool);
+	} else if (auth_buf_size == PK_DER_LEN) {
+		auth_buf = pool_alloc(&pk_auth_buf_pool);
+	} else {
+		return -1;
+	}
+
+	if (i < COT_MAX_VERIFIED_PARAMS) {
+		auth_data[i].type_desc = type_desc;
+		auth_data[i].data.ptr = auth_buf;
+		auth_data[i].data.len = auth_buf_size;
+	} else {
+		ERROR("Out of authentication data array\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * get_auth_param_type_desc() - Get pointer of authentication parameter
+ * @img_id[in]:		Image Id
+ * @type_desc[out]:	Pointer to authentication parameter
+ * @buf_size[out]:	Buffer size which hold hash/pk
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int get_auth_param_type_desc(unsigned int img_id,
+				    auth_param_type_desc_t **type_desc,
+				    unsigned int *buf_size)
+{
+	auth_method_desc_t *img_auth_method = NULL;
+	img_type_t type = auth_img_descs[img_id].img_type;
+
+	if (type == IMG_CERT) {
+		img_auth_method =
+		&auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_SIG];
+		*type_desc = img_auth_method->param.sig.pk;
+		*buf_size = PK_DER_LEN;
+	} else if (type == IMG_RAW) {
+		img_auth_method =
+		&auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_HASH];
+		*type_desc = img_auth_method->param.hash.hash;
+		*buf_size = HASH_DER_LEN;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * set_auth_method() - Update global auth image descriptors with authentication
+ *			method data
+ * @auth_method_type[in]:	Type of authentication method
+ * @oid[in]:			Object Idetifier for pk/hash search
+ * @auth_method[in]:		Pointer to authentication method to set
+ ******************************************************************************/
+static void set_auth_method(auth_method_type_t auth_method_type, char *oid,
+			    auth_method_desc_t *auth_method)
+{
+	auth_param_type_t auth_param_type = AUTH_PARAM_NONE;
+	auth_param_type_desc_t *auth_param_type_desc;
+
+	assert(auth_method != NULL);
+
+	auth_param_type_desc = pool_alloc(&auth_param_type_descs_pool);
+	auth_method->type = auth_method_type;
+
+	if (auth_method_type == AUTH_METHOD_SIG) {
+		auth_param_type = AUTH_PARAM_PUB_KEY;
+		auth_method->param.sig.sig = &sig;
+		auth_method->param.sig.alg = &sig_alg;
+		auth_method->param.sig.data = &raw_data;
+		auth_method->param.sig.pk = auth_param_type_desc;
+	} else if (auth_method_type == AUTH_METHOD_HASH) {
+		auth_param_type = AUTH_PARAM_HASH;
+		auth_method->param.hash.data = &raw_data;
+		auth_method->param.hash.hash = auth_param_type_desc;
+	} else if (auth_method_type == AUTH_METHOD_NV_CTR) {
+		auth_param_type = AUTH_PARAM_NV_CTR;
+		auth_method->param.nv_ctr.cert_nv_ctr = auth_param_type_desc;
+		auth_method->param.nv_ctr.plat_nv_ctr = auth_param_type_desc;
+	}
+
+	auth_param_type_desc->type = auth_param_type;
+	auth_param_type_desc->cookie = (void *)oid;
+}
+
+/*******************************************************************************
+ * get_oid() -	get object identifier from device tree
+ * @dtb[in]:	Pointer to the device tree blob in memory
+ * @node[in]:	Offset of the node
+ * @prop[in]:	Property to read from the given node
+ * @oid[out]:	Object Indentifier of key/hash/nv-counter in certificate
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int get_oid(const void *dtb, int node, const char *prop, char **oid)
+{
+	uint32_t phandle;
+	int rc;
+
+	rc = fdt_read_uint32(dtb, node, prop, &phandle);
+	if (rc < 0) {
+		return rc;
+	}
+
+	node = fdt_node_offset_by_phandle(dtb, phandle);
+	if (node < 0) {
+		return node;
+	}
+
+	*oid = pool_alloc(&oid_pool);
+	rc = fdtw_read_string(dtb, node, "oid", *oid, MAX_OID_NAME_LEN);
+
+	return rc;
+}
+
+/*******************************************************************************
+ * populate_and_set_auth_methods() -  Populate auth method parameters from
+ *			device tree and set authentication method
+ *			structure.
+ * @dtb[in]:		Pointer to the device tree blob in memory
+ * @node[in]:		Offset of the node
+ * @img_id[in]:		Image identifier
+ * @type[in]:		Type of image
+ * @root_certificate[in]:Root certificate (authenticated by ROTPK)
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int populate_and_set_auth_methods(const void *dtb, int node,
+					 unsigned int img_id, img_type_t type,
+					 bool root_certificate)
+{
+	auth_method_type_t auth_method_type = AUTH_METHOD_NONE;
+	int rc;
+	char *oid = NULL;
+
+	auth_method_desc_t *auth_method = pool_alloc_n(&auth_methods_pool,
+					AUTH_METHOD_NUM);
+
+	/*
+	 * This is as per binding document where certificates are
+	 * verified by signature and images are verified by hash.
+	 */
+	if (type == IMG_CERT) {
+		if (root_certificate) {
+			oid = NULL;
+		} else {
+			rc = get_oid(dtb, node, "signing-key", &oid);
+			if (rc < 0) {
+				ERROR("FCONF: Can't read %s property\n",
+					"signing-key");
+				return rc;
+			}
+		}
+		auth_method_type = AUTH_METHOD_SIG;
+	} else if (type == IMG_RAW) {
+		rc = get_oid(dtb, node, "hash", &oid);
+		if (rc < 0) {
+			ERROR("FCONF: Can't read %s property\n",
+				"hash");
+			return rc;
+		}
+		auth_method_type = AUTH_METHOD_HASH;
+	} else {
+		return -1;
+	}
+
+	set_auth_method(auth_method_type, oid,
+			&auth_method[auth_method_type]);
+
+	/* Retrieve the optional property */
+	rc = get_oid(dtb, node, "antirollback-counter", &oid);
+	if (rc == 0) {
+		auth_method_type = AUTH_METHOD_NV_CTR;
+		set_auth_method(auth_method_type, oid,
+				&auth_method[auth_method_type]);
+	}
+
+	auth_img_descs[img_id].img_auth_methods = &auth_method[0];
+
+	return 0;
+}
+
+/*******************************************************************************
+ * get_parent_img_id() - Get parent image id for given child node
+ * @dtb[in]:		Pointer to the device tree blob in memory
+ * @node[in]:		Offset of the child node
+ * @parent_img_id[out]:	Image id of parent
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int get_parent_img_id(const void *dtb, int node,
+			     unsigned int *parent_img_id)
+{
+	uint32_t phandle;
+	int err;
+
+	err = fdt_read_uint32(dtb, node, "parent", &phandle);
+	if (err < 0) {
+		ERROR("FCONF: Could not read %s property in node\n",
+			"parent");
+		return err;
+	}
+
+	node = fdt_node_offset_by_phandle(dtb, phandle);
+	if (node < 0) {
+		ERROR("FCONF: Failed to locate node using its phandle\n");
+		return node;
+	}
+
+	err = fdt_read_uint32(dtb, node, "image-id", parent_img_id);
+	if (err < 0) {
+		ERROR("FCONF: Could not read %s property in node\n",
+			"image-id");
+	}
+
+	return err;
+}
+
+/*******************************************************************************
+ * set_desc_data() - Update data in descriptor's structure
+ * @dtb[in]:	Pointer to the device tree blob in memory
+ * @node[in]:	Offset of the node
+ * @type[in]:	Type of image (RAW/CERT)
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int set_desc_data(const void *dtb, int node, img_type_t type)
+{
+	int rc;
+	bool root_certificate = false;
+	unsigned int img_id, parent_img_id;
+
+	rc = fdt_read_uint32(dtb, node, "image-id", &img_id);
+	if (rc < 0) {
+		ERROR("FCONF: Can't find property %s in node\n",
+			"image-id");
+		return rc;
+	}
+
+	if (fdt_getprop(dtb, node, "root-certificate",
+					NULL) != NULL) {
+		root_certificate = true;
+	}
+
+	if (!root_certificate) {
+		rc = get_parent_img_id(dtb, node, &parent_img_id);
+		if (rc < 0) {
+			return rc;
+		}
+		auth_img_descs[img_id].parent = &auth_img_descs[parent_img_id];
+	}
+
+	auth_img_descs[img_id].img_id = img_id;
+	auth_img_descs[img_id].img_type = type;
+
+	rc = populate_and_set_auth_methods(dtb, node, img_id, type,
+				root_certificate);
+	if (rc < 0) {
+		return rc;
+	}
+
+	if (type == IMG_CERT) {
+		auth_param_desc_t *auth_param =
+			pool_alloc_n(&auth_params_pool,
+					COT_MAX_VERIFIED_PARAMS);
+		auth_img_descs[img_id].authenticated_data = &auth_param[0];
+	}
+
+	cot_desc[img_id] = &auth_img_descs[img_id];
+
+	return rc;
+}
+
+/*******************************************************************************
+ * populate_manifest_descs() - Populate CoT descriptors and update global
+ *			       certificate structures
+ * @dtb[in]:	Pointer to the device tree blob in memory
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int populate_manifest_descs(const void *dtb)
+{
+	int node, child;
+	int rc;
+
+	/*
+	 * Assert the node offset points to "arm, cert-descs"
+	 * compatible property
+	 */
+	const char *compatible_str = "arm, cert-descs";
+
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+	if (node < 0) {
+		ERROR("FCONF: Can't find %s compatible in node\n",
+			compatible_str);
+		return node;
+	}
+
+	fdt_for_each_subnode(child, dtb, node) {
+		rc = set_desc_data(dtb, child, IMG_CERT);
+		if (rc < 0) {
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * populate_image_descs() - Populate CoT descriptors and update global
+ *			    image descriptor structures.
+ * @dtb[in]:	Pointer to the device tree blob in memory
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int populate_image_descs(const void *dtb)
+{
+	int node, child;
+	int rc;
+
+	/*
+	 * Assert the node offset points to "arm, img-descs"
+	 * compatible property
+	 */
+	const char *compatible_str = "arm, img-descs";
+
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+	if (node < 0) {
+		ERROR("FCONF: Can't find %s compatible in node\n",
+			compatible_str);
+		return node;
+	}
+
+	fdt_for_each_subnode(child, dtb, node) {
+		rc = set_desc_data(dtb, child, IMG_RAW);
+		if (rc < 0) {
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * fconf_populate_cot_descs() - Populate CoT descriptors and update global
+ *				structures
+ * @config[in]:	Pointer to the device tree blob in memory
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int fconf_populate_cot_descs(uintptr_t config)
+{
+	auth_param_type_desc_t *type_desc = NULL;
+	unsigned int auth_buf_size = 0U;
+	int rc;
+
+	/* As libfdt uses void *, we can't avoid this cast */
+	const void *dtb = (void *)config;
+
+	/* populate manifest descs information */
+	rc = populate_manifest_descs(dtb);
+	if (rc < 0) {
+		ERROR("FCONF: population of %s descs failed %d\n",
+			"manifest", rc);
+		return rc;
+	}
+
+	/* populate image descs information */
+	rc = populate_image_descs(dtb);
+	if (rc < 0) {
+		ERROR("FCONF: population of %s descs failed %d\n",
+			"images", rc);
+		return rc;
+	}
+
+	/* update parent's authentication data */
+	for (unsigned int i = 0U; i < MAX_NUMBER_IDS; i++) {
+		if (auth_img_descs[i].parent != NULL) {
+			rc = get_auth_param_type_desc(i,
+						&type_desc,
+						&auth_buf_size);
+			if (rc < 0) {
+				ERROR("FCONF: failed to get auth data %d\n",
+					rc);
+				return rc;
+			}
+
+			rc = update_parent_auth_data(auth_img_descs[i].parent,
+						type_desc,
+						auth_buf_size);
+			if (rc < 0) {
+				ERROR("FCONF: auth data update failed %d\n",
+					rc);
+				return rc;
+			}
+		}
+	}
+
+	return rc;
+}
+
+FCONF_REGISTER_POPULATOR(TB_FW, cot_desc, fconf_populate_cot_descs);
+REGISTER_COT(cot_desc);
diff --git a/lib/libc/memset.c b/lib/libc/memset.c
index d8007d8..f9dd4c5 100644
--- a/lib/libc/memset.c
+++ b/lib/libc/memset.c
@@ -1,18 +1,48 @@
 /*
- * 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
  */
 
 #include <stddef.h>
 #include <string.h>
+#include <stdint.h>
 
 void *memset(void *dst, int val, size_t count)
 {
 	char *ptr = dst;
+	uint64_t *ptr64;
+	uint64_t fill = (unsigned char)val;
 
-	while (count--)
+	/* Simplify code below by making sure we write at least one byte. */
+	if (count == 0) {
+		return dst;
+	}
+
+	/* Handle the first part, until the pointer becomes 64-bit aligned. */
+	while (((uintptr_t)ptr & 7)) {
+		*ptr++ = val;
+		if (--count == 0) {
+			return dst;
+		}
+	}
+
+	/* Duplicate the fill byte to the rest of the 64-bit word. */
+	fill |= fill << 8;
+	fill |= fill << 16;
+	fill |= fill << 32;
+
+	/* Use 64-bit writes for as long as possible. */
+	ptr64 = (void *)ptr;
+	for (; count >= 8; count -= 8) {
+		*ptr64++ = fill;
+	}
+
+	/* Handle the remaining part byte-per-byte. */
+	ptr = (void *)ptr64;
+	while (count--) {
 		*ptr++ = val;
+	}
 
 	return dst;
 }
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 38ad1c7..6e80d8c 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.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
  */
@@ -24,37 +24,72 @@
 	}
 }
 
-static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
-			       unsigned int unum)
+static void unsigned_num_print(char **s, size_t n, size_t *chars_printed,
+			      unsigned long long int unum,
+			      unsigned int radix, char padc, int padn,
+			      bool capitalise)
 {
-	/* Enough for a 32-bit unsigned decimal integer (4294967295). */
-	char num_buf[10];
+	/* Just need enough space to store 64 bit decimal integer */
+	char num_buf[20];
 	int i = 0;
+	int width;
 	unsigned int rem;
+	char ascii_a = capitalise ? 'A' : 'a';
 
 	do {
-		rem = unum % 10U;
-		num_buf[i++] = '0' + rem;
-		unum /= 10U;
+		rem = unum % radix;
+		if (rem < 10U) {
+			num_buf[i] = '0' + rem;
+		} else {
+			num_buf[i] = ascii_a + (rem - 10U);
+		}
+		i++;
+		unum /= radix;
 	} while (unum > 0U);
 
-	while (--i >= 0) {
-		if (*chars_printed < n) {
-			*(*s) = num_buf[i];
-			(*s)++;
+	width = i;
+	if (padn > width) {
+		(*chars_printed) += (size_t)padn;
+	} else {
+		(*chars_printed) += (size_t)width;
+	}
+
+	if (*chars_printed < n) {
+
+		if (padn > 0) {
+			while (width < padn) {
+				*(*s)++ = padc;
+				padn--;
+			}
 		}
 
-		(*chars_printed)++;
+		while (--i >= 0) {
+			*(*s)++ = num_buf[i];
+		}
+
+		if (padn < 0) {
+			while (width < -padn) {
+				*(*s)++ = padc;
+				padn++;
+			}
+		}
 	}
 }
 
 /*******************************************************************
- * Reduced snprintf to be used for Trusted firmware.
+ * Reduced vsnprintf to be used for Trusted firmware.
  * The following type specifiers are supported:
  *
+ * %x (or %X) - hexadecimal format
  * %d or %i - signed decimal format
  * %s - string format
  * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number or string with spaces (NN is a decimal number)
+ * %-NN - Right-pad the number or string with spaces (NN is a decimal number)
  *
  * The function panics on all other formats specifiers.
  *
@@ -62,12 +97,15 @@
  * buffer was big enough. If it returns a value lower than n, the
  * whole string has been written.
  *******************************************************************/
-int snprintf(char *s, size_t n, const char *fmt, ...)
+int vsnprintf(char *s, size_t n, const char *fmt, va_list args)
 {
-	va_list args;
 	int num;
-	unsigned int unum;
+	unsigned long long int unum;
 	char *str;
+	char padc;		/* Padding character */
+	int padn;		/* Number of characters to pad */
+	bool left;
+	bool capitalise;
 	size_t chars_printed = 0U;
 
 	if (n == 0U) {
@@ -81,13 +119,40 @@
 		n--;
 	}
 
-	va_start(args, fmt);
 	while (*fmt != '\0') {
+		left = false;
+		padc ='\0';
+		padn = 0;
+		capitalise = false;
 
 		if (*fmt == '%') {
 			fmt++;
 			/* Check the format specifier. */
+loop:
 			switch (*fmt) {
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				padc = (*fmt == '0') ? '0' : ' ';
+				for (padn = 0; *fmt >= '0' && *fmt <= '9'; fmt++) {
+					padn = (padn * 10) + (*fmt - '0');
+				}
+				if (left) {
+					padn = -padn;
+				}
+				goto loop;
+			case '-':
+				left = true;
+				fmt++;
+				goto loop;
+
 			case 'i':
 			case 'd':
 				num = va_arg(args, int);
@@ -104,7 +169,8 @@
 					unum = (unsigned int)num;
 				}
 
-				unsigned_dec_print(&s, n, &chars_printed, unum);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
 				break;
 			case 's':
 				str = va_arg(args, char *);
@@ -112,8 +178,27 @@
 				break;
 			case 'u':
 				unum = va_arg(args, unsigned int);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
+				break;
+			case 'p':
+				unum = (uintptr_t)va_arg(args, void *);
+				if (unum > 0U) {
+					string_print(&s, n, &chars_printed, "0x");
+					padn -= 2;
+				}
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn, false);
+				break;
+			case 'X':
+				capitalise = true;
+			case 'x':
+				unum = va_arg(args, unsigned int);
-				unsigned_dec_print(&s, n, &chars_printed, unum);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn,
+						   capitalise);
 				break;
+
 			default:
 				/* Panic on any other format specifier. */
 				ERROR("snprintf: specifier with ASCII code '%d' not supported.",
@@ -134,10 +219,42 @@
 		chars_printed++;
 	}
 
-	va_end(args);
-
-	if (n > 0U)
+	if (n > 0U) {
 		*s = '\0';
+	}
 
 	return (int)chars_printed;
 }
+
+/*******************************************************************
+ * Reduced snprintf to be used for Trusted firmware.
+ * The following type specifiers are supported:
+ *
+ * %x (or %X) - hexadecimal format
+ * %d or %i - signed decimal format
+ * %s - string format
+ * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number or string with spaces (NN is a decimal number)
+ * %-NN - Right-pad the number or string with spaces (NN is a decimal number)
+ *
+ * The function panics on all other formats specifiers.
+ *
+ * It returns the number of characters that would be written if the
+ * buffer was big enough. If it returns a value lower than n, the
+ * whole string has been written.
+ *******************************************************************/
+int snprintf(char *s, size_t n, const char *fmt, ...)
+{
+	int count;
+	va_list all_args;
+
+	va_start(all_args, fmt);
+	count = vsnprintf(s, n, fmt, all_args);
+	va_end(all_args);
+
+	return count;
+}
diff --git a/lib/libc/strlcat.c b/lib/libc/strlcat.c
new file mode 100644
index 0000000..e60c863
--- /dev/null
+++ b/lib/libc/strlcat.c
@@ -0,0 +1,56 @@
+/*	$OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $	*/
+
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char * dst, const char * src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index cced276..6d81377 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <drivers/delay_timer.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
@@ -973,3 +974,49 @@
 	psci_do_pwrdown_cache_maintenance(power_level);
 #endif
 }
+
+/*******************************************************************************
+ * This function invokes the callback 'stop_func()' with the 'mpidr' of each
+ * online PE. Caller can pass suitable method to stop a remote core.
+ *
+ * 'wait_ms' is the timeout value in milliseconds for the other cores to
+ * transition to power down state. Passing '0' makes it non-blocking.
+ *
+ * The function returns 'PSCI_E_DENIED' if some cores failed to stop within the
+ * given timeout.
+ ******************************************************************************/
+int psci_stop_other_cores(unsigned int wait_ms,
+				   void (*stop_func)(u_register_t mpidr))
+{
+	unsigned int idx, this_cpu_idx;
+
+	this_cpu_idx = plat_my_core_pos();
+
+	/* Invoke stop_func for each core */
+	for (idx = 0U; idx < psci_plat_core_count; idx++) {
+		/* skip current CPU */
+		if (idx == this_cpu_idx) {
+			continue;
+		}
+
+		/* Check if the CPU is ON */
+		if (psci_get_aff_info_state_by_idx(idx) == AFF_STATE_ON) {
+			(*stop_func)(psci_cpu_pd_nodes[idx].mpidr);
+		}
+	}
+
+	/* Need to wait for other cores to shutdown */
+	if (wait_ms != 0U) {
+		while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) {
+			mdelay(1U);
+		}
+
+		if (psci_is_last_on_cpu() != 0U) {
+			WARN("Failed to stop all cores!\n");
+			psci_print_power_domain_map();
+			return PSCI_E_DENIED;
+		}
+	}
+
+	return PSCI_E_SUCCESS;
+}
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
index 5571ab0..eec85cc 100644
--- a/make_helpers/armv7-a-cpus.mk
+++ b/make_helpers/armv7-a-cpus.mk
@@ -44,10 +44,13 @@
 # Defined if ARMv7 core supports the Generic Timer extension.
 
 ifeq ($(filter yes,$(ARM_CORTEX_A7) $(ARM_CORTEX_A12) $(ARM_CORTEX_A15) $(ARM_CORTEX_A17)),yes)
-$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
-$(eval $(call add_define,ARMV7_SUPPORTS_VIRTUALIZATION))
-$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
-$(eval $(call add_define,ARMV7_SUPPORTS_VFP))
+$(eval $(call add_defines,\
+    $(sort \
+        ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING \
+        ARMV7_SUPPORTS_VIRTUALIZATION \
+        ARMV7_SUPPORTS_GENERIC_TIMER \
+        ARMV7_SUPPORTS_VFP \
+)))
 endif
 
 ifeq ($(ARM_CORTEX_A5),yes)
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 1c3d14d..613fca2 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -44,6 +44,13 @@
     DEFINES			+=	-D$(1)$(if $(value $(1)),=$(value $(1)),)
 endef
 
+
+# Convenience function for addding multiple build definitions
+# $(eval $(call add_defines,FOO BOO))
+define add_defines
+    $(foreach def,$1,$(eval $(call add_define,$(def))))
+endef
+
 # Convenience function for adding build definitions
 # $(eval $(call add_define_val,FOO,BAR)) will have:
 # -DFOO=BAR
@@ -57,6 +64,12 @@
     $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
 endef
 
+# Convenience function for verifying options have boolean values
+# $(eval $(call assert_booleans,FOO BOO)) will assert FOO and BOO for 0 or 1 values
+define assert_booleans
+    $(foreach bool,$1,$(eval $(call assert_boolean,$(bool))))
+endef
+
 0-9 := 0 1 2 3 4 5 6 7 8 9
 
 # Function to verify that a given option $(1) contains a numeric value
@@ -67,6 +80,12 @@
 $(if $(__numeric),$(error $(1) must be numeric))
 endef
 
+# Convenience function for verifying options have numeric values
+# $(eval $(call assert_numerics,FOO BOO)) will assert FOO and BOO contain numeric values
+define assert_numerics
+    $(foreach num,$1,$(eval $(call assert_numeric,$(num))))
+endef
+
 # CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
 # $(2) and assign the sequence to $(1)
 define CREATE_SEQ
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index caf5990..7220a5d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -157,6 +157,11 @@
 # Set the default algorithm for the generation of Trusted Board Boot keys
 KEY_ALG				:= rsa
 
+# Set the default key size in case KEY_ALG is rsa
+ifeq ($(KEY_ALG),rsa)
+KEY_SIZE			:= 2048
+endif
+
 # Option to build TF with Measured Boot support
 MEASURED_BOOT			:= 0
 
@@ -311,3 +316,6 @@
 
 # Build option to provide openssl directory path
 OPENSSL_DIR			:= /usr
+
+# Build option to use the SP804 timer instead of the generic one
+USE_SP804_TIMER			:= 0
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 9520934..9c92d3f 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -103,4 +103,7 @@
 # Add SiP owned Secure Partitions CoT (image cert)
 ifneq (${SP_LAYOUT_FILE},)
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/sip_sp_content.crt,--sip-sp-cert))
+ifeq (${COT},dualroot)
+    $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
+endif
 endif
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index 5ab8bdc..26ea88e 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -86,3 +86,5 @@
 		$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -x c -c - -o $1
 endef
 
+MSVC_NMAKE := nmake.exe
+
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index e60ebc6..997aaa6 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -5,6 +5,8 @@
 #
 
 include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+include drivers/arm/gic/v2/gicv2.mk
 
 AW_PLAT			:=	plat/allwinner
 
@@ -12,8 +14,6 @@
 				-I${AW_PLAT}/common/include		\
 				-I${AW_PLAT}/${PLAT}/include
 
-include lib/libfdt/libfdt.mk
-
 PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/${ARCH}/16550_console.S	\
 				${XLAT_TABLES_LIB_SRCS}			\
 				${AW_PLAT}/common/plat_helpers.S	\
@@ -22,9 +22,7 @@
 BL31_SOURCES		+=	drivers/allwinner/axp/common.c		\
 				drivers/allwinner/sunxi_msgbox.c	\
 				drivers/arm/css/scpi/css_scpi.c		\
-				drivers/arm/gic/common/gic_common.c	\
-				drivers/arm/gic/v2/gicv2_helpers.c	\
-				drivers/arm/gic/v2/gicv2_main.c		\
+				${GICV2_SOURCES}			\
 				drivers/delay_timer/delay_timer.c	\
 				drivers/delay_timer/generic_delay_timer.c \
 				lib/cpus/${ARCH}/cortex_a53.S		\
diff --git a/plat/arm/board/a5ds/a5ds_err.c b/plat/arm/board/a5ds/a5ds_err.c
index 65b41dd..feb9fdf 100644
--- a/plat/arm/board/a5ds/a5ds_err.c
+++ b/plat/arm/board/a5ds/a5ds_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 5d610f4..8b0dc5c 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -77,14 +77,14 @@
 TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/a5ds_tb_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))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 
 $(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
 	fdts/$(notdir ${FVP_HW_CONFIG_DTS})))
 # Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 
 FDT_SOURCES		+=	plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
 				plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 9db107c..de6d9d5 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -5,7 +5,9 @@
  */
 
 #include <assert.h>
+#include <errno.h>
 
+#include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <drivers/delay_timer.h>
 #include <drivers/generic_delay_timer.h>
@@ -193,6 +195,24 @@
 		}
 	}
 
+	if (err < 0) {
+		ERROR("Error %d extending Device Tree\n", err);
+		panic();
+	}
+
+	err = fdt_add_cpus_node(fdt, FPGA_MAX_PE_PER_CPU,
+				FPGA_MAX_CPUS_PER_CLUSTER,
+				FPGA_MAX_CLUSTER_COUNT);
+
+	if (err == -EEXIST) {
+		WARN("Not overwriting already existing /cpus node in DTB\n");
+	} else {
+		if (err < 0) {
+			ERROR("Error %d creating the /cpus DT node\n", err);
+			panic();
+		}
+	}
+
 	err = fdt_pack(fdt);
 	if (err < 0) {
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 1e7badf..8904339 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -86,6 +86,7 @@
 PLAT_BL_COMMON_SOURCES	:=	plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S
 
 BL31_SOURCES		+=	common/fdt_wrappers.c				\
+				common/fdt_fixup.c				\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				drivers/arm/pl011/${ARCH}/pl011_console.S	\
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 38cbba9..8239e0d 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -12,7 +12,9 @@
 #include <drivers/arm/cryptocell/cc_rotpk.h>
 #include <drivers/delay_timer.h>
 #include <lib/cassert.h>
+#include <lib/fconf/fconf.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -29,6 +31,16 @@
 #endif
 #endif
 
+#if COT_DESC_IN_DTB && defined(IMAGE_BL2)
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
+#else
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
+	TFW_NVCTR_BASE,
+	NTFW_CTR_BASE
+};
+#endif
+
+
 /* Weak definition may be overridden in specific platform */
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
@@ -183,9 +195,11 @@
 
 	oid = (const char *)cookie;
 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
+		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+							TRUSTED_NV_CTR_ID);
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
+		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+							NON_TRUSTED_NV_CTR_ID);
 	} else {
 		return 1;
 	}
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index 513af3c..9a8d38c 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -48,7 +48,7 @@
 $(eval CORSTONE700_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS)))
 
 # Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config,${CORSTONE700_HW_CONFIG}))
 
 # Check for Linux kernel as a BL33 image by default
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index a1c9094..934a01a 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -5,6 +5,14 @@
  */
 /dts-v1/;
 
+#define AFF 00
+
+#include "fvp-defs.dtsi"
+#undef POST
+#define POST \
+		enable-method = "psci"; \
+		};
+
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
@@ -17,6 +25,7 @@
 		exec_state = <0x0>;
 		load_address = <0x0 0x6000000>;
 		entrypoint = <0x0 0x6000000>;
+		binary_size = <0x80000>;
 	};
 
 	chosen {
@@ -35,31 +44,31 @@
 			is_ffa_partition;
 			debug_name = "cactus-secondary";
 			load_address = <0x7100000>;
-			vcpu_count = <2>;
+			vcpu_count = <8>;
 			mem_size = <1048576>;
 		};
+		vm3 {
+			is_ffa_partition;
+			debug_name = "cactus-tertiary";
+			load_address = <0x7200000>;
+			vcpu_count = <8>;
+			mem_size = <1048576>;
+		};
 	};
 
 	cpus {
 		#address-cells = <0x2>;
 		#size-cells = <0x0>;
 
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <0x2>;
-				};
-			};
-		};
-
-		cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-			next-level-cache = <0xc>;
-			phandle = <0x2>;
-		};
+		CPU_0
+		/* SPM(Hafnium) requires secondary cpu nodes are declared in descending order */
+		CPU_7
+		CPU_6
+		CPU_5
+		CPU_4
+		CPU_3
+		CPU_2
+		CPU_1
 	};
 
 	memory@60000000 {
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 280a64a..fe154e9 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -40,35 +40,34 @@
 	};
 
 	/*
-	 * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in
-	 * network order (big endian), UUID's mentioned in this file are are
-	 * stored in machine order (little endian).
-	 * This will be fixed in future.
+	 * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+	 * network order (big endian)
 	 */
+
 #if ARM_IO_IN_DTB
 	arm-io_policies {
 		fip-handles {
 			compatible = "arm,io-fip-handle";
-			scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>;
-			bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>;
-			bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>;
-			bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>;
-			bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>;
-			bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>;
-			hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>;
-			soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>;
-			tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>;
-			nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>;
-			t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>;
-			scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>;
-			soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>;
-			tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>;
-			nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>;
-			scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>;
-			soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>;
-			tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>;
-			nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>;
-			sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>;
+			scp_bl2_uuid = <0x9766fd3d 0x89bee849 0xae5d78a1 0x40608213>;
+			bl31_uuid = <0x47d4086d 0x4cfe9846 0x9b952950 0xcbbd5a00>;
+			bl32_uuid = <0x05d0e189 0x53dc1347 0x8d2b500a 0x4b7a3e38>;
+			bl32_extra1_uuid = <0x0b70c28b 0x2a5a7840 0x9f650a56 0x82738288>;
+			bl32_extra2_uuid = <0x8ea87bb1 0xcfa23f4d 0x85fde7bb 0xa50220d9>;
+			bl33_uuid = <0xd6d0eea7 0xfcead54b 0x97829934 0xf234b6e4>;
+			hw_cfg_uuid = <0x08b8f1d9 0xc9cf9349 0xa9626fbc 0x6b7265cc>;
+			soc_fw_cfg_uuid = <0x9979814b 0x0376fb46 0x8c8e8d26 0x7f7859e0>;
+			tos_fw_cfg_uuid = <0x26257c1a 0xdbc67f47 0x8d96c4c4 0xb0248021>;
+			nt_fw_cfg_uuid = <0x28da9815 0x93e87e44 0xac661aaf 0x801550f9>;
+			t_key_cert_uuid = <0x827ee890 0xf860e411 0xa1b477a7 0x21b4f94c>;
+			scp_fw_key_uuid = <0x024221a1 0xf860e411 0x8d9bf33c 0x0e15a014>;
+			soc_fw_key_uuid = <0x8ab8becc 0xf960e411 0x9ad0eb48 0x22d8dcf8>;
+			tos_fw_key_cert_uuid = <0x9477d603 0xfb60e411 0x85ddb710 0x5b8cee04>;
+			nt_fw_key_cert_uuid = <0x8ad5832a 0xfb60e411 0x8aafdf30 0xbbc49859>;
+			scp_fw_content_cert_uuid = <0x44be6f04 0x5e63e411 0xb28b73d8 0xeaae9656>;
+			soc_fw_content_cert_uuid = <0xe2b20c20 0x5e63e411 0x9ce8abcc 0xf92bb666>;
+			tos_fw_content_cert_uuid = <0xa49f4411 0x5e63e411 0x87283f05 0x722af33d>;
+			nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>;
+			sp_content_cert_uuid = <0x776dfd44 0x86974c3b 0x91ebc13e 0x025a2a6f>;
 		};
 	};
 #endif /* ARM_IO_IN_DTB */
@@ -77,18 +76,25 @@
 		compatible = "arm,sp";
 #ifdef OPTEE_SP_FW_CONFIG
 		op-tee {
-			uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>;
+			uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
 			load-address = <0x6280000>;
 		};
 #else
 		cactus-primary {
-			uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+			uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
 			load-address = <0x7000000>;
+			owner = "SiP";
 		};
 
 		cactus-secondary {
-			uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>;
+			uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
 			load-address = <0x7100000>;
+			owner = "Plat";
+		};
+
+		cactus-tertiary {
+			uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
+			load-address = <0x7200000>;
 		};
 #endif
 	};
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 0e77c4d..e713bbc 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -64,7 +64,7 @@
 	/* Setup the watchdog to reset the system as soon as possible */
 	sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
 
-	while (1)
+	while (true)
 		wfi();
 }
 
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index cb717e0..6e479ac 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -13,16 +13,18 @@
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
-#include <plat/arm/common/arm_config.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
 #include <platform_def.h>
-
+#include <services/arm_arch_svc.h>
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
 #include "fvp_private.h"
 
 /* Defines for GIC Driver build time selection */
@@ -420,7 +422,7 @@
 
 void fvp_timer_init(void)
 {
-#if FVP_USE_SP804_TIMER
+#if USE_SP804_TIMER
 	/* Enable the clock override for SP804 timer 0, which means that no
 	 * clock dividers are applied and the raw (35MHz) clock will be used.
 	 */
@@ -435,5 +437,42 @@
 	/* Enable System level generic timer */
 	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
 			CNTCR_FCREQ(0U) | CNTCR_EN);
-#endif /* FVP_USE_SP804_TIMER */
+#endif /* USE_SP804_TIMER */
+}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ *                                     feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+	return (int32_t)
+		((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+		 | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+		 | FVP_SOC_ID);
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+	unsigned int sys_id;
+
+	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+	return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+			V2M_SYS_ID_REV_MASK);
 }
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index c5d1568..4efe692 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -27,6 +27,11 @@
 #define FVP_CCI			1
 #define FVP_CCN			2
 
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define FVP_SOC_ID      0
+
 /*******************************************************************************
  * FVP memory map related constants
  ******************************************************************************/
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index 8825198..1ea37f7 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -9,7 +9,9 @@
 #include <string.h>
 
 #include <lib/mmio.h>
+#include <lib/fconf/fconf.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <tools_share/tbbr_oid.h>
@@ -50,9 +52,11 @@
 
 	oid = (const char *)cookie;
 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = TFW_NVCTR_BASE;
+		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+						TRUSTED_NV_CTR_ID);
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
-		nv_ctr_addr = NTFW_CTR_BASE;
+		nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+						NON_TRUSTED_NV_CTR_ID);
 	} else {
 		return 1;
 	}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index a986017..50f6389 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -118,7 +118,11 @@
  * little space for growth.
  */
 #if TRUSTED_BOARD_BOOT
+#if COT_DESC_IN_DTB
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#else
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#endif
 #else
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index f75f556..4565d05 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -7,9 +7,6 @@
 # Use the GICv3 driver on the FVP by default
 FVP_USE_GIC_DRIVER	:= FVP_GICV3
 
-# Use the SP804 timer instead of the generic one
-FVP_USE_SP804_TIMER	:= 0
-
 # Default cluster count for FVP
 FVP_CLUSTER_COUNT	:= 2
 
@@ -21,9 +18,6 @@
 
 FVP_DT_PREFIX		:= fvp-base-gicv3-psci
 
-$(eval $(call assert_boolean,FVP_USE_SP804_TIMER))
-$(eval $(call add_define,FVP_USE_SP804_TIMER))
-
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
 
@@ -155,7 +149,7 @@
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
 
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
 BL1_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 else
 BL1_SOURCES		+=	drivers/delay_timer/generic_delay_timer.c
@@ -174,6 +168,9 @@
 				${FVP_SECURITY_SOURCES}
 
 
+ifeq (${COT_DESC_IN_DTB},1)
+BL2_SOURCES		+=	plat/arm/common/fconf/fconf_nv_cntr_getter.c
+endif
 
 ifeq (${BL2_AT_EL3},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
@@ -182,14 +179,14 @@
 				${FVP_INTERCONNECT_SOURCES}
 endif
 
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
 BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 endif
 
 BL2U_SOURCES		+=	plat/arm/board/fvp/fvp_bl2u_setup.c		\
 				${FVP_SECURITY_SOURCES}
 
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
 BL2U_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 endif
 
@@ -223,7 +220,7 @@
 
 endif
 
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
 BL31_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 else
 BL31_SOURCES		+=	drivers/delay_timer/generic_delay_timer.c
@@ -249,7 +246,7 @@
 FVP_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb
 
 # Add the TOS_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
 ifeq (${SPD},spmd)
@@ -262,23 +259,23 @@
 FVP_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb
 
 # Add the TOS_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 # Add the SOC_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
 
 FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
 $(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
 
 # Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 endif
 
 # Enable Activity Monitor Unit extensions by default
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
index 25e0964..4ccae27 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
@@ -25,7 +25,7 @@
 {
 	arm_bl2_platform_setup();
 
-#ifdef FVP_VE_USE_SP804_TIMER
+#if USE_SP804_TIMER
 	/*
 	 * Enable the clock override for SP804 timer 0, which means that no
 	 * clock dividers are applied and the raw (35 MHz) clock will be used
@@ -37,5 +37,5 @@
 			SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
 #else
 	generic_delay_timer_init();
-#endif /* FVP_VE_USE_SP804_TIMER */
+#endif /* USE_SP804_TIMER */
 }
diff --git a/plat/arm/board/fvp_ve/fvp_ve_err.c b/plat/arm/board/fvp_ve/fvp_ve_err.c
index 7f9d2f7..8d35688 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_err.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index f8e38ff..ac45d57 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -6,8 +6,7 @@
 
 ifdef ARM_CORTEX_A5
 # Use the SP804 timer instead of the generic one
-FVP_VE_USE_SP804_TIMER	:= 1
-$(eval $(call add_define,FVP_VE_USE_SP804_TIMER))
+USE_SP804_TIMER	:= 1
 BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
 endif
 
@@ -82,15 +81,15 @@
 FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 
 FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
 $(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
 	fdts/$(notdir ${FVP_HW_CONFIG_DTS})))
 # Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 endif
 
 NEED_BL32 := yes
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 25a27da..2234055 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -97,7 +97,7 @@
 	/* Setup the watchdog to reset the system as soon as possible */
 	sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
 
-	while (1)
+	while (true)
 		wfi();
 }
 
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 9570d2d..da4918c 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -1,10 +1,13 @@
 /*
- * 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
  */
 
+#include <lib/smccc.h>
 #include <platform_def.h>
+#include <services/arm_arch_svc.h>
+
 #include <plat/arm/common/plat_arm.h>
 
 /*
@@ -91,3 +94,40 @@
 #endif
 
 ARM_CASSERT_MMAP
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ *                                     feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+	return (int32_t)
+		((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+		 | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+		 | JUNO_SOC_ID);
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+	unsigned int sys_id;
+
+	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+	return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+			V2M_SYS_ID_REV_MASK);
+}
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 3b34a9f..ddf99dc 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -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
  */
@@ -9,6 +9,11 @@
 
 #include <lib/utils_def.h>
 
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define JUNO_SOC_ID     1
+
 /*******************************************************************************
  * Juno memory map related constants
  ******************************************************************************/
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 196d3c0..78704b5 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -172,9 +172,9 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 136287a..d7003e9 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -63,8 +63,8 @@
 		PLAT_ARM_GICD_BASE >> 16
 	},
 	.spi_ids = {
-		{32, 255},
-		{0, 0}
+		{32, 479},
+		{512, 959}
 	}
 };
 
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
index 81632a5..8909b55 100644
--- a/plat/arm/board/rddaniel/platform.mk
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -44,14 +44,14 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 FDT_SOURCES		+=	${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk
index 93967ad..61af81a 100644
--- a/plat/arm/board/rddanielxlr/platform.mk
+++ b/plat/arm/board/rddanielxlr/platform.mk
@@ -47,9 +47,9 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,4))
 ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
@@ -61,6 +61,6 @@
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index e09afca..a7c0434 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -41,15 +41,15 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 ifneq ($(CSS_SGI_CHIP_COUNT),1)
  $(error  "Chip count for RDE1Edge should be 1, currently set to \
diff --git a/plat/arm/board/rde1edge/rde1edge_err.c b/plat/arm/board/rde1edge/rde1edge_err.c
index e344d82..c72c18c 100644
--- a/plat/arm/board/rde1edge/rde1edge_err.c
+++ b/plat/arm/board/rde1edge/rde1edge_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index 3f0cc7f..b313426 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -47,15 +47,15 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 FDT_SOURCES		+=	${RDN1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,2))
 ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/rdn1edge/rdn1edge_err.c
index cdcbf25..46d318c 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_err.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index f5d547d..56f5733 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -42,15 +42,15 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 FDT_SOURCES		+=	${SGI575_BASE}/fdts/${PLAT}_nt_fw_config.dts
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 ifneq ($(CSS_SGI_CHIP_COUNT),1)
  $(error  "Chip count for SGI575 should be 1, currently set to \
diff --git a/plat/arm/board/sgi575/sgi575_err.c b/plat/arm/board/sgi575/sgi575_err.c
index c1cc1a7..21bfcb7 100644
--- a/plat/arm/board/sgi575/sgi575_err.c
+++ b/plat/arm/board/sgi575/sgi575_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index 26bc25d..a649939 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/platform.mk
@@ -15,9 +15,9 @@
 TB_FW_CONFIG		:=      ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 PLAT_INCLUDES +=-I${SGM775_BASE}/include/
 
diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/sgm775/sgm775_err.c
index e1e0586..dc114f0 100644
--- a/plat/arm/board/sgm775/sgm775_err.c
+++ b/plat/arm/board/sgm775/sgm775_err.c
@@ -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
  */
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h
index 56c71c1..a8d471e 100644
--- a/plat/arm/board/tc0/include/platform_def.h
+++ b/plat/arm/board/tc0/include/platform_def.h
@@ -183,12 +183,12 @@
  * 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
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x20000
 
 /*
  * 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
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x20000
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 0bf18e4..903fabf 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -79,9 +79,9 @@
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 #Device tree
 TC0_HW_CONFIG_DTS	:=	fdts/tc0.dts
@@ -90,7 +90,7 @@
 $(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))
+$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config,${TC0_HW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
 
diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c
index 4fc0505..83f2e9f 100644
--- a/plat/arm/board/tc0/tc0_err.c
+++ b/plat/arm/board/tc0/tc0_err.c
@@ -11,7 +11,7 @@
  */
 void __dead2 plat_arm_error_handler(int err)
 {
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
deleted file mode 100644
index 69ebd79..0000000
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <bl31/ehf.h>
-
-/*
- * Enumeration of priority levels on ARM platforms.
- */
-ehf_pri_desc_t arm_exceptions[] = {
-#if RAS_EXTENSION
-	/* RAS Priority */
-	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_RAS_PRI),
-#endif
-
-#if SDEI_SUPPORT
-	/* Critical priority SDEI */
-	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
-
-	/* Normal priority SDEI */
-	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
-#endif
-#if SPM_MM
-	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
-#endif
-};
-
-/* Plug in ARM exceptions to Exception Handling Framework. */
-EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS);
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 60d8f6e..c90e93c 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -27,7 +27,7 @@
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
 /* Base address of fw_config received from BL1 */
-static uintptr_t fw_config_base;
+static uintptr_t config_base;
 
 /*
  * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is
@@ -66,7 +66,7 @@
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
 
-	fw_config_base = fw_config;
+	config_base = fw_config;
 
 	/* Initialise the IO layer and register platform IO devices */
 	plat_arm_io_setup();
@@ -152,7 +152,7 @@
 	arm_bl2_plat_arch_setup();
 
 	/* Fill the properties struct with the info from the config dtb */
-	fconf_populate("FW_CONFIG", fw_config_base);
+	fconf_populate("FW_CONFIG", config_base);
 
 	/* TB_FW_CONFIG was also loaded by BL1 */
 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 58ccf0e..fc238b1 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -46,7 +46,10 @@
 					MT_MEMORY | MT_RW | MT_SECURE)
 #if RECLAIM_INIT_CODE
 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
-IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+
+#define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
+					~(PAGE_SIZE - 1))
 
 #define MAP_BL_INIT_CODE	MAP_REGION_FLAT(			\
 					BL_INIT_CODE_BASE,		\
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index e2b99a3..296aaf8 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -216,7 +216,7 @@
 		 * Translate entry point to Physical Address using the EL1&0
 		 * translation regime, including stage 2.
 		 */
-		ats12e1r(ep);
+		AT(ats12e1r, ep);
 	}
 	isb();
 	par = read_par_el1();
@@ -237,38 +237,3 @@
 }
 #endif
 
-/*****************************************************************************
- * plat_is_smccc_feature_available() - This function checks whether SMCCC
- *                                     feature is availabile for platform.
- * @fid: SMCCC function id
- *
- * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
- * otherwise.
- *****************************************************************************/
-int32_t plat_is_smccc_feature_available(u_register_t fid)
-{
-	switch (fid) {
-	case SMCCC_ARCH_SOC_ID:
-	default:
-		return SMC_ARCH_CALL_NOT_SUPPORTED;
-	}
-}
-
-/*
- * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0
- * ToDo: Get proper SOC-ID for every ARM platform and define this
- *       function separately for every ARM platform.
- */
-uint32_t plat_arm_get_soc_id(void)
-{
-	return 0U;
-}
-
-/* Get SOC version */
-int32_t plat_get_soc_version(void)
-{
-	return (int32_t)
-		((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
-		 | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
-		 | plat_arm_get_soc_id());
-}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 96ab2d3..1832c65 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -258,7 +258,7 @@
 endif
 
 ifeq (${EL3_EXCEPTION_HANDLING},1)
-BL31_SOURCES		+=	plat/arm/common/aarch64/arm_ehf.c
+BL31_SOURCES		+=	plat/common/aarch64/plat_ehf.c
 endif
 
 ifeq (${SDEI_SUPPORT},1)
@@ -297,9 +297,14 @@
 
     # Include the selected chain of trust sources.
     ifeq (${COT},tbbr)
-        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
+	BL1_SOURCES     +=      drivers/auth/tbbr/tbbr_cot_common.c		\
+				drivers/auth/tbbr/tbbr_cot_bl1.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        else
+            BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c	\
+				drivers/auth/tbbr/tbbr_cot_bl2.c
+        endif
     else ifeq (${COT},dualroot)
         AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
     else
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 350ecd1..48286c2 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -52,6 +52,7 @@
 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT},
 #if defined(SPD_spmd)
 	[SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
+	[PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT},
 #endif
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
@@ -189,6 +190,11 @@
 		(uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID],
 		open_fip
 	},
+	[PLAT_SP_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID],
+		open_fip
+	},
 #endif
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
@@ -197,7 +203,7 @@
 #ifdef IMAGE_BL2
 
 #if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER	U(20)
+#define FCONF_ARM_IO_UUID_NUMBER	U(21)
 #else
 #define FCONF_ARM_IO_UUID_NUMBER	U(10)
 #endif
@@ -234,6 +240,7 @@
 	{NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
 #if defined(SPD_spmd)
 	{SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"},
+	{PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"},
 #endif
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -242,6 +249,7 @@
 {
 	int err, node;
 	unsigned int i;
+	unsigned int j;
 
 	union uuid_helper_t uuid_helper;
 	io_uuid_spec_t *uuid_ptr;
@@ -267,6 +275,15 @@
 			return err;
 		}
 
+		/* Convert uuid from big endian to little endian */
+		for (j = 0U; j < 4U; j++) {
+			uuid_helper.word[j] =
+				((uuid_helper.word[j] >> 24U) & 0xff) |
+				((uuid_helper.word[j] << 8U) & 0xff0000) |
+				((uuid_helper.word[j] >> 8U) & 0xff00) |
+				((uuid_helper.word[j] << 24U) & 0xff000000);
+		}
+
 		VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
 			load_info[i].name,
 			uuid_helper.word[0], uuid_helper.word[1],
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
index 4459264..7950e7f 100644
--- a/plat/arm/common/fconf/arm_fconf_sp.c
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -30,7 +30,14 @@
 	union uuid_helper_t uuid_helper;
 	unsigned int index = 0;
 	uint32_t val32;
-	const unsigned int sp_start_index = SP_PKG1_ID;
+	bool is_plat_owned = false;
+	const unsigned int sip_start = SP_PKG1_ID;
+	unsigned int sip_index = sip_start;
+	const unsigned int sip_end = sip_start + MAX_SP_IDS / 2;
+	const unsigned int plat_start = SP_PKG5_ID;
+	unsigned int plat_index = plat_start;
+	const unsigned int plat_end = plat_start + MAX_SP_IDS / 2;
+	unsigned int j;
 
 	/* As libfdt use void *, we can't avoid this cast */
 	const void *dtb = (void *)config;
@@ -45,11 +52,13 @@
 	}
 
 	fdt_for_each_subnode(sp_node, dtb, node) {
-		if (index == MAX_SP_IDS) {
+		if ((index == MAX_SP_IDS) || (sip_index == sip_end)
+		    || (plat_index == plat_end)) {
 			ERROR("FCONF: Reached max number of SPs\n");
 			return -1;
 		}
 
+		/* Read UUID */
 		err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4,
 					    uuid_helper.word);
 		if (err < 0) {
@@ -57,15 +66,16 @@
 			return -1;
 		}
 
-		arm_sp.uuids[index] = uuid_helper;
-
-		err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
-		if (err < 0) {
-			ERROR("FCONF: cannot read SP load address\n");
-			return -1;
+		/* Convert uuid from big endian to little endian */
+		for (j = 0U; j < 4U; j++) {
+			uuid_helper.word[j] =
+				((uuid_helper.word[j] >> 24U) & 0xff) |
+				((uuid_helper.word[j] << 8U) & 0xff0000) |
+				((uuid_helper.word[j] >> 8U) & 0xff00) |
+				((uuid_helper.word[j] << 24U) & 0xff000000);
 		}
-		arm_sp.load_addr[index] = val32;
 
+		arm_sp.uuids[index] = uuid_helper;
 		VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n",
 			__func__,
 			uuid_helper.word[0],
@@ -74,8 +84,52 @@
 			uuid_helper.word[3],
 			arm_sp.load_addr[index]);
 
-		/* Add SP information in mem param descriptor */
-		sp_mem_params_descs[index].image_id = sp_start_index + index;
+		/* Read Load address */
+		err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
+		if (err < 0) {
+			ERROR("FCONF: cannot read SP load address\n");
+			return -1;
+		}
+		arm_sp.load_addr[index] = val32;
+
+		/* Read owner field only for dualroot CoT */
+#if defined(ARM_COT_dualroot)
+		/* Owner is an optional field, no need to catch error */
+		fdtw_read_string(dtb, sp_node, "owner",
+				arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN);
+#endif
+		/* If owner is empty mark it as SiP owned */
+		if ((strncmp(arm_sp.owner[index], "SiP",
+			     ARM_SP_OWNER_NAME_LEN) == 0) ||
+		    (strncmp(arm_sp.owner[index], "",
+			     ARM_SP_OWNER_NAME_LEN) == 0)) {
+			is_plat_owned = false;
+		} else if (strcmp(arm_sp.owner[index], "Plat") == 0) {
+			is_plat_owned = true;
+		} else {
+			ERROR("FCONF: %s is not a valid SP owner\n",
+			      arm_sp.owner[index]);
+			return -1;
+		}
+		/*
+		 * Add SP information in mem param descriptor and IO policies
+		 * structure.
+		 */
+		if (is_plat_owned) {
+			sp_mem_params_descs[index].image_id = plat_index;
+			policies[plat_index].image_spec =
+						(uintptr_t)&arm_sp.uuids[index];
+			policies[plat_index].dev_handle = &fip_dev_handle;
+			policies[plat_index].check = open_fip;
+			plat_index++;
+		} else {
+			sp_mem_params_descs[index].image_id = sip_index;
+			policies[sip_index].image_spec =
+						(uintptr_t)&arm_sp.uuids[index];
+			policies[sip_index].dev_handle = &fip_dev_handle;
+			policies[sip_index].check = open_fip;
+			sip_index++;
+		}
 		SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info,
 					PARAM_IMAGE_BINARY, VERSION_2, 0);
 		sp_mem_params_descs[index].image_info.image_max_size =
@@ -84,13 +138,6 @@
 							INVALID_IMAGE_ID;
 		sp_mem_params_descs[index].image_info.image_base =
 							arm_sp.load_addr[index];
-
-		/* Add SP information in IO policies structure */
-		policies[sp_start_index + index].image_spec =
-						(uintptr_t)&arm_sp.uuids[index];
-		policies[sp_start_index + index].dev_handle = &fip_dev_handle;
-		policies[sp_start_index + index].check = open_fip;
-
 		index++;
 	}
 
diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c
new file mode 100644
index 0000000..8d645ef
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, Arm Limited. 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_nv_cntr_getter.h>
+
+/*******************************************************************************
+ * fconf_populate_cot_descs() - Populate available nv-counters and update global
+ *				structure.
+ * @config[in]:	Pointer to the device tree blob in memory
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int fconf_populate_nv_cntrs(uintptr_t config)
+{
+	int rc, node, child;
+	uint32_t id;
+	uintptr_t reg;
+
+	/* As libfdt uses void *, we can't avoid this cast */
+	const void *dtb = (void *)config;
+	const char *compatible_str = "arm, non-volatile-counter";
+
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+	if (node < 0) {
+		ERROR("FCONF: Can't find %s compatible in node\n",
+			compatible_str);
+		return node;
+	}
+
+	fdt_for_each_subnode(child, dtb, node) {
+
+		rc = fdt_read_uint32(dtb, child, "id", &id);
+		if (rc < 0) {
+			ERROR("FCONF: Can't find %s property in node\n", "id");
+			return rc;
+		}
+
+		assert(id < MAX_NV_CTR_IDS);
+
+		rc = fdt_get_reg_props_by_index(dtb, child, 0, &reg, NULL);
+		if (rc < 0) {
+			ERROR("FCONF: Can't find %s property in node\n", "reg");
+			return rc;
+		}
+
+		nv_cntr_base_addr[id] = reg;
+	}
+
+	return 0;
+}
+
+FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs);
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index 6100b78..270093c 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -186,7 +186,7 @@
 	 * Do initial security configuration to allow DRAM/device access
 	 * (if earlier BL has not already done so).
 	 */
-#if RESET_TO_SP_MIN
+#if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME
 	plat_arm_security_setup();
 
 #if defined(PLAT_ARM_MEM_PROT_ADDR)
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
new file mode 100644
index 0000000..da76884
--- /dev/null
+++ b/plat/common/aarch64/plat_ehf.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, Broadcom
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/ehf.h>
+
+#include <platform_def.h>
+
+/*
+ * Enumeration of priority levels on ARM platforms.
+ */
+ehf_pri_desc_t plat_exceptions[] = {
+#if RAS_EXTENSION
+	/* RAS Priority */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI),
+#endif
+
+#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
+#if SPM_MM
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+#endif
+	/* Plaform specific exceptions description */
+#ifdef PLAT_EHF_DESC
+	PLAT_EHF_DESC,
+#endif
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), PLAT_PRI_BITS);
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
index 2baa29a..1c6d68b 100644
--- a/plat/common/plat_bl1_common.c
+++ b/plat/common/plat_bl1_common.c
@@ -60,7 +60,7 @@
 
 __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
 {
-	while (1)
+	while (true)
 		wfi();
 }
 
@@ -83,8 +83,8 @@
  */
 int bl1_plat_handle_post_image_load(unsigned int image_id)
 {
-	meminfo_t *bl2_tzram_layout;
-	meminfo_t *bl1_tzram_layout;
+	meminfo_t *bl2_secram_layout;
+	meminfo_t *bl1_secram_layout;
 	image_desc_t *image_desc;
 	entry_point_info_t *ep_info;
 
@@ -99,7 +99,7 @@
 	ep_info = &image_desc->ep_info;
 
 	/* Find out how much free trusted ram remains after BL1 load */
-	bl1_tzram_layout = bl1_plat_sec_mem_layout();
+	bl1_secram_layout = bl1_plat_sec_mem_layout();
 
 	/*
 	 * Create a new layout of memory for BL2 as seen by BL1 i.e.
@@ -108,14 +108,14 @@
 	 * to BL2. BL2 will read the memory layout before using its
 	 * memory for other purposes.
 	 */
-	bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->total_base;
+	bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
 
-	bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
+	bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout);
 
-	ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout;
+	ep_info->args.arg1 = (uintptr_t)bl2_secram_layout;
 
 	VERBOSE("BL1: BL2 memory layout address = %p\n",
-		(void *) bl2_tzram_layout);
+		(void *) bl2_secram_layout);
 	return 0;
 }
 
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index e65980b..8f4018c 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -9,6 +9,7 @@
 #include <string.h>
 #include <libfdt.h>
 
+#include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index eb2801c..1e55f05 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -16,7 +16,9 @@
 #include <imx8m_psci.h>
 #include <plat_imx8.h>
 
-static uint32_t gpc_imr_offset[] = { 0x30, 0x40, 0x1c0, 0x1d0, };
+static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, };
+
+DEFINE_BAKERY_LOCK(gpc_lock);
 
 #pragma weak imx_set_cpu_pwr_off
 #pragma weak imx_set_cpu_pwr_on
@@ -38,16 +40,27 @@
 
 void imx_set_cpu_pwr_off(unsigned int core_id)
 {
+
+	bakery_lock_get(&gpc_lock);
+
 	/* enable the wfi power down of the core */
 	mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id));
+
+	bakery_lock_release(&gpc_lock);
+
 	/* assert the pcg pcr bit of the core */
 	mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
 }
 
 void imx_set_cpu_pwr_on(unsigned int core_id)
 {
+	bakery_lock_get(&gpc_lock);
+
 	/* clear the wfi power down bit of the core */
 	mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id));
+
+	bakery_lock_release(&gpc_lock);
+
 	/* assert the ncpuporeset */
 	mmio_clrbits_32(IMX_SRC_BASE + SRC_A53RCR1, (1 << core_id));
 	/* assert the pcg pcr bit of the core */
@@ -67,6 +80,8 @@
 
 void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
 {
+	bakery_lock_get(&gpc_lock);
+
 	if (pdn) {
 		/* enable the core WFI PDN & IRQ PUP */
 		mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
@@ -80,6 +95,8 @@
 		/* deassert the pcg pcr bit of the core */
 		mmio_clrbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
 	}
+
+	bakery_lock_release(&gpc_lock);
 }
 
 /*
@@ -133,14 +150,12 @@
 		val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_AD);
 		val &= ~EN_L2_WFI_PDN;
 		/* L2 cache memory is on in WAIT mode */
-		if (is_local_state_off(power_state))
+		if (is_local_state_off(power_state)) {
 			val |= (L2PGE | EN_PLAT_PDN);
-		else
-			val |= EN_PLAT_PDN;
+			imx_a53_plat_slot_config(true);
+		}
 
 		mmio_write_32(IMX_GPC_BASE + LPCR_A53_AD, val);
-
-		imx_a53_plat_slot_config(true);
 	} else {
 		/* clear the slot and ack for cluster power down */
 		imx_a53_plat_slot_config(false);
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index d641628..dbb772d 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -192,7 +192,7 @@
 	 * drived by the 32K OSC, so delay 30us to make sure the counter
 	 * is really running.
 	 */
-	if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
+	if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
 		imx_set_rbc_count();
 		udelay(30);
 	}
diff --git a/plat/imx/imx8m/imx8mm/include/gpc_reg.h b/plat/imx/imx8m/imx8mm/include/gpc_reg.h
index c697af2..1a4eae5 100644
--- a/plat/imx/imx8m/imx8mm/include/gpc_reg.h
+++ b/plat/imx/imx8m/imx8mm/include/gpc_reg.h
@@ -124,4 +124,6 @@
 #define VPU_G2_PGC			0xf00
 #define VPU_H1_PGC			0xf40
 
+#define IRQ_IMR_NUM			U(4)
+
 #endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mn/include/gpc_reg.h b/plat/imx/imx8m/imx8mn/include/gpc_reg.h
index fd10438..8a81368 100644
--- a/plat/imx/imx8m/imx8mn/include/gpc_reg.h
+++ b/plat/imx/imx8m/imx8mn/include/gpc_reg.h
@@ -106,4 +106,6 @@
 #define GPUMIX_PGC			0xdc0
 #define DISPMIX_PGC			0xe80
 
+#define IRQ_IMR_NUM			U(4)
+
 #endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mp/include/gpc_reg.h b/plat/imx/imx8m/imx8mp/include/gpc_reg.h
index 12da6ac..7909937 100644
--- a/plat/imx/imx8m/imx8mp/include/gpc_reg.h
+++ b/plat/imx/imx8m/imx8mp/include/gpc_reg.h
@@ -146,4 +146,6 @@
 #define MEDIAMIX_ISPDWP_PGC		0xf80
 #define DDRMIX_PGC			0xfc0
 
+#define IRQ_IMR_NUM			U(5)
+
 #endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 942ae45..367c941 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -19,9 +19,14 @@
 /* use wfi power down the core */
 void imx_set_cpu_pwr_off(unsigned int core_id)
 {
+	bakery_lock_get(&gpc_lock);
+
 	/* enable the wfi power down of the core */
 	mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
 			(1 << (core_id + 20)));
+
+	bakery_lock_release(&gpc_lock);
+
 	/* assert the pcg pcr bit of the core */
 	mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
 };
@@ -29,6 +34,8 @@
 /* if out of lpm, we need to do reverse steps */
 void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
 {
+	bakery_lock_get(&gpc_lock);
+
 	if (pdn) {
 		/* enable the core WFI PDN & IRQ PUP */
 		mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
@@ -42,6 +49,8 @@
 		/* deassert the pcg pcr bit of the core */
 		mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
 	}
+
+	bakery_lock_release(&gpc_lock);
 }
 
 void imx_pup_pdn_slot_config(int last_core, bool pdn)
diff --git a/plat/imx/imx8m/imx8mq/include/gpc_reg.h b/plat/imx/imx8m/imx8mq/include/gpc_reg.h
index 9f472d6..f171bd9 100644
--- a/plat/imx/imx8m/imx8mq/include/gpc_reg.h
+++ b/plat/imx/imx8m/imx8mq/include/gpc_reg.h
@@ -84,4 +84,6 @@
 #define MASTER1_MAPPING			BIT(1)
 #define MASTER2_MAPPING			BIT(2)
 
+#define IRQ_IMR_NUM			U(4)
+
 #endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 89a0b9d..075da91 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -25,7 +25,6 @@
 #define SLTx_CFG(n)			((SLT0_CFG + ((n) * 4)))
 #define SLT_COREx_PUP(core_id)		(0x2 << ((core_id) * 2))
 
-#define IRQ_IMR_NUM	4
 #define IMR_MASK_ALL	0xffffffff
 
 #define IMX_PD_DOMAIN(name, on)				\
@@ -55,6 +54,8 @@
 	bool always_on;
 };
 
+DECLARE_BAKERY_LOCK(gpc_lock);
+
 /* function declare */
 void imx_gpc_init(void);
 void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint);
diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c
index a07a298..f57e435 100644
--- a/plat/mediatek/common/mtk_plat_common.c
+++ b/plat/mediatek/common/mtk_plat_common.c
@@ -10,8 +10,10 @@
 #include <drivers/arm/cci.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.h>
 #include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
 
 #include <mtk_plat_common.h>
 #include <mtk_sip_svc.h>
@@ -116,3 +118,33 @@
 	spsr = SPSR_MODE32(mode, 0, ee, daif);
 	return spsr;
 }
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ *                                     feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
+ * otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+}
+
+int32_t plat_get_soc_version(void)
+{
+	uint32_t manfid = (JEDEC_MTK_BKID << 24U) | (JEDEC_MTK_MFID << 16U);
+
+	return (int32_t)(manfid | (SOC_CHIP_ID & 0xFFFFU));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	return 0;
+}
diff --git a/plat/mediatek/common/mtk_plat_common.h b/plat/mediatek/common/mtk_plat_common.h
index 55f4c51..919c173 100644
--- a/plat/mediatek/common/mtk_plat_common.h
+++ b/plat/mediatek/common/mtk_plat_common.h
@@ -18,6 +18,9 @@
 #define LINUX_KERNEL_32 0
 #define SMC32_PARAM_MASK		(0xFFFFFFFF)
 
+#define JEDEC_MTK_BKID U(4)
+#define JEDEC_MTK_MFID U(0x26)
+
 struct atf_arg_t {
 	unsigned int atf_magic;
 	unsigned int tee_support;
diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h
index 22129db..d340422 100644
--- a/plat/mediatek/mt8173/include/platform_def.h
+++ b/plat/mediatek/mt8173/include/platform_def.h
@@ -51,6 +51,8 @@
 					 PLATFORM_CLUSTER_COUNT +	\
 					 PLATFORM_CORE_COUNT)
 
+#define SOC_CHIP_ID                     U(0x8173)
+
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h
index 49a0f80..25ccfbc 100644
--- a/plat/mediatek/mt8183/include/platform_def.h
+++ b/plat/mediatek/mt8183/include/platform_def.h
@@ -279,6 +279,8 @@
 					 PLATFORM_CLUSTER_COUNT + \
 					 PLATFORM_CORE_COUNT)
 
+#define SOC_CHIP_ID                     U(0x8183)
+
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h
index e1f0faf..f68015a 100644
--- a/plat/mediatek/mt8192/include/platform_def.h
+++ b/plat/mediatek/mt8192/include/platform_def.h
@@ -59,6 +59,8 @@
 #define PLATFORM_CORE_COUNT             (PLATFORM_CLUSTER0_CORE_COUNT)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER   U(8)
 
+#define SOC_CHIP_ID			U(0x8192)
+
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 5f01416..6c8c4f0 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -4,12 +4,13 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <assert_macros.S>
-#include <cpu_macros.S>
-#include <cortex_a53.h>
 #include <cortex_a57.h>
+#include <cpu_macros.S>
+
 #include <platform_def.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
@@ -167,23 +168,6 @@
 endfunc plat_get_my_entrypoint
 
 	/* -----------------------------------------------------
-	 * int platform_get_core_pos(int mpidr);
-	 *
-	 * result: CorePos = (ClusterId * cpus per cluster) +
-	 *                   CoreId
-	 * -----------------------------------------------------
-	 */
-func platform_get_core_pos
-	and	x1, x0, #MPIDR_CPU_MASK
-	and	x0, x0, #MPIDR_CLUSTER_MASK
-	lsr	x0, x0, #MPIDR_AFFINITY_BITS
-	mov	x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
-	mul	x0, x0, x2
-	add	x0, x1, x0
-	ret
-endfunc platform_get_core_pos
-
-	/* -----------------------------------------------------
 	 * void plat_secondary_cold_boot_setup (void);
 	 *
 	 * This function performs any platform specific actions
@@ -231,7 +215,8 @@
 	 */
 	mov	x0, x17
 	mov	x1, x18
-	mov	x2, #BL31_SIZE
+	adr	x2, __RELA_END__
+	sub	x2, x2, x18
 _loop16:
 	cmp	x2, #16
 	b.lo	_loop1
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
deleted file mode 100644
index a4a4354..0000000
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-
-#include <smmu.h>
-#include <tegra_private.h>
-
-extern void memcpy16(void *dest, const void *src, unsigned int length);
-
-#define SMMU_NUM_CONTEXTS		64U
-#define SMMU_CONTEXT_BANK_MAX_IDX	64U
-
-/*
- * Init SMMU during boot or "System Suspend" exit
- */
-void tegra_smmu_init(void)
-{
-	uint32_t val, cb_idx, smmu_id, ctx_base;
-	uint32_t smmu_counter = plat_get_num_smmu_devices();
-
-	for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) {
-		/* Program the SMMU pagesize and reset CACHE_LOCK bit */
-		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
-		val |= SMMU_GSR0_PGSIZE_64K;
-		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
-		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
-
-		/* reset CACHE LOCK bit for NS Aux. Config. Register */
-		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
-		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
-		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
-
-		/* disable TCU prefetch for all contexts */
-		ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
-				+ SMMU_CBn_ACTLR;
-		for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
-			val = tegra_smmu_read_32(smmu_id,
-				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
-			val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
-			tegra_smmu_write_32(smmu_id, ctx_base +
-				(SMMU_GSR0_PGSIZE_64K * cb_idx), val);
-		}
-
-		/* set CACHE LOCK bit for NS Aux. Config. Register */
-		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
-		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
-		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
-
-		/* set CACHE LOCK bit for S Aux. Config. Register */
-		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
-		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
-		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
-	}
-}
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 40713b2..cb4886f 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -17,7 +17,6 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
-#include <cortex_a53.h>
 #include <cortex_a57.h>
 #include <denver.h>
 #include <drivers/console.h>
@@ -28,6 +27,7 @@
 
 #include <memctrl.h>
 #include <profiler.h>
+#include <smmu.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -180,21 +180,6 @@
 	plat_early_platform_setup();
 
 	/*
-	 * Do initial security configuration to allow DRAM/device access.
-	 */
-	tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
-			(uint32_t)plat_bl31_params_from_bl2.tzdram_size);
-
-#if RELOCATE_BL32_IMAGE
-	/*
-	 * The previous bootloader might not have placed the BL32 image
-	 * inside the TZDRAM. Platform handler to allow relocation of BL32
-	 * image to TZDRAM memory. This behavior might change per platform.
-	 */
-	plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
-#endif
-
-	/*
 	 * Add timestamp for platform early setup exit.
 	 */
 	boot_profiler_add_record("[TF] early setup exit");
@@ -248,12 +233,6 @@
 	tegra_memctrl_setup();
 
 	/*
-	 * Set up the TZRAM memory aperture to allow only secure world
-	 * access
-	 */
-	tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
-
-	/*
 	 * Late setup handler to allow platforms to performs additional
 	 * functionality.
 	 * This handler gets called with MMU enabled.
@@ -274,24 +253,9 @@
 void bl31_plat_runtime_setup(void)
 {
 	/*
-	 * During cold boot, it is observed that the arbitration
-	 * bit is set in the Memory controller leading to false
-	 * error interrupts in the non-secure world. To avoid
-	 * this, clean the interrupt status register before
-	 * booting into the non-secure world
-	 */
-	tegra_memctrl_clear_pending_interrupts();
-
-	/*
-	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
-	 * access to IRAM. Because these clients connect to the MC and
-	 * do not have a direct path to the IRAM, the MC implements AHB
-	 * redirection during boot to allow path to IRAM. In this mode
-	 * accesses to a programmed memory address aperture are directed
-	 * to the AHB bus, allowing access to the IRAM. This mode must be
-	 * disabled before we jump to the non-secure world.
+	 * Platform specific runtime setup
 	 */
-	tegra_memctrl_disable_ahb_redirection();
+	plat_runtime_setup();
 
 	/*
 	 * Add final timestamp before exiting BL31.
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index f412a80..3791018 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -12,37 +12,48 @@
 include lib/xlat_tables_v2/xlat_tables.mk
 PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
 
-COMMON_DIR		:=	plat/nvidia/tegra/common
+TEGRA_COMMON		:=	plat/nvidia/tegra/common
+TEGRA_DRIVERS		:=	plat/nvidia/tegra/drivers
+TEGRA_LIBS		:=	plat/nvidia/tegra/lib
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 TEGRA_GICv3_SOURCES	:=	$(GICV3_SOURCES)				\
 				plat/common/plat_gicv3.c			\
-				${COMMON_DIR}/tegra_gicv3.c
+				${TEGRA_COMMON}/tegra_gicv3.c
 
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
 
 TEGRA_GICv2_SOURCES	:=	${GICV2_SOURCES}				\
 				plat/common/plat_gicv2.c			\
-				${COMMON_DIR}/tegra_gicv2.c
+				${TEGRA_COMMON}/tegra_gicv2.c
+
+TEGRA_GICv3_SOURCES	:=	drivers/arm/gic/common/gic_common.c		\
+				drivers/arm/gic/v3/arm_gicv3_common.c		\
+				drivers/arm/gic/v3/gicv3_main.c			\
+				drivers/arm/gic/v3/gicv3_helpers.c		\
+				plat/common/plat_gicv3.c			\
+				${TEGRA_COMMON}/tegra_gicv3.c
 
 BL31_SOURCES		+=	drivers/delay_timer/delay_timer.c		\
 				drivers/io/io_storage.c				\
 				plat/common/aarch64/crash_console_helpers.S	\
-				${TEGRA_GICv2_SOURCES}				\
-				${COMMON_DIR}/aarch64/tegra_helpers.S		\
-				${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_sdei.c
+				${TEGRA_LIBS}/debug/profiler.c			\
+				${TEGRA_COMMON}/aarch64/tegra_helpers.S		\
+				${TEGRA_LIBS}/debug/profiler.c			\
+				${TEGRA_COMMON}/tegra_bl31_setup.c		\
+				${TEGRA_COMMON}/tegra_delay_timer.c		\
+				${TEGRA_COMMON}/tegra_fiq_glue.c		\
+				${TEGRA_COMMON}/tegra_io_storage.c		\
+				${TEGRA_COMMON}/tegra_platform.c		\
+				${TEGRA_COMMON}/tegra_pm.c			\
+				${TEGRA_COMMON}/tegra_sip_calls.c		\
+				${TEGRA_COMMON}/tegra_sdei.c
 
 ifneq ($(ENABLE_STACK_PROTECTOR), 0)
-BL31_SOURCES		+=	${COMMON_DIR}/tegra_stack_protector.c
+BL31_SOURCES		+=	${TEGRA_COMMON}/tegra_stack_protector.c
+endif
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES		+=	plat/common/aarch64/plat_ehf.c
 endif
diff --git a/plat/nvidia/tegra/common/tegra_delay_timer.c b/plat/nvidia/tegra/common/tegra_delay_timer.c
index cfd9a15..d9547c4 100644
--- a/plat/nvidia/tegra/common/tegra_delay_timer.c
+++ b/plat/nvidia/tegra/common/tegra_delay_timer.c
@@ -22,11 +22,9 @@
 
 	/*
 	 * Generic delay timer implementation expects the timer to be a down
-	 * counter. We apply bitwise NOT operator to the tick values returned
-	 * by read_cntps_tval_el1() to simulate the down counter. The value is
-	 * clipped from 64 to 32 bits.
+	 * counter. The value is clipped from 64 to 32 bits.
 	 */
-	return (uint32_t)(~read_cntps_tval_el1());
+	return (uint32_t)(read_cntps_tval_el1());
 }
 
 /*
diff --git a/plat/nvidia/tegra/common/tegra_ehf.c b/plat/nvidia/tegra/common/tegra_ehf.c
deleted file mode 100644
index ea6e443..0000000
--- a/plat/nvidia/tegra/common/tegra_ehf.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 0804135..7c73e8f 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -108,6 +108,13 @@
 	return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
 }
 
+bool tegra_chipid_is_t194(void)
+{
+	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+
+	return (chip_id == TEGRA_CHIPID_TEGRA19);
+}
+
 /*
  * Read the chip ID value and derive the platform
  */
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 0430048..27dd3a2 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -34,7 +34,7 @@
  * the appropriate State-ID field within the `power_state` parameter which can
  * be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
 ******************************************************************************/
-void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
+static void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
 	/* all affinities use system suspend state id */
 	for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -45,7 +45,7 @@
 /*******************************************************************************
  * Handler called when an affinity instance is about to enter standby.
  ******************************************************************************/
-void tegra_cpu_standby(plat_local_state_t cpu_state)
+static void tegra_cpu_standby(plat_local_state_t cpu_state)
 {
 	u_register_t saved_scr_el3;
 
@@ -84,7 +84,7 @@
  * Handler called when an affinity instance is about to be turned on. The
  * level and mpidr determine the affinity instance.
  ******************************************************************************/
-int32_t tegra_pwr_domain_on(u_register_t mpidr)
+static int32_t tegra_pwr_domain_on(u_register_t mpidr)
 {
 	return tegra_soc_pwr_domain_on(mpidr);
 }
@@ -93,9 +93,12 @@
  * Handler called when a power domain is about to be turned off. The
  * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-void tegra_pwr_domain_off(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	(void)tegra_soc_pwr_domain_off(target_state);
+
+	/* disable GICC */
+	tegra_gic_cpuif_deactivate();
 }
 
 /*******************************************************************************
@@ -113,17 +116,10 @@
  * Handler called when a power domain is about to be suspended. The
  * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	(void)tegra_soc_pwr_domain_suspend(target_state);
 
-	/* Disable console if we are entering deep sleep. */
-	if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
-			PSTATE_ID_SOC_POWERDN) {
-		(void)console_flush();
-		console_switch_state(0);
-	}
-
 	/* disable GICC */
 	tegra_gic_cpuif_deactivate();
 }
@@ -132,12 +128,20 @@
  * Handler called at the end of the power domain suspend sequence. The
  * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-__dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
+static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
 					     *target_state)
 {
 	/* call the chip's power down handler */
 	(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
 
+	/* Disable console if we are entering deep sleep. */
+	if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
+			PSTATE_ID_SOC_POWERDN) {
+		INFO("%s: complete. Entering System Suspend...\n", __func__);
+		(void)console_flush();
+		console_switch_state(0);
+	}
+
 	wfi();
 	panic();
 }
@@ -147,7 +151,7 @@
  * being turned off earlier. The target_state encodes the low power state that
  * each level has woken up from.
  ******************************************************************************/
-void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	const plat_params_from_bl2_t *plat_params;
 
@@ -180,11 +184,6 @@
 		tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
 			(uint32_t)plat_params->tzdram_size);
 
-		/*
-		 * Set up the TZRAM memory aperture to allow only secure world
-		 * access
-		 */
-		tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
 	} else {
 		/*
 		 * Initialize the GIC cpu and distributor interfaces
@@ -203,7 +202,7 @@
  * having been suspended earlier. The target_state encodes the low power state
  * that each level has woken up from.
  ******************************************************************************/
-void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
 	tegra_pwr_domain_on_finish(target_state);
 }
@@ -211,7 +210,7 @@
 /*******************************************************************************
  * Handler called when the system wants to be powered off
  ******************************************************************************/
-__dead2 void tegra_system_off(void)
+static __dead2 void tegra_system_off(void)
 {
 	INFO("Powering down system...\n");
 
@@ -221,7 +220,7 @@
 /*******************************************************************************
  * Handler called when the system wants to be restarted.
  ******************************************************************************/
-__dead2 void tegra_system_reset(void)
+static __dead2 void tegra_system_reset(void)
 {
 	INFO("Restarting system...\n");
 
@@ -237,7 +236,7 @@
 /*******************************************************************************
  * Handler called to check the validity of the power state parameter.
  ******************************************************************************/
-int32_t tegra_validate_power_state(uint32_t power_state,
+static int32_t tegra_validate_power_state(uint32_t power_state,
 				   psci_power_state_t *req_state)
 {
 	assert(req_state != NULL);
@@ -248,7 +247,7 @@
 /*******************************************************************************
  * Platform handler called to check the validity of the non secure entrypoint.
  ******************************************************************************/
-int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
 {
 	int32_t ret = PSCI_E_INVALID_ADDRESS;
 
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index 1d48cc0..80a2c4d 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -52,6 +52,12 @@
 		switch (smc_fid) {
 
 		case TEGRA_SIP_NEW_VIDEOMEM_REGION:
+			/* Check whether Video memory resize is enabled */
+			if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL)
+				!= MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) {
+				ERROR("Video Memory Resize isn't enabled! \n");
+				SMC_RET1(handle, (uint64_t)-ENOTSUP);
+			}
 
 			/*
 			 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/drivers/bpmp/bpmp.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
rename to plat/nvidia/tegra/drivers/bpmp/bpmp.c
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
rename to plat/nvidia/tegra/drivers/bpmp_ipc/intf.c
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
rename to plat/nvidia/tegra/drivers/bpmp_ipc/intf.h
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
rename to plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
rename to plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h
diff --git a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
rename to plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
rename to plat/nvidia/tegra/drivers/gpcdma/gpcdma.c
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c
similarity index 95%
rename from plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
rename to plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c
index c3f95db..b3dcd2a 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
+++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c
@@ -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
  */
@@ -92,20 +93,6 @@
 	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
 }
 
-/*
- * Secure the BL31 TZRAM aperture.
- *
- * phys_base = physical base of TZRAM aperture
- * size_in_bytes = size of aperture in bytes
- */
-void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
-{
-	/*
-	 * The v1 hardware controller does not have any registers
-	 * for setting up the on-chip TZRAM.
-	 */
-}
-
 static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
 				 unsigned long long non_overlap_area_size)
 {
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
similarity index 78%
rename from plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
rename to plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
index 4d69ccc..92120b5 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
@@ -32,38 +32,13 @@
  */
 void tegra_memctrl_setup(void)
 {
-	uint32_t val;
-	const uint32_t *mc_streamid_override_regs;
-	uint32_t num_streamid_override_regs;
-	const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs;
-	uint32_t num_streamid_sec_cfgs;
-	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
-	uint32_t i;
-
 	INFO("Tegra Memory Controller (v2)\n");
 
-	/* Program the SMMU pagesize */
+	/* Initialize the System memory management unit */
 	tegra_smmu_init();
 
-	/* Get the settings from the platform */
-	assert(plat_mc_settings != NULL);
-	mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg;
-	num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs;
-	mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg;
-	num_streamid_sec_cfgs = plat_mc_settings->num_streamid_security_cfgs;
-
-	/* Program all the Stream ID overrides */
-	for (i = 0; i < num_streamid_override_regs; i++)
-		tegra_mc_streamid_write_32(mc_streamid_override_regs[i],
-			MC_STREAM_ID_MAX);
-
-	/* Program the security config settings for all Stream IDs */
-	for (i = 0; i < num_streamid_sec_cfgs; i++) {
-		val = mc_streamid_sec_cfgs[i].override_enable << 16 |
-		      mc_streamid_sec_cfgs[i].override_client_inputs << 8 |
-		      mc_streamid_sec_cfgs[i].override_client_ns_flag << 0;
-		tegra_mc_streamid_write_32(mc_streamid_sec_cfgs[i].offset, val);
-	}
+	/* allow platforms to program custom memory controller settings */
+	plat_memctrl_setup();
 
 	/*
 	 * All requests at boot time, and certain requests during
@@ -80,21 +55,6 @@
 	 */
 	tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG,
 			  MC_SMMU_BYPASS_CONFIG_SETTINGS);
-
-	/*
-	 * Re-configure MSS to allow ROC to deal with ordering of the
-	 * Memory Controller traffic. This is needed as the Memory Controller
-	 * boots with MSS having all control, but ROC provides a performance
-	 * boost as compared to MSS.
-	 */
-	if (plat_mc_settings->reconfig_mss_clients != NULL) {
-		plat_mc_settings->reconfig_mss_clients();
-	}
-
-	/* Program overrides for MC transactions */
-	if (plat_mc_settings->set_txn_overrides != NULL) {
-		plat_mc_settings->set_txn_overrides();
-	}
 }
 
 /*
@@ -102,32 +62,23 @@
  */
 void tegra_memctrl_restore_settings(void)
 {
-	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
-
-	assert(plat_mc_settings != NULL);
-
-	/*
-	 * Re-configure MSS to allow ROC to deal with ordering of the
-	 * Memory Controller traffic. This is needed as the Memory Controller
-	 * resets during System Suspend with MSS having all control, but ROC
-	 * provides a performance boost as compared to MSS.
-	 */
-	if (plat_mc_settings->reconfig_mss_clients != NULL) {
-		plat_mc_settings->reconfig_mss_clients();
-	}
-
-	/* Program overrides for MC transactions */
-	if (plat_mc_settings->set_txn_overrides != NULL) {
-		plat_mc_settings->set_txn_overrides();
-	}
+	/* restore platform's memory controller settings */
+	plat_memctrl_restore();
 
 	/* video memory carveout region */
 	if (video_mem_base != 0ULL) {
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
 				  (uint32_t)video_mem_base);
+		assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO)
+			 == (uint32_t)video_mem_base);
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
 				  (uint32_t)(video_mem_base >> 32));
-		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
+		assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI)
+			 == (uint32_t)(video_mem_base >> 32));
+		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB,
+				  (uint32_t)video_mem_size_mb);
+		assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB)
+			 == (uint32_t)video_mem_size_mb);
 
 		/*
 		 * MCE propagates the VideoMem configuration values across the
@@ -167,7 +118,6 @@
  */
 void tegra_mc_save_context(uint64_t mc_ctx_addr)
 {
-	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
 	uint32_t i, num_entries = 0;
 	mc_regs_t *mc_ctx_regs;
 	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
@@ -177,7 +127,7 @@
 	assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end));
 
 	/* get MC context table */
-	mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx();
+	mc_ctx_regs = plat_memctrl_get_sys_suspend_ctx();
 	assert(mc_ctx_regs != NULL);
 
 	/*
@@ -210,8 +160,12 @@
 	/* save the MC table address */
 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO,
 		(uint32_t)mc_ctx_addr);
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO)
+		== (uint32_t)mc_ctx_addr);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI,
 		(uint32_t)(mc_ctx_addr >> 32));
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI)
+		== (uint32_t)(mc_ctx_addr >> 32));
 }
 
 static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
@@ -361,6 +315,14 @@
 			  (uint32_t)(phys_base >> 32));
 	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
 
+	/* Redundancy check for Video Protect setting */
+	assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO)
+		 == (uint32_t)phys_base);
+	assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI)
+		 == (uint32_t)(phys_base >> 32));
+	assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB)
+		 == (size_in_bytes >> 20));
+
 	/*
 	 * MCE propagates the VideoMem configuration values across the
 	 * CCPLEX.
diff --git a/plat/nvidia/tegra/common/drivers/pmc/pmc.c b/plat/nvidia/tegra/drivers/pmc/pmc.c
similarity index 100%
rename from plat/nvidia/tegra/common/drivers/pmc/pmc.c
rename to plat/nvidia/tegra/drivers/pmc/pmc.c
diff --git a/plat/nvidia/tegra/drivers/smmu/smmu.c b/plat/nvidia/tegra/drivers/smmu/smmu.c
new file mode 100644
index 0000000..4189b00
--- /dev/null
+++ b/plat/nvidia/tegra/drivers/smmu/smmu.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+
+#include <smmu.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
+#define SMMU_NUM_CONTEXTS		64U
+#define SMMU_CONTEXT_BANK_MAX_IDX	64U
+
+#define MISMATCH_DETECTED		0x55AA55AAU
+
+/*
+ * Init SMMU during boot or "System Suspend" exit
+ */
+void tegra_smmu_init(void)
+{
+	uint32_t val, cb_idx, smmu_id, ctx_base;
+	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+
+	for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
+		/* Program the SMMU pagesize and reset CACHE_LOCK bit */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+		val |= SMMU_GSR0_PGSIZE_64K;
+		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
+
+		/* reset CACHE LOCK bit for NS Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
+
+		/* disable TCU prefetch for all contexts */
+		ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
+				+ SMMU_CBn_ACTLR;
+		for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+			val = tegra_smmu_read_32(smmu_id,
+				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
+			val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
+			tegra_smmu_write_32(smmu_id, ctx_base +
+				(SMMU_GSR0_PGSIZE_64K * cb_idx), val);
+		}
+
+		/* set CACHE LOCK bit for NS Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
+
+		/* set CACHE LOCK bit for S Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
+	}
+}
+
+/*
+ * Verify SMMU settings have not been altered during boot
+ */
+void tegra_smmu_verify(void)
+{
+	uint32_t cb_idx, ctx_base, smmu_id, val;
+	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+	uint32_t mismatch = 0U;
+
+	for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
+		/* check PGSIZE_64K bit inr S Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+		if (0U == (val & SMMU_GSR0_PGSIZE_64K)) {
+			ERROR("%s: PGSIZE_64K Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* check CACHE LOCK bit in S Aux. Config. Register */
+		if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+			ERROR("%s: CACHE_LOCK Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* check CACHE LOCK bit in NS Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+		if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+			ERROR("%s: Mismatch - smmu_id=%d, GNSR_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* verify TCU prefetch for all contexts is disabled */
+		ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) +
+			SMMU_CBn_ACTLR;
+		for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+			val = tegra_smmu_read_32(smmu_id,
+				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
+			if (0U != (val & SMMU_CBn_ACTLR_CPRE_BIT)) {
+				ERROR("%s: Mismatch - smmu_id=%d, cb_idx=%d, GSR0_PGSIZE_64K=%x\n",
+					__func__, smmu_id, cb_idx, val);
+				mismatch = MISMATCH_DETECTED;
+			}
+		}
+	}
+
+	/* Treat configuration mismatch as fatal */
+	if ((mismatch == MISMATCH_DETECTED) && tegra_platform_is_silicon()) {
+		panic();
+	}
+}
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S
similarity index 94%
rename from plat/nvidia/tegra/common/drivers/spe/shared_console.S
rename to plat/nvidia/tegra/drivers/spe/shared_console.S
index 6df73ec..9196c1c 100644
--- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/drivers/spe/shared_console.S
@@ -11,8 +11,7 @@
 #define CONSOLE_FLUSH_DATA_TO_PORT	(1 << 26)
 #define CONSOLE_RING_DOORBELL		(1 << 31)
 #define CONSOLE_IS_BUSY			(1 << 31)
-#define CONSOLE_TIMEOUT			0xC000		/* approx. 50 ms */
-#define CONSOLE_WRITE			(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+#define CONSOLE_TIMEOUT			0xC000		/* 50 ms */
 
 	/*
 	 * This file contains a driver implementation to make use of the
@@ -101,7 +100,7 @@
 	/* spe is ready */
 	mov	w2, #0xD		/* '\r' */
 	and	w2, w2, #0xFF
-	mov	w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+	mov	w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
 	orr	w2, w2, w3
 	str	w2, [x1]
 
@@ -111,7 +110,7 @@
 	/* spe is ready */
 	mov	w2, w0
 	and	w2, w2, #0xFF
-	mov	w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+	mov	w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
 	orr	w2, w2, w3
 	str	w2, [x1]
 
@@ -164,7 +163,7 @@
 	cbz	x0, flush_error
 
 	/* flush console */
-	mov	w1, #CONSOLE_WRITE
+	mov	w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
 	str	w1, [x0]
 	mov	w0, #0
 	ret
diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h
index d5ef60d..cc85095 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +11,6 @@
 void tegra_memctrl_setup(void);
 void tegra_memctrl_restore_settings(void);
 void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes);
-void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes);
 void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes);
 void tegra_memctrl_disable_ahb_redirection(void);
 void tegra_memctrl_clear_pending_interrupts(void);
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 509fe32..1e15306 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,58 +8,9 @@
 #ifndef MEMCTRL_V2_H
 #define MEMCTRL_V2_H
 
-#include <tegra_def.h>
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-#include <stdint.h>
-
-/*******************************************************************************
- * Structure to hold the transaction override settings to use to override
- * client inputs
- ******************************************************************************/
-typedef struct mc_txn_override_cfg {
-	uint32_t offset;
-	uint8_t cgid_tag;
-} mc_txn_override_cfg_t;
-
-#define mc_make_txn_override_cfg(off, val) \
-	{ \
-		.offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \
-		.cgid_tag = MC_TXN_OVERRIDE_ ## val \
-	}
-
-/*******************************************************************************
- * Structure to hold the Stream ID to use to override client inputs
- ******************************************************************************/
-typedef struct mc_streamid_override_cfg {
-	uint32_t offset;
-	uint8_t stream_id;
-} mc_streamid_override_cfg_t;
+#include <arch.h>
 
-/*******************************************************************************
- * Structure to hold the Stream ID Security Configuration settings
- ******************************************************************************/
-typedef struct mc_streamid_security_cfg {
-	char *name;
-	uint32_t offset;
-	int override_enable;
-	int override_client_inputs;
-	int override_client_ns_flag;
-} mc_streamid_security_cfg_t;
-
-#define OVERRIDE_DISABLE				1U
-#define OVERRIDE_ENABLE					0U
-#define CLIENT_FLAG_SECURE				0U
-#define CLIENT_FLAG_NON_SECURE				1U
-#define CLIENT_INPUTS_OVERRIDE				1U
-#define CLIENT_INPUTS_NO_OVERRIDE			0U
-/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX			0x7FU
+#include <tegra_def.h>
 
 /*******************************************************************************
  * Memory Controller SMMU Bypass config register
@@ -74,33 +26,15 @@
 #define MC_SMMU_BYPASS_CONFIG_SETTINGS		(MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
 						 MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
 
-#define mc_make_sec_cfg(off, ns, ovrrd, access) \
-	{ \
-		.name = # off, \
-		.offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \
-				MC_STREAMID_OVERRIDE_CFG_ ## off), \
-		.override_client_ns_flag = CLIENT_FLAG_ ## ns, \
-		.override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \
-		.override_enable = OVERRIDE_ ## access \
-	}
+#ifndef __ASSEMBLY__
+
+#include <assert.h>
 
 typedef struct mc_regs {
 	uint32_t reg;
 	uint32_t val;
 } mc_regs_t;
 
-#define mc_make_sid_override_cfg(name) \
-	{ \
-		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
-		.val = 0x00000000U, \
-	}
-
-#define mc_make_sid_security_cfg(name) \
-	{ \
-		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
-		.val = 0x00000000U, \
-	}
-
 #define mc_smmu_bypass_cfg \
 	{ \
 		.reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
@@ -119,20 +53,11 @@
 		.val = 0xFFFFFFFFU, \
 	}
 
-/*******************************************************************************
- * Structure to hold Memory Controller's Configuration settings
- ******************************************************************************/
-typedef struct tegra_mc_settings {
-	const uint32_t *streamid_override_cfg;
-	uint32_t num_streamid_override_cfgs;
-	const mc_streamid_security_cfg_t *streamid_security_cfg;
-	uint32_t num_streamid_security_cfgs;
-	const mc_txn_override_cfg_t *txn_override_cfg;
-	uint32_t num_txn_override_cfgs;
-	void (*reconfig_mss_clients)(void);
-	void (*set_txn_overrides)(void);
-	mc_regs_t* (*get_mc_system_suspend_ctx)(void);
-} tegra_mc_settings_t;
+#endif /* __ASSEMBLY__ */
+
+#ifndef __ASSEMBLY__
+
+#include <lib/mmio.h>
 
 static inline uint32_t tegra_mc_read_32(uint32_t off)
 {
@@ -144,6 +69,7 @@
 	mmio_write_32(TEGRA_MC_BASE + off, val);
 }
 
+#if defined(TEGRA_MC_STREAMID_BASE)
 static inline uint32_t tegra_mc_streamid_read_32(uint32_t off)
 {
 	return mmio_read_32(TEGRA_MC_STREAMID_BASE + off);
@@ -152,54 +78,14 @@
 static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val)
 {
 	mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val);
+	assert(mmio_read_32(TEGRA_MC_STREAMID_BASE + off) == val);
 }
-
-#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
-	((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
-	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+#endif
 
-#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
-	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
+void plat_memctrl_setup(void);
 
-#define mc_set_tsa_passthrough(client) \
-	{ \
-		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
-			(TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
-			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
-			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
-	}
-
-#define mc_set_tsa_w_passthrough(client) \
-	{ \
-		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
-			(TSA_CONFIG_STATIC0_CSW_RESET_W & \
-			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
-			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
-	}
-
-#define mc_set_tsa_r_passthrough(client) \
-	{ \
-		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
-			(TSA_CONFIG_STATIC0_CSR_RESET_R & \
-			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
-			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
-	}
-
-#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
-	{ \
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-				  MC_TXN_OVERRIDE_##normal_axi_id | \
-				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
-				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
-				  MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
-	}
-
-/*******************************************************************************
- * Handler to read memory configuration settings
- *
- * Implemented by SoCs under tegra/soc/txxx
- ******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void);
+void plat_memctrl_restore(void);
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void);
 
 /*******************************************************************************
  * Handler to save MC settings before "System Suspend" to TZDRAM
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 601864f..1de9af6 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -86,6 +86,7 @@
 }
 
 void tegra_smmu_init(void);
+void tegra_smmu_verify(void);
 uint32_t plat_get_num_smmu_devices(void);
 
 #endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/plat_macros.S b/plat/nvidia/tegra/include/plat_macros.S
index 4f01e33..2dc3b41 100644
--- a/plat/nvidia/tegra/include/plat_macros.S
+++ b/plat/nvidia/tegra/include/plat_macros.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +28,7 @@
  * ---------------------------------------------
  */
 .macro plat_crash_print_regs
+#ifdef TEGRA_GICC_BASE
 	mov_imm	x16, TEGRA_GICC_BASE
 
 	/* gicc base address is now in x16 */
@@ -37,7 +39,7 @@
 	ldr	w10, [x16, #GICC_CTLR]
 	/* Store to the crash buf and print to cosole */
 	bl	str_in_crash_buf_print
-
+#endif
 	/* Print the GICD_ISPENDR regs */
 	mov_imm	x16, TEGRA_GICD_BASE
 	add	x7, x16, #GICD_ISPENDR
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 2331869..84b3297 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -66,7 +66,6 @@
 /*******************************************************************************
  * BL31 specific defines.
  ******************************************************************************/
-#define BL31_SIZE			U(0x40000)
 #define BL31_BASE			TZDRAM_BASE
 #define BL31_LIMIT			(TZDRAM_BASE + BL31_SIZE - 1)
 #define BL32_BASE			(TZDRAM_BASE + BL31_SIZE)
@@ -100,6 +99,9 @@
 #define PLAT_SDEI_NORMAL_PRI		U(0x30)
 #define PLAT_TEGRA_WDT_PRIO		U(0x40)
 
+#define PLAT_EHF_DESC			EHF_PRI_DESC(PLAT_PRI_BITS,\
+						     PLAT_TEGRA_WDT_PRIO)
+
 /*******************************************************************************
  * SDEI events
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 8e6c1fd..6b87655 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -11,6 +11,11 @@
 #include <lib/utils_def.h>
 
 /*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE			U(0x40000)
+
+/*******************************************************************************
  * This value is used by the PSCI implementation during the `SYSTEM_SUSPEND`
  * call as the `state-id` field in the 'power state' parameter.
  ******************************************************************************/
@@ -104,6 +109,8 @@
 #define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL	U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED	U(3)
 
 /*******************************************************************************
  * Tegra TZRAM constants
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 1da9b46..a971cec 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -11,6 +11,11 @@
 #include <lib/utils_def.h>
 
 /*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE			U(0x40000)
+
+/*******************************************************************************
  * MCE apertures used by the ARI interface
  *
  * Aperture 0 - Cpu0 (ARM Cortex A-57)
@@ -163,6 +168,8 @@
 #define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB	U(0x64C)
+#define MC_VIDEO_PROTECT_REG_CTRL	U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED	U(3)
 
 /*
  * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
index d051a15..398453e 100644
--- a/plat/nvidia/tegra/include/t186/tegra_mc_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,4 +282,117 @@
 #define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB			(1U << 24)
 #define MC_CLIENT_HOTRESET_STATUS1				0x974U
 
+#ifndef __ASSEMBLY__
+
+/*******************************************************************************
+ * Structure to hold the transaction override settings to use to override
+ * client inputs
+ ******************************************************************************/
+typedef struct mc_txn_override_cfg {
+	uint32_t offset;
+	uint8_t cgid_tag;
+} mc_txn_override_cfg_t;
+
+#define mc_make_txn_override_cfg(off, val) \
+	{ \
+		.offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \
+		.cgid_tag = MC_TXN_OVERRIDE_ ## val \
+	}
+
+/*******************************************************************************
+ * Structure to hold the Stream ID to use to override client inputs
+ ******************************************************************************/
+typedef struct mc_streamid_override_cfg {
+	uint32_t offset;
+	uint8_t stream_id;
+} mc_streamid_override_cfg_t;
+
+/*******************************************************************************
+ * Structure to hold the Stream ID Security Configuration settings
+ ******************************************************************************/
+typedef struct mc_streamid_security_cfg {
+	char *name;
+	uint32_t offset;
+	uint32_t override_enable;
+	uint32_t override_client_inputs;
+	uint32_t override_client_ns_flag;
+} mc_streamid_security_cfg_t;
+
+#define OVERRIDE_DISABLE				1U
+#define OVERRIDE_ENABLE					0U
+#define CLIENT_FLAG_SECURE				0U
+#define CLIENT_FLAG_NON_SECURE				1U
+#define CLIENT_INPUTS_OVERRIDE				1U
+#define CLIENT_INPUTS_NO_OVERRIDE			0U
+
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX			0x7FU
+
+#define mc_make_sec_cfg(off, ns, ovrrd, access) \
+	{ \
+		.name = # off, \
+		.offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \
+				MC_STREAMID_OVERRIDE_CFG_ ## off), \
+		.override_client_ns_flag = CLIENT_FLAG_ ## ns, \
+		.override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \
+		.override_enable = OVERRIDE_ ## access \
+	}
+
+#define mc_make_sid_override_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
+		.val = 0x00000000U, \
+	}
+
+#define mc_make_sid_security_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
+		.val = 0x00000000U, \
+	}
+
+#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
+	((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+
+#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
+	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
+
+#define mc_set_tsa_passthrough(client) \
+	do { \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+			(TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+	} while (0)
+
+#define mc_set_tsa_w_passthrough(client) \
+	do { \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+			(TSA_CONFIG_STATIC0_CSW_RESET_W & \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+	} while (0)
+
+#define mc_set_tsa_r_passthrough(client) \
+	{ \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
+			(TSA_CONFIG_STATIC0_CSR_RESET_R & \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+	} while (0)
+
+#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
+	do { \
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
+				  MC_TXN_OVERRIDE_##normal_axi_id | \
+				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
+				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
+				  MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
+	} while (0)
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index e39f9ca..abe193f 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -10,6 +10,11 @@
 #include <lib/utils_def.h>
 
 /*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE			U(0x40000)
+
+/*******************************************************************************
  * Chip specific cluster and cpu numbers
  ******************************************************************************/
 #define PLATFORM_CLUSTER_COUNT		U(4)
@@ -105,6 +110,8 @@
 #define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL	U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED	U(3)
 
 /*
  * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
@@ -294,4 +301,26 @@
 #define TEGRA_SID_XUSB_VF2			U(0x5f)
 #define TEGRA_SID_XUSB_VF3			U(0x60)
 
+/*******************************************************************************
+ * SCR addresses and expected settings
+ ******************************************************************************/
+#define SCRATCH_RSV68_SCR			U(0x0C398110)
+#define SCRATCH_RSV68_SCR_VAL			U(0x38000101)
+#define SCRATCH_RSV71_SCR			U(0x0C39811C)
+#define SCRATCH_RSV71_SCR_VAL			U(0x38000101)
+#define SCRATCH_RSV72_SCR			U(0x0C398120)
+#define SCRATCH_RSV72_SCR_VAL			U(0x38000101)
+#define SCRATCH_RSV75_SCR			U(0x0C39812C)
+#define SCRATCH_RSV75_SCR_VAL			U(0x3A000005)
+#define SCRATCH_RSV81_SCR			U(0x0C398144)
+#define SCRATCH_RSV81_SCR_VAL			U(0x3A000105)
+#define SCRATCH_RSV97_SCR			U(0x0C398184)
+#define SCRATCH_RSV97_SCR_VAL			U(0x38000101)
+#define SCRATCH_RSV99_SCR			U(0x0C39818C)
+#define SCRATCH_RSV99_SCR_VAL			U(0x38000101)
+#define SCRATCH_RSV109_SCR			U(0x0C3981B4)
+#define SCRATCH_RSV109_SCR_VAL			U(0x38000101)
+#define MISCREG_SCR_SCRTZWELCK			U(0x00109000)
+#define MISCREG_SCR_SCRTZWELCK_VAL		U(0x30000100)
+
 #endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
deleted file mode 100644
index 34bdd75..0000000
--- a/plat/nvidia/tegra/include/t194/tegra_mc_def.h
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TEGRA_MC_DEF_H
-#define TEGRA_MC_DEF_H
-
-/*******************************************************************************
- * Memory Controller Order_id registers
- ******************************************************************************/
-#define MC_CLIENT_ORDER_ID_9				U(0x2a24)
-#define  MC_CLIENT_ORDER_ID_9_RESET_VAL			0x00000000U
-#define  MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK		(0x3U << 12)
-#define  MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID	(3U << 12)
-
-#define MC_CLIENT_ORDER_ID_27				U(0x2a6c)
-#define  MC_CLIENT_ORDER_ID_27_RESET_VAL		0x00000000U
-#define  MC_CLIENT_ORDER_ID_27_PCIE0W_MASK		(0x3U << 4)
-#define  MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID		(2U << 4)
-
-#define MC_CLIENT_ORDER_ID_28				U(0x2a70)
-#define  MC_CLIENT_ORDER_ID_28_RESET_VAL		0x00000000U
-#define  MC_CLIENT_ORDER_ID_28_PCIE4W_MASK		(0x3U << 4)
-#define  MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID		(3U << 4)
-#define  MC_CLIENT_ORDER_ID_28_PCIE5W_MASK		(0x3U << 12)
-#define  MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID		(1U << 12)
-
-#define mc_client_order_id(val, id, client) \
-	((val & ~MC_CLIENT_ORDER_ID_##id##_##client##_MASK) | \
-	MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID)
-
-/*******************************************************************************
- * Memory Controller's VC ID configuration registers
- ******************************************************************************/
-#define VC_NISO						0U
-#define VC_SISO						1U
-#define VC_ISO						2U
-
-#define MC_HUB_PC_VC_ID_0				U(0x2a78)
-#define  MC_HUB_PC_VC_ID_0_RESET_VAL 			0x00020100U
-#define  MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK		(0x3U << 8)
-#define  MC_HUB_PC_VC_ID_0_APB_VC_ID			(VC_NISO << 8)
-
-#define MC_HUB_PC_VC_ID_2				U(0x2a80)
-#define  MC_HUB_PC_VC_ID_2_RESET_VAL 			0x10001000U
-#define  MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK		(0x3U << 28)
-#define  MC_HUB_PC_VC_ID_2_SD_VC_ID			(VC_NISO << 28)
-
-#define MC_HUB_PC_VC_ID_4				U(0x2a88)
-#define  MC_HUB_PC_VC_ID_4_RESET_VAL 			0x10020011U
-#define  MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK		(0x3U << 28)
-#define  MC_HUB_PC_VC_ID_4_NIC_VC_ID			(VC_NISO << 28)
-
-#define MC_HUB_PC_VC_ID_12				U(0x2aa8)
-#define  MC_HUB_PC_VC_ID_12_RESET_VAL 			0x11001011U
-#define  MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID_MASK		(0x3U << 12)
-#define  MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID		(VC_NISO << 12)
-
-#define mc_hub_vc_id(val, id, client) \
-	((val & ~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK) | \
-	MC_HUB_PC_VC_ID_##id##_##client##_VC_ID)
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG0				0xdd0U
-
-#define MC_PCFIFO_CLIENT_CONFIG1				0xdd4U
-#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL			0x20200000U
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED		(0U << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK		(1U << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED		(0U << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK		(1U << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED	(0U << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED		(1U << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK		(1U << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2				0xdd8U
-#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL			0x00002800U
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED	(0U << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK	(1U << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED	(0U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED	(1U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK		(1U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED	(0U << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK		(1U << 21)
-
-#define MC_PCFIFO_CLIENT_CONFIG3				0xddcU
-#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL			0x08000080U
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED	(0U << 4)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK		(1U << 4)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED	(0U << 6)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK		(1U << 6)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0U << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK		(1U << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED	(0U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK		(1U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED		(0U << 27)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK		(1U << 27)
-
-#define MC_PCFIFO_CLIENT_CONFIG4				0xde0U
-#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL			0x5552a022U
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED 	(0U << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK		(1U << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED		(0U << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK		(1U << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED	(0U << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK		(1U << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED 	(0U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK		(1U << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED 	(0U << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK		(1U << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED	(0U << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK		(1U << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED	(0U << 20)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK		(1U << 20)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED	(0U << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK		(1U << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED		(0U << 24)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK		(1U << 24)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED	(0U << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK		(1U << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED		(0U << 28)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK		(1U << 28)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED	(0U << 30)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK		(1U << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5				0xbf4U
-#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL			0x20000001U
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0U << 0)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK		(1U << 0)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED	(0U << 30)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK		(1U << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG6				0xb90U
-#define  MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL			0xaa280000U
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED		(0U << 19)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK		(1U << 19)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED	(0U << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK		(1U << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED	(0U << 25)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK		(1U << 25)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED		(1U << 27)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK		(1U << 27)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED		(1U << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK		(1U << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED		(1U << 31)
-#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK		(1U << 31)
-
-#define MC_PCFIFO_CLIENT_CONFIG7				0xaccU
-#define  MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL			0x0000000aU
-#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED	(0U << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK		(1U << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED	(0U << 3)
-#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK		(1U << 3)
-
-/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX					0x7FU
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA			0x660U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD			0xe0U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR			0x3f8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1			0x758U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC			0x640U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA			0x5f0U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR				0x498U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR			0x4f8U
-#define MC_STREAMID_OVERRIDE_CFG_AXISR				0x460U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD			0x2a0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB			0x5f8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1			0x788U
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW			0x1c8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1			0x780U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR			0x250U
-#define MC_STREAMID_OVERRIDE_CFG_MIU1R				0x540U
-#define MC_STREAMID_OVERRIDE_CFG_MIU0R				0x530U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE1W				0x6d8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA			0x678U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW			0x258U
-#define MC_STREAMID_OVERRIDE_CFG_AXIAPW				0x418U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB			0x338U
-#define MC_STREAMID_OVERRIDE_CFG_SATAW				0x1e8U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA			0x600U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE3R				0x6f0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU3W				0x588U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR			0x4e8U
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR			0xb0U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA			0x320U
-#define MC_STREAMID_OVERRIDE_CFG_MIU2R				0x570U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW			0x500U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW			0x6e8U
-#define MC_STREAMID_OVERRIDE_CFG_SESWR				0x408U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1			0x770U
-#define MC_STREAMID_OVERRIDE_CFG_AXISW				0x468U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB			0x618U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW			0x4d0U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB			0x438U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB				0x238U
-#define MC_STREAMID_OVERRIDE_CFG_HDAR				0xa8U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA			0x300U
-#define MC_STREAMID_OVERRIDE_CFG_ETRW				0x428U
-#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW			0x6a8U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR			0x2a8U
-#define MC_STREAMID_OVERRIDE_CFG_ETRR				0x420U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR				0x310U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD			0x3f0U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR			0x4c8U
-#define MC_STREAMID_OVERRIDE_CFG_SCER				0x4d8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU5W				0x7e8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD			0x6b0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE4R				0x700U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA				0x230U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0W				0x6c8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1			0x778U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA			0x610U
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR				0x368U
-#define MC_STREAMID_OVERRIDE_CFG_SESRD				0x400U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW				0x330U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB			0x318U
-#define MC_STREAMID_OVERRIDE_CFG_ISPFALW			0x720U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW				0x478U
-#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR			0x6a0U
-#define MC_STREAMID_OVERRIDE_CFG_RCER				0x690U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR			0x3c8U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR				0x480U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE4W				0x708U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD				0x360U
-#define MC_STREAMID_OVERRIDE_CFG_APER				0x3d0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU7R				0x8U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD			0x7c8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU7W				0x10U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1			0x768U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC			0x688U
-#define MC_STREAMID_OVERRIDE_CFG_AONW				0x4c0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU4W				0x598U
-#define MC_STREAMID_OVERRIDE_CFG_HDAW				0x1a8U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW				0x4a0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA			0x620U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1			0x748U
-#define MC_STREAMID_OVERRIDE_CFG_MIU1W				0x548U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1			0x508U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1			0x510U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW			0x4b0U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR			0x7d8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC			0x658U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5R				0x710U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR			0x260U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW				0x488U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB			0x680U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB			0x650U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB			0x628U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR			0x6b8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0R				0x6c0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE3W				0x6f8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA			0x630U
-#define MC_STREAMID_OVERRIDE_CFG_MIU6W				0x7f8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE1R				0x6d0U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1			0x7d0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB			0x608U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC			0x670U
-#define MC_STREAMID_OVERRIDE_CFG_MIU0W				0x538U
-#define MC_STREAMID_OVERRIDE_CFG_MIU2W				0x578U
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER			0x138U
-#define MC_STREAMID_OVERRIDE_CFG_AXIAPR				0x410U
-#define MC_STREAMID_OVERRIDE_CFG_AONR				0x4b8U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR			0x4a8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB			0x638U
-#define MC_STREAMID_OVERRIDE_CFG_VIFALW				0x5e8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU6R				0x7f0U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR				0x470U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD			0x3c0U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB			0x430U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1			0x518U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1			0x760U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1			0x798U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW			0x4f0U
-#define MC_STREAMID_OVERRIDE_CFG_APEW				0x3d8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU5R				0x7e0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1			0x750U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA			0x648U
-#define MC_STREAMID_OVERRIDE_CFG_ISPFALR			0x228U
-#define MC_STREAMID_OVERRIDE_CFG_PTCR				0x0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU4R				0x590U
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA				0x220U
-#define MC_STREAMID_OVERRIDE_CFG_VIFALR				0x5e0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR			0x6e0U
-#define MC_STREAMID_OVERRIDE_CFG_RCEW				0x698U
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA1				0x790U
-#define MC_STREAMID_OVERRIDE_CFG_SCEW				0x4e0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU3R				0x580U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW			0x268U
-#define MC_STREAMID_OVERRIDE_CFG_SATAR				0xf8U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR			0x490U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB			0x668U
-#define MC_STREAMID_OVERRIDE_CFG_VIW				0x390U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR			0x158U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5W				0x718U
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV		(0U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV	(1U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV		(2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV	(3U << 4)
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL		(0U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL	(1U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL		(2U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL	(3U << 8)
-
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO				(0U << 12)
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID		(1U << 12)
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR				0x10a8U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA				0x1624U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE1W				0x16dcU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC				0x1644U
-#define MC_TXN_OVERRIDE_CONFIG_PTCR				0x1000U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW				0x1478U
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW				0x11c8U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB			0x162cU
-#define MC_TXN_OVERRIDE_CONFIG_AXISR				0x1460U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB				0x1654U
-#define MC_TXN_OVERRIDE_CONFIG_MIU6R				0x17f4U
-#define MC_TXN_OVERRIDE_CONFIG_MIU5R				0x17e4U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1			0x1784U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0R				0x16c4U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR				0x1470U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD				0x10e0U
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1			0x178cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1				0x1774U
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR			0x16bcU
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1				0x1510U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR				0x14a8U
-#define MC_TXN_OVERRIDE_CONFIG_VIW				0x1390U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5R				0x1714U
-#define MC_TXN_OVERRIDE_CONFIG_AXISW				0x1468U
-#define MC_TXN_OVERRIDE_CONFIG_MIU6W				0x17fcU
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR				0x1480U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1				0x179cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1				0x1764U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR				0x12a8U
-#define MC_TXN_OVERRIDE_CONFIG_MIU7R				0x1008U
-#define MC_TXN_OVERRIDE_CONFIG_SATAR				0x10f8U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW			0x1258U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA				0x15f4U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB				0x1438U
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR			0x17dcU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1				0x176cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB				0x166cU
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW				0x14d0U
-#define MC_TXN_OVERRIDE_CONFIG_AONW				0x14c0U
-#define MC_TXN_OVERRIDE_CONFIG_ETRR				0x1420U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW				0x16ecU
-#define MC_TXN_OVERRIDE_CONFIG_PCIE1R				0x16d4U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC				0x1674U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA				0x164cU
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB				0x1430U
-#define MC_TXN_OVERRIDE_CONFIG_MIU1W				0x1548U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0W				0x16ccU
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD			0x17ccU
-#define MC_TXN_OVERRIDE_CONFIG_MIU7W				0x1010U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1			0x1518U
-#define MC_TXN_OVERRIDE_CONFIG_MIU3R				0x1580U
-#define MC_TXN_OVERRIDE_CONFIG_MIU3W				0x158cU
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR			0x1250U
-#define MC_TXN_OVERRIDE_CONFIG_SESRD				0x1400U
-#define MC_TXN_OVERRIDE_CONFIG_SCER				0x14d8U
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER				0x1138U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA				0x1320U
-#define MC_TXN_OVERRIDE_CONFIG_HDAW				0x11a8U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR				0x13c8U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA				0x1634U
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR				0x14c8U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB				0x1338U
-#define MC_TXN_OVERRIDE_CONFIG_ISPFALR				0x1228U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1				0x175cU
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD			0x16b4U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1			0x1508U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA				0x1664U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1				0x174cU
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB				0x1238U
-#define MC_TXN_OVERRIDE_CONFIG_APEW				0x13d8U
-#define MC_TXN_OVERRIDE_CONFIG_AXIAPR				0x1410U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR				0x16e4U
-#define MC_TXN_OVERRIDE_CONFIG_ISPFALW				0x1724U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR				0x1310U
-#define MC_TXN_OVERRIDE_CONFIG_MIU2W				0x1578U
-#define MC_TXN_OVERRIDE_CONFIG_RCER				0x1694U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE4W				0x170cU
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW				0x14a0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR			0x1490U
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA				0x1220U
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR				0x13f8U
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD				0x1360U
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1			0x17d4U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA				0x1614U
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW				0x14f0U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW				0x1330U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB			0x161cU
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR				0x14f8U
-#define MC_TXN_OVERRIDE_CONFIG_RCEW				0x169cU
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB				0x1318U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA				0x1604U
-#define MC_TXN_OVERRIDE_CONFIG_VIFALR				0x15e4U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE3R				0x16f4U
-#define MC_TXN_OVERRIDE_CONFIG_MIU1R				0x1540U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5W				0x171cU
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR			0x1260U
-#define MC_TXN_OVERRIDE_CONFIG_MIU0W				0x1538U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB			0x160cU
-#define MC_TXN_OVERRIDE_CONFIG_VIFALW				0x15ecU
-#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB			0x15fcU
-#define MC_TXN_OVERRIDE_CONFIG_PCIE3W				0x16fcU
-#define MC_TXN_OVERRIDE_CONFIG_MIU0R				0x1530U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC				0x165cU
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR				0x14e8U
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW				0x1500U
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR			0x10b0U
-#define MC_TXN_OVERRIDE_CONFIG_SESWR				0x1408U
-#define MC_TXN_OVERRIDE_CONFIG_AXIAPW				0x1418U
-#define MC_TXN_OVERRIDE_CONFIG_MIU4R				0x1594U
-#define MC_TXN_OVERRIDE_CONFIG_MIU4W				0x159cU
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD				0x13f0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD				0x13c0U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW				0x14b0U
-#define MC_TXN_OVERRIDE_CONFIG_APER				0x13d0U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1				0x1754U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB				0x1684U
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA				0x1230U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC				0x168cU
-#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR				0x16a4U
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA1				0x1794U
-#define MC_TXN_OVERRIDE_CONFIG_AONR				0x14b8U
-#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW				0x16acU
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW				0x1488U
-#define MC_TXN_OVERRIDE_CONFIG_ETRW				0x1428U
-#define MC_TXN_OVERRIDE_CONFIG_SATAW				0x11e8U
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR				0x1368U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR				0x1158U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1				0x177cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB				0x163cU
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA				0x1300U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA				0x167cU
-#define MC_TXN_OVERRIDE_CONFIG_MIU5W				0x17ecU
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR				0x1498U
-#define MC_TXN_OVERRIDE_CONFIG_MIU2R				0x1570U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW			0x1268U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD				0x12a0U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE4R				0x1704U
-#define MC_TXN_OVERRIDE_CONFIG_SCEW				0x14e0U
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID			(1U << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV			(2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT	(1U << 12)
-
-/*******************************************************************************
- * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
- * MC_TXN_OVERRIDE_CONFIG_{module} registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT			0U
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID			1U
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO				2U
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR				3U
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK				3ULL
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0				0x200U
-#define  MC_CLIENT_HOTRESET_CTRL0_RESET_VAL			0U
-#define  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB			(1U << 0)
-#define  MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB			(1U << 6)
-#define  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB			(1U << 7)
-#define  MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB		(1U << 8)
-#define  MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB		(1U << 9)
-#define  MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB		(1U << 11)
-#define  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB		(1U << 15)
-#define  MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB			(1U << 17)
-#define  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB			(1U << 18)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB		(1U << 19)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB		(1U << 20)
-#define  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB		(1U << 22)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB		(1U << 29)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB		(1U << 30)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB		(1U << 31)
-#define MC_CLIENT_HOTRESET_STATUS0				0x204U
-#define MC_CLIENT_HOTRESET_CTRL1				0x970U
-#define  MC_CLIENT_HOTRESET_CTRL1_RESET_VAL			0U
-#define  MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB		(1U << 0)
-#define  MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB			(1U << 2)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB		(1U << 5)
-#define  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB			(1U << 6)
-#define  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB			(1U << 7)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB		(1U << 8)
-#define  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB			(1U << 12)
-#define  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB		(1U << 13)
-#define  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB		(1U << 17)
-#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB		(1U << 18)
-#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB		(1U << 19)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB		(1U << 20)
-#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB		(1U << 21)
-#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB			(1U << 22)
-#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB			(1U << 23)
-#define  MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB		(1U << 26)
-#define  MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB			(1U << 31)
-#define MC_CLIENT_HOTRESET_STATUS1				0x974U
-#define MC_CLIENT_HOTRESET_CTRL2				0x97cU
-#define  MC_CLIENT_HOTRESET_CTRL2_RESET_VAL			0U
-#define  MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB		(1U << 0)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB		(1U << 2)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB		(1U << 4)
-#define  MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB		(1U << 9)
-#define  MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB		(1U << 10)
-#define  MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB		(1U << 11)
-#define  MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB		(1U << 14)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB		(1U << 16)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB		(1U << 17)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB		(1U << 22)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB		(1U << 23)
-#define  MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB		(1U << 25)
-#define MC_CLIENT_HOTRESET_STATUS2				0x1898U
-
-#define MC_COALESCE_CTRL					0x2930U
-#define MC_COALESCE_CTRL_COALESCER_ENABLE			(1U << 31)
-#define MC_COALESCE_CONFIG_6_0					0x294cU
-#define MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED	(1U << 8)
-#define MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED	(1U << 14)
-
-/*******************************************************************************
- * Tegra TSA Controller constants
- ******************************************************************************/
-#define TEGRA_TSA_BASE						U(0x02000000)
-
-#define TSA_CONFIG_STATIC0_CSR_RESET_R				0x20000000U
-#define TSA_CONFIG_STATIC0_CSW_RESET_W				0x20001000U
-#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV			0x20001000U
-
-#define TSA_CONFIG_STATIC0_CSW_PCIE1W				0x1004U
-#define TSA_CONFIG_STATIC0_CSW_PCIE2AW				0x1008U
-#define TSA_CONFIG_STATIC0_CSW_PCIE3W				0x100cU
-#define TSA_CONFIG_STATIC0_CSW_PCIE4W				0x1028U
-#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW			0x2004U
-#define TSA_CONFIG_STATIC0_CSR_SATAR				0x2010U
-#define TSA_CONFIG_STATIC0_CSW_SATAW				0x2014U
-#define TSA_CONFIG_STATIC0_CSW_PCIE0W				0x2020U
-#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW			0x202cU
-#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR			0x3004U
-#define TSA_CONFIG_STATIC0_CSW_NVENCSWR				0x3010U
-#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR			0x4004U
-#define TSA_CONFIG_STATIC0_CSR_ISPFALR				0x4010U
-#define TSA_CONFIG_STATIC0_CSW_ISPWA				0x4014U
-#define TSA_CONFIG_STATIC0_CSW_ISPWB				0x4018U
-#define TSA_CONFIG_STATIC0_CSW_ISPFALW				0x401cU
-#define TSA_CONFIG_STATIC0_CSW_NVDECSWR				0x5004U
-#define TSA_CONFIG_STATIC0_CSR_EQOSR				0x5010U
-#define TSA_CONFIG_STATIC0_CSW_EQOSW				0x5014U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB				0x5020U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB				0x5024U
-#define TSA_CONFIG_STATIC0_CSW_UFSHCW				0x6004U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCR				0x6010U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCRA				0x6014U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCW				0x6018U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCWA				0x601cU
-#define TSA_CONFIG_STATIC0_CSR_RCER				0x6030U
-#define TSA_CONFIG_STATIC0_CSR_RCEDMAR				0x6034U
-#define TSA_CONFIG_STATIC0_CSW_RCEW				0x6038U
-#define TSA_CONFIG_STATIC0_CSW_RCEDMAW				0x603cU
-#define TSA_CONFIG_STATIC0_CSR_SCER				0x6050U
-#define TSA_CONFIG_STATIC0_CSR_SCEDMAR				0x6054U
-#define TSA_CONFIG_STATIC0_CSW_SCEW				0x6058U
-#define TSA_CONFIG_STATIC0_CSW_SCEDMAW				0x605cU
-#define TSA_CONFIG_STATIC0_CSR_AXIAPR				0x7004U
-#define TSA_CONFIG_STATIC0_CSR_ETRR				0x7008U
-#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR			0x700cU
-#define TSA_CONFIG_STATIC0_CSW_AXIAPW				0x7010U
-#define TSA_CONFIG_STATIC0_CSW_ETRW				0x7014U
-#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD				0x8004U
-#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR				0x8008U
-#define TSA_CONFIG_STATIC0_CSR_AXISR				0x8014U
-#define TSA_CONFIG_STATIC0_CSW_AXISW				0x8018U
-#define TSA_CONFIG_STATIC0_CSR_BPMPR				0x9004U
-#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR				0x9008U
-#define TSA_CONFIG_STATIC0_CSW_BPMPW				0x900cU
-#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW				0x9010U
-#define TSA_CONFIG_STATIC0_CSR_SESRD				0x9024U
-#define TSA_CONFIG_STATIC0_CSR_TSECSRD				0x9028U
-#define TSA_CONFIG_STATIC0_CSR_TSECSRDB				0x902cU
-#define TSA_CONFIG_STATIC0_CSW_SESWR				0x9030U
-#define TSA_CONFIG_STATIC0_CSW_TSECSWR				0x9034U
-#define TSA_CONFIG_STATIC0_CSW_TSECSWRB				0x9038U
-#define TSA_CONFIG_STATIC0_CSW_PCIE5W				0xb004U
-#define TSA_CONFIG_STATIC0_CSW_VICSWR				0xc004U
-#define TSA_CONFIG_STATIC0_CSR_APER				0xd004U
-#define TSA_CONFIG_STATIC0_CSR_APEDMAR				0xd008U
-#define TSA_CONFIG_STATIC0_CSW_APEW				0xd00cU
-#define TSA_CONFIG_STATIC0_CSW_APEDMAW				0xd010U
-#define TSA_CONFIG_STATIC0_CSR_HDAR				0xf004U
-#define TSA_CONFIG_STATIC0_CSW_HDAW				0xf008U
-#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR			0xf014U
-#define TSA_CONFIG_STATIC0_CSR_VIFALR				0x10004U
-#define TSA_CONFIG_STATIC0_CSW_VIW				0x10008U
-#define TSA_CONFIG_STATIC0_CSW_VIFALW				0x1000cU
-#define TSA_CONFIG_STATIC0_CSR_AONR				0x12004U
-#define TSA_CONFIG_STATIC0_CSR_AONDMAR				0x12008U
-#define TSA_CONFIG_STATIC0_CSW_AONW				0x1200cU
-#define TSA_CONFIG_STATIC0_CSW_AONDMAW				0x12010U
-#define TSA_CONFIG_STATIC0_CSR_PCIE1R				0x14004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE2AR				0x14008U
-#define TSA_CONFIG_STATIC0_CSR_PCIE3R				0x1400cU
-#define TSA_CONFIG_STATIC0_CSR_PCIE4R				0x14028U
-#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR			0x15004U
-#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR			0x15010U
-#define TSA_CONFIG_STATIC0_CSR_UFSHCR				0x16004U
-#define TSA_CONFIG_STATIC0_CSW_DLA1WRA				0x18004U
-#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB			0x18010U
-#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB			0x18014U
-#define TSA_CONFIG_STATIC0_CSW_DLA0WRA				0x19004U
-#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB			0x19010U
-#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB			0x19014U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDC				0x1a004U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRC				0x1a008U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRA				0x1a014U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRB				0x1a020U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRB				0x1b004U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDC				0x1b010U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRC				0x1b014U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRA				0x1b020U
-#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD			0x1d004U
-#define TSA_CONFIG_STATIC0_CSR_NVENCSRD				0x1d010U
-#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD			0x1e004U
-#define TSA_CONFIG_STATIC0_CSR_ISPRA				0x1e010U
-#define TSA_CONFIG_STATIC0_CSR_NVDECSRD				0x1f004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE0R				0x21004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE5R				0x23004U
-#define TSA_CONFIG_STATIC0_CSR_VICSRD				0x24004U
-#define TSA_CONFIG_STATIC0_CSR_DLA1RDA				0x26004U
-#define TSA_CONFIG_STATIC0_CSR_DLA0RDA				0x27004U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDA				0x28004U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDB				0x28010U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDB				0x29004U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDA				0x29010U
-
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK			(ULL(0x3) << 11)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU			(ULL(0) << 11)
-#define TSA_CONFIG_CSW_SO_DEV_HUBID_MASK			(ULL(0x3) << 15)
-#define TSA_CONFIG_CSW_SO_DEV_HUB2				(ULL(2) << 15)
-
-#define REORDER_DEPTH_LIMIT					16
-#define TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK			(ULL(0x7FF) << 21)
-#define reorder_depth_limit(limit)				(ULL(limit) << 21)
-
-#define tsa_read_32(client) \
-		mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client)
-
-#define mc_set_tsa_hub2(val, client) \
-	{ \
-		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
-		((val & ~TSA_CONFIG_CSW_SO_DEV_HUBID_MASK) | \
-		TSA_CONFIG_CSW_SO_DEV_HUB2)); \
-	}
-
-#define mc_set_tsa_depth_limit(limit, client) \
-	{ \
-		uint32_t val = mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client); \
-		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
-		((val & ~TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK) | \
-		reorder_depth_limit(limit))); \
-	}
-
-#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index f3013a8..81b25e0 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -11,6 +11,11 @@
 #include <lib/utils_def.h>
 
 /*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE			U(0x40000)
+
+/*******************************************************************************
  * Power down state IDs
  ******************************************************************************/
 #define PSTATE_ID_CORE_POWERDN		U(7)
@@ -240,6 +245,8 @@
 #define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL	U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED	U(3)
 
 /* SMMU configuration registers*/
 #define MC_SMMU_PPCS_ASID_0		0x270U
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index 7dfa4d0..b8297fd 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -30,6 +30,7 @@
 #define TEGRA_CHIPID_TEGRA13		U(0x13)
 #define TEGRA_CHIPID_TEGRA21		U(0x21)
 #define TEGRA_CHIPID_TEGRA18		U(0x18)
+#define TEGRA_CHIPID_TEGRA19		U(0x19)
 
 /*******************************************************************************
  * JEDEC Standard Manufacturer's Identification Code and Bank ID
@@ -52,6 +53,7 @@
 bool tegra_chipid_is_t186(void);
 bool tegra_chipid_is_t210(void);
 bool tegra_chipid_is_t210_b01(void);
+bool tegra_chipid_is_t194(void);
 
 /*
  * Tegra platform identifiers
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index c181c36..cc2ad86 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -68,6 +68,11 @@
        image_info_t *bl33_image_info;
 };
 
+/*******************************************************************************
+* To suppress Coverity MISRA C-2012 Rule 2.2 violations
+*******************************************************************************/
+#define UNUSED_FUNC_NOP()	asm("nop")
+
 /* Declarations for plat_psci_handlers.c */
 int32_t tegra_soc_validate_power_state(uint32_t power_state,
 		psci_power_state_t *req_state);
@@ -82,6 +87,7 @@
 void plat_late_platform_setup(void);
 void plat_relocate_bl32_image(const image_info_t *bl32_img_info);
 bool plat_supports_system_suspend(void);
+void plat_runtime_setup(void);
 
 /* Declarations for plat_secondary.c */
 void plat_secondary_setup(void);
@@ -112,19 +118,6 @@
 plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
 					     const plat_local_state_t *states,
 					     uint32_t ncpu);
-void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state);
-void tegra_cpu_standby(plat_local_state_t cpu_state);
-int32_t tegra_pwr_domain_on(u_register_t mpidr);
-void tegra_pwr_domain_off(const psci_power_state_t *target_state);
-void tegra_pwr_domain_suspend(const psci_power_state_t *target_state);
-void __dead2 tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
-void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state);
-void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state);
-__dead2 void tegra_system_off(void);
-__dead2 void tegra_system_reset(void);
-int32_t tegra_validate_power_state(uint32_t power_state,
-				   psci_power_state_t *req_state);
-int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint);
 
 /* Declarations for tegraXXX_pm.c */
 int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl);
@@ -159,7 +152,7 @@
 
 #if RAS_EXTENSION
 void tegra194_ras_enable(void);
-void tegra194_ras_corrected_err_clear(void);
+void tegra194_ras_corrected_err_clear(uint64_t *cookie);
 #endif
 
 #endif /* TEGRA_PRIVATE_H */
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/lib/debug/profiler.c
similarity index 100%
rename from plat/nvidia/tegra/common/lib/debug/profiler.c
rename to plat/nvidia/tegra/lib/debug/profiler.c
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index a4724e6..6ed1cdf 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -33,9 +33,6 @@
 # do not use coherent memory
 USE_COHERENT_MEM	:=	0
 
-# do not enable SVE
-ENABLE_SVE_FOR_NS	:=	0
-
 # enable D-cache early during CPU warmboot
 WARMBOOT_ENABLE_DCACHE_EARLY := 1
 
@@ -55,27 +52,30 @@
 # Enable SDEI
 SDEI_SUPPORT			:= 1
 
+# modify BUILD_PLAT to point to SoC specific build directory
+BUILD_PLAT	:=	${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
 $(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING))
 $(eval $(call add_define,RELOCATE_BL32_IMAGE))
 
-# modify BUILD_PLAT to point to SoC specific build directory
-BUILD_PLAT	:=	$(abspath ${BUILD_BASE})/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
-
 # platform cflags (enable signed comparisons, disable stdlib)
-TF_CFLAGS	+= -Wsign-compare -nostdlib
+TF_CFLAGS	+= -nostdlib
 
 # override with necessary libc files for the Tegra platform
 override LIBC_SRCS :=	$(addprefix lib/libc/,		\
 			aarch64/setjmp.S		\
 			assert.c			\
+			memchr.c			\
+			memcmp.c			\
 			memcpy.c			\
 			memmove.c			\
 			memset.c			\
 			printf.c			\
 			putchar.c			\
+			strrchr.c			\
 			strlen.c			\
 			snprintf.c)
 
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index 43acdd6..49e8b5d 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -6,9 +6,11 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <common/bl_common.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <memctrl.h>
 #include <plat/common/platform.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
@@ -144,7 +146,16 @@
  ******************************************************************************/
 void plat_early_platform_setup(void)
 {
-	; /* do nothing */
+	plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+	/* Verify chip id is t132 */
+	assert(tegra_chipid_is_t132());
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
 }
 
 /*******************************************************************************
@@ -162,3 +173,29 @@
 {
 	return true;
 }
+
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+	/*
+	 * During cold boot, it is observed that the arbitration
+	 * bit is set in the Memory controller leading to false
+	 * error interrupts in the non-secure world. To avoid
+	 * this, clean the interrupt status register before
+	 * booting into the non-secure world
+	 */
+	tegra_memctrl_clear_pending_interrupts();
+
+	/*
+	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
+	 * access to IRAM. Because these clients connect to the MC and
+	 * do not have a direct path to the IRAM, the MC implements AHB
+	 * redirection during boot to allow path to IRAM. In this mode
+	 * accesses to a programmed memory address aperture are directed
+	 * to the AHB bus, allowing access to the IRAM. This mode must be
+	 * disabled before we jump to the non-secure world.
+	 */
+	tegra_memctrl_disable_ahb_redirection();
+}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index 16bd0ea..9534c07 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -23,11 +23,12 @@
 # platform files
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t132
 
-BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S		\
+BL31_SOURCES		+=	${TEGRA_GICv2_SOURCES}			\
+				drivers/ti/uart/aarch64/16550_console.S	\
 				lib/cpus/aarch64/denver.S		\
-				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
-				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
-				${COMMON_DIR}/drivers/pmc/pmc.c			\
+				${TEGRA_DRIVERS}/flowctrl/flowctrl.c	\
+				${TEGRA_DRIVERS}/memctrl/memctrl_v1.c	\
+				${TEGRA_DRIVERS}/pmc/pmc.c		\
 				${SOC_DIR}/plat_psci_handlers.c		\
 				${SOC_DIR}/plat_sip_calls.c		\
 				${SOC_DIR}/plat_setup.c			\
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 4eb68e4..81de674 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -402,16 +402,8 @@
 
 static void tegra186_memctrl_set_overrides(void)
 {
-	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
-	const mc_txn_override_cfg_t *mc_txn_override_cfgs;
-	uint32_t num_txn_override_cfgs;
 	uint32_t i, val;
 
-	/* Get the settings from the platform */
-	assert(plat_mc_settings != NULL);
-	mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
-	num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
-
 	/*
 	 * Set the MC_TXN_OVERRIDE registers for write clients.
 	 */
@@ -443,11 +435,11 @@
 		/*
 		 * Settings for Tegra186 silicon rev. A02 and onwards.
 		 */
-		for (i = 0; i < num_txn_override_cfgs; i++) {
-			val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
+		for (i = 0; i < ARRAY_SIZE(tegra186_txn_override_cfgs); i++) {
+			val = tegra_mc_read_32(tegra186_txn_override_cfgs[i].offset);
 			val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-			tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
-				val | mc_txn_override_cfgs[i].cgid_tag);
+			tegra_mc_write_32(tegra186_txn_override_cfgs[i].offset,
+				val | tegra186_txn_override_cfgs[i].cgid_tag);
 		}
 	}
 }
@@ -609,7 +601,7 @@
 /*******************************************************************************
  * Handler to return the pointer to the MC's context struct
  ******************************************************************************/
-static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void)
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void)
 {
 	/* index of _END_OF_TABLE_ */
 	tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U;
@@ -617,27 +609,52 @@
 	return tegra186_mc_context;
 }
 
-/*******************************************************************************
- * Struct to hold the memory controller settings
- ******************************************************************************/
-static tegra_mc_settings_t tegra186_mc_settings = {
-	.streamid_override_cfg = tegra186_streamid_override_regs,
-	.num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_override_regs),
-	.streamid_security_cfg = tegra186_streamid_sec_cfgs,
-	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs),
-	.txn_override_cfg = tegra186_txn_override_cfgs,
-	.num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
-	.reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
-	.set_txn_overrides = tegra186_memctrl_set_overrides,
-	.get_mc_system_suspend_ctx = tegra186_get_mc_system_suspend_ctx,
-};
+void plat_memctrl_setup(void)
+{
+	uint32_t val;
+	unsigned int i;
+
+	/* Program all the Stream ID overrides */
+	for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_override_regs); i++) {
+		tegra_mc_streamid_write_32(tegra186_streamid_override_regs[i],
+			MC_STREAM_ID_MAX);
+	}
+
+	/* Program the security config settings for all Stream IDs */
+	for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_sec_cfgs); i++) {
+		val = (tegra186_streamid_sec_cfgs[i].override_enable << 16) |
+		      (tegra186_streamid_sec_cfgs[i].override_client_inputs << 8) |
+		      (tegra186_streamid_sec_cfgs[i].override_client_ns_flag << 0);
+		tegra_mc_streamid_write_32(tegra186_streamid_sec_cfgs[i].offset, val);
+	}
+
+	/*
+	 * Re-configure MSS to allow ROC to deal with ordering of the
+	 * Memory Controller traffic. This is needed as the Memory Controller
+	 * boots with MSS having all control, but ROC provides a performance
+	 * boost as compared to MSS.
+	 */
+	tegra186_memctrl_reconfig_mss_clients();
+
+	/* Program overrides for MC transactions */
+	tegra186_memctrl_set_overrides();
+}
 
 /*******************************************************************************
- * Handler to return the pointer to the memory controller's settings struct
+ * Handler to restore platform specific settings to the memory controller
  ******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void)
+void plat_memctrl_restore(void)
 {
-	return &tegra186_mc_settings;
+	/*
+	 * Re-configure MSS to allow ROC to deal with ordering of the
+	 * Memory Controller traffic. This is needed as the Memory Controller
+	 * boots with MSS having all control, but ROC provides a performance
+	 * boost as compared to MSS.
+	 */
+	tegra186_memctrl_reconfig_mss_clients();
+
+	/* Program overrides for MC transactions */
+	tegra186_memctrl_set_overrides();
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 6f58427..af4182e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -72,6 +72,11 @@
 	case PSTATE_ID_CORE_IDLE:
 	case PSTATE_ID_CORE_POWERDN:
 
+		if (psci_get_pstate_type(power_state) != PSTATE_TYPE_POWERDOWN) {
+			ret = PSCI_E_INVALID_PARAMS;
+			break;
+		}
+
 		/* Core powerdown request */
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
 		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index c216b5d..d6d090a 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -26,6 +26,8 @@
 #include <plat/common/platform.h>
 
 #include <mce.h>
+#include <memctrl.h>
+#include <smmu.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -185,10 +187,20 @@
 {
 	uint64_t impl, val;
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+	const struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params();
+
+	/* Verify chip id is t186 */
+	assert(tegra_chipid_is_t186());
 
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
+
 	impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
 
 	/*
@@ -202,6 +214,13 @@
 		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
 		write_l2ctlr_el1(val);
 	}
+
+	/*
+	 * The previous bootloader might not have placed the BL32 image
+	 * inside the TZDRAM. Platform handler to allow relocation of BL32
+	 * image to TZDRAM memory. This behavior might change per platform.
+	 */
+	plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
 }
 
 /*******************************************************************************
@@ -345,3 +364,34 @@
 {
 	return true;
 }
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+	/*
+	 * During cold boot, it is observed that the arbitration
+	 * bit is set in the Memory controller leading to false
+	 * error interrupts in the non-secure world. To avoid
+	 * this, clean the interrupt status register before
+	 * booting into the non-secure world
+	 */
+	tegra_memctrl_clear_pending_interrupts();
+
+	/*
+	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
+	 * access to IRAM. Because these clients connect to the MC and
+	 * do not have a direct path to the IRAM, the MC implements AHB
+	 * redirection during boot to allow path to IRAM. In this mode
+	 * accesses to a programmed memory address aperture are directed
+	 * to the AHB bus, allowing access to the IRAM. This mode must be
+	 * disabled before we jump to the non-secure world.
+	 */
+	tegra_memctrl_disable_ahb_redirection();
+
+	/*
+	 * Verify the integrity of the previously configured SMMU(s)
+	 * settings
+	 */
+	tegra_smmu_verify();
+}
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index d320aac..5275b8e 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -40,19 +40,20 @@
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t186 \
 				-I${SOC_DIR}/drivers/include
 
-BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S	\
+BL31_SOURCES		+=	${TEGRA_GICv2_SOURCES}			\
+				drivers/ti/uart/aarch64/16550_console.S	\
 				lib/cpus/aarch64/denver.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
-				${COMMON_DIR}/drivers/bpmp_ipc/intf.c   \
-				${COMMON_DIR}/drivers/bpmp_ipc/ivc.c    \
-				${COMMON_DIR}/drivers/gpcdma/gpcdma.c	\
-				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
-				${COMMON_DIR}/drivers/smmu/smmu.c	\
+				${TEGRA_DRIVERS}/bpmp_ipc/intf.c	\
+				${TEGRA_DRIVERS}/bpmp_ipc/ivc.c		\
+				${TEGRA_DRIVERS}/gpcdma/gpcdma.c	\
+				${TEGRA_DRIVERS}/memctrl/memctrl_v2.c	\
+				${TEGRA_DRIVERS}/smmu/smmu.c		\
 				${SOC_DIR}/drivers/mce/mce.c		\
 				${SOC_DIR}/drivers/mce/ari.c		\
 				${SOC_DIR}/drivers/mce/nvg.c		\
 				${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
-				$(SOC_DIR)/drivers/se/se.c \
+				$(SOC_DIR)/drivers/se/se.c		\
 				${SOC_DIR}/plat_memctrl.c		\
 				${SOC_DIR}/plat_psci_handlers.c		\
 				${SOC_DIR}/plat_setup.c			\
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
index 6dafeb2..ef16980 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -56,6 +56,7 @@
 int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time);
 int32_t nvg_roc_clean_cache_trbits(void);
 void nvg_enable_strict_checking_mode(void);
+void nvg_verify_strict_checking_mode(void);
 void nvg_system_shutdown(void);
 void nvg_system_reboot(void);
 void nvg_clear_hsm_corr_status(void);
@@ -70,6 +71,7 @@
 
 /* MCE helper functions */
 void mce_enable_strict_checking(void);
+void mce_verify_strict_checking(void);
 void mce_system_shutdown(void);
 void mce_system_reboot(void);
 void mce_clear_hsm_corr_status(void);
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
index 4663a3d..e3d5bd5 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -217,6 +217,15 @@
 		nvg_enable_strict_checking_mode();
 	}
 }
+void mce_verify_strict_checking(void)
+{
+	bool is_silicon = tegra_platform_is_silicon();
+	bool is_fpga = tegra_platform_is_fpga();
+
+	if (is_silicon || is_fpga) {
+		nvg_verify_strict_checking_mode();
+	}
+}
 #endif
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index fdf9429..f76ab14 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -4,12 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+#include <errno.h>
+
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <denver.h>
-#include <errno.h>
 #include <lib/mmio.h>
+
 #include <mce_private.h>
 #include <platform_def.h>
 #include <t194_nvg.h>
@@ -211,6 +214,15 @@
 
 	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
 }
+
+void nvg_verify_strict_checking_mode(void)
+{
+	uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
+				     STRICT_CHECKING_LOCKED_SET);
+
+	nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG);
+	assert(params == (uint64_t)nvg_get_result());
+}
 #endif
 
 /*
diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
index 9a4d22e..9ddcacf 100644
--- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
@@ -8,406 +8,14 @@
 #include <common/bl_common.h>
 #include <mce.h>
 #include <memctrl_v2.h>
-#include <tegra_mc_def.h>
 #include <tegra_platform.h>
+#include <tegra_private.h>
 
 /*******************************************************************************
- * Array to hold the security configs for stream IDs
- ******************************************************************************/
-const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = {
-	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDEC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDEC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVDEC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU6R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU6W, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU7R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE)
-};
-
-/*******************************************************************************
  * Array to hold MC context for Tegra194
  ******************************************************************************/
 static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = {
 	_START_OF_TABLE_,
-	mc_make_sid_security_cfg(HDAR),
-	mc_make_sid_security_cfg(HOST1XDMAR),
-	mc_make_sid_security_cfg(NVENCSRD),
-	mc_make_sid_security_cfg(SATAR),
-	mc_make_sid_security_cfg(NVENCSWR),
-	mc_make_sid_security_cfg(HDAW),
-	mc_make_sid_security_cfg(SATAW),
-	mc_make_sid_security_cfg(ISPRA),
-	mc_make_sid_security_cfg(ISPFALR),
-	mc_make_sid_security_cfg(ISPWA),
-	mc_make_sid_security_cfg(ISPWB),
-	mc_make_sid_security_cfg(XUSB_HOSTR),
-	mc_make_sid_security_cfg(XUSB_HOSTW),
-	mc_make_sid_security_cfg(XUSB_DEVR),
-	mc_make_sid_security_cfg(XUSB_DEVW),
-	mc_make_sid_security_cfg(TSECSRD),
-	mc_make_sid_security_cfg(TSECSWR),
-	mc_make_sid_security_cfg(SDMMCRA),
-	mc_make_sid_security_cfg(SDMMCR),
-	mc_make_sid_security_cfg(SDMMCRAB),
-	mc_make_sid_security_cfg(SDMMCWA),
-	mc_make_sid_security_cfg(SDMMCW),
-	mc_make_sid_security_cfg(SDMMCWAB),
-	mc_make_sid_security_cfg(VICSRD),
-	mc_make_sid_security_cfg(VICSWR),
-	mc_make_sid_security_cfg(VIW),
-	mc_make_sid_security_cfg(NVDECSRD),
-	mc_make_sid_security_cfg(NVDECSWR),
-	mc_make_sid_security_cfg(APER),
-	mc_make_sid_security_cfg(APEW),
-	mc_make_sid_security_cfg(NVJPGSRD),
-	mc_make_sid_security_cfg(NVJPGSWR),
-	mc_make_sid_security_cfg(SESRD),
-	mc_make_sid_security_cfg(SESWR),
-	mc_make_sid_security_cfg(AXIAPR),
-	mc_make_sid_security_cfg(AXIAPW),
-	mc_make_sid_security_cfg(ETRR),
-	mc_make_sid_security_cfg(ETRW),
-	mc_make_sid_security_cfg(TSECSRDB),
-	mc_make_sid_security_cfg(TSECSWRB),
-	mc_make_sid_security_cfg(AXISR),
-	mc_make_sid_security_cfg(AXISW),
-	mc_make_sid_security_cfg(EQOSR),
-	mc_make_sid_security_cfg(EQOSW),
-	mc_make_sid_security_cfg(UFSHCR),
-	mc_make_sid_security_cfg(UFSHCW),
-	mc_make_sid_security_cfg(NVDISPLAYR),
-	mc_make_sid_security_cfg(BPMPR),
-	mc_make_sid_security_cfg(BPMPW),
-	mc_make_sid_security_cfg(BPMPDMAR),
-	mc_make_sid_security_cfg(BPMPDMAW),
-	mc_make_sid_security_cfg(AONR),
-	mc_make_sid_security_cfg(AONW),
-	mc_make_sid_security_cfg(AONDMAR),
-	mc_make_sid_security_cfg(AONDMAW),
-	mc_make_sid_security_cfg(SCER),
-	mc_make_sid_security_cfg(SCEW),
-	mc_make_sid_security_cfg(SCEDMAR),
-	mc_make_sid_security_cfg(SCEDMAW),
-	mc_make_sid_security_cfg(APEDMAR),
-	mc_make_sid_security_cfg(APEDMAW),
-	mc_make_sid_security_cfg(NVDISPLAYR1),
-	mc_make_sid_security_cfg(VICSRD1),
-	mc_make_sid_security_cfg(NVDECSRD1),
-	mc_make_sid_security_cfg(VIFALR),
-	mc_make_sid_security_cfg(VIFALW),
-	mc_make_sid_security_cfg(DLA0RDA),
-	mc_make_sid_security_cfg(DLA0FALRDB),
-	mc_make_sid_security_cfg(DLA0WRA),
-	mc_make_sid_security_cfg(DLA0FALWRB),
-	mc_make_sid_security_cfg(DLA1RDA),
-	mc_make_sid_security_cfg(DLA1FALRDB),
-	mc_make_sid_security_cfg(DLA1WRA),
-	mc_make_sid_security_cfg(DLA1FALWRB),
-	mc_make_sid_security_cfg(PVA0RDA),
-	mc_make_sid_security_cfg(PVA0RDB),
-	mc_make_sid_security_cfg(PVA0RDC),
-	mc_make_sid_security_cfg(PVA0WRA),
-	mc_make_sid_security_cfg(PVA0WRB),
-	mc_make_sid_security_cfg(PVA0WRC),
-	mc_make_sid_security_cfg(PVA1RDA),
-	mc_make_sid_security_cfg(PVA1RDB),
-	mc_make_sid_security_cfg(PVA1RDC),
-	mc_make_sid_security_cfg(PVA1WRA),
-	mc_make_sid_security_cfg(PVA1WRB),
-	mc_make_sid_security_cfg(PVA1WRC),
-	mc_make_sid_security_cfg(RCER),
-	mc_make_sid_security_cfg(RCEW),
-	mc_make_sid_security_cfg(RCEDMAR),
-	mc_make_sid_security_cfg(RCEDMAW),
-	mc_make_sid_security_cfg(NVENC1SRD),
-	mc_make_sid_security_cfg(NVENC1SWR),
-	mc_make_sid_security_cfg(PCIE0R),
-	mc_make_sid_security_cfg(PCIE0W),
-	mc_make_sid_security_cfg(PCIE1R),
-	mc_make_sid_security_cfg(PCIE1W),
-	mc_make_sid_security_cfg(PCIE2AR),
-	mc_make_sid_security_cfg(PCIE2AW),
-	mc_make_sid_security_cfg(PCIE3R),
-	mc_make_sid_security_cfg(PCIE3W),
-	mc_make_sid_security_cfg(PCIE4R),
-	mc_make_sid_security_cfg(PCIE4W),
-	mc_make_sid_security_cfg(PCIE5R),
-	mc_make_sid_security_cfg(PCIE5W),
-	mc_make_sid_security_cfg(ISPFALW),
-	mc_make_sid_security_cfg(DLA0RDA1),
-	mc_make_sid_security_cfg(DLA1RDA1),
-	mc_make_sid_security_cfg(PVA0RDA1),
-	mc_make_sid_security_cfg(PVA0RDB1),
-	mc_make_sid_security_cfg(PVA1RDA1),
-	mc_make_sid_security_cfg(PVA1RDB1),
-	mc_make_sid_security_cfg(PCIE5R1),
-	mc_make_sid_security_cfg(NVENCSRD1),
-	mc_make_sid_security_cfg(NVENC1SRD1),
-	mc_make_sid_security_cfg(ISPRA1),
-	mc_make_sid_security_cfg(PCIE0R1),
-	mc_make_sid_security_cfg(MIU0R),
-	mc_make_sid_security_cfg(MIU0W),
-	mc_make_sid_security_cfg(MIU1R),
-	mc_make_sid_security_cfg(MIU1W),
-	mc_make_sid_security_cfg(MIU2R),
-	mc_make_sid_security_cfg(MIU2W),
-	mc_make_sid_security_cfg(MIU3R),
-	mc_make_sid_security_cfg(MIU3W),
-	mc_make_sid_override_cfg(HDAR),
-	mc_make_sid_override_cfg(HOST1XDMAR),
-	mc_make_sid_override_cfg(NVENCSRD),
-	mc_make_sid_override_cfg(SATAR),
-	mc_make_sid_override_cfg(NVENCSWR),
-	mc_make_sid_override_cfg(HDAW),
-	mc_make_sid_override_cfg(SATAW),
-	mc_make_sid_override_cfg(ISPRA),
-	mc_make_sid_override_cfg(ISPFALR),
-	mc_make_sid_override_cfg(ISPWA),
-	mc_make_sid_override_cfg(ISPWB),
-	mc_make_sid_override_cfg(XUSB_HOSTR),
-	mc_make_sid_override_cfg(XUSB_HOSTW),
-	mc_make_sid_override_cfg(XUSB_DEVR),
-	mc_make_sid_override_cfg(XUSB_DEVW),
-	mc_make_sid_override_cfg(TSECSRD),
-	mc_make_sid_override_cfg(TSECSWR),
-	mc_make_sid_override_cfg(SDMMCRA),
-	mc_make_sid_override_cfg(SDMMCR),
-	mc_make_sid_override_cfg(SDMMCRAB),
-	mc_make_sid_override_cfg(SDMMCWA),
-	mc_make_sid_override_cfg(SDMMCW),
-	mc_make_sid_override_cfg(SDMMCWAB),
-	mc_make_sid_override_cfg(VICSRD),
-	mc_make_sid_override_cfg(VICSWR),
-	mc_make_sid_override_cfg(VIW),
-	mc_make_sid_override_cfg(NVDECSRD),
-	mc_make_sid_override_cfg(NVDECSWR),
-	mc_make_sid_override_cfg(APER),
-	mc_make_sid_override_cfg(APEW),
-	mc_make_sid_override_cfg(NVJPGSRD),
-	mc_make_sid_override_cfg(NVJPGSWR),
-	mc_make_sid_override_cfg(SESRD),
-	mc_make_sid_override_cfg(SESWR),
-	mc_make_sid_override_cfg(AXIAPR),
-	mc_make_sid_override_cfg(AXIAPW),
-	mc_make_sid_override_cfg(ETRR),
-	mc_make_sid_override_cfg(ETRW),
-	mc_make_sid_override_cfg(TSECSRDB),
-	mc_make_sid_override_cfg(TSECSWRB),
-	mc_make_sid_override_cfg(AXISR),
-	mc_make_sid_override_cfg(AXISW),
-	mc_make_sid_override_cfg(EQOSR),
-	mc_make_sid_override_cfg(EQOSW),
-	mc_make_sid_override_cfg(UFSHCR),
-	mc_make_sid_override_cfg(UFSHCW),
-	mc_make_sid_override_cfg(NVDISPLAYR),
-	mc_make_sid_override_cfg(BPMPR),
-	mc_make_sid_override_cfg(BPMPW),
-	mc_make_sid_override_cfg(BPMPDMAR),
-	mc_make_sid_override_cfg(BPMPDMAW),
-	mc_make_sid_override_cfg(AONR),
-	mc_make_sid_override_cfg(AONW),
-	mc_make_sid_override_cfg(AONDMAR),
-	mc_make_sid_override_cfg(AONDMAW),
-	mc_make_sid_override_cfg(SCER),
-	mc_make_sid_override_cfg(SCEW),
-	mc_make_sid_override_cfg(SCEDMAR),
-	mc_make_sid_override_cfg(SCEDMAW),
-	mc_make_sid_override_cfg(APEDMAR),
-	mc_make_sid_override_cfg(APEDMAW),
-	mc_make_sid_override_cfg(NVDISPLAYR1),
-	mc_make_sid_override_cfg(VICSRD1),
-	mc_make_sid_override_cfg(NVDECSRD1),
-	mc_make_sid_override_cfg(VIFALR),
-	mc_make_sid_override_cfg(VIFALW),
-	mc_make_sid_override_cfg(DLA0RDA),
-	mc_make_sid_override_cfg(DLA0FALRDB),
-	mc_make_sid_override_cfg(DLA0WRA),
-	mc_make_sid_override_cfg(DLA0FALWRB),
-	mc_make_sid_override_cfg(DLA1RDA),
-	mc_make_sid_override_cfg(DLA1FALRDB),
-	mc_make_sid_override_cfg(DLA1WRA),
-	mc_make_sid_override_cfg(DLA1FALWRB),
-	mc_make_sid_override_cfg(PVA0RDA),
-	mc_make_sid_override_cfg(PVA0RDB),
-	mc_make_sid_override_cfg(PVA0RDC),
-	mc_make_sid_override_cfg(PVA0WRA),
-	mc_make_sid_override_cfg(PVA0WRB),
-	mc_make_sid_override_cfg(PVA0WRC),
-	mc_make_sid_override_cfg(PVA1RDA),
-	mc_make_sid_override_cfg(PVA1RDB),
-	mc_make_sid_override_cfg(PVA1RDC),
-	mc_make_sid_override_cfg(PVA1WRA),
-	mc_make_sid_override_cfg(PVA1WRB),
-	mc_make_sid_override_cfg(PVA1WRC),
-	mc_make_sid_override_cfg(RCER),
-	mc_make_sid_override_cfg(RCEW),
-	mc_make_sid_override_cfg(RCEDMAR),
-	mc_make_sid_override_cfg(RCEDMAW),
-	mc_make_sid_override_cfg(NVENC1SRD),
-	mc_make_sid_override_cfg(NVENC1SWR),
-	mc_make_sid_override_cfg(PCIE0R),
-	mc_make_sid_override_cfg(PCIE0W),
-	mc_make_sid_override_cfg(PCIE1R),
-	mc_make_sid_override_cfg(PCIE1W),
-	mc_make_sid_override_cfg(PCIE2AR),
-	mc_make_sid_override_cfg(PCIE2AW),
-	mc_make_sid_override_cfg(PCIE3R),
-	mc_make_sid_override_cfg(PCIE3W),
-	mc_make_sid_override_cfg(PCIE4R),
-	mc_make_sid_override_cfg(PCIE4W),
-	mc_make_sid_override_cfg(PCIE5R),
-	mc_make_sid_override_cfg(PCIE5W),
-	mc_make_sid_override_cfg(ISPFALW),
-	mc_make_sid_override_cfg(DLA0RDA1),
-	mc_make_sid_override_cfg(DLA1RDA1),
-	mc_make_sid_override_cfg(PVA0RDA1),
-	mc_make_sid_override_cfg(PVA0RDB1),
-	mc_make_sid_override_cfg(PVA1RDA1),
-	mc_make_sid_override_cfg(PVA1RDB1),
-	mc_make_sid_override_cfg(PCIE5R1),
-	mc_make_sid_override_cfg(NVENCSRD1),
-	mc_make_sid_override_cfg(NVENC1SRD1),
-	mc_make_sid_override_cfg(ISPRA1),
-	mc_make_sid_override_cfg(PCIE0R1),
-	mc_make_sid_override_cfg(MIU0R),
-	mc_make_sid_override_cfg(MIU0W),
-	mc_make_sid_override_cfg(MIU1R),
-	mc_make_sid_override_cfg(MIU1W),
-	mc_make_sid_override_cfg(MIU2R),
-	mc_make_sid_override_cfg(MIU2W),
-	mc_make_sid_override_cfg(MIU3R),
-	mc_make_sid_override_cfg(MIU3W),
 	mc_smmu_bypass_cfg,	/* TBU settings */
 	_END_OF_TABLE_,
 };
@@ -415,7 +23,7 @@
 /*******************************************************************************
  * Handler to return the pointer to the MC's context struct
  ******************************************************************************/
-static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void)
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void)
 {
 	/* index of _END_OF_TABLE_ */
 	tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U;
@@ -424,20 +32,19 @@
 }
 
 /*******************************************************************************
- * Struct to hold the memory controller settings
+ * Handler to restore platform specific settings to the memory controller
  ******************************************************************************/
-static tegra_mc_settings_t tegra194_mc_settings = {
-	.streamid_security_cfg = tegra194_streamid_sec_cfgs,
-	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs),
-	.get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx
-};
+void plat_memctrl_restore(void)
+{
+	UNUSED_FUNC_NOP(); /* do nothing */
+}
 
 /*******************************************************************************
- * Handler to return the pointer to the memory controller's settings struct
+ * Handler to program platform specific settings to the memory controller
  ******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void)
+void plat_memctrl_setup(void)
 {
-	return &tegra194_mc_settings;
+	UNUSED_FUNC_NOP(); /* do nothing */
 }
 
 /*******************************************************************************
@@ -447,6 +54,8 @@
 void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
 {
 	uint32_t sec_reg_ctrl = tegra_mc_read_32(MC_SECURITY_CFG_REG_CTRL_0);
+	uint32_t phys_base_lo = (uint32_t)phys_base & 0xFFF00000;
+	uint32_t phys_base_hi = (uint32_t)(phys_base >> 32);
 
 	/*
 	 * Check TZDRAM carveout register access status. Setup TZDRAM fence
@@ -461,8 +70,8 @@
 		 */
 		INFO("Configuring TrustZone DRAM Memory Carveout\n");
 
-		tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
-		tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+		tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base_lo);
+		tegra_mc_write_32(MC_SECURITY_CFG3_0, phys_base_hi);
 		tegra_mc_write_32(MC_SECURITY_CFG1_0, (uint32_t)(size_in_bytes >> 20));
 
 		/*
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index e226372..41a85ee 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -418,16 +418,28 @@
 
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST);
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0);
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1);
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2);
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3);
 			mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 				XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+			assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+				XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV);
 		}
 	}
 
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index 54c2924..0c4c6fa 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -9,6 +9,7 @@
 
 #include <common/debug.h>
 #include <lib/bakery_lock.h>
+#include <lib/cassert.h>
 #include <lib/extensions/ras.h>
 #include <lib/utils_def.h>
 #include <services/sdei.h>
@@ -26,6 +27,17 @@
  */
 #define ERR_FR_EN_BITS_MASK	0xFFFFFFFF00000000ULL
 
+/*
+ * Number of RAS errors will be cleared per 'tegra194_ras_corrected_err_clear'
+ * function call.
+ */
+#define RAS_ERRORS_PER_CALL	8
+
+/*
+ * the max possible RAS node index value.
+ */
+#define RAS_NODE_INDEX_MAX	0x1FFFFFFFU
+
 /* bakery lock for platform RAS handler. */
 static DEFINE_BAKERY_LOCK(ras_handler_lock);
 #define ras_lock()		bakery_lock_get(&ras_handler_lock)
@@ -151,12 +163,41 @@
 
 /*
  * Function to clear RAS ERR<n>STATUS for corrected RAS error.
- * This function ignores any new RAS error signaled during clearing; it is not
- * multi-core safe(no ras_lock is taken to reduce overhead).
+ *
+ * This function clears number of 'RAS_ERRORS_PER_CALL' RAS errors at most.
+ * 'cookie' - in/out cookie parameter to specify/store last visited RAS
+ *            error record index. it is set to '0' to indicate no more RAS
+ *            error record to clear.
  */
-void tegra194_ras_corrected_err_clear(void)
+void tegra194_ras_corrected_err_clear(uint64_t *cookie)
 {
+	/*
+	 * 'last_node' and 'last_idx' represent last visited RAS node index from
+	 * previous function call. they are set to 0 when first smc call is made
+	 * or all RAS error are visited by followed multipile smc calls.
+	 */
+	union prev_record {
+		struct record {
+			uint32_t last_node;
+			uint32_t last_idx;
+		} rec;
+		uint64_t value;
+	} prev;
+
 	uint64_t clear_ce_status = 0ULL;
+	int32_t nerrs_per_call = RAS_ERRORS_PER_CALL;
+	uint32_t i;
+
+	if (cookie == NULL) {
+		return;
+	}
+
+	prev.value = *cookie;
+
+	if ((prev.rec.last_node >= RAS_NODE_INDEX_MAX) ||
+		(prev.rec.last_idx >= RAS_NODE_INDEX_MAX)) {
+		return;
+	}
 
 	ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL);
 	ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL);
@@ -164,25 +205,56 @@
 	ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL);
 	ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL);
 
-	for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) {
+
+	for (i = prev.rec.last_node; i < err_record_mappings.num_err_records; i++) {
 
 		const struct err_record_info *info = &err_record_mappings.err_records[i];
 		uint32_t idx_start = info->sysreg.idx_start;
 		uint32_t num_idx = info->sysreg.num_idx;
 
+		uint32_t j;
+
-		for (uint32_t j = 0U; j < num_idx; j++) {
+		j = (i == prev.rec.last_node && prev.value != 0UL) ?
+				(prev.rec.last_idx + 1U) : 0U;
+
+		for (; j < num_idx; j++) {
 
 			uint64_t status;
 			uint32_t err_idx = idx_start + j;
 
+			if (err_idx >= RAS_NODE_INDEX_MAX) {
+				return;
+			}
+
 			write_errselr_el1(err_idx);
 			status = read_erxstatus_el1();
 
 			if (ERR_STATUS_GET_FIELD(status, CE) != 0U) {
 				write_erxstatus_el1(clear_ce_status);
 			}
+
+			--nerrs_per_call;
+
+			/* only clear 'nerrs_per_call' errors each time. */
+			if (nerrs_per_call <= 0) {
+				prev.rec.last_idx = j;
+				prev.rec.last_node = i;
+				/* save last visited error record index
+				 * into cookie.
+				 */
+				*cookie = prev.value;
+
+				return;
+			}
 		}
 	}
+
+	/*
+	 * finish if all ras error records are checked or provided index is out
+	 * of range.
+	 */
+	*cookie = 0ULL;
+	return;
 }
 
 /* Function to probe an error from error record group. */
@@ -330,18 +402,26 @@
 static struct ras_aux_data per_core_ras_group[] = {
 	PER_CORE_RAS_GROUP_NODES
 };
+CASSERT(ARRAY_SIZE(per_core_ras_group) < RAS_NODE_INDEX_MAX,
+	assert_max_per_core_ras_group_size);
 
 static struct ras_aux_data per_cluster_ras_group[] = {
 	PER_CLUSTER_RAS_GROUP_NODES
 };
+CASSERT(ARRAY_SIZE(per_cluster_ras_group) < RAS_NODE_INDEX_MAX,
+	assert_max_per_cluster_ras_group_size);
 
 static struct ras_aux_data scf_l3_ras_group[] = {
 	SCF_L3_BANK_RAS_GROUP_NODES
 };
+CASSERT(ARRAY_SIZE(scf_l3_ras_group) < RAS_NODE_INDEX_MAX,
+	assert_max_scf_l3_ras_group_size);
 
 static struct ras_aux_data ccplex_ras_group[] = {
     CCPLEX_RAS_GROUP_NODES
 };
+CASSERT(ARRAY_SIZE(ccplex_ras_group) < RAS_NODE_INDEX_MAX,
+	assert_max_ccplex_ras_group_size);
 
 /*
  * We have same probe and handler for each error record group, use a macro to
@@ -395,6 +475,9 @@
 	ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group),
 };
 
+CASSERT(ARRAY_SIZE(carmel_ras_records) < RAS_NODE_INDEX_MAX,
+	assert_max_carmel_ras_records_size);
+
 REGISTER_ERR_RECORD_INFO(carmel_ras_records);
 
 /* dummy RAS interrupt */
diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c
index 0882142..1cb14ad 100644
--- a/plat/nvidia/tegra/soc/t194/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c
@@ -4,11 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+#include <string.h>
+
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
+
 #include <mce.h>
-#include <string.h>
 #include <tegra194_private.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
@@ -52,15 +55,21 @@
 
 	/* write lower 32 bits first, then the upper 11 bits */
 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
+	assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW) == addr_low);
 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
+	assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH) == addr_high);
 
 	/* save reset vector to be used during SYSTEM_SUSPEND exit */
 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
 			addr_low);
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO) == addr_low);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
 			addr_high);
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI) == addr_high);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO,
 						(uint32_t)tzdram_addr);
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO) == (uint32_t)tzdram_addr);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI,
 						(uint32_t)src_len_bytes);
+	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI) == (uint32_t)src_len_bytes);
 }
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 399aebb..8f7d1e9 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -20,10 +20,11 @@
 #include <bl31/interrupt_mgmt.h>
 #include <mce.h>
 #include <mce_private.h>
+#include <memctrl.h>
 #include <plat/common/platform.h>
+#include <smmu.h>
 #include <spe.h>
 #include <tegra_def.h>
-#include <tegra_mc_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
@@ -32,6 +33,27 @@
 #define TEGRA_CONSOLE_SPE_ID		0xFE
 
 /*******************************************************************************
+ * Structure to store the SCR addresses and its expected settings.
+ *******************************************************************************
+ */
+typedef struct {
+	uint32_t scr_addr;
+	uint32_t scr_val;
+} scr_settings_t;
+
+static const scr_settings_t t194_scr_settings[] = {
+	{ SCRATCH_RSV68_SCR, SCRATCH_RSV68_SCR_VAL },
+	{ SCRATCH_RSV71_SCR, SCRATCH_RSV71_SCR_VAL },
+	{ SCRATCH_RSV72_SCR, SCRATCH_RSV72_SCR_VAL },
+	{ SCRATCH_RSV75_SCR, SCRATCH_RSV75_SCR_VAL },
+	{ SCRATCH_RSV81_SCR, SCRATCH_RSV81_SCR_VAL },
+	{ SCRATCH_RSV97_SCR, SCRATCH_RSV97_SCR_VAL },
+	{ SCRATCH_RSV99_SCR, SCRATCH_RSV99_SCR_VAL },
+	{ SCRATCH_RSV109_SCR, SCRATCH_RSV109_SCR_VAL },
+	{ MISCREG_SCR_SCRTZWELCK, MISCREG_SCR_SCRTZWELCK_VAL }
+};
+
+/*******************************************************************************
  * The Tegra power domain tree has a single system level power domain i.e. a
  * single root node. The first entry in the power domain descriptor specifies
  * the number of power domains at the highest power level.
@@ -66,8 +88,6 @@
 static const mmap_region_t tegra_mmap[] = {
 	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x4000U, /* 16KB */
 			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
-			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
 	MAP_REGION_FLAT(TEGRA_GPCDMA_BASE, 0x10000U, /* 64KB */
 			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
 	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x8000U, /* 32KB */
@@ -197,6 +217,24 @@
 }
 
 /*******************************************************************************
+ * Verify SCR settings
+ ******************************************************************************/
+static inline bool tegra194_is_scr_valid(void)
+{
+	uint32_t scr_val;
+	bool ret = true;
+
+	for (uint8_t i = 0U; i < ARRAY_SIZE(t194_scr_settings); i++) {
+		scr_val = mmio_read_32((uintptr_t)t194_scr_settings[i].scr_addr);
+		if (scr_val != t194_scr_settings[i].scr_val) {
+			ERROR("Mismatch at SCR addr = 0x%x\n", t194_scr_settings[i].scr_addr);
+			ret = false;
+		}
+	}
+	return ret;
+}
+
+/*******************************************************************************
  * Handler for early platform setup
  ******************************************************************************/
 void plat_early_platform_setup(void)
@@ -205,6 +243,14 @@
 	uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
 	uint64_t actlr_elx;
 
+	/* Verify chip id is t194 */
+	assert(tegra_chipid_is_t194());
+
+	/* Verify SCR settings */
+	if (tegra_platform_is_silicon()) {
+		assert(tegra194_is_scr_valid());
+	}
+
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
@@ -248,16 +294,28 @@
 
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST);
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0);
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1);
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2);
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3);
 		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
 			XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+		assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV);
 	}
 
 	/*
@@ -267,14 +325,20 @@
 		actlr_elx = read_actlr_el3();
 		actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3;
 		write_actlr_el3(actlr_elx);
+		/* check if the bit is actually set */
+		assert((read_actlr_el3() & DENVER_CPU_ENABLE_DUAL_EXEC_EL3) != 0ULL);
 
 		actlr_elx = read_actlr_el2();
 		actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2;
 		write_actlr_el2(actlr_elx);
+		/* check if the bit is actually set */
+		assert((read_actlr_el2() & DENVER_CPU_ENABLE_DUAL_EXEC_EL2) != 0ULL);
 
 		actlr_elx = read_actlr_el1();
 		actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1;
 		write_actlr_el1(actlr_elx);
+		/* check if the bit is actually set */
+		assert((read_actlr_el1() & DENVER_CPU_ENABLE_DUAL_EXEC_EL1) != 0ULL);
 	}
 }
 
@@ -283,8 +347,6 @@
 	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,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
 };
 
@@ -343,6 +405,7 @@
 	 * enabling TZSRAM and TZDRAM
 	 */
 	mce_enable_strict_checking();
+	mce_verify_strict_checking();
 #endif
 }
 
@@ -353,3 +416,34 @@
 {
 	return true;
 }
+
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+	/*
+	 * During cold boot, it is observed that the arbitration
+	 * bit is set in the Memory controller leading to false
+	 * error interrupts in the non-secure world. To avoid
+	 * this, clean the interrupt status register before
+	 * booting into the non-secure world
+	 */
+	tegra_memctrl_clear_pending_interrupts();
+
+	/*
+	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
+	 * access to IRAM. Because these clients connect to the MC and
+	 * do not have a direct path to the IRAM, the MC implements AHB
+	 * redirection during boot to allow path to IRAM. In this mode
+	 * accesses to a programmed memory address aperture are directed
+	 * to the AHB bus, allowing access to the IRAM. This mode must be
+	 * disabled before we jump to the non-secure world.
+	 */
+	tegra_memctrl_disable_ahb_redirection();
+
+	/*
+	 * Verify the integrity of the previously configured SMMU(s) settings
+	 */
+	tegra_smmu_verify();
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index a3f996d..1eef559 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -73,11 +73,25 @@
 
 #if RAS_EXTENSION
 	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
-		/* clear all RAS error records for corrected errors at first. */
-		tegra194_ras_corrected_err_clear();
-		/* clear HSM corrected error status. */
-		mce_clear_hsm_corr_status();
+	{
+		/*
+		 * clear all RAS error records for corrected errors at first.
+		 * x1 shall be 0 for first SMC call after FHI is asserted.
+		 * */
+		uint64_t local_x1 = x1;
+
+		tegra194_ras_corrected_err_clear(&local_x1);
+		if (local_x1 == 0ULL) {
+			/* clear HSM corrected error status after all corrected
+			 * RAS errors are cleared.
+			 */
+			mce_clear_hsm_corr_status();
+		}
+
+		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1);
+
 		break;
+	}
 #endif
 
 	default:
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
index 819920f..0ff5407 100644
--- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -58,6 +58,13 @@
 	subs	x2, x2, #1
 	b.ne	m_loop1
 
+	/*
+	 * Synchronization barriers to make sure that memory is flushed out
+	 * before we start execution in SysRAM.
+	 */
+	dsb	sy
+	isb
+
 boot_cpu:
 	adr	x0, __tegra194_cpu_reset_handler_data
 	ldr	x0, [x0]
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index d7d15f5..339375f 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -38,13 +38,13 @@
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t194 \
 				-I${SOC_DIR}/drivers/include
 
-BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S \
+BL31_SOURCES		+=	${TEGRA_GICv2_SOURCES}			\
+				drivers/ti/uart/aarch64/16550_console.S \
 				lib/cpus/aarch64/denver.S		\
-				${COMMON_DIR}/drivers/bpmp_ipc/intf.c	\
-				${COMMON_DIR}/drivers/bpmp_ipc/ivc.c	\
-				${COMMON_DIR}/drivers/gpcdma/gpcdma.c	\
-				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c	\
-				${COMMON_DIR}/drivers/smmu/smmu.c	\
+				${TEGRA_DRIVERS}/bpmp_ipc/intf.c	\
+				${TEGRA_DRIVERS}/bpmp_ipc/ivc.c		\
+				${TEGRA_DRIVERS}/memctrl/memctrl_v2.c	\
+				${TEGRA_DRIVERS}/smmu/smmu.c		\
 				${SOC_DIR}/drivers/mce/mce.c		\
 				${SOC_DIR}/drivers/mce/nvg.c		\
 				${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
@@ -57,8 +57,12 @@
 				${SOC_DIR}/plat_smmu.c			\
 				${SOC_DIR}/plat_trampoline.S
 
+ifeq (${USE_GPC_DMA}, 1)
+BL31_SOURCES		+=	${TEGRA_DRIVERS}/gpcdma/gpcdma.c
+endif
+
 ifeq (${ENABLE_CONSOLE_SPE},1)
-BL31_SOURCES		+=	${COMMON_DIR}/drivers/spe/shared_console.S
+BL31_SOURCES		+=	${TEGRA_DRIVERS}/spe/shared_console.S
 endif
 
 # RAS sources
@@ -67,3 +71,13 @@
 				lib/extensions/ras/ras_common.c			\
 				${SOC_DIR}/plat_ras.c
 endif
+
+# SPM dispatcher
+ifeq (${SPD},spmd)
+# include device tree helper library
+include lib/libfdt/libfdt.mk
+# sources to support spmd
+BL31_SOURCES		+=	plat/common/plat_spmd_manifest.c	\
+				common/fdt_wrappers.c			\
+				${LIBFDT_SRCS}
+endif
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index f2b267b..68cd38e 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -165,6 +165,15 @@
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 	uint64_t val;
 
+	/* Verify chip id is t210 */
+	assert(tegra_chipid_is_t210());
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
+
 	/* platform parameter passed by the previous bootloader */
 	if (plat_params->l2_ecc_parity_prot_dis != 1) {
 		/* Enable ECC Parity Protection for Cortex-A57 CPUs */
@@ -282,3 +291,28 @@
 		return false;
 	}
 }
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+	/*
+	 * During cold boot, it is observed that the arbitration
+	 * bit is set in the Memory controller leading to false
+	 * error interrupts in the non-secure world. To avoid
+	 * this, clean the interrupt status register before
+	 * booting into the non-secure world
+	 */
+	tegra_memctrl_clear_pending_interrupts();
+
+	/*
+	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
+	 * access to IRAM. Because these clients connect to the MC and
+	 * do not have a direct path to the IRAM, the MC implements AHB
+	 * redirection during boot to allow path to IRAM. In this mode
+	 * accesses to a programmed memory address aperture are directed
+	 * to the AHB bus, allowing access to the IRAM. This mode must be
+	 * disabled before we jump to the non-secure world.
+	 */
+	tegra_memctrl_disable_ahb_redirection();
+}
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index 14e3324..724cfc3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -25,20 +25,21 @@
 
 ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING	:= 1
 
-PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t210 \
+PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t210		\
 				-I${SOC_DIR}/drivers/se
 
-BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S		\
+BL31_SOURCES		+=	${TEGRA_GICv2_SOURCES}				\
+				drivers/ti/uart/aarch64/16550_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				lib/cpus/aarch64/cortex_a57.S			\
-				${COMMON_DIR}/drivers/bpmp/bpmp.c		\
-				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
-				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
-				${COMMON_DIR}/drivers/pmc/pmc.c			\
+				${TEGRA_DRIVERS}/bpmp/bpmp.c			\
+				${TEGRA_DRIVERS}/flowctrl/flowctrl.c		\
+				${TEGRA_DRIVERS}/memctrl/memctrl_v1.c		\
+				${TEGRA_DRIVERS}/pmc/pmc.c			\
 				${SOC_DIR}/plat_psci_handlers.c			\
 				${SOC_DIR}/plat_setup.c				\
 				${SOC_DIR}/drivers/se/security_engine.c		\
-				${SOC_DIR}/plat_secondary.c		\
+				${SOC_DIR}/plat_secondary.c			\
 				${SOC_DIR}/plat_sip_calls.c
 
 # Enable workarounds for selected Cortex-A57 erratas.
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 365cfb7..7f8e4c4 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,5 +1,6 @@
+
 /*
- * 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
  */
@@ -77,7 +78,11 @@
 	MAP_DEVICE2,
 #endif
 	MAP_NS_DRAM0,
+#if SPM_MM
+	QEMU_SP_IMAGE_MMAP,
+#else
 	MAP_BL32_MEM,
+#endif
 	{0}
 };
 #endif
@@ -88,7 +93,11 @@
 #ifdef MAP_DEVICE1
 	MAP_DEVICE1,
 #endif
+#if SPM_MM
+	QEMU_SPM_BUF_EL3_MMAP,
+#else
 	MAP_BL32_MEM,
+#endif
 	{0}
 };
 #endif
diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c
new file mode 100644
index 0000000..e9ab1a5
--- /dev/null
+++ b/plat/qemu/common/qemu_spm.c
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved.
+ */
+
+#include <bl31/ehf.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <services/spm_mm_partition.h>
+
+#include <platform_def.h>
+
+/* Region equivalent to MAP_DEVICE1 suitable for mapping at EL0 */
+#define MAP_DEVICE1_EL0	MAP_REGION_FLAT(DEVICE1_BASE,			\
+					DEVICE1_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+const mmap_region_t plat_qemu_secure_partition_mmap[] = {
+	MAP_DEVICE1_EL0, /* for the UART */
+	QEMU_SP_IMAGE_MMAP,
+	QEMU_SPM_BUF_EL0_MMAP,
+	QEMU_SP_IMAGE_NS_BUF_MMAP,
+	QEMU_SP_IMAGE_RW_MMAP,
+	{0}
+};
+
+/*
+ * 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] = {0x80000000, 0},
+	[1] = {0x80000001, 0},
+	[2] = {0x80000002, 0},
+	[3] = {0x80000003, 0},
+	[4] = {0x80000004, 0},
+	[5] = {0x80000005, 0},
+	[6] = {0x80000006, 0},
+	[7] = {0x80000007, 0}
+};
+
+const spm_mm_boot_info_t plat_qemu_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         = PLAT_QEMU_SP_IMAGE_BASE,
+	.sp_mem_limit        = BL32_LIMIT,
+	.sp_image_base       = PLAT_QEMU_SP_IMAGE_BASE,
+	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
+	.sp_heap_base        = PLAT_QEMU_SP_IMAGE_HEAP_BASE,
+	.sp_ns_comm_buf_base = PLAT_QEMU_SP_IMAGE_NS_BUF_BASE,
+	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
+	.sp_image_size       = PLAT_QEMU_SP_IMAGE_SIZE,
+	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+	.sp_heap_size        = PLAT_QEMU_SP_IMAGE_HEAP_SIZE,
+	.sp_ns_comm_buf_size = PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE,
+	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
+	.num_sp_mem_regions  = PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS,
+	.num_cpus            = PLATFORM_CORE_COUNT,
+	.mp_info             = sp_mp_info
+};
+
+/* Enumeration of priority levels on QEMU platforms. */
+ehf_pri_desc_t qemu_exceptions[] = {
+	EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI)
+};
+
+/* Plug in QEMU exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions),
+			QEMU_PRI_BITS);
+
+const mmap_region_t *plat_get_secure_partition_mmap(void *cookie)
+{
+	return plat_qemu_secure_partition_mmap;
+}
+
+const spm_mm_boot_info_t *
+plat_get_secure_partition_boot_info(void *cookie)
+{
+	return &plat_qemu_secure_partition_boot_info;
+}
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 9441437..14bf049 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -84,7 +84,7 @@
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY):
+    $(ROT_KEY): | $(BUILD_PLAT)
 	@echo "  OPENSSL $@"
 	$(Q)openssl genrsa 2048 > $@ 2>/dev/null
 
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index d0a56cf..7634005 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -1,10 +1,11 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Linaro Limited and Contributors.
+ * All rights reserved.
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <plat/common/common_def.h>
@@ -107,9 +108,10 @@
  * Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using
  * the current BL1 RW debug size plus a little space for growth.
  */
+#define BL1_SIZE			0x12000
 #define BL1_RO_BASE			SEC_ROM_BASE
 #define BL1_RO_LIMIT			(SEC_ROM_BASE + SEC_ROM_SIZE)
-#define BL1_RW_BASE			(BL1_RW_LIMIT - 0x12000)
+#define BL1_RW_BASE			(BL1_RW_LIMIT - BL1_SIZE)
 #define BL1_RW_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
 
 /*
@@ -118,7 +120,8 @@
  * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
  * size plus a little space for growth.
  */
-#define BL2_BASE			(BL31_BASE - 0x1D000)
+#define BL2_SIZE			0x1D000
+#define BL2_BASE			(BL31_BASE - BL2_SIZE)
 #define BL2_LIMIT			BL31_BASE
 
 /*
@@ -127,8 +130,9 @@
  * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
  * current BL3-1 debug size plus a little space for growth.
  */
-#define BL31_BASE			(BL31_LIMIT - 0x20000)
-#define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
+#define BL31_SIZE			0x50000
+#define BL31_BASE			(BL31_LIMIT - BL31_SIZE)
+#define BL31_LIMIT			(BL1_RW_BASE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
 
 
@@ -138,12 +142,11 @@
  * BL3-2 can execute from Secure SRAM, or Secure DRAM.
  */
 #define BL32_SRAM_BASE			BL_RAM_BASE
-#define BL32_SRAM_LIMIT			BL31_BASE
-#define BL32_DRAM_BASE			SEC_DRAM_BASE
-#define BL32_DRAM_LIMIT			(SEC_DRAM_BASE + SEC_DRAM_SIZE)
+#define BL32_SRAM_LIMIT			BL2_BASE
 
 #define BL32_MEM_BASE			BL_RAM_BASE
-#define BL32_MEM_SIZE			BL_RAM_SIZE
+#define BL32_MEM_SIZE			(BL_RAM_SIZE - BL1_SIZE - \
+					BL2_SIZE - BL31_SIZE)
 #define BL32_BASE			BL32_SRAM_BASE
 #define BL32_LIMIT			BL32_SRAM_LIMIT
 
@@ -152,11 +155,21 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 42)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 42)
+#if SPM_MM
+#define MAX_MMAP_REGIONS		12
+#define MAX_XLAT_TABLES			11
+#else
 #define MAX_MMAP_REGIONS		11
 #define MAX_XLAT_TABLES			10
+#endif
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
 
+#if SPM_MM && defined(IMAGE_BL31)
+# define PLAT_SP_IMAGE_MMAP_REGIONS	30
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES	20
+#endif
+
 /*
  * PL011 related constants
  */
@@ -165,6 +178,10 @@
 #define UART0_CLK_IN_HZ			1
 #define UART1_CLK_IN_HZ			1
 
+/* Secure UART */
+#define UART2_BASE			0x60040000
+#define UART2_CLK_IN_HZ			1
+
 #define PLAT_QEMU_BOOT_UART_BASE	UART0_BASE
 #define PLAT_QEMU_BOOT_UART_CLK_IN_HZ	UART0_CLK_IN_HZ
 
@@ -179,7 +196,7 @@
 #define QEMU_FLASH1_SIZE		0x10000000
 
 #define PLAT_QEMU_FIP_BASE		0x00008000
-#define PLAT_QEMU_FIP_MAX_SIZE		0x00020000
+#define PLAT_QEMU_FIP_MAX_SIZE		0x00400000
 
 /* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */
 #define DEVICE0_BASE			0x40000000
@@ -240,4 +257,99 @@
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
 
+#if SPM_MM
+#define PLAT_QEMU_SP_IMAGE_BASE		BL_RAM_BASE
+#define PLAT_QEMU_SP_IMAGE_SIZE		ULL(0x300000)
+
+#ifdef IMAGE_BL2
+/* In BL2 all memory allocated to the SPM Payload image is marked as RW. */
+# define QEMU_SP_IMAGE_MMAP		MAP_REGION_FLAT( \
+						PLAT_QEMU_SP_IMAGE_BASE, \
+						PLAT_QEMU_SP_IMAGE_SIZE, \
+						MT_MEMORY | MT_RW | \
+						MT_SECURE)
+#elif IMAGE_BL31
+/* All SPM Payload memory is marked as code in S-EL0 */
+# define QEMU_SP_IMAGE_MMAP		MAP_REGION2(PLAT_QEMU_SP_IMAGE_BASE, \
+						PLAT_QEMU_SP_IMAGE_BASE, \
+						PLAT_QEMU_SP_IMAGE_SIZE, \
+						MT_CODE | MT_SECURE | \
+						MT_USER,		\
+						PAGE_SIZE)
+#endif
+
+/*
+ * EL3 -> S-EL0 secure shared memory
+ */
+#define PLAT_SPM_BUF_PCPU_SIZE		ULL(0x10000)
+#define PLAT_SPM_BUF_SIZE		(PLATFORM_CORE_COUNT * \
+					PLAT_SPM_BUF_PCPU_SIZE)
+#define PLAT_SPM_BUF_BASE		(BL32_LIMIT - PLAT_SPM_BUF_SIZE)
+
+#define QEMU_SPM_BUF_EL3_MMAP		MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, \
+						PLAT_SPM_BUF_SIZE, \
+						MT_RW_DATA | MT_SECURE)
+
+#define QEMU_SPM_BUF_EL0_MMAP		MAP_REGION2(PLAT_SPM_BUF_BASE,	\
+						PLAT_SPM_BUF_BASE,	\
+						PLAT_SPM_BUF_SIZE,	\
+						MT_RO_DATA | MT_SECURE | \
+						MT_USER,		\
+						PAGE_SIZE)
+
+/*
+ * Shared memory between Normal world and S-EL0 for
+ * passing data during service requests. It will be marked as RW and NS.
+ */
+#define PLAT_QEMU_SP_IMAGE_NS_BUF_BASE	(PLAT_QEMU_DT_BASE +		\
+						PLAT_QEMU_DT_MAX_SIZE)
+#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE	ULL(0x10000)
+#define QEMU_SP_IMAGE_NS_BUF_MMAP	MAP_REGION2( \
+					PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \
+					PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \
+					PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, \
+					MT_RW_DATA | MT_NS | \
+					MT_USER, \
+					PAGE_SIZE)
+
+#define PLAT_SP_IMAGE_NS_BUF_BASE	PLAT_QEMU_SP_IMAGE_NS_BUF_BASE
+#define PLAT_SP_IMAGE_NS_BUF_SIZE	PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE
+
+#define PLAT_QEMU_SP_IMAGE_HEAP_BASE	(PLAT_QEMU_SP_IMAGE_BASE + \
+					PLAT_QEMU_SP_IMAGE_SIZE)
+#define PLAT_QEMU_SP_IMAGE_HEAP_SIZE	ULL(0x800000)
+
+#define PLAT_SP_IMAGE_STACK_BASE	(PLAT_QEMU_SP_IMAGE_HEAP_BASE + \
+						PLAT_QEMU_SP_IMAGE_HEAP_SIZE)
+#define PLAT_SP_IMAGE_STACK_PCPU_SIZE	ULL(0x10000)
+#define QEMU_SP_IMAGE_STACK_TOTAL_SIZE	(PLATFORM_CORE_COUNT * \
+						PLAT_SP_IMAGE_STACK_PCPU_SIZE)
+
+#define QEMU_SP_IMAGE_RW_MMAP		MAP_REGION2( \
+					PLAT_QEMU_SP_IMAGE_HEAP_BASE, \
+					PLAT_QEMU_SP_IMAGE_HEAP_BASE, \
+					(QEMU_SP_IMAGE_STACK_TOTAL_SIZE + \
+					PLAT_QEMU_SP_IMAGE_HEAP_SIZE), \
+					MT_RW_DATA | MT_SECURE | \
+					MT_USER, \
+					PAGE_SIZE)
+
+/* Total number of memory regions with distinct properties */
+#define PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS	6
+
+/*
+ * Name of the section to put the translation tables used by the S-EL1/S-EL0
+ * context of a Secure Partition.
+ */
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME		"qemu_sp_xlat_table"
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	"qemu_sp_xlat_table"
+
+/* Cookies passed to the Secure Partition at boot. Not used by QEMU platforms.*/
+#define PLAT_SPM_COOKIE_0		ULL(0)
+#define PLAT_SPM_COOKIE_1		ULL(0)
+#endif
+
+#define QEMU_PRI_BITS		2
+#define PLAT_SP_PRI		0x20
+
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 09856d6..3aa7cbe 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Linaro Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,6 +8,12 @@
 
 include lib/libfdt/libfdt.mk
 
+ifeq (${SPM_MM},1)
+NEED_BL32		:=	yes
+EL3_EXCEPTION_HANDLING	:=	1
+GICV2_G0_FOR_EL3	:=	1
+endif
+
 # Enable new version of image loading on QEMU platforms
 LOAD_IMAGE_V2		:=	1
 
@@ -80,6 +86,9 @@
 				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c	\
 				${QEMU_GIC_SOURCES}
+ifeq (${SPM_MM},1)
+	BL31_SOURCES		+=	${PLAT_QEMU_COMMON_PATH}/qemu_spm.c
+endif
 
 SEPARATE_CODE_AND_RODATA	:= 1
 ENABLE_STACK_PROTECTOR		:= 0
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
index 0e867be..4d9d320 100644
--- a/plat/qti/common/inc/qti_plat.h
+++ b/plat/qti/common/inc/qti_plat.h
@@ -50,4 +50,7 @@
 
 void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
 
+void qti_pmic_prepare_reset(void);
+void qti_pmic_prepare_shutdown(void);
+
 #endif /* QTI_PLAT_H */
diff --git a/plat/qti/common/inc/qti_rng.h b/plat/qti/common/inc/qti_rng.h
new file mode 100644
index 0000000..62c31f3
--- /dev/null
+++ b/plat/qti/common/inc/qti_rng.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_RNG_H
+#define QTI_RNG_H
+
+#include <stdint.h>
+
+int qti_rng_get_data(uint8_t *out, uint32_t out_len);
+
+#endif /* QTI_RNG_H */
diff --git a/plat/qti/common/inc/spmi_arb.h b/plat/qti/common/inc/spmi_arb.h
new file mode 100644
index 0000000..362f740
--- /dev/null
+++ b/plat/qti/common/inc/spmi_arb.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMI_ARB_H
+#define SPMI_ARB_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * WARNING: This driver does not arbitrate access with the kernel. These APIs
+ * must only be called when the kernel is known to be quiesced (such as before
+ * boot or while the system is shutting down).
+ ******************************************************************************/
+
+/* 32-bit addresses combine (U)SID, PID and register address. */
+
+int spmi_arb_read8(uint32_t addr);
+int spmi_arb_write8(uint32_t addr, uint8_t data);
+
+#endif /* SPMI_ARB_H */
diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c
new file mode 100644
index 0000000..b189a8b
--- /dev/null
+++ b/plat/qti/common/src/pm8998.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+
+#include <qti_plat.h>
+#include <spmi_arb.h>
+
+/*
+ * This driver implements PON support for PM8998-compatible PMICs. This can
+ * include other part numbers like PM6150.
+ */
+
+#define PON_PS_HOLD_RESET_CTL		0x85a
+#define RESET_TYPE_WARM_RESET		1
+#define RESET_TYPE_SHUTDOWN		4
+
+#define PON_PS_HOLD_RESET_CTL2		0x85b
+#define S2_RESET_EN			BIT(7)
+
+static void configure_ps_hold(uint32_t reset_type)
+{
+	/* QTI recommends disabling reset for 10 cycles before reconfiguring. */
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
+	mdelay(1);
+
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
+	mdelay(1);
+}
+
+void qti_pmic_prepare_reset(void)
+{
+	configure_ps_hold(RESET_TYPE_WARM_RESET);
+}
+
+void qti_pmic_prepare_shutdown(void)
+{
+	configure_ps_hold(RESET_TYPE_SHUTDOWN);
+}
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 4a5877c..5f1b7aa 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -9,6 +9,8 @@
 #include <arch_helpers.h>
 #include <bl31/bl31.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
 #include <lib/psci/psci.h>
 
 #include <platform.h>
@@ -204,14 +206,25 @@
 	/* We should never reach here */
 }
 
+static __dead2 void assert_ps_hold(void)
+{
+	mmio_write_32(QTI_PS_HOLD_REG, 0);
+	mdelay(1000);
+
+	/* Should be dead before reaching this. */
+	panic();
+}
+
 __dead2 void qti_system_off(void)
 {
-	qtiseclib_psci_system_off();
+	qti_pmic_prepare_shutdown();
+	assert_ps_hold();
 }
 
 __dead2 void qti_system_reset(void)
 {
-	qtiseclib_psci_system_reset();
+	qti_pmic_prepare_reset();
+	assert_ps_hold();
 }
 
 void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/qti/common/src/qti_rng.c b/plat/qti/common/src/qti_rng.c
new file mode 100644
index 0000000..f63f3b8
--- /dev/null
+++ b/plat/qti/common/src/qti_rng.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+
+#include <lib/mmio.h>
+
+#include <qti_rng.h>
+#include <qti_rng_io.h>
+
+int qti_rng_get_data(uint8_t *out, uint32_t out_len)
+{
+	uint32_t tmp_rndm = 0;
+	uint32_t bytes_left = out_len;
+	int i = 0;
+
+	if (NULL == out || 0 == out_len) {
+		return -1;
+	}
+
+	/*
+	 * RNG HW initialized at previous boot image.
+	 * RNG clocks are expected to be ON.
+	 */
+
+	do {
+		/* There is no data to read */
+		if ((mmio_read_32(SEC_PRNG_STATUS) &
+		     SEC_PRNG_STATUS_DATA_AVAIL_BMSK) == 0) {
+			continue;
+		}
+
+		while ((tmp_rndm = mmio_read_32(SEC_PRNG_DATA_OUT)) == 0) {
+			;
+		}
+
+		for (i = 0; i < 4; i++) {
+			*out = (uint8_t) (tmp_rndm >> (8 * i));
+
+			out++;
+			bytes_left--;
+
+			if (bytes_left == 0) {
+				break;
+			}
+		}
+
+	} while (bytes_left != 0);
+
+	return 0;
+}
diff --git a/plat/qti/common/src/qti_stack_protector.c b/plat/qti/common/src/qti_stack_protector.c
index b2dbfb0..572830f 100644
--- a/plat/qti/common/src/qti_stack_protector.c
+++ b/plat/qti/common/src/qti_stack_protector.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,16 +9,18 @@
 
 #include <platform.h>
 #include <platform_def.h>
+#include <qti_rng.h>
 #include <qtiseclib_interface.h>
 
 u_register_t plat_get_stack_protector_canary(void)
 {
 	u_register_t random = 0x0;
 
-	/* get random data , the below API doesn't return random = 0 in success
-	 * case */
-	qtiseclib_prng_get_data((uint8_t *) &random, sizeof(random));
-	assert(0x0 != random);
+	/*
+	 * get random data , the below API doesn't return random = 0 on success
+	 */
+	qti_rng_get_data((uint8_t *) &random, sizeof(random));
+	assert(random != 0x0);
 
 	return random;
 }
diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c
new file mode 100644
index 0000000..16e85a6
--- /dev/null
+++ b/plat/qti/common/src/spmi_arb.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <spmi_arb.h>
+
+#define REG_APID_MAP(apid)	(0x0C440900U + 4U * i)
+#define NUM_APID		0x80
+
+#define PPID_MASK		(0xfffU << 8)
+
+#define REG_ARB_CMD(apid)	(0x0C600000U + 0x10000U * apid)
+/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */
+#define OPC_EXT_WRITEL		0
+#define OPC_EXT_READL		1
+
+#define REG_ARB_STATUS(apid)	(0x0C600008U + 0x10000U * apid)
+#define ARB_STATUS_DONE		BIT(0)
+#define ARB_STATUS_FAILURE	BIT(1)
+#define ARB_STATUS_DENIED	BIT(2)
+#define ARB_STATUS_DROPPED	BIT(3)
+
+/* Fake status to report driver errors. */
+#define ARB_FAKE_STATUS_TIMEOUT	BIT(8)
+
+#define REG_ARB_RDATA0(apid)	(0x0C600018U + 0x10000U * apid)
+#define REG_ARB_WDATA0(apid)	(0x0C600010U + 0x10000U * apid)
+
+static int addr_to_apid(uint32_t addr)
+{
+	unsigned int i;
+
+	for (i = 0U; i < NUM_APID; i++) {
+		uint32_t reg = mmio_read_32(REG_APID_MAP(i));
+		if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+static int wait_for_done(uint16_t apid)
+{
+	unsigned int timeout = 100;
+
+	while (timeout-- != 0U) {
+		uint32_t status = mmio_read_32(REG_ARB_STATUS(apid));
+		if ((status & ARB_STATUS_DONE) != 0U) {
+			if ((status & ARB_STATUS_FAILURE) != 0U ||
+			    (status & ARB_STATUS_DENIED) != 0U ||
+			    (status & ARB_STATUS_DROPPED) != 0U) {
+				return status & 0xff;
+			}
+			return 0;
+		}
+		mdelay(1);
+	}
+	ERROR("SPMI_ARB timeout!\n");
+	return ARB_FAKE_STATUS_TIMEOUT;
+}
+
+static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr,
+			uint8_t bytes)
+{
+	mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 |
+					 (addr & 0xff) << 4 | (bytes - 1));
+}
+
+int spmi_arb_read8(uint32_t addr)
+{
+	int apid = addr_to_apid(addr);
+
+	if (apid < 0) {
+		return apid;
+	}
+
+	arb_command(apid, OPC_EXT_READL, addr, 1);
+
+	int ret = wait_for_done(apid);
+	if (ret != 0) {
+		ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
+		return ret;
+	}
+
+	return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff;
+}
+
+int spmi_arb_write8(uint32_t addr, uint8_t data)
+{
+	int apid = addr_to_apid(addr);
+
+	if (apid < 0) {
+		return apid;
+	}
+
+	mmio_write_32(REG_ARB_WDATA0(apid), data);
+	arb_command(apid, OPC_EXT_WRITEL, addr, 1);
+
+	int ret = wait_for_done(apid);
+	if (ret != 0) {
+		ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n",
+		      addr, data, ret);
+	}
+
+	return ret;
+}
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
index 9c4a724..2252557 100644
--- a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
+++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
@@ -16,6 +16,9 @@
 
 /* Standard Library API's */
 void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len);
+int qtiseclib_cb_strcmp(const char *s1, const char *s2);
+void *qtiseclib_cb_memset(void *s, int c, size_t n);
+void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n);
 
 #define QTISECLIB_CB_ERROR(...)		qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__)
 #define QTISECLIB_CB_NOTICE(...)	qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__)
@@ -41,6 +44,8 @@
 
 void qtiseclib_cb_udelay(uint32_t usec);
 
+int qtiseclib_cb_console_flush(void);
+
 #if QTI_SDI_BUILD
 int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
 int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
index edabc5b..315bd6b 100644
--- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h
+++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
@@ -63,7 +63,6 @@
 void qtiseclib_bl31_platform_setup(void);
 void qtiseclib_invoke_isr(uint32_t irq, void *handle);
 void qtiseclib_panic(void);
-int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len);
 
 int qtiseclib_mem_assign(const memprot_info_t *mem_info,
 			 uint32_t mem_info_list_cnt,
@@ -79,10 +78,6 @@
 void qtiseclib_psci_node_power_off(const uint8_t *states);
 void qtiseclib_psci_node_suspend(const uint8_t *states);
 void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
-__attribute__ ((noreturn))
-void qtiseclib_psci_system_off(void);
-__attribute__ ((noreturn))
-void qtiseclib_psci_system_reset(void);
 void qtiseclib_disable_cluster_coherency(uint8_t state);
 
 #endif /* QTISECLIB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
index 1b1393e..331a104 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -29,6 +29,21 @@
 	return memcpy(dst, src, len);
 }
 
+int qtiseclib_cb_strcmp(const char *s1, const char *s2)
+{
+	return strcmp(s1, s2);
+}
+
+void *qtiseclib_cb_memset(void *s, int c, size_t n)
+{
+	return memset(s, c, n);
+}
+
+void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n)
+{
+	return memmove(dest, src, n);
+}
+
 /* Printing logs below or equal LOG_LEVEL from QTISECLIB. */
 void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...)
 {
@@ -106,6 +121,11 @@
 	udelay(usec);
 }
 
+int qtiseclib_cb_console_flush(void)
+{
+	return console_flush();
+}
+
 #if QTI_SDI_BUILD
 void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx)
 {
diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
index 494083b..9c93d51 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
@@ -67,17 +67,6 @@
 {
 }
 
-int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len)
-{
-	/* fill dummy data to avoid assert and print
-	 * stub implementation in setup call
-	 */
-	for (int i = 0; i < out_len; i++) {
-		out[i] = 0x11;
-	}
-	return 0;
-}
-
 int
 qtiseclib_mem_assign(const memprot_info_t *mem_info,
 		     uint32_t mem_info_list_cnt,
@@ -117,18 +106,6 @@
 
 void qtiseclib_psci_node_suspend_finish(const uint8_t *states)
 {
-}
-
-void qtiseclib_psci_system_off(void)
-{
-	while (1) {
-	};
-}
-
-void qtiseclib_psci_system_reset(void)
-{
-	while (1) {
-	};
 }
 
 void qtiseclib_disable_cluster_coherency(uint8_t state)
diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h
index d95b365..17e1310 100644
--- a/plat/qti/sc7180/inc/platform_def.h
+++ b/plat/qti/sc7180/inc/platform_def.h
@@ -173,4 +173,10 @@
  */
 #define BL31_LIMIT				(BL31_BASE + BL31_SIZE)
 
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG				0x0C264000
+/*----------------------------------------------------------------------------*/
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/sc7180/inc/qti_rng_io.h b/plat/qti/sc7180/inc/qti_rng_io.h
new file mode 100644
index 0000000..f50234f
--- /dev/null
+++ b/plat/qti/sc7180/inc/qti_rng_io.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_RNG_IO_H
+#define QTI_RNG_IO_H
+
+#define SEC_PRNG_STATUS			0x00791004
+#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK	0x1
+#define SEC_PRNG_DATA_OUT		0x00791000
+
+
+#endif /* QTI_RNG_IO_H */
+
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
index 45e6b33..ec560d0 100644
--- a/plat/qti/sc7180/platform.mk
+++ b/plat/qti/sc7180/platform.mk
@@ -51,6 +51,7 @@
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S	\
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S	\
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S	\
+				$(QTI_PLAT_PATH)/common/src/pm8998.c			\
 				$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c	\
 				$(QTI_PLAT_PATH)/common/src/qti_common.c		\
 				$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c		\
@@ -59,6 +60,8 @@
 				$(QTI_PLAT_PATH)/common/src/qti_syscall.c		\
 				$(QTI_PLAT_PATH)/common/src/qti_topology.c		\
 				$(QTI_PLAT_PATH)/common/src/qti_pm.c			\
+				$(QTI_PLAT_PATH)/common/src/qti_rng.c			\
+				$(QTI_PLAT_PATH)/common/src/spmi_arb.c			\
 				$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c	\
 
 
@@ -78,7 +81,7 @@
 PSCI_SOURCES		:=	plat/common/plat_psci_common.c				\
 
 # GIC-600 configuration
-GICV3_IMPL			:=	GIC600
+GICV3_SUPPORT_GIC600	:=	1
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index 2ff81ed..aec53ee 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -230,12 +230,27 @@
 
 void params_early_setup(u_register_t plat_param_from_bl2)
 {
+	int ret;
+
 	/*
 	 * Test if this is a FDT passed as a platform-specific parameter
 	 * block.
 	 */
-	if (!dt_process_fdt(plat_param_from_bl2))
+	ret = dt_process_fdt(plat_param_from_bl2);
+	if (!ret) {
+		return;
+	} else if (ret != -FDT_ERR_BADMAGIC) {
+		/*
+		 * If we found an FDT but couldn't parse it (e.g. corrupt, not
+		 * enough space), return and don't attempt to parse the param
+		 * as something else, since we know that will also fail. All
+		 * we're doing is setting up UART, this doesn't need to be
+		 * fatal.
+		 */
+		WARN("%s: found FDT but could not parse: error %d\n",
+		     __func__, ret);
 		return;
+	}
 
 	bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler);
 }
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 4d627b8..6c23923 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -210,7 +210,7 @@
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY):
+    $(ROT_KEY): | $(BUILD_PLAT)
 	@echo "  OPENSSL $@"
 	$(Q)openssl genrsa 2048 > $@ 2>/dev/null
 
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 9998236..41eacc8 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -46,16 +46,23 @@
 $(error "No boot device driver is enabled")
 endif
 
-$(eval $(call assert_boolean,STM32MP_EMMC))
-$(eval $(call assert_boolean,STM32MP_SDMMC))
-$(eval $(call assert_boolean,STM32MP_RAW_NAND))
-$(eval $(call assert_boolean,STM32MP_SPI_NAND))
-$(eval $(call assert_boolean,STM32MP_SPI_NOR))
-$(eval $(call add_define,STM32MP_EMMC))
-$(eval $(call add_define,STM32MP_SDMMC))
-$(eval $(call add_define,STM32MP_RAW_NAND))
-$(eval $(call add_define,STM32MP_SPI_NAND))
-$(eval $(call add_define,STM32MP_SPI_NOR))
+$(eval $(call assert_booleans,\
+    $(sort \
+        STM32MP_EMMC \
+        STM32MP_SDMMC \
+        STM32MP_RAW_NAND \
+        STM32MP_SPI_NAND \
+        STM32MP_SPI_NOR \
+)))
+
+$(eval $(call add_defines,\
+    $(sort \
+        STM32MP_EMMC \
+        STM32MP_SDMMC \
+        STM32MP_RAW_NAND \
+        STM32MP_SPI_NAND \
+        STM32MP_SPI_NOR \
+)))
 
 PLAT_INCLUDES		:=	-Iplat/st/common/include/
 PLAT_INCLUDES		+=	-Iplat/st/stm32mp1/include/
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 5d7d495..8866fb5 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -16,9 +16,9 @@
 				plat/st/stm32mp1/stm32mp1_topology.c
 
 # Generic GIC v2
-BL32_SOURCES		+=	drivers/arm/gic/common/gic_common.c	\
-				drivers/arm/gic/v2/gicv2_helpers.c	\
-				drivers/arm/gic/v2/gicv2_main.c		\
+include drivers/arm/gic/v2/gicv2.mk
+
+BL32_SOURCES		+=	${GICV2_SOURCES}			\
 				plat/common/plat_gicv2.c		\
 				plat/st/stm32mp1/stm32mp1_gic.c
 
diff --git a/services/spd/tlkd/tlkd_common.c b/services/spd/tlkd/tlkd_common.c
index dbe6c2e..820bd8a 100644
--- a/services/spd/tlkd/tlkd_common.c
+++ b/services/spd/tlkd/tlkd_common.c
@@ -38,16 +38,16 @@
 	int at = type & AT_MASK;
 	switch (at) {
 	case 0:
-		ats12e1r(va);
+		AT(ats12e1r, va);
 		break;
 	case 1:
-		ats12e1w(va);
+		AT(ats12e1w, va);
 		break;
 	case 2:
-		ats12e0r(va);
+		AT(ats12e0r, va);
 		break;
 	case 3:
-		ats12e0w(va);
+		AT(ats12e0w, va);
 		break;
 	default:
 		assert(0); /* Unreachable */
diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h
index 9c1c38c..c66f7db 100644
--- a/services/spd/trusty/smcall.h
+++ b/services/spd/trusty/smcall.h
@@ -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
  */
@@ -71,4 +72,11 @@
 #define SMC_YC_VDEV_KICK_VQ	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U)
 #define SMC_YC_SET_ROT_PARAMS	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U)
 
+/*
+ * Standard Trusted OS Function IDs that fall under Trusted OS call range
+ * according to SMC calling convention
+ */
+#define SMC_FC64_GET_UUID		SMC_FASTCALL64_NR(63U, 0xFF01U) /* Implementation UID */
+#define SMC_FC_GET_UUID			SMC_FASTCALL_NR(63U, 0xFF01U) /* Implementation.UID */
+
 #endif /* SMCALL_H */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index b10da76..e102b82 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,11 +17,18 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
 #include <plat/common/platform.h>
+#include <tools_share/uuid.h>
 
 #include "sm_err.h"
 #include "smcall.h"
 
+/* Trusty UID: RFC-4122 compliant UUID version 4 */
+DEFINE_SVC_UUID2(trusty_uuid,
+		 0x40ee25f0, 0xa2bc, 0x304c, 0x8c, 0x4c,
+		 0xa1, 0x73, 0xc5, 0x7d, 0x8a, 0xf1);
+
 /* macro to check if Hypervisor is enabled in the HCR_EL2 register */
 #define HYP_ENABLE_FLAG		0x286001U
 
@@ -256,6 +264,11 @@
 		SMC_RET1(handle, SMC_UNK);
 	} else {
 		switch (smc_fid) {
+		case SMC_FC64_GET_UUID:
+		case SMC_FC_GET_UUID:
+			/* provide the UUID for the service to the client */
+			SMC_UUID_RET(handle, trusty_uuid);
+			break;
 		case SMC_FC64_SET_FIQ_HANDLER:
 			return trusty_set_fiq_handler(handle, x1, x2, x3);
 		case SMC_FC64_GET_FIQ_REGS:
@@ -263,6 +276,12 @@
 		case SMC_FC_FIQ_EXIT:
 			return trusty_fiq_exit(handle, x1, x2, x3);
 		default:
+			/* Not all OENs greater than SMC_ENTITY_SECURE_MONITOR are supported */
+			if (SMC_ENTITY(smc_fid) > SMC_ENTITY_SECURE_MONITOR) {
+				VERBOSE("%s: unsupported SMC FID (0x%x)\n", __func__, smc_fid);
+				SMC_RET1(handle, SMC_UNK);
+			}
+
 			if (is_hypervisor_mode())
 				vmid = SMC_GET_GP(handle, CTX_GPREG_X7);
 
@@ -502,7 +521,7 @@
 	trusty_fast,
 
 	OEN_TOS_START,
-	SMC_ENTITY_SECURE_MONITOR,
+	OEN_TOS_END,
 	SMC_TYPE_FAST,
 	trusty_setup,
 	trusty_smc_handler
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 38d43f1..73f7c85 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -10,6 +10,7 @@
 
 SPMD_SOURCES	+=	$(addprefix services/std_svc/spmd/,	\
 			${ARCH}/spmd_helpers.S			\
+			spmd_pm.c				\
 			spmd_main.c)
 
 # Let the top-level Makefile know that we intend to include a BL32 image
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 4c2b58d..6aab558 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -42,13 +42,42 @@
 static entry_point_info_t *spmc_ep_info;
 
 /*******************************************************************************
+ * SPM Core context on CPU based on mpidr.
+ ******************************************************************************/
+spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr)
+{
+	int core_idx = plat_core_pos_by_mpidr(mpidr);
+
+	if (core_idx < 0) {
+		ERROR("Invalid mpidr: %llx, returned ID: %d\n", mpidr, core_idx);
+		panic();
+	}
+
+	return &spm_core_context[core_idx];
+}
+
+/*******************************************************************************
  * 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 spmd_get_context_by_mpidr(read_mpidr());
+}
+
+/*******************************************************************************
+ * SPM Core entry point information get helper.
+ ******************************************************************************/
+entry_point_info_t *spmd_spmc_ep_info_get(void)
+{
+	return spmc_ep_info;
+}
 
-	return &spm_core_context[linear_id];
+/*******************************************************************************
+ * SPM Core ID getter.
+ ******************************************************************************/
+uint16_t spmd_spmc_id_get(void)
+{
+	return spmc_attrs.spmc_id;
 }
 
 /*******************************************************************************
@@ -125,9 +154,19 @@
 {
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	uint64_t rc;
+	unsigned int linear_id = plat_my_core_pos();
+	unsigned int core_id;
 
 	VERBOSE("SPM Core init start.\n");
-	ctx->state = SPMC_STATE_RESET;
+	ctx->state = SPMC_STATE_ON_PENDING;
+
+	/* Set the SPMC context state on other CPUs to OFF */
+	for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
+		if (core_id != linear_id) {
+			spm_core_context[core_id].state = SPMC_STATE_OFF;
+			spm_core_context[core_id].secondary_ep.entry_point = 0UL;
+		}
+	}
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
@@ -135,7 +174,8 @@
 		return 0;
 	}
 
-	ctx->state = SPMC_STATE_IDLE;
+	ctx->state = SPMC_STATE_ON;
+
 	VERBOSE("SPM Core init end.\n");
 
 	return 1;
@@ -216,7 +256,6 @@
 	}
 
 	SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr);
-	assert(spmc_ep_info->pc == BL32_BASE);
 
 	/*
 	 * Populate SPSR for SPM Core based upon validated parameters from the
@@ -248,6 +287,9 @@
 
 	INFO("SPM Core setup done.\n");
 
+	/* Register power management hooks with PSCI */
+	psci_register_spd_pm_hook(&spmd_pm);
+
 	/* Register init function for deferred init. */
 	bl31_register_bl32_init(&spmd_init);
 
@@ -301,8 +343,8 @@
 				 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;
+	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
+	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
 
 	/* Save incoming security state */
 	cm_el1_sysregs_context_save(secure_state_in);
@@ -334,6 +376,46 @@
 		 FFA_PARAM_MBZ, FFA_PARAM_MBZ);
 }
 
+/*******************************************************************************
+ * spmd_check_address_in_binary_image
+ ******************************************************************************/
+bool spmd_check_address_in_binary_image(uint64_t address)
+{
+	assert(!check_uptr_overflow(spmc_attrs.load_address, spmc_attrs.binary_size));
+
+	return ((address >= spmc_attrs.load_address) &&
+		(address < (spmc_attrs.load_address + spmc_attrs.binary_size)));
+}
+
+/******************************************************************************
+ * spmd_is_spmc_message
+ *****************************************************************************/
+static bool spmd_is_spmc_message(unsigned int ep)
+{
+	return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID)
+		&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
+}
+
+/******************************************************************************
+ * spmd_handle_spmc_message
+ *****************************************************************************/
+static int spmd_handle_spmc_message(unsigned long long msg,
+		unsigned long long parm1, unsigned long long parm2,
+		unsigned long long parm3, unsigned long long parm4)
+{
+	VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__,
+		msg, parm1, parm2, parm3, parm4);
+
+	switch (msg) {
+	case SPMD_DIRECT_MSG_SET_ENTRY_POINT:
+		return spmd_pm_secondary_core_set_ep(parm1, parm2, parm3);
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
 /*******************************************************************************
  * 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
@@ -367,7 +449,7 @@
 		 * this CPU. If so, then indicate that the SPM Core initialised
 		 * unsuccessfully.
 		 */
-		if (secure_origin && (ctx->state == SPMC_STATE_RESET)) {
+		if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) {
 			spmd_spm_core_sync_exit(x2);
 		}
 
@@ -451,24 +533,57 @@
 
 		break; /* not reached */
 
+	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+		if (secure_origin && spmd_is_spmc_message(x1)) {
+			ret = spmd_handle_spmc_message(x3, x4,
+				SMC_GET_GP(handle, CTX_GPREG_X5),
+				SMC_GET_GP(handle, CTX_GPREG_X6),
+				SMC_GET_GP(handle, CTX_GPREG_X7));
+
+			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);
+		} else {
+			/* Forward direct message to the other world */
+			return spmd_smc_forward(smc_fid, secure_origin,
+				x1, x2, x3, x4, handle);
+		}
+		break; /* Not reached */
+
+	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+		if (secure_origin && spmd_is_spmc_message(x1)) {
+			spmd_spm_core_sync_exit(0);
+		} else {
+			/* Forward direct message to the other world */
+			return spmd_smc_forward(smc_fid, secure_origin,
+				x1, x2, x3, x4, handle);
+		}
+		break; /* Not reached */
+
 	case FFA_RX_RELEASE:
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
 	case FFA_RXTX_UNMAP:
+	case FFA_PARTITION_INFO_GET:
+		/*
+		 * Should not be allowed to forward FFA_PARTITION_INFO_GET
+		 * from Secure world to Normal world
+		 *
+		 * Fall through to forward the call to the other world
+		 */
 	case FFA_MSG_RUN:
 		/* This interface must be invoked only by the Normal world */
+
 		if (secure_origin) {
 			return spmd_ffa_error_return(handle,
-						      FFA_ERROR_NOT_SUPPORTED);
+						     FFA_ERROR_NOT_SUPPORTED);
 		}
 
 		/* Fall through to forward the call to the other world */
-
-	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:
@@ -500,7 +615,7 @@
 		 * this CPU from the Secure world. If so, then indicate that the
 		 * SPM Core initialised successfully.
 		 */
-		if (secure_origin && (ctx->state == SPMC_STATE_RESET)) {
+		if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) {
 			spmd_spm_core_sync_exit(0);
 		}
 
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
new file mode 100644
index 0000000..64ddbe5
--- /dev/null
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include "spmd_private.h"
+
+/*******************************************************************************
+ * spmd_build_spmc_message
+ *
+ * Builds an SPMD to SPMC direct message request.
+ ******************************************************************************/
+static void spmd_build_spmc_message(gp_regs_t *gpregs, unsigned long long message)
+{
+	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
+	write_ctx_reg(gpregs, CTX_GPREG_X1,
+		(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
+		spmd_spmc_id_get());
+	write_ctx_reg(gpregs, CTX_GPREG_X2, FFA_PARAM_MBZ);
+	write_ctx_reg(gpregs, CTX_GPREG_X3, message);
+}
+
+/*******************************************************************************
+ * spmd_pm_secondary_core_set_ep
+ ******************************************************************************/
+int spmd_pm_secondary_core_set_ep(unsigned long long mpidr,
+		uintptr_t entry_point, unsigned long long context)
+{
+	int id = plat_core_pos_by_mpidr(mpidr);
+
+	if ((id < 0) || (id >= PLATFORM_CORE_COUNT)) {
+		ERROR("%s inconsistent MPIDR (%llx)\n", __func__, mpidr);
+		return -EINVAL;
+	}
+
+	/*
+	 * Check entry_point address is a PA within
+	 * load_address <= entry_point < load_address + binary_size
+	 */
+	if (!spmd_check_address_in_binary_image(entry_point)) {
+		ERROR("%s entry point is not within image boundaries (%llx)\n",
+		      __func__, mpidr);
+		return -EINVAL;
+	}
+
+	spmd_spm_core_context_t *ctx = spmd_get_context_by_mpidr(mpidr);
+	spmd_pm_secondary_ep_t *secondary_ep = &ctx->secondary_ep;
+	if (secondary_ep->locked) {
+		ERROR("%s entry locked (%llx)\n", __func__, mpidr);
+		return -EINVAL;
+	}
+
+	/* Fill new entry to corresponding secondary core id and lock it */
+	secondary_ep->entry_point = entry_point;
+	secondary_ep->context = context;
+	secondary_ep->locked = true;
+
+	VERBOSE("%s %d %llx %lx %llx\n",
+		__func__, id, mpidr, entry_point, context);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This CPU has been turned on. Enter SPMC to initialise S-EL1 or S-EL2. As part
+ * of the SPMC initialization path, they will initialize any SPs that they
+ * manage. Entry into SPMC is done after initialising minimal architectural
+ * state that guarantees safe execution.
+ ******************************************************************************/
+static void spmd_cpu_on_finish_handler(u_register_t unused)
+{
+	entry_point_info_t *spmc_ep_info = spmd_spmc_ep_info_get();
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+	unsigned int linear_id = plat_my_core_pos();
+	uint64_t rc;
+
+	assert(ctx != NULL);
+	assert(ctx->state != SPMC_STATE_ON);
+	assert(spmc_ep_info != NULL);
+
+	/*
+	 * TODO: this might require locking the spmc_ep_info structure,
+	 * or provisioning one structure per cpu
+	 */
+	if (ctx->secondary_ep.entry_point == 0UL) {
+		goto exit;
+	}
+
+	spmc_ep_info->pc = ctx->secondary_ep.entry_point;
+	cm_setup_context(&ctx->cpu_ctx, spmc_ep_info);
+	write_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx), CTX_GPREG_X0,
+		      ctx->secondary_ep.context);
+
+	/* Mark CPU as initiating ON operation */
+	ctx->state = SPMC_STATE_ON_PENDING;
+
+	rc = spmd_spm_core_sync_entry(ctx);
+	if (rc != 0ULL) {
+		ERROR("%s failed (%llu) on CPU%u\n", __func__, rc,
+			linear_id);
+		ctx->state = SPMC_STATE_OFF;
+		return;
+	}
+
+exit:
+	ctx->state = SPMC_STATE_ON;
+
+	VERBOSE("CPU %u on!\n", linear_id);
+}
+
+/*******************************************************************************
+ * spmd_cpu_off_handler
+ ******************************************************************************/
+static int32_t spmd_cpu_off_handler(u_register_t unused)
+{
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+	unsigned int linear_id = plat_my_core_pos();
+	int64_t rc;
+
+	assert(ctx != NULL);
+	assert(ctx->state != SPMC_STATE_OFF);
+
+	if (ctx->secondary_ep.entry_point == 0UL) {
+		goto exit;
+	}
+
+	/* Build an SPMD to SPMC direct message request. */
+	spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx), PSCI_CPU_OFF);
+
+	rc = spmd_spm_core_sync_entry(ctx);
+	if (rc != 0ULL) {
+		ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id);
+	}
+
+	/* TODO expect FFA_DIRECT_MSG_RESP returned from SPMC */
+
+exit:
+	ctx->state = SPMC_STATE_OFF;
+
+	VERBOSE("CPU %u off!\n", linear_id);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Structure populated by the SPM Dispatcher to perform any bookkeeping before
+ * PSCI executes a power mgmt. operation.
+ ******************************************************************************/
+const spd_pm_ops_t spmd_pm = {
+	.svc_on_finish = spmd_cpu_on_finish_handler,
+	.svc_off = spmd_cpu_off_handler
+};
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 4946309..eff0dd9 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -30,14 +30,24 @@
 #define SPMD_C_RT_CTX_ENTRIES		(SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
 
 #ifndef __ASSEMBLER__
-#include <services/ffa_svc.h>
 #include <stdint.h>
+#include <lib/psci/psci_lib.h>
+#include <plat/common/platform.h>
+#include <services/ffa_svc.h>
 
 typedef enum spmc_state {
 	SPMC_STATE_RESET = 0,
-	SPMC_STATE_IDLE
+	SPMC_STATE_OFF,
+	SPMC_STATE_ON_PENDING,
+	SPMC_STATE_ON
 } spmc_state_t;
 
+typedef struct spmd_pm_secondary_ep {
+	uintptr_t entry_point;
+	uintptr_t context;
+	bool locked;
+} spmd_pm_secondary_ep_t;
+
 /*
  * Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of
  * the SPM core (SPMC) at the next lower EL.
@@ -46,16 +56,20 @@
 	uint64_t c_rt_ctx;
 	cpu_context_t cpu_ctx;
 	spmc_state_t state;
+	spmd_pm_secondary_ep_t secondary_ep;
 } spmd_spm_core_context_t;
 
 /*
  * Reserve ID for NS physical FFA Endpoint.
  */
-#define FFA_NS_ENDPOINT_ID		U(0)
+#define FFA_NS_ENDPOINT_ID			U(0)
 
-/* Mask and shift to check valid secure FFA Endpoint ID. */
-#define SPMC_SECURE_ID_MASK		U(1)
-#define SPMC_SECURE_ID_SHIFT		U(15)
+/* Mask and shift to check valid secure FF-A Endpoint ID. */
+#define SPMC_SECURE_ID_MASK			U(1)
+#define SPMC_SECURE_ID_SHIFT			U(15)
+
+#define SPMD_DIRECT_MSG_ENDPOINT_ID		U(FFA_ENDPOINT_ID_MAX - 1)
+#define SPMD_DIRECT_MSG_SET_ENTRY_POINT		U(1)
 
 /* Functions used to enter/exit SPMC synchronously */
 uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
@@ -65,9 +79,25 @@
 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);
 
+/* SPMD SPD power management handlers */
+extern const spd_pm_ops_t spmd_pm;
+
+/* SPMC entry point information helper */
+entry_point_info_t *spmd_spmc_ep_info_get(void);
+
+/* SPMC ID getter */
+uint16_t spmd_spmc_id_get(void);
+
+/* SPMC context on CPU based on mpidr */
+spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr);
+
 /* SPMC context on current CPU get helper */
 spmd_spm_core_context_t *spmd_get_context(void);
 
+int spmd_pm_secondary_core_set_ep(unsigned long long mpidr,
+		uintptr_t entry_point, unsigned long long context);
+bool spmd_check_address_in_binary_image(uint64_t address);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_PRIVATE_H */
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 19f736f..0ec08b0 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -4,11 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROJECT		:= cert_create
 PLAT		:= none
 V		?= 0
 DEBUG		:= 0
-BINARY		:= ${PROJECT}${BIN_EXT}
+CRTTOOL		?= cert_create${BIN_EXT}
+BINARY		:= $(notdir ${CRTTOOL})
 OPENSSL_DIR	:= /usr
 COT		:= tbbr
 
diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h
index 1d959d4..3e50c89 100644
--- a/tools/cert_create/include/dualroot/cot.h
+++ b/tools/cert_create/include/dualroot/cot.h
@@ -23,6 +23,7 @@
 
 	/* Certificates owned by the platform owner. */
 	NON_TRUSTED_FW_CONTENT_CERT,
+	PLAT_SECURE_PARTITION_CONTENT_CERT,
 };
 
 /* Certificate extensions. */
diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c
index a12ea21..4dd4cf0 100644
--- a/tools/cert_create/src/dualroot/cot.c
+++ b/tools/cert_create/src/dualroot/cot.c
@@ -152,12 +152,27 @@
 			SP_PKG2_HASH_EXT,
 			SP_PKG3_HASH_EXT,
 			SP_PKG4_HASH_EXT,
+		},
+		.num_ext = 5
+	},
+
+	[PLAT_SECURE_PARTITION_CONTENT_CERT] = {
+		.id = PLAT_SECURE_PARTITION_CONTENT_CERT,
+		.opt = "plat-sp-cert",
+		.help_msg = "Platform owned Secure Partition Content Certificate (output file)",
+		.fn = NULL,
+		.cn = "Platform owned Secure Partition Content Certificate",
+		.key = PROT_KEY,
+		.issuer = PLAT_SECURE_PARTITION_CONTENT_CERT,
+		.ext = {
+			NON_TRUSTED_FW_NVCOUNTER_EXT,
 			SP_PKG5_HASH_EXT,
 			SP_PKG6_HASH_EXT,
 			SP_PKG7_HASH_EXT,
 			SP_PKG8_HASH_EXT,
+			PROT_PK_EXT,
 		},
-		.num_ext = 9
+		.num_ext = 6
 	},
 
 	[FWU_CERT] = {
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index cb81d0b..6eb6fae 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,14 +1,14 @@
 #
-# Copyright (c) 2019, Linaro Limited. All rights reserved.
+# Copyright (c) 2019-2020, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROJECT		:= encrypt_fw
 V		?= 0
 BUILD_INFO	?= 1
 DEBUG		:= 0
-BINARY		:= ${PROJECT}${BIN_EXT}
+ENCTOOL		?= encrypt_fw${BIN_EXT}
+BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
 OBJECTS := src/encrypt.o \
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index ef35014..df8ab5c 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,8 @@
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
-PROJECT := fiptool${BIN_EXT}
+FIPTOOL ?= fiptool${BIN_EXT}
+PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
 V ?= 0
 
diff --git a/tools/fiptool/Makefile.msvc b/tools/fiptool/Makefile.msvc
index 58dbb89..9081bc6 100644
--- a/tools/fiptool/Makefile.msvc
+++ b/tools/fiptool/Makefile.msvc
@@ -1,30 +1,37 @@
-#

-# Copyright (c) 2019, Arm Limited. All rights reserved.

-#

-# SPDX-License-Identifier: BSD-3-Clause

-#

-

-CC = cl.exe

-LD = link.exe

-

-FIPTOOL = fiptool.exe

-OBJECTS = fiptool.obj tbbr_config.obj win_posix.obj

-

-INC = -I. -I..\..\include\tools_share

-CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT

-

-all: $(FIPTOOL)

-

-$(FIPTOOL): $(OBJECTS)

-	$(LD) /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $**

-

-.PHONY: clean realclean

-

-clean:

-	del /f /q $(OBJECTS) > nul

-

-realclean:

-	del /f /q $(OBJECTS) $(FIPTOOL) > nul

-

-.c.obj:

-	$(CC) -c $(CFLAGS) $(INC) $< -Fo$@

+#
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CC = cl.exe
+LD = link.exe
+
+# FIPTOOLPATH and FIPTOOL are passed from the main makefile.
+
+OBJECTS = $(FIPTOOLPATH)\fiptool.obj     \
+          $(FIPTOOLPATH)\tbbr_config.obj \
+          $(FIPTOOLPATH)\win_posix.obj
+
+INC = -I$(FIPTOOLPATH) -Iinclude\tools_share
+
+CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT
+
+all: $(FIPTOOL)
+
+$(FIPTOOL): $(OBJECTS)
+	$(LD) /nologo /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $**
+
+.PHONY: clean realclean
+
+clean:
+	-@del /f /q $(OBJECTS) > nul
+	-@del /f /q $(FIPTOOLPATH)\*.pdb > nul
+
+realclean:
+	-@del /f /q $(OBJECTS) > nul
+	-@del /f /q $(FIPTOOLPATH)\*.pdb > nul
+	-@del /f /q $(FIPTOOL) > nul
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index bf721c1..c1e5217 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -162,6 +162,11 @@
 		.cmdline_name = "sip-sp-cert"
 	},
 	{
+		.name = "Platform owned Secure Partition content certificate",
+		.uuid = UUID_PLAT_SECURE_PARTITION_CONTENT_CERT,
+		.cmdline_name = "plat-sp-cert"
+	},
+	{
 		.name = NULL,
 		.uuid = { {0} },
 		.cmdline_name = NULL,
diff --git a/tools/fiptool/win_posix.c b/tools/fiptool/win_posix.c
index 48feb16..33b44d4 100644
--- a/tools/fiptool/win_posix.c
+++ b/tools/fiptool/win_posix.c
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -137,7 +137,8 @@
  * Note that we only match over the shorter length of the pair, to allow
  * for abbreviation or say --match=value
  * Long option names may be abbreviated if the abbreviation is unique or an
- * exact match for some defined option.
+ * exact match for some defined option. This function does not check that the
+ * abbreviations are unique and should be handled by the caller.
  * A long option may take a parameter, of the form --opt=param or --opt param.
 */
 static
@@ -160,42 +161,72 @@
 {
 	int result = RET_UNKNOWN_OPT;
 	size_t loptn = 0;
+	bool match_found = false;
 
-	while (longopts[loptn].name != 0) {
-		if (optmatch(optname, longopts[loptn].name) == 0) {
-			/* We found a match. */
-			result = longopts[loptn].val;
-			if (indexptr != 0)
-				*indexptr = loptn;
-			switch (longopts[loptn].has_arg) {
-			case required_argument:
-				if ((optind + 1) >= argc) {
-					/* Missing argument. */
-					optopt = result;
-					return RET_NO_PARAM;
-				}
-				/* Fallthrough to get option value. */
+	/*
+	 * Long option names may be abbreviated if the abbreviation
+	 * is unique or an exact match for some defined option.
+	 * To handle this:
+	 * - First search for an exact match.
+	 * - If exact match was not found search for a abbreviated match.
+	 * By doing this an incorrect option selection can be avoided.
+	 */
 
-			case optional_argument:
-				if ((argc - optind) > 0) {
-					/* Found argument. */
-					optarg = argv[++optind];
-				}
-				/* Fallthrough to handle flag. */
+	/* 1. Search for an exact match. */
+	while (longopts[loptn].name != NULL) {
+		if (strcmp(optname, longopts[loptn].name) == 0) {
+			match_found = true;
+			break;
+		}
+		++loptn;
+	}
 
-			case no_argument:
-				optind++;
-				if (longopts[loptn].flag != 0) {
-					*longopts[loptn].flag = result;
-					result = 0;
-				}
+	/* 2. If exact match was not found search for a abbreviated match. */
+	if (!match_found) {
+		loptn = 0;
+		while (longopts[loptn].name != NULL) {
+			if (optmatch(optname, longopts[loptn].name) == 0) {
+				match_found = true;
 				break;
+			}
+			++loptn;
+		}
+	}
+
+	if (match_found) {
+		/* We found a match. */
+		result = longopts[loptn].val;
+		if (indexptr != 0) {
+			*indexptr = loptn;
+		}
+		switch (longopts[loptn].has_arg) {
+		case required_argument:
+			if ((optind + 1) >= argc) {
+				/* Missing argument. */
+				optopt = result;
+				return RET_NO_PARAM;
+			}
+			/* Fallthrough to get option value. */
 
+		case optional_argument:
+			if ((argc - optind) > 0) {
+				/* Found argument. */
+				optarg = argv[++optind];
 			}
-			return result;
+			/* Fallthrough to handle flag. */
+
+		case no_argument:
+			optind++;
+			if (longopts[loptn].flag != 0) {
+				*longopts[loptn].flag = result;
+				result = 0;
+			}
+			break;
+
 		}
-		++loptn;
+		return result;
 	}
+
 	/*
 	 * If getopt finds an option character in argv that was not included
 	 * in options, ... it returns '?' and sets the external variable
diff --git a/tools/fiptool/win_posix.h b/tools/fiptool/win_posix.h
index 836ffed..6f0d8e6 100644
--- a/tools/fiptool/win_posix.h
+++ b/tools/fiptool/win_posix.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,13 +9,15 @@
 
 #define _CRT_SECURE_NO_WARNINGS
 
-#include <direct.h>
-#include <io.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 
+#include <direct.h>
+#include <io.h>
+
 #include "uuid.h"
 
 /* Derive or provide Windows equivalents of Posix/GCC/Unix stuff. */
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index 9325207..1fa85fb 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,8 @@
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
-PROJECT := sptool${BIN_EXT}
+SPTOOL  ?= sptool${BIN_EXT}
+PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
 V ?= 0
 
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 2153a56..a37e702 100755
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -19,6 +19,7 @@
 param1: Generated mk file "sp_gen.mk"
 param2: "SP_LAYOUT_FILE", json file containing platform provided information
 param3: plat out directory
+param4: CoT parameter
 
 Generated "sp_gen.mk" file contains triplet of following information for each
 Secure Partition entry
@@ -58,11 +59,39 @@
 gen_file = os.path.abspath(sys.argv[1])
 out_dir = os.path.abspath(sys.argv[3])
 dtb_dir = out_dir + "/fdts/"
+MAX_SP = 8
+dualroot = sys.argv[4].lower() == "dualroot"
+split = int(MAX_SP / 2)
 print(dtb_dir)
+platform_count = 1
+sip_count = 1
 
 with open(gen_file, 'w') as out_file:
     for idx, key in enumerate(data.keys()):
 
+        pkg_num = idx + 1
+
+        if (pkg_num > MAX_SP):
+            print("WARNING: Too many secure partitions\n")
+            exit(-1)
+
+        if dualroot:
+            owner = data[key].get('owner')
+            if owner == "Plat":
+                if (platform_count > split):
+                    print("WARNING: Maximum Secure partitions by Plat " +
+                    "have been exceeded (" + str(split) + ")\n")
+                    exit(-1)
+                pkg_num = split + platform_count
+                platform_count += 1
+            elif (sip_count > split):
+                print("WARNING: Maximum Secure partitions by SiP " +
+                "have been exceeded (" + str(split) + ")\n")
+                exit(-1)
+            else:
+                pkg_num = sip_count
+                sip_count += 1
+
         """
         Append FDT_SOURCES
         """
@@ -81,10 +110,10 @@
         Extract uuid from partition manifest
         """
         pm_file = open(dts)
-        key = "uuid"
+        uuid_key = "uuid"
 
         for line in pm_file:
-            if key in line:
+            if uuid_key in line:
                 uuid_hex = re.findall(r'\<(.+?)\>', line)[0];
 
         # PM has uuid in format 0xABC... 0x... 0x... 0x...
@@ -103,5 +132,6 @@
         """
         Append CRT_ARGS
         """
-        out_file.write("CRT_ARGS += --sp-pkg" + str(idx + 1) + " " + dst + "\n")
+
+        out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
         out_file.write("\n")