Merge "fix(sdei): ensure that interrupt ID is valid" into integration
diff --git a/Makefile b/Makefile
index 7f781a0..f55dfdd 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
 #
 VERSION_MAJOR			:= 2
 VERSION_MINOR			:= 9
-VERSION_PATCH			:= 0
+VERSION_PATCH			:= 0	# Only used for LTS releases
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
 
 # Default goal is build all images
@@ -414,7 +414,6 @@
 ################################################################################
 # Common sources and include directories
 ################################################################################
-include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
 include lib/compiler-rt/compiler-rt.mk
 
 BL_COMMON_SOURCES	+=	common/bl_common.c			\
@@ -503,6 +502,12 @@
 		ifneq ($(SP_LAYOUT_FILE),)
 		BL2_ENABLE_SP_LOAD := 1
 		endif
+
+		ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
+			ifneq ($(SPMC_AT_EL3),1)
+			$(error SEL0 SP cannot be enabled without SPMC at EL3)
+			endif
+		endif
 	else
 		# All other SPDs in spd directory
 		SPD_DIR := spd
@@ -651,111 +656,6 @@
 endif #(FEAT_RME)
 
 ################################################################################
-# Generic definitions
-################################################################################
-include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
-
-ifeq (${BUILD_BASE},)
-     BUILD_BASE		:=	./build
-endif
-BUILD_PLAT		:=	$(abspath ${BUILD_BASE})/${PLAT}/${BUILD_TYPE}
-
-SPDS			:=	$(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*))))
-
-# Platforms providing their own TBB makefile may override this value
-INCLUDE_TBBR_MK		:=	1
-
-################################################################################
-# Include SPD Makefile if one has been specified
-################################################################################
-
-ifneq (${SPD},none)
-	ifeq (${ARCH},aarch32)
-                $(error "Error: SPD is incompatible with AArch32.")
-	endif
-
-	ifdef EL3_PAYLOAD_BASE
-                $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
-                $(warning "The SPD and its BL32 companion will be present but \
-                ignored.")
-	endif
-
-	ifeq (${SPD},spmd)
-	# SPMD is located in std_svc directory
-		SPD_DIR := std_svc
-
-		ifeq ($(SPMD_SPM_AT_SEL2),1)
-			CTX_INCLUDE_EL2_REGS := 1
-			ifeq ($(SPMC_AT_EL3),1)
-                                $(error SPM cannot be enabled in both S-EL2 and EL3.)
-			endif
-		endif
-
-		ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
-			DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
-		endif
-
-		ifeq ($(TS_SP_FW_CONFIG),1)
-		DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
-		endif
-
-		ifneq ($(ARM_BL2_SP_LIST_DTS),)
-		DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
-		endif
-
-		ifneq ($(SP_LAYOUT_FILE),)
-		BL2_ENABLE_SP_LOAD := 1
-		endif
-
-		ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
-			ifneq ($(SPMC_AT_EL3),1)
-			$(error SEL0 SP cannot be enabled without SPMC at EL3)
-			endif
-		endif
-	else
-		# All other SPDs in spd directory
-		SPD_DIR := spd
-	endif #(SPD)
-
-	# We expect to locate an spd.mk under the specified SPD directory
-	SPD_MAKE	:=	$(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
-
-	ifeq (${SPD_MAKE},)
-                $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
-	endif
-        $(info Including ${SPD_MAKE})
-        include ${SPD_MAKE}
-
-	# If there's BL32 companion for the chosen SPD, we expect that the SPD's
-	# Makefile would set NEED_BL32 to "yes". In this case, the build system
-	# supports two mutually exclusive options:
-	# * BL32 is built from source: then BL32_SOURCES must contain the list
-	#   of source files to build BL32
-	# * BL32 is a prebuilt binary: then BL32 must point to the image file
-	#   that will be included in the FIP
-	# If both BL32_SOURCES and BL32 are defined, the binary takes precedence
-	# over the sources.
-endif #(SPD=none)
-
-ifeq (${ENABLE_SPMD_LP}, 1)
-ifneq (${SPD},spmd)
-        $(error Error: ENABLE_SPMD_LP requires SPD=spmd.)
-endif
-ifeq ($(SPMC_AT_EL3),1)
-        $(error SPMC at EL3 not supported when enabling SPMD Logical partitions.)
-endif
-endif
-
-ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
-	ifeq (${SPD},none)
-		ifeq (${ENABLE_RME},0)
-                        $(error CTX_INCLUDE_EL2_REGS is available only when SPD \
-                        or RME is enabled)
-		endif
-	endif
-endif
-
-################################################################################
 # Include rmmd Makefile if RME is enabled
 ################################################################################
 ifneq (${ENABLE_RME},0)
@@ -809,6 +709,14 @@
 	BL2_RUNS_AT_EL3	:=	0
 endif
 
+# This internal flag is set to 1 when Firmware First handling of External aborts
+# is required by lowe ELs. Currently only NS requires this support.
+ifeq ($(HANDLE_EA_EL3_FIRST_NS),1)
+	FFH_SUPPORT := 1
+else
+	FFH_SUPPORT := 0
+endif
+
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
 
 ifeq (${ARM_ARCH_MAJOR},7)
@@ -970,18 +878,9 @@
 # RAS_EXTENSION is deprecated, provide alternate build options
 ifeq ($(RAS_EXTENSION),1)
         $(error "RAS_EXTENSION is now deprecated, please use ENABLE_FEAT_RAS \
-        and RAS_FFH_SUPPORT instead")
+        and HANDLE_EA_EL3_FIRST_NS instead")
 endif
 
-# RAS firmware first handling requires that EAs are handled in EL3 first
-ifeq ($(RAS_FFH_SUPPORT),1)
-	ifneq ($(ENABLE_FEAT_RAS),1)
-                $(error For RAS_FFH_SUPPORT, ENABLE_FEAT_RAS must also be 1)
-	endif
-	ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
-                $(error For RAS_FFH_SUPPORT, HANDLE_EA_EL3_FIRST_NS must also be 1)
-	endif
-endif #(RAS_FFH_SUPPORT)
 
 # When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled
 ifeq ($(FAULT_INJECTION_SUPPORT),1)
@@ -1283,6 +1182,8 @@
 	ENABLE_RUNTIME_INSTRUMENTATION \
 	ENABLE_SME_FOR_SWD \
 	ENABLE_SVE_FOR_SWD \
+	ENABLE_FEAT_RAS	\
+	FFH_SUPPORT	\
 	ERROR_DEPRECATED \
 	FAULT_INJECTION_SUPPORT \
 	GENERATE_COT \
@@ -1337,7 +1238,6 @@
 	ERRATA_ABI_SUPPORT \
 	ERRATA_NON_ARM_INTERCONNECT \
 	CONDITIONAL_CMO \
-	RAS_FFH_SUPPORT \
 	PSA_CRYPTO	\
 	ENABLE_CONSOLE_GETC \
 )))
@@ -1360,7 +1260,6 @@
 	ENABLE_FEAT_AMU \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
-	ENABLE_FEAT_RAS	\
 	ENABLE_FEAT_DIT \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
@@ -1443,6 +1342,8 @@
 	ENABLE_SPE_FOR_NS \
 	ENABLE_SVE_FOR_NS \
 	ENABLE_SVE_FOR_SWD \
+	ENABLE_FEAT_RAS \
+	FFH_SUPPORT \
 	ENCRYPT_BL31 \
 	ENCRYPT_BL32 \
 	ERROR_DEPRECATED \
@@ -1460,8 +1361,6 @@
 	PROGRAMMABLE_RESET_ADDRESS \
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
-	ENABLE_FEAT_RAS \
-	RAS_FFH_SUPPORT \
 	RESET_TO_BL31 \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index dd6b4dc..28d2187 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -15,31 +15,11 @@
 #include <cpu_macros.S>
 #include <context.h>
 
-	.globl	handle_lower_el_ea_esb
 	.globl	handle_lower_el_sync_ea
 	.globl	handle_lower_el_async_ea
-
-
-/*
- * Function to delegate External Aborts synchronized by ESB instruction at EL3
- * vector entry. This function assumes GP registers x0-x29 have been saved, and
- * are available for use. It delegates the handling of the EA to platform
- * handler, and returns only upon successfully handling the EA; otherwise
- * panics. On return from this function, the original exception handler is
- * expected to resume.
- */
-func handle_lower_el_ea_esb
-	mov	x0, #ERROR_EA_ESB
-	mrs	x1, DISR_EL1
-	b	ea_proceed
-endfunc handle_lower_el_ea_esb
-
-
+	.globl	handle_pending_async_ea
 /*
- * This function forms the tail end of Synchronous Exception entry from lower
- * EL, and expects to handle Synchronous External Aborts from lower EL and CPU
- * Implementation Defined Exceptions. If any other kind of exception is detected,
- * then this function reports unhandled exception.
+ * This function handles Synchronous External Aborts from lower EL.
  *
  * It delegates the handling of the EA to platform handler, and upon successfully
  * handling the EA, exits EL3; otherwise panics.
@@ -57,27 +37,8 @@
 	cmp	x30, #EC_DABORT_LOWER_EL
 	b.eq	1f
 
-	/* Save GP registers */
-	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
-	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
-	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-
-	/* Get the cpu_ops pointer */
-	bl	get_cpu_ops_ptr
-
-	/* Get the cpu_ops exception handler */
-	ldr	x0, [x0, #CPU_E_HANDLER_FUNC]
-
-	/*
-	 * If the reserved function pointer is NULL, this CPU does not have an
-	 * implementation defined exception handler function
-	 */
-	cbz	x0, 2f
-	mrs	x1, esr_el3
-	ubfx	x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
-	blr	x0
-	b	2f
-
+	/* EA other than above are unhandled exceptions */
+	no_ret	report_unhandled_exception
 1:
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
@@ -98,14 +59,6 @@
 	/* el3_exit assumes SP_EL0 on entry */
 	msr	spsel, #MODE_SP_EL0
 	b	el3_exit
-2:
-	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
-	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
-	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-
-	/* Synchronous exceptions other than the above are assumed to be EA */
-	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	no_ret	report_unhandled_exception
 endfunc handle_lower_el_sync_ea
 
 
@@ -140,6 +93,73 @@
 	b	el3_exit
 endfunc handle_lower_el_async_ea
 
+/*
+ * Handler for async EA from lower EL synchronized at EL3 entry in FFH mode.
+ *
+ * This scenario may arise when there is an error (EA) in the system which is not
+ * yet signaled to PE while executing in lower EL. During entry into EL3, the errors
+ * are synchronized either implicitly or explicitly causing async EA to pend at EL3.
+ *
+ * On detecting the pending EA (via ISR_EL1.A), if the EA routing model is Firmware
+ * First handling (FFH, SCR_EL3.EA = 1) this handler first handles the pending EA
+ * and then handles the original exception.
+ *
+ * This function assumes x30 has been saved.
+ */
+func handle_pending_async_ea
+	/*
+	 * Prepare for nested handling of EA. Stash sysregs clobbered by nested
+	 * exception and handler
+	 */
+	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
+	mrs	x30, esr_el3
+	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
+	mrs	x30, spsr_el3
+	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
+	mrs	x30, elr_el3
+	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
+
+	mov	x30, #1
+	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	/*
+	 * Restore the original x30 saved as part of entering EL3. This is not
+	 * required for the current function but for EL3 SError vector entry
+	 * once PSTATE.A bit is unmasked. We restore x30 and then the same
+	 * value is stored in EL3 SError vector entry.
+	 */
+	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+	/*
+	 * After clearing PSTATE.A bit pending SError will trigger at current EL.
+	 * Put explicit synchronization event to ensure newly unmasked interrupt
+	 * is taken immediately.
+	 */
+	unmask_async_ea
+
+	/* Restore the original exception information along with zeroing the storage */
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
+	msr	elr_el3, x30
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
+	msr	spsr_el3, x30
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
+	msr	esr_el3, x30
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
+
+	/*
+	 * If the original exception corresponds to SError from lower El, eret back
+	 * to lower EL, otherwise return to vector table for original exception handling.
+	 */
+	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x30, #EC_SERROR
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
+	b.eq	1f
+	ret
+1:
+	exception_return
+endfunc handle_pending_async_ea
 
 /*
  * Prelude for Synchronous External Abort handling. This function assumes that
@@ -149,7 +169,7 @@
  * x1: EA syndrome
  */
 func delegate_sync_ea
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	/*
 	 * Check for Uncontainable error type. If so, route to the platform
 	 * fatal error handler rather than the generic EA one.
@@ -179,7 +199,7 @@
  * x1: EA syndrome
  */
 func delegate_async_ea
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	/* Check Exception Class to ensure SError, as this function should
 	 * only be invoked for SError. If that is not the case, which implies
 	 * either an HW error or programming error, panic.
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 8298696..ed48311 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -13,6 +13,7 @@
 #include <bl31/sync_handle.h>
 #include <common/runtime_svc.h>
 #include <context.h>
+#include <cpu_macros.S>
 #include <el3_common_macros.S>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/smccc.h>
@@ -47,72 +48,30 @@
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	.endm
 
-	/*
-	 * Macro that prepares entry to EL3 upon taking an exception.
-	 *
-	 * With RAS_FFH_SUPPORT, this macro synchronizes pending errors with an
-	 * ESB instruction. When an error is thus synchronized, the handling is
-	 * delegated to platform EA handler.
-	 *
-	 * Without RAS_FFH_SUPPORT, this macro synchronizes pending errors using
-	 * a DSB, unmasks Asynchronous External Aborts and saves X30 before
-	 * setting the flag CTX_IS_IN_EL3.
-	 */
-	.macro check_and_unmask_ea
-#if RAS_FFH_SUPPORT
-	/* Synchronize pending External Aborts */
-	esb
-
-	/* Unmask the SError interrupt */
-	msr	daifclr, #DAIF_ABT_BIT
-
-	/* Check for SErrors synchronized by the ESB instruction */
-	mrs	x30, DISR_EL1
-	tbz	x30, #DISR_A_BIT, 1f
-
-	/*
-	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
-	 * Also save PMCR_EL0 and  set the PSTATE to a known state.
-	 */
-	bl	prepare_el3_entry
-
-	bl	handle_lower_el_ea_esb
-
-	/* Restore general purpose, PMCR_EL0 and ARMv8.3-PAuth registers */
-	bl	restore_gp_pmcr_pauth_regs
-1:
-#else
-	/*
-	 * Note 1: The explicit DSB at the entry of various exception vectors
-	 * for handling exceptions from lower ELs can inadvertently trigger an
-	 * SError exception in EL3 due to pending asynchronous aborts in lower
-	 * ELs. This will end up being handled by serror_sp_elx which will
-	 * ultimately panic and die.
-	 * The way to workaround is to update a flag to indicate if the exception
-	 * truly came from EL3. This flag is allocated in the cpu_context
-	 * structure and located at offset "CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3"
-	 * This is not a bullet proof solution to the problem at hand because
-	 * we assume the instructions following "isb" that help to update the
-	 * flag execute without causing further exceptions.
-	 */
+	.macro restore_x30
+	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	.endm
 
 	/*
-	 * For SoCs which do not implement RAS, use DSB as a barrier to
-	 * synchronize pending external aborts.
+	 * Macro that synchronizes errors (EA) and checks for pending SError.
+	 * On detecting a pending SError it either reflects it back to lower
+	 * EL (KFH) or handles it in EL3 (FFH) based on EA routing model.
 	 */
-	dsb	sy
-
-	/* Unmask the SError interrupt */
-	msr	daifclr, #DAIF_ABT_BIT
-
-	/* Use ISB for the above unmask operation to take effect immediately */
-	isb
-
-	/* Refer Note 1. */
-	mov 	x30, #1
-	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	dmb	sy
+	.macro	sync_and_handle_pending_serror
+	synchronize_errors
+	mrs	x30, ISR_EL1
+	tbz	x30, #ISR_A_SHIFT, 2f
+#if FFH_SUPPORT
+	mrs	x30, scr_el3
+	tst	x30, #SCR_EA_BIT
+	b.eq	1f
+	bl	handle_pending_async_ea
+	b	2f
 #endif
+1:
+	/* This function never returns, but need LR for decision making */
+	bl	reflect_pending_async_ea_to_lower_el
+2:
 	.endm
 
 	/* ---------------------------------------------------------------------
@@ -147,9 +106,19 @@
 	cmp	x30, #EC_AARCH64_SYS
 	b.eq	sync_handler64
 
-	/* Synchronous exceptions other than the above are assumed to be EA */
-	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	cmp	x30, #EC_IMP_DEF_EL3
+	b.eq	imp_def_el3_handler
+
+	/* If FFH Support then try to handle lower EL EA exceptions. */
+#if FFH_SUPPORT
+	mrs	x30, scr_el3
+	tst	x30, #SCR_EA_BIT
+	b.eq	1f
 	b	handle_lower_el_sync_ea
+#endif
+1:
+	/* Synchronous exceptions other than the above are unhandled */
+	b	report_unhandled_exception
 	.endm
 
 vector_base runtime_exceptions
@@ -217,22 +186,33 @@
 end_vector_entry fiq_sp_elx
 
 vector_entry serror_sp_elx
-#if !RAS_FFH_SUPPORT
+#if FFH_SUPPORT
 	/*
 	 * This will trigger if the exception was taken due to SError in EL3 or
 	 * because of pending asynchronous external aborts from lower EL that got
-	 * triggered due to explicit synchronization in EL3. Refer Note 1.
+	 * triggered due to implicit/explicit synchronization in EL3 (SCR_EL3.EA=1)
+	 * during EL3 entry. For the former case we continue with "plat_handle_el3_ea".
+	 * The later case will occur when PSTATE.A bit is cleared in
+	 * "handle_pending_async_ea". This means we are doing a nested
+	 * exception in EL3. Call the handler for async EA which will eret back to
+	 * original el3 handler if it is nested exception. Also, unmask EA so that we
+	 * catch any further EA arise when handling this nested exception at EL3.
 	 */
-	/* Assumes SP_EL3 on entry */
 	save_x30
-	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	cbnz	x30, 1f
-
-	/* Handle asynchronous external abort from lower EL */
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	cbz	x30, 1f
+	/*
+	 * This is nested exception handling, clear the flag to avoid taking this
+	 * path for further exceptions caused by EA handling
+	 */
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	unmask_async_ea
 	b	handle_lower_el_async_ea
 1:
+	restore_x30
 #endif
 	no_ret	plat_handle_el3_ea
+
 end_vector_entry serror_sp_elx
 
 	/* ---------------------------------------------------------------------
@@ -248,34 +228,41 @@
 	 */
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	b 	handle_interrupt_exception
 end_vector_entry fiq_aarch64
 
+	/*
+	 * Need to synchronize any outstanding SError since we can get a burst of errors.
+	 * So reuse the sync mechanism to catch any further errors which are pending.
+	 */
 vector_entry serror_aarch64
+#if FFH_SUPPORT
 	save_x30
 	apply_at_speculative_wa
-#if RAS_FFH_SUPPORT
-	msr	daifclr, #DAIF_ABT_BIT
+	sync_and_handle_pending_serror
+	unmask_async_ea
+	b	handle_lower_el_async_ea
 #else
-	check_and_unmask_ea
+	b	report_unhandled_exception
 #endif
-	b	handle_lower_el_async_ea
-
 end_vector_entry serror_aarch64
 
 	/* ---------------------------------------------------------------------
@@ -291,34 +278,41 @@
 	 */
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
 	save_x30
 	apply_at_speculative_wa
-	check_and_unmask_ea
+	sync_and_handle_pending_serror
+	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry fiq_aarch32
 
+	/*
+	 * Need to synchronize any outstanding SError since we can get a burst of errors.
+	 * So reuse the sync mechanism to catch any further errors which are pending.
+	 */
 vector_entry serror_aarch32
+#if FFH_SUPPORT
 	save_x30
 	apply_at_speculative_wa
-#if RAS_FFH_SUPPORT
-	msr	daifclr, #DAIF_ABT_BIT
+	sync_and_handle_pending_serror
+	unmask_async_ea
+	b	handle_lower_el_async_ea
 #else
-	check_and_unmask_ea
+	b	report_unhandled_exception
 #endif
-	b	handle_lower_el_async_ea
-
 end_vector_entry serror_aarch32
 
 #ifdef MONITOR_TRAPS
@@ -608,6 +602,114 @@
 	b	el3_exit
 endfunc handle_interrupt_exception
 
+func imp_def_el3_handler
+	/* Save GP registers */
+	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+
+	/* Get the cpu_ops pointer */
+	bl	get_cpu_ops_ptr
+
+	/* Get the cpu_ops exception handler */
+	ldr	x0, [x0, #CPU_E_HANDLER_FUNC]
+
+	/*
+	 * If the reserved function pointer is NULL, this CPU does not have an
+	 * implementation defined exception handler function
+	 */
+	cbz	x0, el3_handler_exit
+	mrs	x1, esr_el3
+	ubfx	x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	blr	x0
+el3_handler_exit:
+	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	restore_x30
+	no_ret	report_unhandled_exception
+endfunc imp_def_el3_handler
+
+/*
+ * Handler for async EA from lower EL synchronized at EL3 entry in KFH mode.
+ *
+ * This scenario may arise when there is an error (EA) in the system which is not
+ * yet signaled to PE while executing in lower EL. During entry into EL3, the errors
+ * are synchronized either implicitly or explicitly causing async EA to pend at EL3.
+ *
+ * On detecting the pending EA (via ISR_EL1.A) and if the EA routing model is
+ * KFH (SCR_EL3.EA = 1) this handler reflects ther error back to lower EL.
+ *
+ * This function assumes x30 has been saved.
+ */
+func reflect_pending_async_ea_to_lower_el
+	/*
+	 * As the original exception was not handled we need to ensure that we return
+	 * back to the instruction which caused the exception. To acheive that, eret
+	 * to "elr-4" (Label "subtract_elr_el3") for SMC or simply eret otherwise
+	 * (Label "skip_smc_check").
+	 *
+	 * LIMITATION: It could be that async EA is masked at the target exception level
+	 * or the priority of async EA wrt to the EL3/secure interrupt is lower, which
+	 * causes back and forth between lower EL and EL3. In case of back and forth between
+	 * lower EL and EL3, we can track the loop count in "CTX_NESTED_EA_FLAG" and leverage
+	 * previous ELR in "CTX_SAVED_ELR_EL3" to detect this cycle and further panic
+	 * to indicate a problem here (Label "check_loop_ctr"). If we are in this cycle, loop
+	 * counter retains its value but if we do a normal el3_exit this flag gets cleared.
+	 * However, setting SCR_EL3.IESB = 1, should give priority to SError handling
+	 * as per AArch64.TakeException pseudo code in Arm ARM.
+	 *
+	 * TODO: In future if EL3 gets a capability to inject a virtual SError to lower
+	 * ELs, we can remove the el3_panic and handle the original exception first and
+	 * inject SError to lower EL before ereting back.
+	 */
+	stp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	ldr	x29, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
+	mrs	x28, elr_el3
+	cmp	x29, x28
+	b.eq	check_loop_ctr
+	str	x28, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
+	/* Zero the loop counter */
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	b	skip_loop_ctr
+check_loop_ctr:
+	ldr	x29, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	add	x29, x29, #1
+	str	x29, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
+	cmp	x29, #ASYNC_EA_REPLAY_COUNTER
+	b.ge	el3_panic
+skip_loop_ctr:
+	/*
+	 * Logic to distinguish if we came from SMC or any other exception.
+	 * Use offsets in vector entry to get which exception we are handling.
+	 * In each vector entry of size 0x200, address "0x0-0x80" is for sync
+	 * exception and "0x80-0x200" is for async exceptions.
+	 * Use vector base address (vbar_el3) and exception offset (LR) to
+	 * calculate whether the address we came from is any of the following
+	 * "0x0-0x80", "0x200-0x280", "0x400-0x480" or "0x600-0x680"
+	 */
+	mrs	x29, vbar_el3
+	sub	x30, x30, x29
+	and	x30, x30, #0x1ff
+	cmp	x30, #0x80
+	b.ge	skip_smc_check
+	/* Its a synchronous exception, Now check if it is SMC or not? */
+	mrs	x30, esr_el3
+	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x30, #EC_AARCH32_SMC
+	b.eq	subtract_elr_el3
+	cmp	x30, #EC_AARCH64_SMC
+	b.eq	subtract_elr_el3
+	b	skip_smc_check
+subtract_elr_el3:
+	sub	x28, x28, #4
+skip_smc_check:
+	msr	elr_el3, x28
+	ldp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	exception_return
+endfunc reflect_pending_async_ea_to_lower_el
+
 	/* ---------------------------------------------------------------------
 	 * The following code handles exceptions caused by BRK instructions.
 	 * Following a BRK instruction, the only real valid cause of action is
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index a1fc12b..3359526 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -39,7 +39,6 @@
 				bl31/interrupt_mgmt.c				\
 				bl31/aarch64/bl31_entrypoint.S			\
 				bl31/aarch64/crash_reporting.S			\
-				bl31/aarch64/ea_delegate.S			\
 				bl31/aarch64/runtime_exceptions.S		\
 				bl31/bl31_context_mgmt.c			\
 				bl31/bl31_traps.c				\
@@ -67,6 +66,10 @@
 BL31_SOURCES		+=	bl31/ehf.c
 endif
 
+ifeq (${FFH_SUPPORT},1)
+BL31_SOURCES		+=	bl31/aarch64/ea_delegate.S
+endif
+
 ifeq (${SDEI_SUPPORT},1)
 ifeq (${EL3_EXCEPTION_HANDLING},0)
   $(error EL3_EXCEPTION_HANDLING must be 1 for SDEI support)
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 3d2783d..5e7f630 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -25,6 +25,18 @@
          code freeze       ver w.x       code freeze     ver y.z
 
 
+Version numbering
+~~~~~~~~~~~~~~~~~
+TF-A version is given in Makefile, through several macros:
+
+- VERSION_MAJOR
+- VERSION_MINOR
+- VERSION_PATCH
+
+For example, TF-A v2.10 has VERSION_MAJOR=2, VERSION_MINOR=10 and VERSION_PATCH=0.
+
+This VERSION_PATCH macro is only increased for LTS releases.
+
 Upcoming Releases
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 8d00345..747367a 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -10,6 +10,9 @@
 Reference Manual and `RAS Supplement`_. The rest of this document assumes
 familiarity with architecture and terminology.
 
+**IMPORTANT NOTE**: TF-A implementation assumes that if RAS extension is present
+then FEAT_IESB is also implmented.
+
 There are two philosophies for handling RAS errors from Non-secure world point
 of view.
 
@@ -56,26 +59,87 @@
 EA's originating/attributed to NS world are handled first in NS and Kernel navigates
 the std error records directly.
 
+-  KFH is the default handling mode if platform does not explicitly enable FFH mode.
+-  KFH mode does not need any EL3 involvement except for the reflection of errors back
+   to lower EL. This happens when there is an error (EA) in the system which is not yet
+   signaled to PE while executing at lower EL. During entry into EL3 the errors (EA) are
+   synchronized causing async EA to pend at EL3.
+
+Error Syncronization at EL3 entry
+=================================
+
+During entry to EL3 from lower EL, if there is any pending async EAs they are either
+reflected back to lower EL (KFH) or handled in EL3 itself (FFH).
+
-**KFH can be supported in a platform without TF-A being aware of it but there are few
-corner cases where TF-A needs to have special handling, which is currently missing and
-will be added in future**
+|Image 1|
 
 TF-A build options
 ==================
 
-- **ENABLE_FEAT_RAS**: Manage FEAT_RAS extension when switching the world.
-- **RAS_FFH_SUPPORT**: Pull in necessary framework and platform hooks for Firmware first
-  handling(FFH) of RAS errors.
+- **ENABLE_FEAT_RAS**: Enable RAS extension feature at EL3.
+- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH
 - **RAS_TRAP_NS_ERR_REC_ACCESS**: Trap Non-secure access of RAS error record registers.
-- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and RAS_FFH_SUPPORT
-  put together.
+- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and
+  HANDLE_EA_EL3_FIRST_NS put together.
+
+RAS internal macros
+
+- **FFH_SUPPORT**: Gets enabled if **HANDLE_EA_EL3_FIRST_NS** is enabled.
 
 RAS feature has dependency on some other TF-A build flags
 
 - **EL3_EXCEPTION_HANDLING**: Required for FFH
-- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH
 - **FAULT_INJECTION_SUPPORT**: Required for testing RAS feature on fvp platform
 
+TF-A Tests
+==========
+
+RAS functionality is regularly tested in TF-A CI using `RAS test group`_ which has multiple
+configurations for testing lower EL External aborts.
+
+All the tests are written in TF-A tests which runs as NS-EL2 payload.
+
+- **FFH without RAS extension**
+
+  *fvp-ea-ffh,fvp-ea-ffh:fvp-tftf-fip.tftf-aemv8a-debug*
+
+   Couple of tests, one each for sync EA and async EA from lower EL which gets handled in El3.
+   Inject External aborts(sync/async) which traps in EL3, FVP has a handler which gracefully
+   handles these errors and returns back to TF-A Tests
+
+   Build Configs : **HANDLE_EA_EL3_FIRST_NS** , **PLATFORM_TEST_EA_FFH**
+
+- **FFH with RAS extension**
+
+  Three Tests :
+
+  - *fvp-ras-ffh,fvp-single-fault:fvp-tftf-fip.tftf-aemv8a.fi-debug*
+
+    Inject an unrecoverable RAS error, which gets handled in EL3.
+
+  - *fvp-ras-ffh,fvp-uncontainable:fvp-tftf.fault-fip.tftf-aemv8a.fi-debug*
+
+    Inject uncontainable RAS errors which causes platform to panic.
+
+  - *fvp-ras-ffh,fvp-ras-ffh-nested:fvp-tftf-fip.tftf-ras_ffh_nested-aemv8a.fi-debug*
+
+    Test nested exception handling at El3 for synchronized async EAs. Inject an SError in lower EL
+    which remain pending until we enter EL3 through SMC call. At EL3 entry on encountering a pending
+    async EA it will handle the async EA first (nested exception) before handling the original SMC call.
+
+-  **KFH with RAS extension**
+
+  Couple of tests in the group :
+
+  - *fvp-ras-kfh,fvp-ras-kfh:fvp-tftf-fip.tftf-aemv8a.fi-debug*
+
+    Inject and handle RAS errors in TF-A tests (no El3 involvement)
+
+  - *fvp-ras-kfh,fvp-ras-kfh-reflect:fvp-tftf-fip.tftf-ras_kfh_reflection-aemv8a.fi-debug*
+
+    Reflection of synchronized errors from EL3 to TF-A tests, two tests one each for reflecting
+    in IRQ and SMC path.
+
 RAS Framework
 =============
 
@@ -238,7 +302,7 @@
 Enabling RAS support is a platform choice
 
 The RAS support in |TF-A| introduces a default implementation of
-``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_FFH_SUPPORT``
+``plat_ea_handler``, the External Abort handler in EL3. When ``ENABLE_FEAT_RAS``
 is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
 top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
 to through platform-supplied error records, probe them, and when an error is
@@ -277,3 +341,6 @@
 *Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _RAS Supplement: https://developer.arm.com/documentation/ddi0587/latest
+.. _RAS Test group: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/group/tf-l3-boot-tests-ras?h=refs/heads/master
+
+.. |Image 1| image:: ../resources/diagrams/bl31-exception-entry-error-synchronization.png
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 146026b..d03daf8 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -612,6 +612,10 @@
    interconnect IP. This needs to be enabled for r0p0, r1p0, r2p0 and r2p1 and
    is still open.
 
+-  ``ERRATA_A710_2742423``: This applies errata 2742423 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
+   r2p1 of the CPU and is still open.
+
 -  ``ERRATA_A710_2768515``: This applies errata 2768515 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
    r2p1 of the CPU and is still open.
@@ -655,6 +659,14 @@
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
+-  ``ERRATA_N2_2340933``: This applies errata 2340933 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+   r0p1.
+
+-  ``ERRATA_N2_2346952``: This applies errata 2346952 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2 of the CPU,
+   it is fixed in r0p3.
+
 -  ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0, r0p1, r0p2, r0p3 and is still open.
 
@@ -721,6 +733,10 @@
    This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 and is
    still open.
 
+-  ``ERRATA_X2_2742423``: This applies errata 2742423 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
+
 -  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and is still open.
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 879ddda..ff69b43 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1118,6 +1118,65 @@
    ``bl31_main()`` will set up the return to the normal world firmware BL33 and
    continue the boot process in the normal world.
 
+Exception handling in BL31
+--------------------------
+
+When exception occurs, PE must execute handler corresponding to exception. The
+location in memory where the handler is stored is called the exception vector.
+For ARM architecture, exception vectors are stored in a table, called the exception
+vector table.
+
+Each EL (except EL0) has its own vector table, VBAR_ELn register stores the base
+of vector table. Refer to `AArch64 exception vector table`_
+
+Current EL with SP_EL0
+~~~~~~~~~~~~~~~~~~~~~~
+
+-  Sync exception : Not expected except for BRK instruction, its debugging tool which
+   a programmer may place at specific points in a program, to check the state of
+   processor flags at these points in the code.
+
+-  IRQ/FIQ : Unexpected exception, panic
+
+-  SError : "plat_handle_el3_ea", defaults to panic
+
+Current EL with SP_ELx
+~~~~~~~~~~~~~~~~~~~~~~
+
+-  Sync exception : Unexpected exception, panic
+
+-  IRQ/FIQ : Unexpected exception, panic
+
+-  SError : "plat_handle_el3_ea" Except for special handling of lower EL's SError exception
+   which gets triggered in EL3 when PSTATE.A is unmasked. Its only applicable when lower
+   EL's EA is routed to EL3 (FFH_SUPPORT=1).
+
+Lower EL Exceptions
+~~~~~~~~~~~~~~~~~~~
+
+Applies to all the exceptions in both AArch64/AArch32 mode of lower EL.
+
+Before handling any lower EL exception, we synchronize the errors at EL3 entry to ensure
+that any errors pertaining to lower EL is isolated/identified. If we continue without
+identifying these errors early on then these errors will trigger in EL3 (as SError from
+current EL) any time after PSTATE.A is unmasked. This is wrong because the error originated
+in lower EL but exception happened in EL3.
+
+To solve this problem, synchronize the errors at EL3 entry and check for any pending
+errors (async EA). If there is no pending error then continue with original exception.
+If there is a pending error then, handle them based on routing model of EA's. Refer to
+:ref:`Reliability, Availability, and Serviceability (RAS) Extensions` for details about
+routing models.
+
+-  KFH : Reflect it back to lower EL using **reflect_pending_async_ea_to_lower_el()**
+
+-  FFH : Handle the synchronized error first using **handle_pending_async_ea()** after
+   that continue with original exception. It is the only scenario where EL3 is capable
+   of doing nested exception handling.
+
+After synchronizing and handling lower EL SErrors, unmask EA (PSTATE.A) to ensure
+that any further EA's caused by EL3 are caught.
+
 Crash Reporting in BL31
 -----------------------
 
@@ -2803,5 +2862,6 @@
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
 .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
 .. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
+.. _AArch64 exception vector table: https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table
 
 .. |Image 1| image:: ../resources/diagrams/rt-svc-descs-layout.png
diff --git a/docs/getting_started/build-internals.rst b/docs/getting_started/build-internals.rst
index a015d71..390c367 100644
--- a/docs/getting_started/build-internals.rst
+++ b/docs/getting_started/build-internals.rst
@@ -12,3 +12,10 @@
    interest when Armv8.4-SecEL2 or RME extension is implemented.
    Default is 0 (disabled). This option will be set to 1 (enabled) when ``SPD=spmd``
    and ``SPMD_SPM_AT_SEL2`` is set or when ``ENABLE_RME`` is set to 1 (enabled).
+
+- ``FFH_SUPPORT``: This boolean option provides support to enable Firmware First
+  handling (FFH) of External aborts and SError interrupts originating from lower
+  ELs which gets trapped in EL3. This option will be set to 1 (enabled) if
+  ``HANDLE_EA_EL3_FIRST_NS`` is set. Currently only NS world routes EA to EL3 but
+  in future when Secure/Realm wants to use FFH then they can introduce new macros
+  which will enable this option implicitly.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 347cf20..43b13d6 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -811,14 +811,12 @@
 -  ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI
    OS-initiated mode. This option defaults to 0.
 
--  ``ENABLE_FEAT_RAS``: Numeric value to enable Armv8.2 RAS features. RAS features
+-  ``ENABLE_FEAT_RAS``: Boolean flag to enable Armv8.2 RAS features. RAS features
    are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
-   or later CPUs. This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism.
-
--  ``RAS_FFH_SUPPORT``: Support to enable Firmware first handling of RAS errors
-   originating from NS world. When ``RAS_FFH_SUPPORT`` is set to ``1``,
-   ``HANDLE_EA_EL3_FIRST_NS`` and ``ENABLE_FEAT_RAS`` must also be set to ``1``.
+   or later CPUs. This flag can take the values 0 or 1. The default value is 0.
+   NOTE: This flag enables use of IESB capability to reduce entry latency into
+   EL3 even when RAS error handling is not performed on the platform. Hence this
+   flag is recommended to be turned on Armv8.2 and later CPUs.
 
 -  ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
    of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index fc3effd..f135ca2 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -73,9 +73,9 @@
 +----------------+----------------+--------------------+--------------------+
 |    mt6795      |      MTK       |        2.5         |       2.7          |
 +----------------+----------------+--------------------+--------------------+
-|    sgi575      |      Arm       |        2.8         |       2.10         |
+|    sgi575      |      Arm       |        2.8         |       TBD          |
 +----------------+----------------+--------------------+--------------------+
-|    rdn1edge    |      Arm       |        2.8         |       2.10         |
+|    rdn1edge    |      Arm       |        2.8         |       TBD          |
 +----------------+----------------+--------------------+--------------------+
 |    tc0         |      Arm       |        2.8         |       2.10         |
 +----------------+----------------+--------------------+--------------------+
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 5d04639..1db7695 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -14,6 +14,11 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
 ```
 
+To build bl32 TSP you have to rebuild bl31 too
+```bash
+make CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net SPD=tspd RESET_TO_BL31=1 bl31 bl32
+```
+
 To build TF-A for JTAG DCC console:
 ```bash
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index 09a6ee2..b71776d 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -19,6 +19,11 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
 ```
 
+To build bl32 TSP you have to rebuild bl31 too
+```bash
+make CROSS_COMPILE=aarch64-none-elf- PLAT=versal SPD=tspd RESET_TO_BL31=1 bl31 bl32
+```
+
 To build TF-A for JTAG DCC console
 ```bash
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 VERSAL_CONSOLE=dcc
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index f612e1c..082497c 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -3298,10 +3298,10 @@
     Argument : uint64_t
     Return   : void
 
-This function is invoked by the RAS framework for the platform to handle an
-External Abort received at EL3. The intention of the function is to attempt to
-resolve the cause of External Abort and return; if that's not possible, to
-initiate orderly shutdown of the system.
+This function is invoked by the runtime exception handling framework for the
+platform to handle an External Abort received at EL3. The intention of the
+function is to attempt to resolve the cause of External Abort and return;
+if that's not possible then an orderly shutdown of the system is initiated.
 
 The first parameter (``int ea_reason``) indicates the reason for External Abort.
 Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``.
@@ -3316,13 +3316,8 @@
 (``uint64_t flags``) indicates the preempted security state. These parameters
 are received from the top-level exception handler.
 
-If ``RAS_FFH_SUPPORT`` is set to ``1``, the default implementation of this
-function iterates through RAS handlers registered by the platform. If any of the
-RAS handlers resolve the External Abort, no further action is taken.
-
-If ``RAS_FFH_SUPPORT`` is set to ``0``, or if none of the platform RAS handlers
-could resolve the External Abort, the default implementation prints an error
-message, and panics.
+This function must be implemented if a platform expects Firmware First handling
+of External Aborts.
 
 Function : plat_handle_uncontainable_ea
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png b/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png
new file mode 100644
index 0000000..cdfdcb9
--- /dev/null
+++ b/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png
Binary files differ
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 83e94ca..3ba86e9 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -120,6 +120,14 @@
 	.endm
 #endif
 
+	/* Macro for error synchronization */
+	.macro synchronize_errors
+	/* Complete any stores that may return an abort */
+	dsb	sy
+	/* Synchronise the CPU context with the completion of the dsb */
+	isb
+	.endm
+
 #if (ARM_ARCH_MAJOR == 7)
 	/* ARMv7 does not support stl instruction */
 	.macro stl _reg, _write_lock
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 13927bd..e9d22b6 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -962,6 +962,7 @@
 #define EC_AARCH64_HVC			U(0x16)
 #define EC_AARCH64_SMC			U(0x17)
 #define EC_AARCH64_SYS			U(0x18)
+#define EC_IMP_DEF_EL3			U(0x1f)
 #define EC_IABORT_LOWER_EL		U(0x20)
 #define EC_IABORT_CUR_EL		U(0x21)
 #define EC_PC_ALIGN			U(0x22)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 6091f62..d09ad0f 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -292,4 +292,29 @@
 #endif
 	.endm
 
+	/*
+	 * Macro to unmask External Aborts by changing PSTATE.A bit.
+	 * Put explicit synchronization event to ensure newly unmasked interrupt
+	 * is taken immediately.
+	 */
+	.macro  unmask_async_ea
+	msr     daifclr, #DAIF_ABT_BIT
+	isb
+	.endm
+
+	/* Macro for error synchronization on exception boundries.
+	 * With FEAT_RAS enabled, it is assumed that FEAT_IESB is also present
+	 * and enabled.
+	 * FEAT_IESB provides an implicit error synchronization event at exception
+	 * entry and exception return, so there is no need for any explicit instruction.
+	 */
+	.macro synchronize_errors
+#if !ENABLE_FEAT_RAS
+	/* Complete any stores that may return an abort */
+	dsb	sy
+	/* Synchronise the CPU context with the completion of the dsb */
+	isb
+#endif
+	.endm
+
 #endif /* ASM_MACROS_S */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 9c9c00f..a78837f 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -208,6 +208,10 @@
 		 */
 		mov_imm	x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
 				| SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
+#if ENABLE_FEAT_RAS
+		/* If FEAT_RAS is present assume FEAT_IESB is also present */
+		orr	x0, x0, #SCTLR_IESB_BIT
+#endif
 		msr	sctlr_el3, x0
 		isb
 	.endif /* _init_sctlr */
diff --git a/include/bl31/ea_handle.h b/include/bl31/ea_handle.h
index 68f012c..7cd7b6a 100644
--- a/include/bl31/ea_handle.h
+++ b/include/bl31/ea_handle.h
@@ -21,4 +21,6 @@
 /* RAS event signalled as peripheral interrupt */
 #define ERROR_INTERRUPT		3
 
+#define ASYNC_EA_REPLAY_COUNTER	U(100)
+
 #endif /* EA_HANDLE_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 0d50854..b379fab 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,5 +65,8 @@
 #define NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV		ULL(9)
 #define CPUECTLR2_EL1_PF_MODE_LSB			U(11)
 #define CPUECTLR2_EL1_PF_MODE_WIDTH			U(4)
+#define CPUECTLR2_EL1_TXREQ_STATIC_FULL 		ULL(0)
+#define CPUECTLR2_EL1_TXREQ_LSB				U(0)
+#define CPUECTLR2_EL1_TXREQ_WIDTH			U(3)
 
 #endif /* NEOVERSE_N2_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 470d113..47d91de 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -63,7 +63,22 @@
 #define CTX_PMCR_EL0		U(0x28)
 #define CTX_IS_IN_EL3		U(0x30)
 #define CTX_MPAM3_EL3		U(0x38)
-#define CTX_EL3STATE_END	U(0x40) /* Align to the next 16 byte boundary */
+/* Constants required in supporting nested exception in EL3 */
+#define CTX_SAVED_ELR_EL3	U(0x40)
+/*
+ * General purpose flag, to save various EL3 states
+ * FFH mode : Used to identify if handling nested exception
+ * KFH mode : Used as counter value
+ */
+#define CTX_NESTED_EA_FLAG	U(0x48)
+#if FFH_SUPPORT
+ #define CTX_SAVED_ESR_EL3	U(0x50)
+ #define CTX_SAVED_SPSR_EL3	U(0x58)
+ #define CTX_SAVED_GPREG_LR	U(0x60)
+ #define CTX_EL3STATE_END	U(0x70) /* Align to the next 16 byte boundary */
+#else
+ #define CTX_EL3STATE_END	U(0x50) /* Align to the next 16 byte boundary */
+#endif
 
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 314eb93..9176e88 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -774,7 +774,7 @@
 #define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
 
 /* Priority levels for ARM platforms */
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 #define PLAT_RAS_PRI			0x10
 #endif
 #define PLAT_SDEI_CRITICAL_PRI		0x60
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index c618d98..f3931d7 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -178,6 +178,14 @@
 
 check_erratum_ls cortex_a710, ERRATUM(2371105), CPU_REV(2, 0)
 
+workaround_reset_start cortex_a710, ERRATUM(2742423), ERRATA_A710_2742423
+	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+	sysreg_bit_set CORTEX_A710_CPUACTLR5_EL1, BIT(55)
+	sysreg_bit_clear CORTEX_A710_CPUACTLR5_EL1, BIT(56)
+workaround_reset_end cortex_a710, ERRATUM(2742423)
+
+check_erratum_ls cortex_a710, ERRATUM(2742423), CPU_REV(2, 1)
+
 workaround_runtime_start cortex_a710, ERRATUM(2768515), ERRATA_A710_2768515
 	/* dsb before isb of power down sequence */
 	dsb	sy
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 855d196..258288c 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -118,6 +118,14 @@
 
 check_erratum_ls cortex_x2, ERRATUM(2371105), CPU_REV(2, 0)
 
+workaround_reset_start cortex_x2, ERRATUM(2742423), ERRATA_X2_2742423
+	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+	sysreg_bit_set CORTEX_X2_CPUACTLR5_EL1, BIT(55)
+	sysreg_bit_clear CORTEX_X2_CPUACTLR5_EL1, BIT(56)
+workaround_reset_end cortex_x2, ERRATUM(2742423)
+
+check_erratum_ls cortex_x2, ERRATUM(2742423), CPU_REV(2, 1)
+
 workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
 	/* dsb before isb of power down sequence */
 	dsb	sy
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index ead3908..477522f 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -165,6 +165,23 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2326639), CPU_REV(0, 0)
 
+workaround_runtime_start neoverse_n2, ERRATUM(2340933), ERRATA_N2_2340933
+	/* Set bit 61 in CPUACTLR5_EL1 */
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, BIT(61)
+workaround_runtime_end neoverse_n2, ERRATUM(2340933)
+
+check_erratum_ls neoverse_n2, ERRATUM(2340933), CPU_REV(0, 0)
+
+workaround_runtime_start neoverse_n2, ERRATUM(2346952), ERRATA_N2_2346952
+	/* Set TXREQ to STATIC and full L2 TQ size */
+	mrs	x1, NEOVERSE_N2_CPUECTLR2_EL1
+	mov	x0, #CPUECTLR2_EL1_TXREQ_STATIC_FULL
+	bfi	x1, x0, #CPUECTLR2_EL1_TXREQ_LSB, #CPUECTLR2_EL1_TXREQ_WIDTH
+	msr	NEOVERSE_N2_CPUECTLR2_EL1, x1
+workaround_runtime_end neoverse_n2, ERRATUM(2346952)
+
+check_erratum_ls neoverse_n2, ERRATUM(2346952), CPU_REV(0, 2)
+
 workaround_reset_start neoverse_n2, ERRATUM(2376738), ERRATA_N2_2376738
 	/* Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM
 	 * ST to behave like PLD/PFRM LD and not cause
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index ea29047..434ee08 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -607,6 +607,11 @@
 # and is still open.
 CPU_FLAG_LIST += ERRATA_A710_2701952
 
+# Flag to apply erratum 2742423 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
+# open.
+CPU_FLAG_LIST += ERRATA_A710_2742423
+
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is
 # still open.
@@ -656,10 +661,18 @@
 # to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2280757
 
-# Flag to apply erraturm 2326639 workaroud during powerdown. This erratum
+# Flag to apply erratum 2326639 workaroud during powerdown. This erratum
 # applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2326639
 
+# Flag to apply erratum 2340933 workaroud during reset. This erratum
+# applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_N2_2340933
+
+# Flag to apply erratum 2346952 workaround during reset. This erratum applies
+# to r0p0, r0p1, r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
+CPU_FLAG_LIST += ERRATA_N2_2346952
+
 # Flag to apply erratum 2376738 workaround during reset. This erratum applies
 # to revision r0p0, r0p1, r0p2, r0p3 of the Neoverse N2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_N2_2376738
@@ -730,6 +743,10 @@
 # and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2701952
 
+# Flag to apply erratum 2742423 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_X2_2742423
+
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is
 # still open.
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 41b25d6..631094f 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -649,23 +649,9 @@
 1:
 #endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
 
-/*
- * This is a hot path, so we don't want to do some actual FEAT_RAS runtime
- * detection here. The "esb" is a cheaper variant, so using "dsb" in the
- * ENABLE_FEAT_RAS==2 case is not ideal, but won't hurt.
- */
-#if IMAGE_BL31 && ENABLE_FEAT_RAS == 1
-	/* ----------------------------------------------------------
-	 * Issue Error Synchronization Barrier to synchronize SErrors
-	 * before exiting EL3. We're running with EAs unmasked, so
-	 * any synchronized errors would be taken immediately;
-	 * therefore no need to inspect DISR_EL1 register.
- 	 * ----------------------------------------------------------
-	 */
-	esb
-#else
-	dsb	sy
-#endif /* IMAGE_BL31 && ENABLE_FEAT_RAS */
+#if IMAGE_BL31
+	synchronize_errors
+#endif /* IMAGE_BL31 */
 
 	/* ----------------------------------------------------------
 	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
@@ -689,7 +675,8 @@
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 
 #ifdef IMAGE_BL31
-	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
+	/* Clear the EL3 flag as we are exiting el3 */
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
 #endif /* IMAGE_BL31 */
 
 	exception_return
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index ea22655..e02917c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -191,9 +191,6 @@
 # Enable PSCI OS-initiated mode support
 PSCI_OS_INIT_MODE		:= 0
 
-# Enable RAS Firmware First Handling Support
-RAS_FFH_SUPPORT			:= 0
-
 # By default, BL1 acts as the reset handler, not BL31
 RESET_TO_BL31			:= 0
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index f7c174f..2fdff34 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -56,7 +56,6 @@
 	ENABLE_FEAT_RNG			:= 2
 	ENABLE_FEAT_TWED		:= 2
 	ENABLE_FEAT_GCS			:= 2
-	ENABLE_FEAT_RAS			:= 2
 ifeq (${ARCH}, aarch64)
 ifneq (${SPD}, spmd)
 ifeq (${SPM_MM}, 0)
@@ -398,8 +397,12 @@
 endif
 endif
 
-ifeq (${RAS_FFH_SUPPORT},1)
+ifeq (${HANDLE_EA_EL3_FIRST_NS},1)
+ifeq (${ENABLE_FEAT_RAS},1)
 BL31_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_ras.c
+else
+BL31_SOURCES		+= 	plat/arm/board/fvp/aarch64/fvp_ea.c
+endif
 endif
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
@@ -519,16 +522,19 @@
 # Test specific macros, keep them at bottom of this file
 $(eval $(call add_define,PLATFORM_TEST_EA_FFH))
 ifeq (${PLATFORM_TEST_EA_FFH}, 1)
-    ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
-         $(error "PLATFORM_TEST_EA_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
+    ifeq (${FFH_SUPPORT}, 0)
+         $(error "PLATFORM_TEST_EA_FFH expects FFH_SUPPORT to be 1")
     endif
-BL31_SOURCES	+= plat/arm/board/fvp/aarch64/fvp_ea.c
+
 endif
 
 $(eval $(call add_define,PLATFORM_TEST_RAS_FFH))
 ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
-    ifeq (${RAS_EXTENSION}, 0)
-         $(error "PLATFORM_TEST_RAS_FFH expects RAS_EXTENSION to be 1")
+    ifeq (${ENABLE_FEAT_RAS}, 0)
+         $(error "PLATFORM_TEST_RAS_FFH expects ENABLE_FEAT_RAS to be 1")
+    endif
+    ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
+         $(error "PLATFORM_TEST_RAS_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
     endif
 endif
 
diff --git a/plat/arm/board/morello/fdts/morello_nt_fw_config.dts b/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
index e730d34..6ec282d 100644
--- a/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,4 +23,19 @@
 		scc-config = <0x0>;
 #endif
 	};
+
+	/*
+	 * Placeholder for firmware-version node with default values.
+	 * The value will be set to the correct values during
+	 * the BL2 stage of boot.
+	 */
+	firmware-version {
+#ifdef TARGET_PLATFORM_SOC
+		mcc-fw-version = <0x0>;
+		pcc-fw-version = <0x0>;
+#endif
+		scp-fw-version = <0x0>;
+		scp-fw-commit = <0x0>;
+		tfa-fw-version = "unknown-dirty_00000000";
+	};
 };
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index e42a03c..25122e6 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -15,6 +15,15 @@
 						MORELLO_NS_SRAM_SIZE,	\
 						MT_DEVICE | MT_RW | MT_SECURE)
 
+/* SDS Firmware version defines */
+#define MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID	U(2)
+#define MORELLO_SDS_FIRMWARE_VERSION_OFFSET	U(0)
+#ifdef TARGET_PLATFORM_FVP
+# define MORELLO_SDS_FIRMWARE_VERSION_SIZE	U(8)
+#else
+# define MORELLO_SDS_FIRMWARE_VERSION_SIZE	U(16)
+#endif
+
 /* SDS Platform information defines */
 #define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID	U(8)
 #define MORELLO_SDS_PLATFORM_INFO_OFFSET	U(0)
@@ -122,8 +131,40 @@
 } __packed;
 #endif
 
-/* Compile time assertion to ensure the size of structure is of the required bytes */
+/* SDS Firmware revision struct definition */
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Firmware revision structure stored in SDS.
+ * This structure holds information about firmware versions.
+ *	- SCP firmware version
+ *	- SCP firmware commit
+ */
+struct morello_firmware_version {
+	uint32_t scp_fw_ver;
+	uint32_t scp_fw_commit;
+} __packed;
+#else
+/*
+ * Firmware revision structure stored in SDS.
+ * This structure holds information about firmware versions.
+ *	- SCP firmware version
+ *	- SCP firmware commit
+ *	- MCC firmware version
+ *	- PCC firmware version
+ */
+struct morello_firmware_version {
+	uint32_t scp_fw_ver;
+	uint32_t scp_fw_commit;
+	uint32_t mcc_fw_ver;
+	uint32_t pcc_fw_ver;
+} __packed;
+#endif
+
+/* Compile time assertions to ensure the size of structures are of the required bytes */
 CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
 		assert_invalid_plat_info_size);
 
+CASSERT(sizeof(struct morello_firmware_version) == MORELLO_SDS_FIRMWARE_VERSION_SIZE,
+		assert_invalid_firmware_version_size);
+
 #endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index b5d9bd5..4ea2bb3 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -23,7 +23,8 @@
 }
 
 /*******************************************************************************
- * This function inserts Platform information via device tree nodes as,
+ * This function inserts Platform information and firmware versions
+ * via device tree nodes as,
  *	platform-info {
  *		local-ddr-size = <0x0 0x0>;
  *#ifdef TARGET_PLATFORM_SOC
@@ -33,12 +34,22 @@
  *		scc-config = <0x0>;
  *#endif
  *	};
+ *	firmware-version {
+ *#ifdef TARGET_PLATFORM_SOC
+ *		mcc-fw-version = <0x0>;
+ *		pcc-fw-version = <0x0>;
+ *#endif
+ *		scp-fw-version = <0x0>;
+ *		scp-fw-commit = <0x0>;
+ *		tfa-fw-version = "unknown-dirty_00000000";
+ *	};
  ******************************************************************************/
-static int plat_morello_append_config_node(struct morello_plat_info *plat_info)
+static int plat_morello_append_config_node(struct morello_plat_info *plat_info,
+				struct morello_firmware_version *fw_version)
 {
 	bl_mem_params_node_t *mem_params;
 	void *fdt;
-	int nodeoffset, err;
+	int nodeoffset_plat, nodeoffset_fw, err;
 	uint64_t usable_mem_size;
 
 	usable_mem_size = plat_info->local_ddr_size;
@@ -57,35 +68,41 @@
 		return -1;
 	}
 
-	nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info");
-	if (nodeoffset < 0) {
+	nodeoffset_plat = fdt_subnode_offset(fdt, 0, "platform-info");
+	if (nodeoffset_plat < 0) {
 		ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
 		return -1;
 	}
 
+	nodeoffset_fw = fdt_subnode_offset(fdt, 0, "firmware-version");
+	if (nodeoffset_fw < 0) {
+		ERROR("NT_FW_CONFIG: Failed to get firmware-version node offset\n");
+		return -1;
+	}
+
 #ifdef TARGET_PLATFORM_SOC
-	err = fdt_setprop_u64(fdt, nodeoffset, "remote-ddr-size",
+	err = fdt_setprop_u64(fdt, nodeoffset_plat, "remote-ddr-size",
 			plat_info->remote_ddr_size);
 	if (err < 0) {
 		ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
 		return -1;
 	}
 
-	err = fdt_setprop_u32(fdt, nodeoffset, "remote-chip-count",
+	err = fdt_setprop_u32(fdt, nodeoffset_plat, "remote-chip-count",
 			plat_info->remote_chip_count);
 	if (err < 0) {
 		ERROR("NT_FW_CONFIG: Failed to set remote-chip-count\n");
 		return -1;
 	}
 
-	err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode",
+	err = fdt_setprop_u32(fdt, nodeoffset_plat, "multichip-mode",
 			plat_info->multichip_mode);
 	if (err < 0) {
 		ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
 		return -1;
 	}
 
-	err = fdt_setprop_u32(fdt, nodeoffset, "scc-config",
+	err = fdt_setprop_u32(fdt, nodeoffset_plat, "scc-config",
 			plat_info->scc_config);
 	if (err < 0) {
 		ERROR("NT_FW_CONFIG: Failed to set scc-config\n");
@@ -95,8 +112,41 @@
 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
 		usable_mem_size = get_mem_client_mode(plat_info->local_ddr_size);
 	}
+
+	err = fdt_setprop_u32(fdt, nodeoffset_fw, "mcc-fw-version",
+			fw_version->mcc_fw_ver);
+	if (err < 0) {
+		ERROR("NT_FW_CONFIG: Failed to set mcc-fw-version\n");
+		return -1;
+	}
+
+	err = fdt_setprop_u32(fdt, nodeoffset_fw, "pcc-fw-version",
+			fw_version->pcc_fw_ver);
+	if (err < 0) {
+		ERROR("NT_FW_CONFIG: Failed to set pcc-fw-version\n");
+		return -1;
+	}
 #endif
-	err = fdt_setprop_u64(fdt, nodeoffset, "local-ddr-size",
+	err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-version",
+			fw_version->scp_fw_ver);
+	if (err < 0) {
+		ERROR("NT_FW_CONFIG: Failed to set scp-fw-version\n");
+		return -1;
+	}
+
+	err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-commit",
+			fw_version->scp_fw_commit);
+	if (err < 0) {
+		ERROR("NT_FW_CONFIG: Failed to set scp-fw-commit\n");
+		return -1;
+	}
+
+	err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", version_string);
+	if (err < 0) {
+		WARN("NT_FW_CONFIG: Unable to set tfa-fw-version\n");
+	}
+
+	err = fdt_setprop_u64(fdt, nodeoffset_plat, "local-ddr-size",
 			usable_mem_size);
 	if (err < 0) {
 		ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
@@ -115,6 +165,7 @@
 {
 	int ret;
 	struct morello_plat_info plat_info;
+	struct morello_firmware_version fw_version;
 
 	ret = sds_init();
 	if (ret != SDS_OK) {
@@ -132,6 +183,16 @@
 		panic();
 	}
 
+	ret = sds_struct_read(MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID,
+				MORELLO_SDS_FIRMWARE_VERSION_OFFSET,
+				&fw_version,
+				MORELLO_SDS_FIRMWARE_VERSION_SIZE,
+				SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Error getting firmware version from SDS. ret:%d\n", ret);
+		panic();
+	}
+
 	/* Validate plat_info SDS */
 #ifdef TARGET_PLATFORM_FVP
 	if (plat_info.local_ddr_size == 0U) {
@@ -146,7 +207,7 @@
 		panic();
 	}
 
-	ret = plat_morello_append_config_node(&plat_info);
+	ret = plat_morello_append_config_node(&plat_info, &fw_version);
 	if (ret != 0) {
 		panic();
 	}
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 1506714..ef8f3d4 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -69,7 +69,7 @@
 BL31_CFLAGS		+=	-DPLAT_XLAT_TABLES_DYNAMIC
 endif
 
-ifeq (${RAS_FFH_SUPPORT},1)
+ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
 BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
 				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
 				${CSS_ENT_BASE}/ras/sgi_ras_sram.c	\
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index f117456..2a6c658 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -137,7 +137,7 @@
 
 	sgi_bl31_common_platform_setup();
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	sgi_ras_platform_setup(&ras_config);
 #endif
 }
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
index b836a7f..7cd4a1c 100644
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -15,7 +15,7 @@
 
 static const arm_tzc_regions_info_t tzc_regions[] = {
 	ARM_TZC_REGIONS_DEF,
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	RDN2_TZC_CPER_REGION,
 #endif
 	{}
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 8ca33ca..8db6f1d 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -21,8 +21,6 @@
 
 ENABLE_FEAT_RAS		:=	1
 
-RAS_FFH_SUPPORT		:=	0
-
 SDEI_SUPPORT		:=	0
 
 EL3_EXCEPTION_HANDLING	:=	0
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index cfd1aac..f47bc3e 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -295,7 +295,7 @@
 	/* Initialize power controller before setting up topology */
 	plat_arm_pwrc_setup();
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	ras_init();
 #endif
 
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 421c8e9..bbb39d5 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -352,7 +352,7 @@
 endif
 
 # RAS sources
-ifeq (${RAS_FFH_SUPPORT},1)
+ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
 BL31_SOURCES		+=	lib/extensions/ras/std_err_record.c		\
 				lib/extensions/ras/ras_common.c
 endif
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 8c16877..5becbcd 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -41,7 +41,7 @@
 static const interrupt_prop_t arm_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0),
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	INTR_PROP_DESC(PLAT_CORE_FAULT_IRQ, PLAT_RAS_PRI, INTR_GROUP0,
 			GIC_INTR_CFG_LEVEL)
 #endif
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 8a13bf3..9dfe040 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -204,13 +204,13 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 #define PLAT_SP_PRI				PLAT_RAS_PRI
 #else
 #define PLAT_SP_PRI				0x10
 #endif
 
-#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && RAS_FFH_SUPPORT
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && ENABLE_FEAT_RAS && FFH_SUPPORT
 /*
  * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
  * memory shared between EL3 and S-EL0.
@@ -239,7 +239,7 @@
  */
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#endif /* SPM_MM && RAS_FFH_SUPPORT */
+#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
 
 /* Platform ID address */
 #define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 358316c..2cd7034 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -10,8 +10,6 @@
 
 ENABLE_FEAT_RAS			:=	1
 
-RAS_FFH_SUPPORT			:=	0
-
 SDEI_SUPPORT			:=	0
 
 EL3_EXCEPTION_HANDLING		:=	0
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 7f79d54..01b426e 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -93,7 +93,7 @@
 	PLAT_ARM_SECURE_MAP_DEVICE,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	CSS_SGI_SP_CPER_BUF_MMAP,
 #endif
 	ARM_SP_IMAGE_RW_MMAP,
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 85f99d4..624fed3 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -87,7 +87,7 @@
 	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	CSS_SGI_SP_CPER_BUF_MMAP,
 #endif
 	ARM_SP_IMAGE_RW_MMAP,
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index eca81b1..ab99b15 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -11,7 +11,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/console.h>
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 #include <lib/extensions/ras.h>
 #endif
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
@@ -29,7 +29,9 @@
 #pragma weak plat_sdei_validate_entry_point
 #endif
 
+#if FFH_SUPPORT
 #pragma weak plat_ea_handler = plat_default_ea_handler
+#endif
 
 void bl31_plat_runtime_setup(void)
 {
@@ -77,11 +79,12 @@
 	return "EL1";
 }
 
+#if FFH_SUPPORT
 /* Handler for External Aborts from lower EL including RAS errors */
 void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
 {
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	/* Call RAS EA handler */
 	int handled = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
 	if (handled != 0)
@@ -99,3 +102,4 @@
 	 */
 	lower_el_panic();
 }
+#endif
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index 41b175d..6100a20 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -12,7 +12,7 @@
  * Enumeration of priority levels on ARM platforms.
  */
 ehf_pri_desc_t plat_exceptions[] = {
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 	/* RAS Priority */
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI),
 #endif
@@ -26,7 +26,7 @@
 #endif
 
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 #if (PLAT_SP_PRI != PLAT_RAS_PRI)
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
 #endif
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index f93585d..ad80596 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -154,7 +154,7 @@
 		     void *handle,
 		     uint64_t flags);
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
 void tegra194_ras_enable(void);
 void tegra194_ras_corrected_err_clear(uint64_t *cookie);
 #endif
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index d6d090a..b21faa3 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -302,14 +302,14 @@
 	 */
 	if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
 	    (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
-		ret = PSCI_E_NOT_PRESENT;
+		ret = -1;
 	} else {
 		/* calculate the core position */
 		pos = cpu_id + (cluster_id << 2U);
 
 		/* check for non-existent CPUs */
 		if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
-			ret = PSCI_E_NOT_PRESENT;
+			ret = -1;
 		} else {
 			ret = (int32_t)pos;
 		}
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index 2f438c3..841d70b 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -484,7 +484,7 @@
 void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
 {
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
 #else
 	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index d3d09d3..6850330 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -254,7 +254,7 @@
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	/* Enable Uncorrectable RAS error */
 	tegra194_ras_enable();
 #endif
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index f0704ed..6e42e64 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -71,7 +71,7 @@
 
 		break;
 
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
 	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
 	{
 		/*
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 289e921..e6e0b5e 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -37,7 +37,7 @@
 
 # enable RAS handling
 HANDLE_EA_EL3_FIRST_NS			:= 1
-RAS_FFH_SUPPORT				:= 1
+ENABLE_FEAT_RAS				:= 1
 
 # platform files
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t194 \
@@ -71,7 +71,7 @@
 endif
 
 # RAS sources
-ifeq (${RAS_FFH_SUPPORT},1)
+ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
 BL31_SOURCES		+=	lib/extensions/ras/std_err_record.c		\
 				lib/extensions/ras/ras_common.c			\
 				${SOC_DIR}/plat_ras.c
diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h
index edfa73f..ade6d7a 100644
--- a/plat/ti/k3/board/generic/include/board_def.h
+++ b/plat/ti/k3/board/generic/include/board_def.h
@@ -12,8 +12,8 @@
 /* The ports must be in order and contiguous */
 #define K3_CLUSTER0_CORE_COUNT		U(2)
 #define K3_CLUSTER1_CORE_COUNT		U(2)
-#define K3_CLUSTER2_CORE_COUNT		U(2)
-#define K3_CLUSTER3_CORE_COUNT		U(2)
+#define K3_CLUSTER2_CORE_COUNT		U(0)
+#define K3_CLUSTER3_CORE_COUNT		U(0)
 
 #define PLAT_PROC_START_ID		U(32)
 #define PLAT_PROC_DEVICE_START_ID	U(202)
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 495f0c7..d04d805 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -155,14 +155,14 @@
 	ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
 	if (ret) {
 		ERROR("Could not clear response queue (%d)\n", ret);
-		return ret;
+		goto unlock;
 	}
 
 	/* Send the message */
 	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, tx_msg);
 	if (ret) {
 		ERROR("Message sending failed (%d)\n", ret);
-		return ret;
+		goto unlock;
 	}
 
 	/* Get the response if requested */
@@ -170,13 +170,14 @@
 		ret = ti_sci_get_response(rx_msg, SP_RESPONSE);
 		if (ret != 0U) {
 			ERROR("Failed to get response (%d)\n", ret);
-			return ret;
+			goto unlock;
 		}
 	}
 
+unlock:
 	bakery_lock_release(&ti_sci_xfer_lock);
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -211,6 +212,42 @@
 }
 
 /**
+ * ti_sci_query_fw_caps() - Get the FW/SoC capabilities
+ * @handle:		Pointer to TI SCI handle
+ * @fw_caps:		Each bit in fw_caps indicating one FW/SOC capability
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+int ti_sci_query_fw_caps(uint64_t *fw_caps)
+{
+	struct ti_sci_msg_hdr req;
+	struct ti_sci_msg_resp_query_fw_caps resp;
+
+	struct ti_sci_xfer xfer;
+	int ret;
+
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_FW_CAPS, 0,
+				    &req, sizeof(req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret != 0U) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0U) {
+		ERROR("Transfer send failed (%d)\n", ret);
+		return ret;
+	}
+
+	if (fw_caps)
+		*fw_caps = resp.fw_caps;
+
+	return 0;
+}
+
+/**
  * ti_sci_device_set_state() - Set device state
  *
  * @id:		Device identifier
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index 06944a7..c702a71 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -141,10 +141,13 @@
  * Core control operations
  *
  * - ti_sci_core_reboot() - Command to request system reset
+ * - ti_sci_query_fw_caps() - Get the FW/SoC capabilities
+ *              @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
  *
  * Return: 0 if all went well, else returns appropriate error value.
  */
 int ti_sci_core_reboot(void);
+int ti_sci_query_fw_caps(uint64_t *fw_caps);
 
 /**
  * Processor control operations
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 36909f5..7f1c368 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -22,6 +22,7 @@
 #define TI_SCI_MSG_WAKE_REASON		0x0003
 #define TI_SCI_MSG_GOODBYE		0x0004
 #define TI_SCI_MSG_SYS_RESET		0x0005
+#define TI_SCI_MSG_QUERY_FW_CAPS	0x0022
 
 /* Device requests */
 #define TI_SCI_MSG_SET_DEVICE_STATE	0x0200
@@ -124,6 +125,30 @@
 } __packed;
 
 /**
+ * struct ti_sci_msg_resp_query_fw_caps - Response for query firmware caps
+ * @hdr:	Generic header
+ * @fw_caps:	Each bit in fw_caps indicating one FW/SOC capability
+ *		MSG_FLAG_CAPS_GENERIC: Generic capability (LPM not supported)
+ *		MSG_FLAG_CAPS_LPM_DEEP_SLEEP: Deep Sleep LPM
+ *		MSG_FLAG_CAPS_LPM_MCU_ONLY: MCU only LPM
+ *		MSG_FLAG_CAPS_LPM_STANDBY: Standby LPM
+ *		MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
+ *
+ * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
+ * providing currently available SOC/firmware capabilities. SoC that don't
+ * support low power modes return only MSG_FLAG_CAPS_GENERIC capability.
+ */
+struct ti_sci_msg_resp_query_fw_caps {
+	struct ti_sci_msg_hdr hdr;
+#define MSG_FLAG_CAPS_GENERIC		TI_SCI_MSG_FLAG(0)
+#define MSG_FLAG_CAPS_LPM_DEEP_SLEEP	TI_SCI_MSG_FLAG(1)
+#define MSG_FLAG_CAPS_LPM_MCU_ONLY	TI_SCI_MSG_FLAG(2)
+#define MSG_FLAG_CAPS_LPM_STANDBY	TI_SCI_MSG_FLAG(3)
+#define MSG_FLAG_CAPS_LPM_PARTIAL_IO	TI_SCI_MSG_FLAG(4)
+	uint64_t fw_caps;
+} __packed;
+
+/**
  * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
  * @hdr:		Generic header
  * @id:	Indicates which device to modify
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index 0199822..eda9430 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -19,10 +19,8 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-#if K3_PM_SYSTEM_SUSPEND
 static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
 static gicv3_dist_ctx_t dist_ctx;
-#endif
 
 static const interrupt_prop_t k3_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
@@ -94,7 +92,6 @@
 	gicv3_rdistif_init(plat_my_core_pos());
 }
 
-#if K3_PM_SYSTEM_SUSPEND
 void k3_gic_save_context(void)
 {
 	for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
@@ -110,4 +107,3 @@
 		gicv3_rdistif_init_restore(i, &rdist_ctx[i]);
 	}
 }
-#endif
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index d846495..e8d73db 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,7 +234,6 @@
 	return PSCI_E_SUCCESS;
 }
 
-#if K3_PM_SYSTEM_SUSPEND
 static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	unsigned int core, proc_id;
@@ -266,18 +265,15 @@
 		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
 	}
 }
-#endif
 
-static const plat_psci_ops_t k3_plat_psci_ops = {
+static plat_psci_ops_t k3_plat_psci_ops = {
 	.cpu_standby = k3_cpu_standby,
 	.pwr_domain_on = k3_pwr_domain_on,
 	.pwr_domain_off = k3_pwr_domain_off,
 	.pwr_domain_on_finish = k3_pwr_domain_on_finish,
-#if K3_PM_SYSTEM_SUSPEND
 	.pwr_domain_suspend = k3_pwr_domain_suspend,
 	.pwr_domain_suspend_finish = k3_pwr_domain_suspend_finish,
 	.get_sys_suspend_power_state = k3_get_sys_suspend_power_state,
-#endif
 	.system_off = k3_system_off,
 	.system_reset = k3_system_reset,
 	.validate_power_state = k3_validate_power_state,
@@ -286,8 +282,27 @@
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const plat_psci_ops_t **psci_ops)
 {
+	uint64_t fw_caps = 0;
+	int ret;
+
 	k3_sec_entrypoint = sec_entrypoint;
 
+	ret = ti_sci_query_fw_caps(&fw_caps);
+	if (ret) {
+		ERROR("Unable to query firmware capabilities (%d)\n", ret);
+	}
+
+	/* If firmware does not support any known suspend mode */
+	if (!(fw_caps & (MSG_FLAG_CAPS_LPM_DEEP_SLEEP |
+			 MSG_FLAG_CAPS_LPM_MCU_ONLY |
+			 MSG_FLAG_CAPS_LPM_STANDBY |
+			 MSG_FLAG_CAPS_LPM_PARTIAL_IO))) {
+		/* Disable PSCI suspend support */
+		k3_plat_psci_ops.pwr_domain_suspend = NULL;
+		k3_plat_psci_ops.pwr_domain_suspend_finish = NULL;
+		k3_plat_psci_ops.get_sys_suspend_power_state = NULL;
+	}
+
 	*psci_ops = &k3_plat_psci_ops;
 
 	return 0;
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index fb633a8..23efa31 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -44,10 +44,6 @@
 K3_USART_BAUD		:=	115200
 $(eval $(call add_define,K3_USART_BAUD))
 
-# Enable system suspend modes
-K3_PM_SYSTEM_SUSPEND	:=	0
-$(eval $(call add_define,K3_PM_SYSTEM_SUSPEND))
-
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 72ba107..9cdb0ba 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -68,7 +68,6 @@
 	IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
 	IOCTL_TCM_COMB_CONFIG = 3,
 	IOCTL_SET_TAPDELAY_BYPASS = 4,
-	IOCTL_SET_SGMII_MODE = 5,
 	IOCTL_SD_DLL_RESET = 6,
 	IOCTL_SET_SD_TAPDELAY = 7,
 	 /* Ioctl for clock driver */
diff --git a/plat/xilinx/common/tsp/tsp.mk b/plat/xilinx/common/tsp/tsp.mk
new file mode 100644
index 0000000..b80f531
--- /dev/null
+++ b/plat/xilinx/common/tsp/tsp.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files for AMD-Xilinx platforms
+BL32_SOURCES		+=	plat/common/aarch64/platform_mp_stack.S		\
+				plat/xilinx/common/tsp/tsp_plat_setup.c
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/common/tsp/tsp_plat_setup.c
similarity index 67%
rename from plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
rename to plat/xilinx/common/tsp/tsp_plat_setup.c
index a9f2dbd..21c29c3 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/common/tsp/tsp_plat_setup.c
@@ -1,11 +1,13 @@
 /*
  * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <plat/arm/common/plat_arm.h>
 #include <platform_tsp.h>
@@ -22,10 +24,24 @@
 	 * messages from TSP
 	 */
 	static console_t tsp_boot_console;
-	(void)console_cdns_register(UART_BASE,
-				       get_uart_clk(),
-				       UART_BAUDRATE,
-				       &tsp_boot_console);
+	int32_t rc;
+
+#if defined(PLAT_zynqmp)
+	rc = console_cdns_register((uintptr_t)UART_BASE,
+				   (uint32_t)get_uart_clk(),
+				   (uint32_t)UART_BAUDRATE,
+				   &tsp_boot_console);
+#else
+	rc = console_pl011_register((uintptr_t)UART_BASE,
+				    (uint32_t)get_uart_clk(),
+				    (uint32_t)UART_BAUDRATE,
+				    &tsp_boot_console);
+#endif
+
+	if (rc == 0) {
+		panic();
+	}
+
 	console_set_scope(&tsp_boot_console,
 			  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
 }
@@ -35,8 +51,16 @@
  ******************************************************************************/
 void tsp_platform_setup(void)
 {
+/*
+ * For ZynqMP, the GICv2 driver needs to be initialized in S-EL1,
+ * and for other platforms, the GICv3 driver is initialized in EL3.
+ * This is because S-EL1 can use GIC system registers to manage
+ * interrupts and does not need to be initialized again in SEL1.
+ */
+#if defined(PLAT_zynqmp)
 	plat_arm_gic_driver_init();
 	plat_arm_gic_init();
+#endif
 }
 
 /*******************************************************************************
@@ -52,12 +76,14 @@
 			MT_CODE | MT_SECURE),
 		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
 			MT_RO_DATA | MT_SECURE),
+#if defined(PLAT_zynqmp) || defined(PLAT_versal)
 		MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
 			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
 			MT_DEVICE | MT_RW | MT_SECURE),
+#endif
 		{0}
 	};
 
-	setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_get_mmap());
 	enable_mmu_el1(0);
 }
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 6541f27..aba190d 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -33,7 +33,7 @@
 	{ 0 }
 };
 
-const mmap_region_t *plat_versal_get_mmap(void)
+const mmap_region_t *plat_get_mmap(void)
 {
 	return plat_versal_mmap;
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 48f774d..cd105c6 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -115,6 +115,19 @@
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
+
+		/*
+		 * The BL32 load address is indicated as 0x0 in the handoff
+		 * parameters, which is different from the default/user-provided
+		 * load address of 0x60000000 but the flags are correctly
+		 * configured. Consequently, in this scenario, set the PC
+		 * to the requested BL32_BASE address.
+		 */
+
+		/* TODO: Remove the following check once this is fixed from PLM */
+		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
+			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
+		}
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
@@ -190,6 +203,8 @@
 	if (rc != 0) {
 		panic();
 	}
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -218,6 +233,6 @@
 		{0}
 	};
 
-	setup_page_tables(bl_regions, plat_versal_get_mmap());
+	setup_page_tables(bl_regions, plat_get_mmap());
 	enable_mmu(0);
 }
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 26545ba..a4210cd 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -20,7 +20,7 @@
 uint32_t get_uart_clk(void);
 void versal_config_setup(void);
 
-const mmap_region_t *plat_versal_get_mmap(void);
+const mmap_region_t *plat_get_mmap(void);
 
 extern uint32_t platform_id, platform_version;
 
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 0ac76b5..92c0ba6 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -48,6 +48,7 @@
  * IRQ constants
  ******************************************************************************/
 #define VERSAL_IRQ_SEC_PHY_TIMER		U(29)
+#define ARM_IRQ_SEC_PHY_TIMER	29
 
 /*******************************************************************************
  * CCI-400 related constants
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 494c30d..7c53daa 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -54,6 +54,9 @@
 $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
 endif
 
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS := 1
+
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/common/ipi_mailbox_service/	\
diff --git a/plat/xilinx/versal/tsp/tsp-versal.mk b/plat/xilinx/versal/tsp/tsp-versal.mk
new file mode 100644
index 0000000..bf32de3
--- /dev/null
+++ b/plat/xilinx/versal/tsp/tsp-versal.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index df18814..69c5c87 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -34,7 +34,7 @@
 	{ 0 }
 };
 
-const mmap_region_t *plat_versal_net_get_mmap(void)
+const mmap_region_t *plat_get_mmap(void)
 {
 	return plat_versal_net_mmap;
 }
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 08f79de..56ef27b 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -131,6 +131,19 @@
 		}
 
 		INFO("BL31: PLM to TF-A handover success\n");
+
+		/*
+		 * The BL32 load address is indicated as 0x0 in the handoff
+		 * parameters, which is different from the default/user-provided
+		 * load address of 0x60000000 but the flags are correctly
+		 * configured. Consequently, in this scenario, set the PC
+		 * to the requested BL32_BASE address.
+		 */
+
+		/* TODO: Remove the following check once this is fixed from PLM */
+		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
+			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
+		}
 	} else {
 		INFO("BL31: setting up default configs\n");
 
@@ -213,6 +226,8 @@
 	if (rc != 0) {
 		panic();
 	}
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -234,6 +249,6 @@
 		{0}
 	};
 
-	setup_page_tables(bl_regions, plat_versal_net_get_mmap());
+	setup_page_tables(bl_regions, plat_get_mmap());
 	enable_mmu(0);
 }
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 3eb8052..9cd8636 100644
--- a/plat/xilinx/versal_net/include/plat_private.h
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -20,7 +20,7 @@
 void versal_net_config_setup(void);
 uint32_t get_uart_clk(void);
 
-const mmap_region_t *plat_versal_net_get_mmap(void);
+const mmap_region_t *plat_get_mmap(void);
 
 void plat_versal_net_gic_driver_init(void);
 void plat_versal_net_gic_init(void);
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index a53cad9..dd20faa 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -128,6 +128,7 @@
  * IRQ constants
  ******************************************************************************/
 #define VERSAL_NET_IRQ_SEC_PHY_TIMER	U(29)
+#define ARM_IRQ_SEC_PHY_TIMER	29
 
 /*******************************************************************************
  * UART related constants
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index fb229bb..f299189 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -69,6 +69,9 @@
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
 endif
 
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS := 1
+
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/common/ipi_mailbox_service/	\
diff --git a/plat/xilinx/versal_net/tsp/tsp-versal_net.mk b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
new file mode 100644
index 0000000..87638ab
--- /dev/null
+++ b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal NET platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
+
+BL32_SOURCES		+=	plat/xilinx/versal_net/plat_topology.c		\
+				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index e1c8ee8..dba1734 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -27,13 +27,18 @@
  * This doesn't include TZRAM as the 'mem_layout' argument passed to
  * configure_mmu_elx() will give the available subset of that,
  */
-const mmap_region_t plat_arm_mmap[] = {
+const mmap_region_t plat_zynqmp_mmap[] = {
 	{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
 	{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
 	{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
 	{0}
 };
 
+const mmap_region_t *plat_get_mmap(void)
+{
+	return plat_zynqmp_mmap;
+}
+
 static uint32_t zynqmp_get_silicon_ver(void)
 {
 	static unsigned int ver;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 8018535..baf6717 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -190,6 +190,8 @@
 #endif
 
 	custom_runtime_setup();
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -219,6 +221,6 @@
 
 	custom_mmap_add();
 
-	setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_get_mmap());
 	enable_mmu_el3(0);
 }
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index dda005a..afa102d 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -13,9 +13,12 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/bl_common.h>
 #include <drivers/cadence/cdns_uart.h>
+#include <lib/xlat_tables/xlat_tables.h>
 
 void zynqmp_config_setup(void);
 
+const mmap_region_t *plat_get_mmap(void);
+
 uint32_t zynqmp_calc_core_pos(u_register_t mpidr);
 
 /* ZynqMP specific functions */
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 38f2d9b..d715ce2 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -221,20 +221,6 @@
 #define IOU_TAPDLY_BYPASS			U(0XFF180390)
 #define TAP_DELAY_MASK				U(0x7)
 
-/* SGMII mode */
-#define IOU_GEM_CTRL				U(0xFF180360)
-#define IOU_GEM_CLK_CTRL			U(0xFF180308)
-#define SGMII_SD_MASK				U(0x3)
-#define SGMII_SD_OFFSET				U(2)
-#define SGMII_PCS_SD_0				U(0x0)
-#define SGMII_PCS_SD_1				U(0x1)
-#define SGMII_PCS_SD_PHY			U(0x2)
-#define GEM_SGMII_MASK				U(0x4)
-#define GEM_CLK_CTRL_MASK			U(0xF)
-#define GEM_CLK_CTRL_OFFSET			U(5)
-#define GEM_RX_SRC_SEL_GTR			U(0x1)
-#define GEM_SGMII_MODE				U(0x4)
-
 /* SD DLL reset */
 #define ZYNQMP_SD_DLL_CTRL			U(0xFF180358)
 #define ZYNQMP_SD0_DLL_RST_MASK			U(0x00000004)
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index b778932..e266615 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -49,6 +49,10 @@
     ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
         $(eval $(call add_define,ZYNQMP_ATF_MEM_PROGBITS_SIZE))
     endif
+
+    # enable assert() when TF-A runs from DDR memory.
+    ENABLE_ASSERTIONS := 1
+
 endif
 
 ifdef ZYNQMP_BL32_MEM_BASE
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index e812ad6..dd21499 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -174,67 +174,6 @@
 }
 
 /**
- * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device.
- * @nid: Node ID of the device.
- * @value: Enable/Disable.
- *
- * This function enable/disable SGMII mode for the GEM device.
- * While enabling SGMII mode, it also ties the GEM PCS Signal
- * Detect to 1 and selects EMIO for RX clock generation.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
-						  uint32_t value)
-{
-	uint32_t val, mask, shift;
-	enum pm_ret_status ret;
-
-	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
-		return PM_RET_ERROR_ARGS;
-	}
-
-	switch (nid) {
-	case NODE_ETH_0:
-		shift = 0;
-		break;
-	case NODE_ETH_1:
-		shift = 1;
-		break;
-	case NODE_ETH_2:
-		shift = 2;
-		break;
-	case NODE_ETH_3:
-		shift = 3;
-		break;
-	default:
-		return PM_RET_ERROR_ARGS;
-	}
-
-	if (value == PM_SGMII_DISABLE) {
-		mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
-		ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
-	} else {
-		/* Tie the GEM PCS Signal Detect to 1 */
-		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
-		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
-		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
-		if (ret != PM_RET_SUCCESS) {
-			return ret;
-		}
-
-		/* Set the GEM to SGMII mode */
-		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
-		val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
-		val <<= GEM_CLK_CTRL_OFFSET * shift;
-		ret =  pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
-	}
-
-	return ret;
-}
-
-/**
  * pm_ioctl_sd_dll_reset() -  Reset DLL logic.
  * @nid: Node ID of the device.
  * @type: Reset type.
@@ -684,9 +623,6 @@
 	case IOCTL_SET_TAPDELAY_BYPASS:
 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
 		break;
-	case IOCTL_SET_SGMII_MODE:
-		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
-		break;
 	case IOCTL_SD_DLL_RESET:
 		ret = pm_ioctl_sd_dll_reset(nid, arg1);
 		break;
@@ -752,7 +688,6 @@
 		IOCTL_RPU_BOOT_ADDR_CONFIG,
 		IOCTL_TCM_COMB_CONFIG,
 		IOCTL_SET_TAPDELAY_BYPASS,
-		IOCTL_SET_SGMII_MODE,
 		IOCTL_SD_DLL_RESET,
 		IOCTL_SET_SD_TAPDELAY,
 		IOCTL_SET_PLL_FRAC_MODE,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 6b094db..bf94b7c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -36,10 +36,6 @@
 #define	PM_TAPDELAY_BYPASS_DISABLE 0U
 #define	PM_TAPDELAY_BYPASS_ENABLE 1U
 
-//sgmii mode
-#define	PM_SGMII_DISABLE 0U
-#define	PM_SGMII_ENABLE 1U
-
 enum tap_delay_type {
 	PM_TAPDELAY_INPUT,
 	PM_TAPDELAY_OUTPUT,
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 0199597..6b42055 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -163,10 +163,6 @@
 		.api_id = PM_MMIO_WRITE,
 	},
 	{
-		.id = IOCTL_SET_SGMII_MODE,
-		.api_id = PM_MMIO_WRITE,
-	},
-	{
 		.id = IOCTL_SD_DLL_RESET,
 		.api_id = PM_MMIO_WRITE,
 	},
diff --git a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
index f91a04c..1d6366f 100644
--- a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
+++ b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
@@ -4,5 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 
 # TSP source files specific to ZynqMP platform
-BL32_SOURCES		+=	plat/common/aarch64/platform_mp_stack.S		\
-				plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 38ba638..0b263e5 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -328,8 +328,9 @@
 		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
 		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
-		[16 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423},
+		[16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
+		[17 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A710_H_INC */
@@ -350,14 +351,16 @@
 		[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
 		[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
 		[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
-		[12] = {2376738, 0x00, 0x03, ERRATA_N2_2376738},
-		[13] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
-		[14] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
+		[12] = {2340933, 0x00, 0x00, ERRATA_N2_2340933},
+		[13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952},
+		[14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+		[15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
+		[16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[15] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
-		[16] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
-		[17] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
-		[18 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
+		[18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
+		[19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
+		[20 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_N2_H_INC */
@@ -377,8 +380,9 @@
 		[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
 		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
-		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423},
+		[11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
+		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_X2_H_INC */
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index d6d25d8..8b78b13 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -125,17 +125,13 @@
 	pmuv3_enable(ctx);
 
 	/*
-	 * If SME/SME2 is supported and enabled for NS world, then enables SME
-	 * for Realm world. RMM will save/restore required registers that are
-	 * shared with SVE/FPU so that Realm can use FPU or SVE.
+	 * Enable access to TPIDR2_EL0 if SME/SME2 is enabled for Non Secure world.
 	 */
 	if (is_feat_sme_supported()) {
-		/* sme_enable() also enables SME2 if supported by hardware */
 		sme_enable(ctx);
 	}
 }
 
-#if IMAGE_BL31
 static void manage_extensions_realm_per_world(void)
 {
 	if (is_feat_sve_supported()) {
@@ -152,8 +148,15 @@
 		sys_reg_trace_disable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
 	}
 
+	/*
+	 * If SME/SME2 is supported and enabled for NS world, then disable trapping
+	 * of SME instructions for Realm world. RMM will save/restore required
+	 * registers that are shared with SVE/FPU so that Realm can use FPU or SVE.
+	 */
+	if (is_feat_sme_supported()) {
+		sme_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+	}
 }
-#endif /* IMAGE_BL31 */
 
 /*******************************************************************************
  * Jump to the RMM for the first time.
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 72376f7..e567b53 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -4,14 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-ifneq (${ARCH},aarch64)
-	$(error "Error: SPMD is only supported on aarch64.")
-endif
-
-ifneq (${ENABLE_SME_FOR_NS},0)
-	$(error "Error: SPMD is not compatible with ENABLE_SME_FOR_NS")
-endif
-
 SPMD_SOURCES	+=	$(addprefix services/std_svc/spmd/,	\
 			${ARCH}/spmd_helpers.S			\
 			spmd_pm.c				\