Merge "docs(maintainers): add maintainers for i.MX9 SoCs" into integration
diff --git a/.gitignore b/.gitignore
index ac9a11d..e07d997 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
 tools/renesas/rzg_layout_create/*.elf
 tools/fiptool/fiptool
 tools/fiptool/fiptool.exe
+tools/memory/memory/__pycache__/
 tools/cert_create/src/*.o
 tools/cert_create/src/**/*.o
 tools/cert_create/cert_create
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 6207066..7b6a1f5 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -15,6 +15,7 @@
     python: "3.10"
   apt_packages:
     - plantuml
+    - librsvg2-bin
   jobs:
     post_create_environment:
       - pip install poetry=="1.3.2"
@@ -24,3 +25,8 @@
 
 sphinx:
   configuration: docs/conf.py
+
+# Auxiliary formats to export to (in addition to the default HTML output).
+formats:
+  - pdf
+
diff --git a/Makefile b/Makefile
index 8a0a2e0..8e2fd81 100644
--- a/Makefile
+++ b/Makefile
@@ -139,6 +139,7 @@
 SPTOOLPATH		?=	tools/sptool
 SPTOOL			?=	${SPTOOLPATH}/sptool.py
 SP_MK_GEN		?=	${SPTOOLPATH}/sp_mk_generator.py
+SP_DTS_LIST_FRAGMENT	?=	${BUILD_PLAT}/sp_list_fragment.dts
 
 # Variables for use with ROMLIB
 ROMLIBPATH		?=	lib/romlib
@@ -220,14 +221,6 @@
 # Will set march-directive from platform configuration
 else
 	target32-directive	= 	-target armv8a-none-eabi
-
-# Set the compiler's target architecture profile based on
-# ARM_ARCH_MAJOR ARM_ARCH_MINOR options
-	ifeq (${ARM_ARCH_MINOR},0)
-		march-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
-	else
-		march-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
-	endif #(ARM_ARCH_MINOR)
 endif #(ARM_ARCH_MAJOR)
 
 ################################################################################
@@ -279,12 +272,12 @@
 
 ifneq ($(findstring clang,$(notdir $(CC))),)
 	ifneq ($(findstring armclang,$(notdir $(CC))),)
-		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi $(march-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march-directive)
+		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi
+		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi
 		LD			:=	$(LINKER)
 	else
-		TF_CFLAGS_aarch32	=	$(target32-directive) $(march-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march-directive)
+		TF_CFLAGS_aarch32	=	$(target32-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-elf
 		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
 
 		AR			:=	$(shell $(CC) --print-prog-name llvm-ar)
@@ -296,8 +289,6 @@
 	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
 	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring gcc,$(notdir $(CC))),)
-	TF_CFLAGS_aarch32	=	$(march-directive)
-	TF_CFLAGS_aarch64	=	$(march-directive)
 	ifeq ($(ENABLE_LTO),1)
 		# Enable LTO only for aarch64
 		ifeq (${ARCH},aarch64)
@@ -308,8 +299,6 @@
 	endif
 	LD			=	$(LINKER)
 else
-	TF_CFLAGS_aarch32	=	$(march-directive)
-	TF_CFLAGS_aarch64	=	$(march-directive)
 	LD			=	$(LINKER)
 endif #(clang)
 
@@ -635,6 +624,15 @@
 	# 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)
@@ -671,6 +669,14 @@
 
 include ${PLAT_MAKEFILE_FULL}
 
+################################################################################
+# Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
+# up with appropriate march values for compiler.
+################################################################################
+include ${MAKE_HELPERS_DIRECTORY}march.mk
+
+TF_CFLAGS   +=	$(march-directive)
+
 # This internal flag is common option which is set to 1 for scenarios
 # when the BL2 is running in EL3 level. This occurs in two scenarios -
 # 4 world system running BL2 at EL3 and two world system without BL1 running
@@ -762,8 +768,8 @@
                 ifeq (${AARCH32_SP_MAKE},)
                         $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
                 endif
-        $(info Including ${AARCH32_SP_MAKE})
-        include ${AARCH32_SP_MAKE}
+                $(info Including ${AARCH32_SP_MAKE})
+                include ${AARCH32_SP_MAKE}
         endif
 endif #(ARCH=aarch32)
 
@@ -1185,6 +1191,7 @@
 	SPM_MM \
 	SPMC_AT_EL3 \
 	SPMD_SPM_AT_SEL2 \
+	ENABLE_SPMD_LP \
 	TRUSTED_BOARD_BOOT \
 	USE_COHERENT_MEM \
 	USE_DEBUGFS \
@@ -1249,6 +1256,7 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
+	ENABLE_FEAT_MTE_PERM \
 	ENABLE_MPAM_FOR_LOWER_ELS \
 	ENABLE_RME \
 	ENABLE_SPE_FOR_NS \
@@ -1393,12 +1401,14 @@
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
+	ENABLE_FEAT_MTE_PERM \
 	FEATURE_DETECTION \
 	TWED_DELAY \
 	ENABLE_FEAT_TWED \
 	CONDITIONAL_CMO \
 	IMPDEF_SYSREG_TRAP \
 	SVE_VECTOR_LEN \
+	ENABLE_SPMD_LP \
 )))
 
 ifeq (${SANITIZE_UB},trap)
@@ -1544,8 +1554,8 @@
 
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
-$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
-	${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT}
+$(BUILD_PLAT)/sp_gen.mk : ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
+	${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
 sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
 	@${ECHO_BLANK_LINE}
 	@echo "Built SP Images successfully"
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 95fe50e..53946ab 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -25,6 +25,10 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
+ifeq (${ENABLE_PMF},1)
+BL1_SOURCES		+=	lib/pmf/pmf_main.c
+endif
+
 ifneq ($(findstring gcc,$(notdir $(LD))),)
         BL1_LDFLAGS	+=	-Wl,--sort-section=alignment
 else ifneq ($(findstring ld,$(notdir $(LD))),)
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 3f64e27..6fe5511 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,9 @@
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/console.h>
+#include <lib/bootmarker_capture.h>
 #include <lib/cpus/errata.h>
+#include <lib/pmf/pmf.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 #include <smccc_helpers.h>
@@ -31,6 +33,11 @@
 uint64_t bl1_apiakey[2];
 #endif
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_REGISTER_SERVICE(bl_svc, PMF_RT_INSTR_SVC_ID,
+		BL_TOTAL_IDS, PMF_DUMP_ENABLE)
+#endif
+
 /*******************************************************************************
  * Helper utility to calculate the BL2 memory layout taking into consideration
  * the BL1 RW data assuming that it is at the top of the memory layout.
@@ -81,6 +88,10 @@
 {
 	unsigned int image_id;
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL1_ENTRY, PMF_CACHE_MAINT);
+#endif
+
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
 	NOTICE("BL1: %s\n", version_string);
@@ -156,6 +167,10 @@
 
 	bl1_prepare_next_image(image_id);
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL1_EXIT, PMF_CACHE_MAINT);
+#endif
+
 	console_flush();
 }
 
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 1663c52..b70a3fb 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -49,3 +49,7 @@
 
 BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2_el3.ld.S
 endif
+
+ifeq (${ENABLE_PMF},1)
+BL2_SOURCES		+=	lib/pmf/pmf_main.c
+endif
\ No newline at end of file
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index ce83692..923a554 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -16,7 +16,9 @@
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/console.h>
 #include <drivers/fwu/fwu.h>
+#include <lib/bootmarker_capture.h>
 #include <lib/extensions/pauth.h>
+#include <lib/pmf/pmf.h>
 #include <plat/common/platform.h>
 
 #include "bl2_private.h"
@@ -27,6 +29,11 @@
 #define NEXT_IMAGE	"BL32"
 #endif
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_REGISTER_SERVICE(bl_svc, PMF_RT_INSTR_SVC_ID,
+		BL_TOTAL_IDS, PMF_DUMP_ENABLE);
+#endif
+
 #if RESET_TO_BL2
 /*******************************************************************************
  * Setup function for BL2 when RESET_TO_BL2=1
@@ -81,6 +88,10 @@
 {
 	entry_point_info_t *next_bl_ep_info;
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_ENTRY, PMF_CACHE_MAINT);
+#endif
+
 	NOTICE("BL2: %s\n", version_string);
 	NOTICE("BL2: %s\n", build_message);
 
@@ -118,8 +129,6 @@
 	disable_mmu_icache_secure();
 #endif /* !__aarch64__ */
 
-	console_flush();
-
 #if ENABLE_PAUTH
 	/*
 	 * Disable pointer authentication before running next boot image
@@ -127,6 +136,12 @@
 	pauth_disable_el1();
 #endif /* ENABLE_PAUTH */
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_EXIT, PMF_CACHE_MAINT);
+#endif
+
+	console_flush();
+
 	/*
 	 * Run next BL image via an SMC to BL1. Information on how to pass
 	 * control to the BL32 (if present) and BL33 software images will
@@ -137,6 +152,9 @@
 
 	NOTICE("BL2: Booting " NEXT_IMAGE "\n");
 	print_entry_point_info(next_bl_ep_info);
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_EXIT, PMF_CACHE_MAINT);
+#endif
 	console_flush();
 
 #if ENABLE_PAUTH
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 851ac47..7336b91 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -152,92 +152,6 @@
 	b	handle_lower_el_sync_ea
 	.endm
 
-
-	/* ---------------------------------------------------------------------
-	 * This macro handles FIQ or IRQ interrupts i.e. EL3, S-EL1 and NS
-	 * interrupts.
-	 * ---------------------------------------------------------------------
-	 */
-	.macro	handle_interrupt_exception label
-
-	/*
-	 * 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
-
-#if ENABLE_PAUTH
-	/* Load and program APIAKey firmware key */
-	bl	pauth_load_bl31_apiakey
-#endif
-
-	/* Save the EL3 system registers needed to return from this exception */
-	mrs	x0, spsr_el3
-	mrs	x1, elr_el3
-	stp	x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-
-	/* Switch to the runtime stack i.e. SP_EL0 */
-	ldr	x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
-	mov	x20, sp
-	msr	spsel, #MODE_SP_EL0
-	mov	sp, x2
-
-	/*
-	 * Find out whether this is a valid interrupt type.
-	 * If the interrupt controller reports a spurious interrupt then return
-	 * to where we came from.
-	 */
-	bl	plat_ic_get_pending_interrupt_type
-	cmp	x0, #INTR_TYPE_INVAL
-	b.eq	interrupt_exit_\label
-
-	/*
-	 * Get the registered handler for this interrupt type.
-	 * A NULL return value could be 'cause of the following conditions:
-	 *
-	 * a. An interrupt of a type was routed correctly but a handler for its
-	 *    type was not registered.
-	 *
-	 * b. An interrupt of a type was not routed correctly so a handler for
-	 *    its type was not registered.
-	 *
-	 * c. An interrupt of a type was routed correctly to EL3, but was
-	 *    deasserted before its pending state could be read. Another
-	 *    interrupt of a different type pended at the same time and its
-	 *    type was reported as pending instead. However, a handler for this
-	 *    type was not registered.
-	 *
-	 * a. and b. can only happen due to a programming error. The
-	 * occurrence of c. could be beyond the control of Trusted Firmware.
-	 * It makes sense to return from this exception instead of reporting an
-	 * error.
-	 */
-	bl	get_interrupt_type_handler
-	cbz	x0, interrupt_exit_\label
-	mov	x21, x0
-
-	mov	x0, #INTR_ID_UNAVAILABLE
-
-	/* Set the current security state in the 'flags' parameter */
-	mrs	x2, scr_el3
-	ubfx	x1, x2, #0, #1
-
-	/* Restore the reference to the 'handle' i.e. SP_EL3 */
-	mov	x2, x20
-
-	/* x3 will point to a cookie (not used now) */
-	mov	x3, xzr
-
-	/* Call the interrupt type handler */
-	blr	x21
-
-interrupt_exit_\label:
-	/* Return from exception, possibly in a different security state */
-	b	el3_exit
-
-	.endm
-
-
 vector_base runtime_exceptions
 
 	/* ---------------------------------------------------------------------
@@ -342,14 +256,14 @@
 	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
-	handle_interrupt_exception irq_aarch64
+	b	handle_interrupt_exception
 end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
 	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
-	handle_interrupt_exception fiq_aarch64
+	b 	handle_interrupt_exception
 end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
@@ -385,14 +299,14 @@
 	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
-	handle_interrupt_exception irq_aarch32
+	b	handle_interrupt_exception
 end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
 	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
-	handle_interrupt_exception fiq_aarch32
+	b	handle_interrupt_exception
 end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
@@ -611,6 +525,90 @@
 endfunc sync_exception_handler
 
 	/* ---------------------------------------------------------------------
+	 * This function handles FIQ or IRQ interrupts i.e. EL3, S-EL1 and NS
+	 * interrupts.
+	 *
+	 * Note that x30 has been explicitly saved and can be used here
+	 * ---------------------------------------------------------------------
+	 */
+func handle_interrupt_exception
+	/*
+	 * 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
+
+#if ENABLE_PAUTH
+	/* Load and program APIAKey firmware key */
+	bl	pauth_load_bl31_apiakey
+#endif
+
+	/* Save the EL3 system registers needed to return from this exception */
+	mrs	x0, spsr_el3
+	mrs	x1, elr_el3
+	stp	x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+
+	/* Switch to the runtime stack i.e. SP_EL0 */
+	ldr	x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+	mov	x20, sp
+	msr	spsel, #MODE_SP_EL0
+	mov	sp, x2
+
+	/*
+	 * Find out whether this is a valid interrupt type.
+	 * If the interrupt controller reports a spurious interrupt then return
+	 * to where we came from.
+	 */
+	bl	plat_ic_get_pending_interrupt_type
+	cmp	x0, #INTR_TYPE_INVAL
+	b.eq	interrupt_exit
+
+	/*
+	 * Get the registered handler for this interrupt type.
+	 * A NULL return value could be 'cause of the following conditions:
+	 *
+	 * a. An interrupt of a type was routed correctly but a handler for its
+	 *    type was not registered.
+	 *
+	 * b. An interrupt of a type was not routed correctly so a handler for
+	 *    its type was not registered.
+	 *
+	 * c. An interrupt of a type was routed correctly to EL3, but was
+	 *    deasserted before its pending state could be read. Another
+	 *    interrupt of a different type pended at the same time and its
+	 *    type was reported as pending instead. However, a handler for this
+	 *    type was not registered.
+	 *
+	 * a. and b. can only happen due to a programming error. The
+	 * occurrence of c. could be beyond the control of Trusted Firmware.
+	 * It makes sense to return from this exception instead of reporting an
+	 * error.
+	 */
+	bl	get_interrupt_type_handler
+	cbz	x0, interrupt_exit
+	mov	x21, x0
+
+	mov	x0, #INTR_ID_UNAVAILABLE
+
+	/* Set the current security state in the 'flags' parameter */
+	mrs	x2, scr_el3
+	ubfx	x1, x2, #0, #1
+
+	/* Restore the reference to the 'handle' i.e. SP_EL3 */
+	mov	x2, x20
+
+	/* x3 will point to a cookie (not used now) */
+	mov	x3, xzr
+
+	/* Call the interrupt type handler */
+	blr	x21
+
+interrupt_exit:
+	/* Return from exception, possibly in a different security state */
+	b	el3_exit
+endfunc handle_interrupt_exception
+
+	/* ---------------------------------------------------------------------
 	 * The following code handles exceptions caused by BRK instructions.
 	 * Following a BRK instruction, the only real valid cause of action is
 	 * to print some information and panic, as the code that caused it is
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 8f1f043..cae55f3 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 #include <common/feat_detect.h>
 #include <common/runtime_svc.h>
 #include <drivers/console.h>
+#include <lib/bootmarker_capture.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/pmf/pmf.h>
 #include <lib/runtime_instr.h>
@@ -24,10 +25,15 @@
 #include <services/std_svc.h>
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
-PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
-	RT_INSTR_TOTAL_IDS, PMF_STORE_ENABLE)
+	PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
+		RT_INSTR_TOTAL_IDS, PMF_STORE_ENABLE)
 #endif
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_REGISTER_SERVICE(bl_svc, PMF_RT_INSTR_SVC_ID,
+		BL_TOTAL_IDS, PMF_DUMP_ENABLE)
+#endif
+
 /*******************************************************************************
  * This function pointer is used to initialise the BL32 image. It's initialized
  * by SPD calling bl31_register_bl32_init after setting up all things necessary
@@ -123,6 +129,10 @@
 	detect_arch_features();
 #endif /* FEATURE_DETECTION */
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_ENTRY, PMF_CACHE_MAINT);
+#endif
+
 #ifdef SUPPORT_UNKNOWN_MPID
 	if (unsupported_mpid_flag == 0) {
 		NOTICE("Unsupported MPID detected!\n");
@@ -163,6 +173,7 @@
 	if (bl32_init != NULL) {
 		INFO("BL31: Initializing BL32\n");
 
+		console_flush();
 		int32_t rc = (*bl32_init)();
 
 		if (rc == 0) {
@@ -178,6 +189,7 @@
 	if (rmm_init != NULL) {
 		INFO("BL31: Initializing RMM\n");
 
+		console_flush();
 		int32_t rc = (*rmm_init)();
 
 		if (rc == 0) {
@@ -199,6 +211,11 @@
 	 * from BL31
 	 */
 	bl31_plat_runtime_setup();
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_EXIT, PMF_CACHE_MAINT);
+	console_flush();
+#endif
 }
 
 /*******************************************************************************
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index f102967..693dd4b 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,11 +62,8 @@
  * The Cold boot/Reset entrypoint for SP_MIN
  */
 func sp_min_entrypoint
-#if !RESET_TO_SP_MIN
 	/* ---------------------------------------------------------------
-	 * Preceding bootloader has populated r0 with a pointer to a
-	 * 'bl_params_t' structure & r1 with a pointer to platform
-	 * specific structure
+	 * Stash the previous bootloader arguments r0 - r3 for later use.
 	 * ---------------------------------------------------------------
 	 */
 	mov	r9, r0
@@ -74,6 +71,7 @@
 	mov	r11, r2
 	mov	r12, r3
 
+#if !RESET_TO_SP_MIN
 	/* ---------------------------------------------------------------------
 	 * For !RESET_TO_SP_MIN systems, only the primary CPU ever reaches
 	 * sp_min_entrypoint() during the cold boot flow, so the cold/warm boot
@@ -91,11 +89,6 @@
 		_init_c_runtime=1				\
 		_exception_vectors=sp_min_vector_table		\
 		_pie_fixup_size=FIXUP_SIZE
-
-	/* ---------------------------------------------------------------------
-	 * Relay the previous bootloader's arguments to the platform layer
-	 * ---------------------------------------------------------------------
-	 */
 #else
 	/* ---------------------------------------------------------------------
 	 * For RESET_TO_SP_MIN systems which have a programmable reset address,
@@ -111,24 +104,16 @@
 		_init_c_runtime=1				\
 		_exception_vectors=sp_min_vector_table		\
 		_pie_fixup_size=FIXUP_SIZE
-
-	/* ---------------------------------------------------------------------
-	 * For RESET_TO_SP_MIN systems, BL32 (SP_MIN) is the first bootloader
-	 * to run so there's no argument to relay from a previous bootloader.
-	 * Zero the arguments passed to the platform layer to reflect that.
-	 * ---------------------------------------------------------------------
-	 */
-	mov	r9, #0
-	mov	r10, #0
-	mov	r11, #0
-	mov	r12, #0
-
 #endif /* RESET_TO_SP_MIN */
 
 #if SP_MIN_WITH_SECURE_FIQ
 	route_fiq_to_sp_min r4
 #endif
 
+	/* ---------------------------------------------------------------------
+	 * Relay the previous bootloader's arguments to the platform layer
+	 * ---------------------------------------------------------------------
+	 */
 	mov	r0, r9
 	mov	r1, r10
 	mov	r2, r11
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 0b7bc57..065468c 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -17,6 +17,7 @@
 				bl32/sp_min/aarch32/entrypoint.S	\
 				common/runtime_svc.c			\
 				plat/common/aarch32/plat_sp_min_common.c\
+				services/arm_arch_svc/arm_arch_svc_setup.c	\
 				services/std_svc/std_svc_setup.c	\
 				${PSCI_LIB_SOURCES}
 
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index f050160..26cf207 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -134,6 +134,7 @@
 	assert(NON_SECURE == GET_SECURITY_STATE(next_image_info->h.attr));
 
 	INFO("SP_MIN: Preparing exit to normal world\n");
+	print_entry_point_info(next_image_info);
 
 	psci_prepare_next_non_secure_ctx(next_image_info);
 	smc_set_next_ctx(NON_SECURE);
diff --git a/changelog.yaml b/changelog.yaml
index 47cfc1e..9f5d4b7 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -628,6 +628,13 @@
               - plat/zynqmp
               - plat/xilinx/zynqmp
 
+      - title: Nuvoton
+        scope: nuvoton
+
+        subsections:
+          - title: npcm845x
+            scope: npcm845x
+
   - title: Bootloader Images
     scope: bl
 
@@ -1343,5 +1350,8 @@
       - title: Node Package Manager (NPM)
         scope: npm
 
+      - title: Poetry
+        scope: poetry
+
       - title: zlib
         scope: zlib
diff --git a/common/feat_detect.c b/common/feat_detect.c
index d2e94e9..a1ffc39 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -203,7 +203,7 @@
 	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1);
 
 	/* v8.9 features */
-	check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
+	check_feature(ENABLE_FEAT_TCR2, read_feat_tcr2_id_field(),
 		      "TCR2", 1, 1);
 	check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(),
 		      "S2PIE", 1, 1);
@@ -213,6 +213,8 @@
 		      "S2POE", 1, 1);
 	check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
 		      "S1POE", 1, 1);
+	check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
+		      "MTE_PERM", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index a27c26c..026a463 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -196,12 +196,14 @@
 
 JTAG DCC console driver
 ^^^^^^^^^^^^^^^^^^^^^^^
-:M: Michal Simek <michal.simek@amd.com>
-:G: `michalsimek`_
-:M: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
-:G: `venkatesh`_
-:F: drivers/arm/dcc/
-:F: include/drivers/arm/dcc.h
+:|M|: Michal Simek <michal.simek@amd.com>
+:|G|: `michalsimek`_
+:|M|: Amit Nagal <amit.nagal@amd.com>
+:|G|: `amit-nagal`_
+:|M|: Akshay Belsare <akshay.belsare@amd.com>
+:|G|: `Akshay-Belsare`_
+:|F|: drivers/arm/dcc/
+:|F|: include/drivers/arm/dcc.h
 
 Power State Coordination Interface (PSCI)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -583,6 +585,20 @@
 :|F|: drivers/marvell/
 :|F|: tools/marvell/
 
+Nuvoton npcm845x platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Hila Miranda-Kuzi <hila.miranda.kuzi1@gmail.com>
+:|G|: `hilamirandakuzi1`_
+:|M|: Margarita Glushkin <rutigl@gmail.com>
+:|G|: `rutigl`_
+:|M|: Avi Fishman <avi.fishman@nuvoton.com>
+:|G|: `avifishman`_
+:|F|: docs/plat/npcm845x.rst
+:|F|: drivers/nuvoton/
+:|F|: include/drivers/nuvoton/
+:|F|: include/plat/nuvoton/
+:|F|: plat/nuvoton/
+
 NVidia platform ports
 ^^^^^^^^^^^^^^^^^^^^^
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
@@ -705,7 +721,10 @@
 :|M|: Nikita Travkin <nikita@trvn.ru>
 :|G|: `TravMurav`_
 :|F|: docs/plat/qti-msm8916.rst
+:|F|: plat/qti/mdm9607/
+:|F|: plat/qti/msm8909/
 :|F|: plat/qti/msm8916/
+:|F|: plat/qti/msm8939/
 
 Raspberry Pi 3 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -802,8 +821,10 @@
 ^^^^^^^^^^^^^^^^^^^^
 :|M|: Michal Simek <michal.simek@amd.com>
 :|G|: `michalsimek`_
-:|M|: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
-:|G|: `venkatesh`_
+:|M|: Amit Nagal <amit.nagal@amd.com>
+:|G|: `amit-nagal`_
+:|M|: Akshay Belsare <akshay.belsare@amd.com>
+:|G|: `Akshay-Belsare`_
 :|F|: docs/plat/xilinx\*
 :|F|: plat/xilinx/
 
@@ -967,7 +988,6 @@
 .. _TonyXie06: https://github.com/TonyXie06
 .. _TravMurav: https://github.com/TravMurav
 .. _vwadekar: https://github.com/vwadekar
-.. _venkatesh: https://github.com/vabbarap
 .. _Yann-lms: https://github.com/Yann-lms
 .. _manish-pandey-arm: https://github.com/manish-pandey-arm
 .. _mardyk01: https://github.com/mardyk01
@@ -1001,3 +1021,8 @@
 .. _jimmy-brisson: https://github.com/theotherjimmy
 .. _ChiaweiW: https://github.com/chiaweiw
 .. _Neal-liu: https://github.com/neal-liu
+.. _amit-nagal: https://github.com/amit-nagal
+.. _Akshay-Belsare: https://github.com/Akshay-Belsare
+.. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
+.. _rutigl: https://github.com/rutigl
+.. _avifishman: https://github.com/avifishman
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 919eea5..f228e6b 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -157,7 +157,7 @@
 
  git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git
  cd tf-a-tests
- make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 all pack_realm
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 ENABLE_REALM_PAYLOAD_TESTS=1 all
 
 This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged
 and **sp_layout.json** in the **build/fvp/debug** directory.
diff --git a/docs/conf.py b/docs/conf.py
index 345f53b..9e7a5f8 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -26,7 +26,7 @@
     "myst_parser",
     "sphinx.ext.autosectionlabel",
     "sphinxcontrib.plantuml",
-    "sphinxcontrib.inkscapeconverter",
+    "sphinxcontrib.rsvgconverter",
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -108,4 +108,5 @@
 latex_elements = {
     "maxlistdepth": "10",
     "pointsize": "11pt",
+    "extraclassoptions": "openany"
 }
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index ecbefdd..d1bf0d3 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -117,7 +117,8 @@
 
 -  ``ERRATA_A53_836870``: This applies errata 836870 workaround to Cortex-A53
    CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
-   r0p4 and onwards, this errata is enabled by default in hardware.
+   r0p4 and onwards, this errata is enabled by default in hardware. Identical to
+   ``A53_DISABLE_NON_TEMPORAL_HINT``.
 
 -  ``ERRATA_A53_843419``: This applies erratum 843419 workaround at link time
    to Cortex-A53 CPU.  This needs to be enabled for some variants of revision
@@ -527,6 +528,10 @@
    IP. This needs to be enabled for revisions r0p0 and r0p1. It has been fixed
    in r0p2.
 
+-  ``ERRATA_V2_2801372``: This applies errata 2801372 workaround to Neoverse-V2
+   CPU, this affects all configurations. This needs to be enabled for revisions
+   r0p0 and r0p1. It has been fixed in r0p2.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -597,47 +602,53 @@
 For Neoverse N2, the following errata build flags are defined :
 
 -  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
+
+-  ``ERRATA_N2_2009478``: This applies errata 2009478 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2025414``: This applies errata 2025414 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2189731``: This applies errata 2189731 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2138956``: This applies errata 2138956 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2, r0p3 and is still open.
 
 -  ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2138958``: This applies errata 2138958 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2242400``: This applies errata 2242400 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
 -  ``ERRATA_N2_2326639``: This applies errata 2326639 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
 -  ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
-   r0p1.
+   CPU. This needs to be enabled for revision r0p0, r0p1, r0p2, r0p3 and is still open.
 
 -  ``ERRATA_N2_2388450``: This applies errata 2388450 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
+-  ``ERRATA_N2_2743014``: This applies errata 2743014 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
+   in r0p3.
+
 -  ``ERRATA_N2_2743089``: This applies errata 2743089 workaround to Neoverse-N2
    CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
    in r0p3.
@@ -647,6 +658,10 @@
    interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
    It is fixed in r0p3.
 
+-  ``ERRATA_N2_2779511``: This applies errata 2779511 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
+   in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -703,6 +718,10 @@
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
   CPU, it is still open.
 
+- ``ERRATA_X3_2742421``: This applies errata 2742421 workaround to
+  Cortex-X3 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
+  r1p1. It is fixed in r1p2.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 3d648c4..879ddda 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2636,19 +2636,17 @@
   architectural features up to ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR`` are included
   and unconditionally enabled by TF-A build system.
 
-- Passed to compiler via "-march" option to generate binary target : Tell the
-  compiler to emit instructions upto ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR``
+- ``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` are passed to a march.mk build utility
+  this will try to come up with an appropriate -march value to be passed to compiler
+  by probing the compiler and checking what's supported by the compiler and what's best
+  that can be used. But if platform provides a ``MARCH_DIRECTIVE`` then it will used
+  directly and compiler probing will be skipped.
 
 The build system requires that the platform provides a valid numeric value based on
 CPU architecture extension, otherwise it defaults to base Armv8.0-A architecture.
 Subsequent Arm Architecture versions also support extensions which were introduced
 in previous versions.
 
-**TO-DO** : Its planned to decouple the two functionalities and introduce a new macro
-for compiler usage. The requirement for this decoupling arises becasue TF-A code
-always provides support for the latest and greatest architecture features but this
-is not the case for the target compiler.
-
 .. seealso:: :ref:`Build Options`
 
 For details on the Architecture Extension and available features, please refer
@@ -2738,7 +2736,7 @@
 
 .. code:: make
 
-   MARCH_DIRECTIVE := -mach=armv7-a
+   MARCH_DIRECTIVE := -march=armv7-a
 
 Code Structure
 --------------
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index d20fc58..ecc68b2 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -11,6 +11,7 @@
    drtm_poc
    rss
    psci_osi_mode
+   measured_boot
 
 --------------
 
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
new file mode 100644
index 0000000..c4e5213
--- /dev/null
+++ b/docs/design_documents/measured_boot.rst
@@ -0,0 +1,234 @@
+Measured Boot Design
+====================
+
+This document briefly explains the Measured-Boot design implementation
+in |TF-A|.
+
+Introduction
+------------
+
+Measured Boot is the process of computing and securely recording hashes of code
+and critical data at each stage in the boot chain before the code/data is used.
+
+These measurements can be leveraged by other components in the system to
+implement a complete attestation system. For example, they could be used to
+enforce local attestation policies (such as releasing certain platform keys or
+not), or they could be securely sent to a remote challenger a.k.a. `verifier`
+after boot to attest to the state of the code and critical-data.
+
+Measured Boot does not authenticate the code or critical-data, but simply
+records what code/critical-data was present on the system during boot.
+
+It is assumed that BL1 is implicitly trusted (by virtue of immutability) and
+acts as the root of trust for measurement hence it is not measured.
+
+The Measured Boot implementation in TF-A supports multiple backends to securely
+store measurements mentioned below in the :ref:`Measured Boot Backends` section.
+
+Critical data
+-------------
+
+All firmware images - i.e. BLx images and their corresponding configuration
+files, if any - must be measured. In addition to that, there might be specific
+pieces of data which needs to be measured as well. These are typically different
+on each platform. They are referred to as *critical data*.
+
+Critical data for the platform can be determined using the following criteria:
+
+#. Data that influence boot flow behaviour such as -
+
+   - Configuration parameters that alter the boot flow path.
+   - Parameters that determine which firmware to load from NV-Storage to
+     SRAM/DRAM to pass the boot process successfully.
+
+#. Hardware configurations settings, debug settings and security policies
+   that need to be in a valid state for a device to maintain its security
+   posture during boot and runtime.
+#. Security-sensitive data that is being updated by hardware.
+
+Examples of Critical data:
+
+#. The list of errata workarounds being applied at reset.
+#. State of fuses such as whether an SoC is in secure mode.
+#. NV counters that determine whether firmware is up-to-date and secure.
+
+Measurement slot
+----------------
+
+The measurement slot resides in a Trusted Module and can be either a secure
+register or memory.
+The measurement slot is used to provide a method to cryptographically record
+(measure) images and critical data on a platform.
+The measurement slot update calculation, called an **extend** operation, is
+a one-way hash of all the previous measurements and the new measurement. It
+is the only way to change the slot value, thus no measurements can ever be
+removed or overwritten.
+
+.. _Measured Boot Backends:
+
+Measured Boot Backends
+----------------------
+
+The Measured Boot implementation in TF-A supports:
+
+#. Event Log
+
+   The TCG Event Log holds a record of measurements made into the Measurement
+   Slot aka PCR (Platform Configuration Register).
+
+   The `TCG EFI Protocol Specification`_ provides details on how to measure
+   components. The Arm document
+   `Arm® Server Base Security Guide`_ provides specific guidance for
+   measurements on an SBSA/SBBR server system. By considering these
+   specifications it is decided that -
+
+   #. Use PCR0 for images measurements.
+   #. Use PCR1 for Critical data measurements.
+
+   TCG has specified the architecture for the structure of this log in the
+   `TCG EFI Protocol Specification`_. The specification describes two event
+   log event records—the legacy, fixed size SHA1 structure called TCG_PCR_EVENT
+   and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
+   Log driver implemented in TF-A covers later part.
+
+#. RSS
+
+   It is one of physical backend to extend the measurements. Please refer this
+   document :ref:`Runtime Security Subsystem (RSS)` for more details.
+
+Platform Interface
+------------------
+
+Every image which gets successfully loaded in memory (and authenticated, if
+trusted boot is enabled) then gets measured. In addition to that, platforms
+can measure any relevant piece of critical data at any point during the boot.
+The following diagram outlines the call sequence for Measured Boot platform
+interfaces invoked from generic code:
+
+.. image:: ../resources/diagrams/measured_boot_design.png
+
+These platform interfaces are used by BL1 and BL2 only, and are declared in
+``include/plat/common/platform.h``.
+BL31 does not load and thus does not measure any image.
+
+Responsibilities of these platform interfaces are -
+
+#. **Function : blx_plat_mboot_init()**
+
+   .. code-block:: c
+
+      void bl1_plat_mboot_init(void);
+      void bl2_plat_mboot_init(void);
+
+   Initialise all Measured Boot backends supported by the platform
+   (e.g. Event Log buffer, RSS). As these functions do not return any value,
+   the platform should deal with error management, such as logging the error
+   somewhere, or panicking the system if this is considered a fatal error.
+
+   - On the Arm FVP port -
+
+     - In BL1, this function is used to initialize the Event Log backend
+       driver, and also to write header information in the Event Log
+       buffer.
+     - In BL2, this function is used to initialize the Event Log buffer with
+       the information received from the BL1. It results in panic on
+       error.
+
+#. **Function : plat_mboot_measure_image()**
+
+   .. code-block:: c
+
+      int plat_mboot_measure_image(unsigned int image_id,
+                                   image_info_t *image_data);
+
+   - Measure the image using a hash function of the crypto module.
+
+   - Record the measurement in the corresponding backend -
+
+     - If it is Event Log backend, then record the measurement in TCG Event Log
+       format.
+     - If it is a secure crypto-processor (like RSS), then extend the designated
+       PCR (or slot) with the given measurement.
+   - This function must return 0 on success, a signed integer error code
+     otherwise.
+   - On the Arm FVP port, this function measures the given image and then
+     records that measurement in the Event Log buffer.
+     The passed id is used to retrieve information about on how to measure
+     the image (e.g. PCR number).
+
+#. **Function : blx_plat_mboot_finish()**
+
+   .. code-block:: c
+
+      void bl1_plat_mboot_finish(void);
+      void bl2_plat_mboot_finish(void);
+
+   - Do all teardown operations with respect to initialised Measured Boot backends.
+     This could be -
+
+     - Pass the Event Log details (start address and size) to Normal world or to
+       Secure World using any platform implementation way.
+     - Measure all critical data if any.
+     - As these functions do not return any value, the platform should deal with
+       error management, such as logging the error somewhere, or panicking the
+       system if this is considered a fatal error.
+
+   - On the Arm FVP port -
+
+     - In BL1, this function is used to pass the base address of
+       the Event Log buffer and its size to BL2 via tb_fw_config to extend the
+       Event Log buffer with the measurement of various images loaded by BL2.
+       It results in panic on error.
+     - In BL2, this function is used to pass the Event Log buffer information
+       (base address and size) to non-secure(BL33) and trusted OS(BL32) via
+       nt_fw and tos_fw config respectively.
+       See :ref:`DTB binding for Event Log properties` for a description of the
+       bindings used for Event Log properties.
+
+#. **Function : plat_mboot_measure_critical_data()**
+
+   .. code-block:: c
+
+      int plat_mboot_measure_critical_data(unsigned int critical_data_id,
+                                           const void *base,
+                                           size_t size);
+
+   This interface is not invoked by the generic code and it is up to the
+   platform layer to call it where appropriate.
+
+   This function measures the given critical data structure and records its
+   measurement using the Measured Boot backend driver.
+   This function must return 0 on success, a signed integer error code
+   otherwise.
+
+   In FVP, Non volatile counters get measured and recorded as Critical data
+   using the backend via this interface.
+
+#. **Function : plat_mboot_measure_key()**
+
+   .. code-block:: c
+
+      int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+                                 size_t pk_len);
+
+   - This function is used by the platform to measure the passed key and
+     publicise it using any of the supported backends.
+   - The authentication module within the trusted boot framework calls this
+     function for every ROTPK involved in verifying the signature of a root
+     certificate and for every subsidiary key that gets extracted from a key
+     certificate for later authentication of a content certificate.
+   - A cookie, passed as the first argument, serves as a key-OID pointer
+     associated with the public key data, passed as the second argument.
+   - Public key data size is passed as the third argument to this function.
+   - This function must return 0 on success, a signed integer error code
+     otherwise.
+   - In FVP platform, this function is used to calculate the hash of the given
+     key and forward this hash to RSS alongside the measurement of the image
+     which the key signs.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+
+.. _Arm® Server Base Security Guide: https://developer.arm.com/documentation/den0086/latest
+.. _TCG EFI Protocol Specification: https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 7f9519e..86cf4d1 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -10,6 +10,8 @@
 This section focuses on the `TCG event log`_ backend, which stores measurements
 in secure memory.
 
+See details of :ref:`Measured Boot Design`.
+
 The driver also provides mechanisms to pass the Event Log to normal world if
 needed.
 
diff --git a/docs/design_documents/rss.rst b/docs/design_documents/rss.rst
index 2be8067..18d5436 100644
--- a/docs/design_documents/rss.rst
+++ b/docs/design_documents/rss.rst
@@ -134,12 +134,10 @@
 - ``Delegated attestation``: Query the platform attestation token and derive a
   delegated attestation key. More info on the delegated attestation service
   in RSS can be found in the ``delegated_attestation_integration_guide`` [4]_ .
-- ``OTP assets management``: RSS provides access for AP to assets in OTP.
-  These are keys for image signature verification and non-volatile counters
-  for anti-rollback protection. Only RSS has direct access to the OTP. Public
-  keys used by AP during the trusted boot process can be requested from RSS.
-  Furthermore, AP can request RSS to increase a non-volatile counter. Please
-  refer to the ``RSS key management`` [5]_ document for more details.
+- ``OTP assets management``: Public keys used by AP during the trusted boot
+  process can be requested from RSS. Furthermore, AP can request RSS to
+  increase a non-volatile counter. Please refer to the
+  ``RSS key management`` [5]_ document for more details.
 
 Runtime service API
 ^^^^^^^^^^^^^^^^^^^
@@ -262,7 +260,8 @@
 - ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
 
 .. Note::
-    Signer-id and version info is not implemented in TF-A yet.
+    Version info is not implemented in TF-A yet.
+
 
 The caller must specify in which measurement slot to extend a certain
 measurement and metadata. A measurement slot can be extended by multiple
@@ -321,9 +320,38 @@
             size_t  version_size;
             uint8_t sw_type[SW_TYPE_MAX_SIZE];
             size_t  sw_type_size;
+            void    *pk_oid;
             bool    lock_measurement;
     };
 
+Signer-ID API
+^^^^^^^^^^^^^
+
+This function calculates the hash of a public key (signer-ID) using the
+``Measurement algorithm`` and stores it in the ``rss_mboot_metadata`` field
+named ``signer_id``.
+Prior to calling this function, the caller must ensure that the ``signer_id``
+field points to the zero-filled buffer.
+
+Defined here:
+
+- ``include/drivers/measured_boot/rss/rss_measured_boot.h``
+
+.. code-block:: c
+
+   int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+                               const void *pk_oid,
+                               const void *pk_ptr,
+                               size_t pk_len)
+
+
+- First parameter is the pointer to the ``rss_mboot_metadata`` structure.
+- Second parameter is the pointer to the key-OID of the public key.
+- Third parameter is the pointer to the public key buffer.
+- Fourth parameter is the size of public key buffer.
+- This function returns 0 on success, a signed integer error code
+  otherwise.
+
 Build time config options
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -361,8 +389,8 @@
     INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
     INFO:    Measured boot extend measurement:
     INFO:     - slot        : 7
-    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - signer_id   : b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec 32 73
+    INFO:                   : e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22 9a da
     INFO:     - version     :
     INFO:     - version_size: 0
     INFO:     - sw_type     : TB_FW_CONFIG
@@ -377,8 +405,8 @@
     INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
     INFO:    Measured boot extend measurement:
     INFO:     - slot        : 8
-    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - signer_id   : b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec 32 73
+    INFO:                   : e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22 9a da
     INFO:     - version     :
     INFO:     - version_size: 0
     INFO:     - sw_type     : BL_2
@@ -483,31 +511,31 @@
     INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
     INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
     INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
-    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 04 60 01 6a
+    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 b0 f3 82 09
+    INFO:            12 97 d8 3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2
+    INFO:            49 59 f6 5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6a
     INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
     INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
     INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
-    INFO:            20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
+    INFO:            20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec 32
+    INFO:            73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22 9a
+    INFO:            da 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
     INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
     INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
-    INFO:            e3 ee af 1b 05 a4 05 58 20 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 65 42 4c 5f
+    INFO:            e3 ee af 1b 05 a4 05 58 20 b0 f3 82 09 12 97 d8
+    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
+    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 65 42 4c 5f
     INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
     INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
-    INFO:            2d 30 28 05 c3 a4 05 58 20 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 6e 53 45 43
+    INFO:            2d 30 28 05 c3 a4 05 58 20 b0 f3 82 09 12 97 d8
+    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
+    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6e 53 45 43
     INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
     INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
     INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
-    INFO:            58 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
+    INFO:            58 20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec
+    INFO:            32 73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22
+    INFO:            9a da 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
     INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
     INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
     INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
@@ -559,31 +587,31 @@
                 "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
             },
             {
-                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
                 "SW_COMPONENT_VERSION": "",
                 "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
                 "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
             },
             {
-                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
                 "SW_COMPONENT_VERSION": "",
                 "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
                 "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
             },
             {
-                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
                 "SW_COMPONENT_VERSION": "",
                 "SW_COMPONENT_TYPE": "BL_2\u0000",
                 "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
             },
             {
-                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
                 "SW_COMPONENT_VERSION": "",
                 "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
                 "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
             },
             {
-                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
                 "SW_COMPONENT_VERSION": "",
                 "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
                 "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
@@ -595,6 +623,57 @@
         "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
     }
 
+RSS OTP Assets Management
+-------------------------
+
+RSS provides access for AP to assets in OTP, which include keys for image
+signature verification and non-volatile counters for anti-rollback protection.
+
+Non-Volatile Counter API
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+AP/RSS interface for retrieving and incrementing non-volatile counters API is
+as follows.
+
+Defined here:
+
+- ``include/lib/psa/rss_platform_api.h``
+
+.. code-block:: c
+
+    psa_status_t rss_platform_nv_counter_increment(uint32_t counter_id)
+
+    psa_status_t rss_platform_nv_counter_read(uint32_t counter_id,
+            uint32_t size, uint8_t *val)
+
+Through this service, we can read/increment any of the 3 non-volatile
+counters used on an Arm CCA platform:
+
+- ``Non-volatile counter for CCA firmware (BL2, BL31, RMM).``
+- ``Non-volatile counter for secure firmware.``
+- ``Non-volatile counter for non-secure firmware.``
+
+Public Key API
+^^^^^^^^^^^^^^
+
+AP/RSS interface for reading the ROTPK is as follows.
+
+Defined here:
+
+- ``include/lib/psa/rss_platform_api.h``
+
+.. code-block:: c
+
+    psa_status_t rss_platform_key_read(enum rss_key_id_builtin_t key,
+            uint8_t *data, size_t data_size, size_t *data_length)
+
+Through this service, we can read any of the 3 ROTPKs used on an
+Arm CCA platform:
+
+- ``ROTPK for CCA firmware (BL2, BL31, RMM).``
+- ``ROTPK for secure firmware.``
+- ``ROTPK for non-secure firmware.``
+
 References
 ----------
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a5633e9..2c018c3 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -45,6 +45,12 @@
    compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
    *Armv8 Architecture Extensions* in :ref:`Firmware Design`.
 
+-  ``ARM_BL2_SP_LIST_DTS``: Path to DTS file snippet to override the hardcoded
+   SP nodes in tb_fw_config.
+
+-  ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
+   SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
+
 -  ``BL2``: This is an optional build option which specifies the path to BL2
    image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
    built.
@@ -302,6 +308,13 @@
    flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_MTE_PERM``: Numeric value to enable support for
+   ``FEAT_MTE_PERM``, which introduces Allocation tag access permission to
+   memory region attributes. ``FEAT_MTE_PERM`` is a optional architectural
+   feature available from v8.9 and upwards.  This flag can take the values 0 to
+   2, to align  with the ``FEATURE_DETECTION`` mechanism. Default value is
+   ``0``.
+
 -  ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
    Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a
    permission fault for any privileged data access from EL1/EL2 to virtual
@@ -506,6 +519,20 @@
    Firmware as error. It can take the value 1 (flag the use of deprecated
    APIs as error) or 0. The default is 0.
 
+-  ``ETHOSN_NPU_DRIVER``: boolean option to enable a SiP service that can
+   configure an Arm® Ethos™-N NPU. To use this service the target platform's
+   ``HW_CONFIG`` must include the device tree nodes for the NPU. Currently, only
+   the Arm Juno platform has this included in its ``HW_CONFIG`` and the platform
+   only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0.
+
+-  ``ETHOSN_NPU_TZMP1``: boolean option to enable TZMP1 support for the
+   Arm® Ethos™-N NPU. Requires ``ETHOSN_NPU_DRIVER`` and
+   ``TRUSTED_BOARD_BOOT`` to be enabled.
+
+-  ``ETHOSN_NPU_FW``: location of the NPU firmware binary
+   (```ethosn.bin```). This firmware image will be included in the FIP and
+   loaded at runtime.
+
 -  ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
    targeted at EL3. When set ``0`` (default), no exceptions are expected or
    handled at EL3, and a panic will result. The exception to this rule is when
@@ -714,6 +741,13 @@
 
    This option defaults to 0.
 
+-  ``MARCH_DIRECTIVE``: used to pass a -march option from the platform build
+   options to the compiler. An example usage:
+
+   .. code:: make
+
+      MARCH_DIRECTIVE := -march=armv8.5-a
+
 -  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
    specifies the file that contains the Non-Trusted World private key in PEM
    format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
@@ -727,6 +761,10 @@
    1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
    wants the timer registers to be saved and restored.
 
+-  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in
+   tb_fw_config device tree. This flag is defined only when
+   ``ARM_SPMC_MANIFEST_DTS`` manifest file name contains pattern optee_sp.
+
 -  ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
    for the BL image. It can be either 0 (include) or 1 (remove). The default
    value is 0.
@@ -875,6 +913,12 @@
    support pre-Armv8.4 platforms (aka not implementing the ``FEAT_SEL2``
    extension).
 
+-  ``ENABLE_SPMD_LP`` : This boolean option is used jointly with the SPM
+   Dispatcher option (``SPD=spmd``). When enabled (1) it indicates support
+   for logical partitions in EL3, managed by the SPMD as defined in the FF-A
+   1.2 specification. This flag is disabled by default. This flag must not be
+   used if ``SPMC_AT_EL3`` is enabled. This is an experimental feature.
+
 -  ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
    Partition Manager (SPM) implementation. The default value is ``0``
    (disabled). This option cannot be enabled (``1``) when SPM Dispatcher is
@@ -936,6 +980,9 @@
       When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
       must also be set to ``1``.
 
+-  ``TS_SP_FW_CONFIG``: DTC build flag to include Trusted Services (Crypto and
+   internal-trusted-storage) as SP in tb_fw_config device tree.
+
 -  ``TWED_DELAY``: Numeric value to be set in order to delay the trapping of
    WFE instruction. ``ENABLE_FEAT_TWED`` build option must be enabled to set
    this delay. It can take values in the range (0-15). Default value is ``0``
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index aa8c2bb..50fff57 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -74,6 +74,26 @@
 
    poetry run make -C docs help
 
+To build the documentation in PDF format, additionally ensure that the following
+packages are installed:
+
+- FreeSerif font
+- latexmk
+- librsvg2-bin
+- xelatex
+- xindy
+
+Below is an example set of instructions to install the required packages
+(tested on Ubuntu):
+
+.. code:: shell
+
+	sudo apt install fonts-freefont-otf latexmk librsvg2-bin texlive-xetex xindy
+
+Once all the dependencies are installed, run the command ``poetry run make -C
+docs latexpdf`` to build the documentation. Output from the build process
+(``trustedfirmware-a.pdf``) can be found in ``docs/build/latex``.
+
 Building rendered documentation from Poetry's virtual environment
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/perf/psci-performance-instr.rst b/docs/perf/psci-performance-instr.rst
index 16f386f..41094b2 100644
--- a/docs/perf/psci-performance-instr.rst
+++ b/docs/perf/psci-performance-instr.rst
@@ -13,16 +13,17 @@
 Performance Measurement Framework
 ---------------------------------
 
-The Performance Measurement Framework `PMF`_ is a framework that provides
-mechanisms for collecting and retrieving timestamps at runtime from the
-Performance Measurement Unit (`PMU`_). The PMU is a generalized abstraction for
-accessing CPU hardware registers used to measure hardware events. This means,
-for instance, that the PMU might be used to place instrumentation points at
-logical locations in code for tracing purposes.
+The Performance Measurement Framework :ref:`PMF <firmware_design_pmf>`
+is a framework that provides mechanisms for collecting and retrieving timestamps
+at runtime from the Performance Measurement Unit
+(:ref:`PMU <Performance Monitoring Unit>`).
+The PMU is a generalized abstraction for accessing CPU hardware registers used to
+measure hardware events. This means, for instance, that the PMU might be used to
+place instrumentation points at logical locations in code for tracing purposes.
 
 TF-A utilises the PMF as a backend for the two instrumentation services it
 provides--PSCI Statistics and Runtime Instrumentation. The PMF is used by
-these services to facilitate collection and retrieval of timestamps.  For
+these services to facilitate collection and retrieval of timestamps. For
 instance, the PSCI Statistics service registers the PMF service
 ``psci_svc`` to track its residency statistics.
 
@@ -112,6 +113,4 @@
 
 *Copyright (c) 2023, Arm Limited. All rights reserved.*
 
-.. _PMF: ../design/firmware-design.html#performance-measurement-framework
-.. _PMU: performance-monitoring-unit.html
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index 7a484b8..d458d86 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -34,8 +34,9 @@
 - TF-A [`v2.9-rc0`_]
 - TFTF [`v2.9-rc0`_]
 
-Please see the Runtime Instrumentation `Testing Methodology`_ page for more
-details.
+Please see the Runtime Instrumentation :ref:`Testing Methodology
+<Runtime Instrumentation Methodology>`
+page for more details.
 
 Procedure
 ---------
@@ -418,4 +419,3 @@
 .. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
 .. _v2.9-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.9-rc0
-.. _Testing Methodology: ../perf/psci-performance-methodology.html
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
index 70a1436..ae1b89b 100644
--- a/docs/perf/psci-performance-n1sdp.rst
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -10,8 +10,8 @@
 - TFTF [`v2.9-rc0`_]
 - SCP/MCP `Prebuilt Images`_
 
-Please see the Runtime Instrumentation `Testing Methodology`_ page for more
-details.
+Please see the Runtime Instrumentation :ref:`Testing Methodology
+<Runtime Instrumentation Methodology>` page for more details.
 
 Procedure
 ---------
@@ -200,4 +200,3 @@
 .. _user guide: https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-docs/-/blob/master/docs/n1sdp/user-guide.rst
 .. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.11.0/n1sdp/release/
 .. _N1SDP: https://developer.arm.com/documentation/101489/latest
-.. _Testing Methodology: ../perf/psci-performance-methodology.html
\ No newline at end of file
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index e0b9242..e81052b 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -95,33 +95,6 @@
    platforms. If this option is specified, then the path to the CryptoCell
    SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
 
--  ``ARM_ETHOSN_NPU_DRIVER``: boolean option to enable a SiP service that can
-   configure an Arm® Ethos™-N NPU. To use this service the target platform's
-   ``HW_CONFIG`` must include the device tree nodes for the NPU. Currently, only
-   the Arm Juno platform has this included in its ``HW_CONFIG`` and the platform
-   only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0.
-
--  ``ARM_ETHOSN_NPU_TZMP1``: boolean option to enable TZMP1 support for the
-   Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` and
-   ``TRUSTED_BOARD_BOOT`` to be enabled.
-
--  ``ARM_ETHOSN_NPU_FW``: location of the NPU firmware binary
-   (```ethosn.bin```). This firmware image will be included in the FIP and
-   loaded at runtime.
-
--  ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
-   SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
-
--  ``ARM_BL2_SP_LIST_DTS``: Path to DTS file snippet to override the hardcoded
-   SP nodes in tb_fw_config.
-
--  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in tb_fw_config
-   device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest
-   file name contains pattern optee_sp.
-
--  ``TS_SP_FW_CONFIG``: DTC build flag to include Trusted Services (Crypto and
-   internal-trusted-storage) as SP in tb_fw_config device tree.
-
 -  ``ARM_GPT_SUPPORT``: Enable GPT parser to get the entry address and length of
    the various partitions present in the GPT image. This support is available
    only for the BL2 component, and it is disabled by default.
diff --git a/docs/plat/arm/morello/index.rst b/docs/plat/arm/morello/index.rst
index b18001c..91549c0 100644
--- a/docs/plat/arm/morello/index.rst
+++ b/docs/plat/arm/morello/index.rst
@@ -12,9 +12,19 @@
 Boot Sequence
 -------------
 
-The execution begins from SCP_BL1 which loads the SCP_BL2 and starts its
-execution. SCP_BL2 powers up the AP which starts execution at AP_BL31. The AP
-then continues executing and hands off execution to Non-secure world (UEFI).
+The SCP initializes the RVBAR registers to point to the AP_BL1. Once RVBAR is
+initialized, the primary core is powered on. The primary core boots the AP_BL1.
+It performs minimum initialization necessary to load and authenticate the AP
+firmware image (the FIP image) from the AP QSPI NOR Flash Memory into the
+Trusted SRAM.
+
+AP_BL1 authenticates and loads the AP_BL2 image. AP_BL2 performs additional
+initializations, and then authenticates and loads the AP_BL31 and AP_BL33.
+AP_BL2 then transfers execution control to AP_BL31, which is the EL3 runtime
+firmware. Execution is finally handed off to AP_BL33, which is the non-secure
+world (UEFI).
+
+SCP -> AP_BL1 -> AP_BL2 -> AP_BL31 -> AP_BL33
 
 Build Procedure (TF-A only)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -30,4 +40,4 @@
 
       make PLAT=morello all
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index fe2cc44..2eec68c 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -28,6 +28,7 @@
    imx8
    imx8m
    imx9
+   npcm845x
    nxp/index
    poplar
    qemu
diff --git a/docs/plat/npcm845x.rst b/docs/plat/npcm845x.rst
new file mode 100644
index 0000000..91dbfd9
--- /dev/null
+++ b/docs/plat/npcm845x.rst
@@ -0,0 +1,21 @@
+Nuvoton NPCM845X
+================
+
+Nuvoton NPCM845X is the Nuvoton Arbel NPCM8XX Board Management controller (BMC) SoC.
+
+The Nuvoton Arbel NPCM845X SoC is a fourth-generation BMC.
+The NPCM845X computing subsystem comprises a quadcore Arm Cortex-A35 CPU.
+
+This SoC includes secured components, i.e., bootblock stored in ROM,
+u-boot, OPTEE-OS, trusted-firmware-a and Linux.
+Every stage is measured and validated by the bootblock.
+This SoC was tested on the Arbel NPCM845X evaluation board.
+
+
+How to Build
+------------
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-none-elf- PLAT=npcm845x all SPD=opteed
+
diff --git a/docs/plat/qti-msm8916.rst b/docs/plat/qti-msm8916.rst
index d7c3642..3bc121a 100644
--- a/docs/plat/qti-msm8916.rst
+++ b/docs/plat/qti-msm8916.rst
@@ -1,16 +1,27 @@
-Qualcomm Snapdragon 410 (MSM8916/APQ8016)
-=========================================
+Qualcomm MSM8916
+================
+The MSM8916 platform port in TF-A supports multiple similar Qualcomm SoCs:
 
-The `Qualcomm Snapdragon 410`_ is Qualcomm's first 64-bit SoC, released in 2014
-with four ARM Cortex-A53 cores. There are differents variants (MSM8916,
-APQ8016(E), ...) that are all very similar. A popular device based on APQ8016E
-is the `DragonBoard 410c`_ single-board computer, but the SoC is also used in
-various mid-range smartphones/tablets.
++-----------------------+----------------+-------------------+-----------------+
+| System-on-Chip (SoC)  | TF-A Platform  | Application CPU   | Supports        |
++=======================+================+===================+=================+
+| `Snapdragon 410`_     |``PLAT=msm8916``| 4x ARM Cortex-A53 | AArch64/AArch32 |
+| (MSM8x16, APQ8016(E)) |                |                   |                 |
+| (`DragonBoard 410c`_) |                |                   |                 |
++-----------------------+----------------+-------------------+-----------------+
+| `Snapdragon 615`_     |``PLAT=msm8939``| 4x ARM Cortex-A53 | AArch64/AArch32 |
+| (MSM8x39, APQ8039)    |                | 4x ARM Cortex-A53 |                 |
++-----------------------+----------------+-------------------+-----------------+
+| `Snapdragon 210`_     |``PLAT=msm8909``| 4x ARM Cortex-A7  | AArch32 only    |
+| (MSM8x09, APQ8009)    |                |                   |                 |
++-----------------------+----------------+-------------------+-----------------+
+| `Snapdragon X5 Modem`_|``PLAT=mdm9607``| 1x ARM Cortex-A7  | AArch32 only    |
+| (MDM9x07)             |                |                   |                 |
++-----------------------+----------------+-------------------+-----------------+
 
-The TF-A port for MSM8916 provides a minimal, community-maintained
-EL3 firmware. It is primarily based on information from the public
-`Snapdragon 410E Technical Reference Manual`_ combined with a lot of
-trial and error to actually make it work.
+It provides a minimal, community-maintained EL3 firmware and PSCI implementation,
+based on information from the public `Snapdragon 410E Technical Reference Manual`_
+combined with a lot of trial and error to actually make it work.
 
 .. note::
 	Unlike the :doc:`QTI SC7180/SC7280 <qti>` ports, this port does **not**
@@ -56,24 +67,27 @@
 
 Build
 -----
-It is possible to build for either AArch64 or AArch32. AArch64 is the preferred
-build option.
+It is possible to build for either AArch64 or AArch32. Some platforms use 32-bit
+CPUs that only support AArch32 (see table above). For all others AArch64 is the
+preferred build option.
 
 AArch64 (BL31)
 ^^^^^^^^^^^^^^
-Setup the cross compiler for AArch64 and build BL31 for ``msm8916``::
+Setup the cross compiler for AArch64 and build BL31 for one of the platforms in
+the table above::
 
-	$ make CROSS_COMPILE=aarch64-none-elf- PLAT=msm8916
+	$ make CROSS_COMPILE=aarch64-none-elf- PLAT=...
 
-The BL31 ELF image is generated in ``build/msm8916/release/bl31/bl31.elf``.
+The BL31 ELF image is generated in ``build/$PLAT/release/bl31/bl31.elf``.
 
 AArch32 (BL32/SP_MIN)
 ^^^^^^^^^^^^^^^^^^^^^
-Setup the cross compiler for AArch32 and build BL32 with SP_MIN for ``msm8916``::
+Setup the cross compiler for AArch32 and build BL32 with SP_MIN for one of the
+platforms in the table above::
 
-	$ make CROSS_COMPILE=arm-none-eabi- PLAT=msm8916 ARCH=aarch32 AARCH32_SP=sp_min
+	$ make CROSS_COMPILE=arm-none-eabi- PLAT=... ARCH=aarch32 AARCH32_SP=sp_min
 
-The BL32 ELF image is generated in ``build/msm8916/release/bl32/bl32.elf``.
+The BL32 ELF image is generated in ``build/$PLAT/release/bl32/bl32.elf``.
 
 Build Options
 -------------
@@ -186,7 +200,10 @@
 	[0] welcome to lk
 	...
 
-.. _Qualcomm Snapdragon 410: https://www.qualcomm.com/products/snapdragon-processors-410
+.. _Snapdragon 210: https://www.qualcomm.com/products/snapdragon-processors-210
+.. _Snapdragon 410: https://www.qualcomm.com/products/snapdragon-processors-410
+.. _Snapdragon 615: https://www.qualcomm.com/products/snapdragon-processors-615
+.. _Snapdragon X5 Modem: https://www.qualcomm.com/products/snapdragon-modems-4g-lte-x5
 .. _DragonBoard 410c: https://www.96boards.org/product/dragonboard410c/
 .. _Snapdragon 410E Technical Reference Manual: https://developer.qualcomm.com/download/sd410/snapdragon-410e-technical-reference-manual.pdf
 .. _U-Boot for DragonBoard 410c: https://u-boot.readthedocs.io/en/latest/board/qualcomm/dragonboard410c.html
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index b557a16..5a017ce 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -591,32 +591,32 @@
 If the platform port uses the Arm® Ethos™-N NPU driver with TZMP1 support
 enabled, the following constants and configuration must also be defined:
 
-- **ARM_ETHOSN_NPU_PROT_FW_NSAID**
+- **ETHOSN_NPU_PROT_FW_NSAID**
 
   Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to
   access the protected memory that contains the NPU's firmware.
 
-- **ARM_ETHOSN_NPU_PROT_DATA_RW_NSAID**
+- **ETHOSN_NPU_PROT_DATA_RW_NSAID**
 
   Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
   read/write access to the protected memory that contains inference data.
 
-- **ARM_ETHOSN_NPU_PROT_DATA_RO_NSAID**
+- **ETHOSN_NPU_PROT_DATA_RO_NSAID**
 
   Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
   read-only access to the protected memory that contains inference data.
 
-- **ARM_ETHOSN_NPU_NS_RW_DATA_NSAID**
+- **ETHOSN_NPU_NS_RW_DATA_NSAID**
 
   Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
   read/write access to the non-protected memory.
 
-- **ARM_ETHOSN_NPU_NS_RO_DATA_NSAID**
+- **ETHOSN_NPU_NS_RO_DATA_NSAID**
 
   Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for
   read-only access to the non-protected memory.
 
-- **ARM_ETHOSN_NPU_FW_IMAGE_BASE** and **ARM_ETHOSN_NPU_FW_IMAGE_LIMIT**
+- **ETHOSN_NPU_FW_IMAGE_BASE** and **ETHOSN_NPU_FW_IMAGE_LIMIT**
 
   Defines the physical address range that the NPU's firmware will be loaded
   into and executed from.
@@ -634,10 +634,10 @@
 - Add MMU mappings such that:
 
  - BL2 can write the NPU firmware into the region defined by
-   ``ARM_ETHOSN_NPU_FW_IMAGE_BASE`` and ``ARM_ETHOSN_NPU_FW_IMAGE_LIMIT``
+   ``ETHOSN_NPU_FW_IMAGE_BASE`` and ``ETHOSN_NPU_FW_IMAGE_LIMIT``
  - BL31 (SiP service) can read the NPU firmware from the same region
 
-- Add the firmware image ID ``ARM_ETHOSN_NPU_FW_IMAGE_ID`` to the list of images
+- Add the firmware image ID ``ETHOSN_NPU_FW_IMAGE_ID`` to the list of images
   loaded by BL2.
 
 Please see the reference implementation code for the Juno platform as an example.
@@ -1509,43 +1509,6 @@
 the SMCCC function specified in the argument; otherwise returns
 SMC_ARCH_CALL_NOT_SUPPORTED.
 
-Function : plat_mboot_measure_image()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : unsigned int, image_info_t *
-    Return   : int
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function measures the given image and records its measurement using
-   the measured boot backend driver.
--  On the Arm FVP port, this function measures the given image using its
-   passed id and information and then records that measurement in the
-   Event Log buffer.
--  This function must return 0 on success, a signed integer error code
-   otherwise.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : plat_mboot_measure_critical_data()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : unsigned int, const void *, size_t
-    Return   : int
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function measures the given critical data structure and records its
-   measurement using the measured boot backend driver.
--  This function must return 0 on success, a signed integer error code
-   otherwise.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Function : plat_can_cmo()
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1813,42 +1776,6 @@
 The default implementation of this function asserts therefore platforms must
 override it when using the FWU feature.
 
-Function : bl1_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to initialize the backend driver(s) of measured boot.
--  On the Arm FVP port, this function is used to initialize the Event Log
-   backend driver, and also to write header information in the Event Log buffer.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl1_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to finalize the measured boot backend driver(s),
-   and also, set the information for the next bootloader component to
-   extend the measurement if needed.
--  On the Arm FVP port, this function is used to pass the base address of
-   the Event Log buffer and its size to BL2 via tb_fw_config to extend the
-   Event Log buffer with the measurement of various images loaded by BL2.
-   It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Boot Loader Stage 2 (BL2)
 -------------------------
 
@@ -1980,42 +1907,6 @@
 must return 0, otherwise it must return 1. The default implementation
 of this always returns 0.
 
-Function : bl2_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to initialize the backend driver(s) of measured boot.
--  On the Arm FVP port, this function is used to initialize the Event Log
-   backend driver with the Event Log buffer information (base address and
-   size) received from BL1. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl2_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : void
-
-When the MEASURED_BOOT flag is enabled:
-
--  This function is used to finalize the measured boot backend driver(s),
-   and also, set the information for the next bootloader component to extend
-   the measurement if needed.
--  On the Arm FVP port, this function is used to pass the Event Log buffer
-   information (base address and size) to non-secure(BL33) and trusted OS(BL32)
-   via nt_fw and tos_fw config respectively. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
 Boot Loader Stage 2 (BL2) at EL3
 --------------------------------
 
@@ -3664,6 +3555,12 @@
 dynamically allocating memory. This may also have the affect of limiting the
 amount of open resources per driver.
 
+Measured Boot Platform Interface
+--------------------------------
+
+Enabling the MEASURED_BOOT flag adds extra platform requirements. Please refer
+to :ref:`Measured Boot Design` for more details.
+
 --------------
 
 *Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/process/code-review-guidelines.rst b/docs/process/code-review-guidelines.rst
index ccdd110..bd42811 100644
--- a/docs/process/code-review-guidelines.rst
+++ b/docs/process/code-review-guidelines.rst
@@ -94,6 +94,14 @@
    directory to have the freedom to change it in any way. This way, your changes
    benefit everyone and will be maintained over time.
 
+-  It is the patch-author's responsibility to respond to review comments within
+   21 days. In the event that the patch-author does not respond within this
+   timeframe, the maintainer is entitled to abandon the patch(es).
+   Patch author(s) may be busy with other priorities, causing a delay in
+   responding to active review comments after posting patch(es). In such a
+   situation, if the author's patch(es) is/are abandoned, they can restore
+   their work for review by resolving comments, merge-conflicts, and revising
+   their original submissions.
 
 Guidelines for all reviewers
 ----------------------------
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index c951754..faf9634 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -79,7 +79,13 @@
 FWU-update_struct_layers		= "background"
 FWU-update_struct_opts			=
 
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG)
+MB_DESIGN_DIA				= measured_boot_design.dia
+MB_DESIGN_PNG				= measured_boot_design.png
+
+measured_boot_design_layers		= "background"
+measured_boot_design_opts		=
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG) $(MB_DESIGN_PNG)
 
 $(RESET_PNGS):$(RESET_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -99,3 +105,6 @@
 
 $(PSA_FWU_PNG):$(PSA_FWU_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(MB_DESIGN_PNG):$(MB_DESIGN_DIA)
+	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/measured_boot_design.dia b/docs/resources/diagrams/measured_boot_design.dia
new file mode 100644
index 0000000..fdae464
--- /dev/null
+++ b/docs/resources/diagrams/measured_boot_design.dia
Binary files differ
diff --git a/docs/resources/diagrams/measured_boot_design.png b/docs/resources/diagrams/measured_boot_design.png
new file mode 100644
index 0000000..42469be
--- /dev/null
+++ b/docs/resources/diagrams/measured_boot_design.png
Binary files differ
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 71ec9b1..57a5e1b 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -7,10 +7,7 @@
 
 This document provides a generic threat model for TF-A firmware.
 
-.. note::
-
- This threat model doesn't consider Root and Realm worlds introduced by
- :ref:`Realm Management Extension (RME)`.
+.. _Target of Evaluation:
 
 ********************
 Target of Evaluation
@@ -36,33 +33,12 @@
 - There is no Secure-EL2. We don't consider threats that may come with
   Secure-EL2 software.
 
+- There are no Root and Realm worlds. These are introduced by :ref:`Realm
+  Management Extension (RME)`.
+
 - No experimental features are enabled. We do not consider threats that may come
   from them.
 
-.. note::
-
- In the current Measured Boot design, BL1, BL2, and BL31, as well as the
- secure world components, form the |SRTM|. Measurement data is currently
- considered an asset to be protected against attack, and this is achieved
- by storing them in the Secure Memory.
- Beyond the measurements stored inside the TCG-compliant Event Log buffer,
- there are no other assets to protect or threats to defend against that
- could compromise |TF-A| execution environment's security.
-
- There are general security assets and threats associated with remote/delegated
- attestation. However, these are outside the |TF-A| security boundary and
- should be dealt with by the appropriate agent in the platform/system.
- Since current Measured Boot design does not use local attestation, there would
- be no further assets to protect(like unsealed keys).
-
- A limitation of the current Measured Boot design is that it is dependent upon
- Secure Boot as implementation of Measured Boot does not extend measurements
- into a discrete |TPM|, where they would be securely stored and protected
- against tampering. This implies that if Secure-Boot is compromised, Measured
- Boot may also be compromised.
-
- Platforms must carefully evaluate the security of the default implementation
- since the |SRTM| includes all secure world components.
 
 Data Flow Diagram
 =================
@@ -108,6 +84,8 @@
   |                 |   interrupts and registers.                            |
   +-----------------+--------------------------------------------------------+
 
+
+.. _threat_analysis:
 
 ***************
 Threat Analysis
@@ -286,201 +264,16 @@
 Also, some mitigations require enabling specific features, which must be
 explicitly turned on via a build flag.
 
-These are highlighted in the ``Mitigations implemented?`` box.
-
-+------------------------+----------------------------------------------------+
-| ID                     | 01                                                 |
-+========================+====================================================+
-| Threat                 | | **An attacker can mangle firmware images to      |
-|                        |   execute arbitrary code**                         |
-|                        |                                                    |
-|                        | | Some TF-A images are loaded from external        |
-|                        |   storage. It is possible for an attacker to access|
-|                        |   the external flash memory and change its contents|
-|                        |   physically, through the Rich OS, or using the    |
-|                        |   updating mechanism to modify the non-volatile    |
-|                        |   images to execute arbitrary code.                |
-+------------------------+----------------------------------------------------+
-| Diagram Elements       | DF1, DF4, DF5                                      |
-+------------------------+----------------------------------------------------+
-| Affected TF-A          | BL2, BL31                                          |
-| Components             |                                                    |
-+------------------------+----------------------------------------------------+
-| Assets                 | Code Execution                                     |
-+------------------------+----------------------------------------------------+
-| Threat Agent           | PhysicalAccess, NSCode, SecCode                    |
-+------------------------+----------------------------------------------------+
-| Threat Type            | Tampering, Elevation of Privilege                  |
-+------------------------+------------------+-----------------+---------------+
-| Application            | Server           | IoT             | Mobile        |
-+------------------------+------------------+-----------------+---------------+
-| Impact                 | Critical (5)     | Critical (5)    | Critical (5)  |
-+------------------------+------------------+-----------------+---------------+
-| Likelihood             | Critical (5)     | Critical (5)    | Critical (5)  |
-+------------------------+------------------+-----------------+---------------+
-| Total Risk Rating      | Critical (25)    | Critical (25)   | Critical (25) |
-+------------------------+------------------+-----------------+---------------+
-| Mitigations            | | 1) Implement the `Trusted Board Boot (TBB)`_     |
-|                        |   feature which prevents malicious firmware from   |
-|                        |   running on the platform by authenticating all    |
-|                        |   firmware images.                                 |
-|                        |                                                    |
-|                        | | 2) Perform extra checks on unauthenticated data, |
-|                        |   such as FIP metadata, prior to use.              |
-+------------------------+----------------------------------------------------+
-| Mitigations            | | 1) Yes, provided that the ``TRUSTED_BOARD_BOOT`` |
-| implemented?           |   build option is set to 1.                        |
-|                        |                                                    |
-|                        | | 2) Yes.                                          |
-+------------------------+----------------------------------------------------+
-
-+------------------------+----------------------------------------------------+
-| ID                     | 02                                                 |
-+========================+====================================================+
-| Threat                 | | **An attacker may attempt to boot outdated,      |
-|                        |   potentially vulnerable firmware image**          |
-|                        |                                                    |
-|                        | | When updating firmware, an attacker may attempt  |
-|                        |   to rollback to an older version that has unfixed |
-|                        |   vulnerabilities.                                 |
-+------------------------+----------------------------------------------------+
-| Diagram Elements       | DF1, DF4, DF5                                      |
-+------------------------+----------------------------------------------------+
-| Affected TF-A          | BL2, BL31                                          |
-| Components             |                                                    |
-+------------------------+----------------------------------------------------+
-| Assets                 | Code Execution                                     |
-+------------------------+----------------------------------------------------+
-| Threat Agent           | PhysicalAccess, NSCode, SecCode                    |
-+------------------------+----------------------------------------------------+
-| Threat Type            | Tampering                                          |
-+------------------------+------------------+-----------------+---------------+
-| Application            | Server           | IoT             | Mobile        |
-+------------------------+------------------+-----------------+---------------+
-| Impact                 | Critical (5)     | Critical (5)    | Critical (5)  |
-+------------------------+------------------+-----------------+---------------+
-| Likelihood             | Critical (5)     | Critical (5)    | Critical (5)  |
-+------------------------+------------------+-----------------+---------------+
-| Total Risk Rating      | Critical (25)    | Critical (25)   | Critical (25) |
-+------------------------+------------------+-----------------+---------------+
-| Mitigations            | Implement anti-rollback protection using           |
-|                        | non-volatile counters (NV counters) as required    |
-|                        | by `TBBR-Client specification`_.                   |
-+------------------------+----------------------------------------------------+
-| Mitigations            | | Yes / Platform specific.                         |
-| implemented?           |                                                    |
-|                        | | After a firmware image is validated, the image   |
-|                        |   revision number taken from a certificate         |
-|                        |   extension field is compared with the             |
-|                        |   corresponding NV counter stored in hardware to   |
-|                        |   make sure the new counter value is larger than   |
-|                        |   the current counter value.                       |
-|                        |                                                    |
-|                        | | **Platforms must implement this protection using |
-|                        |   platform specific hardware NV counters.**        |
-+------------------------+----------------------------------------------------+
+When such conditions must be met, these are highlighted in the ``Mitigations
+implemented?`` box.
 
-+------------------------+-------------------------------------------------------+
-| ID                     | 03                                                    |
-+========================+=======================================================+
-| Threat                 | | **An attacker can use Time-of-Check-Time-of-Use     |
-|                        |   (TOCTOU) attack to bypass image authentication      |
-|                        |   during the boot process**                           |
-|                        |                                                       |
-|                        | | Time-of-Check-Time-of-Use (TOCTOU) threats occur    |
-|                        |   when the security check is produced before the time |
-|                        |   the resource is accessed. If an attacker is sitting |
-|                        |   in the middle of the off-chip images, they could    |
-|                        |   change the binary containing executable code right  |
-|                        |   after the integrity and authentication check has    |
-|                        |   been performed.                                     |
-+------------------------+-------------------------------------------------------+
-| Diagram Elements       | DF1                                                   |
-+------------------------+-------------------------------------------------------+
-| Affected TF-A          | BL1, BL2                                              |
-| Components             |                                                       |
-+------------------------+-------------------------------------------------------+
-| Assets                 | Code Execution, Sensitive Data                        |
-+------------------------+-------------------------------------------------------+
-| Threat Agent           | PhysicalAccess                                        |
-+------------------------+-------------------------------------------------------+
-| Threat Type            | Elevation of Privilege                                |
-+------------------------+---------------------+-----------------+---------------+
-| Application            | Server              | IoT             | Mobile        |
-+------------------------+---------------------+-----------------+---------------+
-| Impact                 | N/A                 | Critical (5)    | Critical (5)  |
-+------------------------+---------------------+-----------------+---------------+
-| Likelihood             | N/A                 | Medium (3)      | Medium (3)    |
-+------------------------+---------------------+-----------------+---------------+
-| Total Risk Rating      | N/A                 | High (15)       | High (15)     |
-+------------------------+---------------------+-----------------+---------------+
-| Mitigations            | Copy image to on-chip memory before authenticating    |
-|                        | it.                                                   |
-+------------------------+-------------------------------------------------------+
-| Mitigations            | | Platform specific.                                  |
-| implemented?           |                                                       |
-|                        | | The list of images to load and their location is    |
-|                        |   platform specific. Platforms are responsible for    |
-|                        |   arranging images to be loaded in on-chip memory.    |
-+------------------------+-------------------------------------------------------+
+As our :ref:`Target of Evaluation` is made of several, distinct firmware images,
+some threats are confined in specific images, while others apply to each of
+them. To help developers implement mitigations in the right place, threats below
+are categorized based on the firmware image that should mitigate them.
 
-+------------------------+-------------------------------------------------------+
-| ID                     | 04                                                    |
-+========================+=======================================================+
-| Threat                 | | **An attacker with physical access can execute      |
-|                        |   arbitrary image by bypassing the signature          |
-|                        |   verification stage using glitching techniques**     |
-|                        |                                                       |
-|                        | | Glitching (Fault injection) attacks attempt to put  |
-|                        |   a hardware into a undefined state by manipulating an|
-|                        |   environmental variable such as power supply.        |
-|                        |                                                       |
-|                        | | TF-A relies on a chain of trust that starts with the|
-|                        |   ROTPK, which is the key stored inside the chip and  |
-|                        |   the root of all validation processes. If an attacker|
-|                        |   can break this chain of trust, they could execute   |
-|                        |   arbitrary code on the device. This could be         |
-|                        |   achieved with physical access to the device by      |
-|                        |   attacking the normal execution flow of the          |
-|                        |   process using glitching techniques that target      |
-|                        |   points where the image is validated against the     |
-|                        |   signature.                                          |
-+------------------------+-------------------------------------------------------+
-| Diagram Elements       | DF1                                                   |
-+------------------------+-------------------------------------------------------+
-| Affected TF-A          | BL1, BL2                                              |
-| Components             |                                                       |
-+------------------------+-------------------------------------------------------+
-| Assets                 | Code Execution                                        |
-+------------------------+-------------------------------------------------------+
-| Threat Agent           | PhysicalAccess                                        |
-+------------------------+-------------------------------------------------------+
-| Threat Type            | Tampering, Elevation of Privilege                     |
-+------------------------+---------------------+-----------------+---------------+
-| Application            | Server              | IoT             | Mobile        |
-+------------------------+---------------------+-----------------+---------------+
-| Impact                 | N/A                 | Critical (5)    | Critical (5)  |
-+------------------------+---------------------+-----------------+---------------+
-| Likelihood             | N/A                 | Medium (3)      | Medium (3)    |
-+------------------------+---------------------+-----------------+---------------+
-| Total Risk Rating      | N/A                 | High (15)       | High (15)     |
-+------------------------+---------------------+-----------------+---------------+
-| Mitigations            | Mechanisms to detect clock glitch and power           |
-|                        | variations.                                           |
-+------------------------+-------------------------------------------------------+
-| Mitigations            | | No.                                                 |
-| implemented?           |                                                       |
-|                        | | The most effective mitigation is adding glitching   |
-|                        |   detection and mitigation circuit at the hardware    |
-|                        |   level.                                              |
-|                        |                                                       |
-|                        | | However, software techniques, such as adding        |
-|                        |   redundant checks when performing conditional        |
-|                        |   branches that are security sensitive, can be used   |
-|                        |   to harden TF-A against such attacks.                |
-|                        |   **At the moment TF-A doesn't implement such         |
-|                        |   mitigations.**                                      |
-+------------------------+-------------------------------------------------------+
+General Threats for All Firmware Images
+---------------------------------------
 
 +------------------------+---------------------------------------------------+
 | ID                     | 05                                                |
@@ -598,77 +391,34 @@
 +------------------------+----------------------------------------------------+
 
 +------------------------+------------------------------------------------------+
-| ID                     | 07                                                   |
+| ID                     | 08                                                   |
 +========================+======================================================+
-| Threat                 | | **An attacker can perform a denial-of-service      |
-|                        |   attack by using a broken SMC call that causes the  |
-|                        |   system to reboot or enter into unknown state.**    |
+| Threat                 | | **Memory corruption due to memory overflows and    |
+|                        |   lack of boundary checking when accessing resources |
+|                        |   could allow an attacker to execute arbitrary code, |
+|                        |   modify some state variable to change the normal    |
+|                        |   flow of the program, or leak sensitive             |
+|                        |   information**                                      |
 |                        |                                                      |
-|                        | | Secure and non-secure clients access TF-A services |
-|                        |   through SMC calls. Malicious code can attempt to   |
-|                        |   place the TF-A runtime into an inconsistent state  |
-|                        |   by calling unimplemented SMC call or by passing    |
-|                        |   invalid arguments.                                 |
+|                        | | Like in other software, TF-A has multiple points   |
+|                        |   where memory corruption security errors can arise. |
+|                        |                                                      |
+|                        | | Some of the errors include integer overflow,       |
+|                        |   buffer overflow, incorrect array boundary checks,  |
+|                        |   and incorrect error management.                    |
+|                        |   Improper use of asserts instead of proper input    |
+|                        |   validations might also result in these kinds of    |
+|                        |   errors in release builds.                          |
 +------------------------+------------------------------------------------------+
 | Diagram Elements       | DF4, DF5                                             |
 +------------------------+------------------------------------------------------+
-| Affected TF-A          | BL31                                                 |
+| Affected TF-A          | BL1, BL2, BL31                                       |
 | Components             |                                                      |
 +------------------------+------------------------------------------------------+
-| Assets                 | Availability                                         |
+| Assets                 | Code Execution, Sensitive Data                       |
 +------------------------+------------------------------------------------------+
 | Threat Agent           | NSCode, SecCode                                      |
 +------------------------+------------------------------------------------------+
-| Threat Type            | Denial of Service                                    |
-+------------------------+-------------------+----------------+-----------------+
-| Application            | Server            | IoT            | Mobile          |
-+------------------------+-------------------+----------------+-----------------+
-| Impact                 | Medium (3)        | Medium (3)     | Medium (3)      |
-+------------------------+-------------------+----------------+-----------------+
-| Likelihood             | High (4)          | High (4)       | High (4)        |
-+------------------------+-------------------+----------------+-----------------+
-| Total Risk Rating      | High (12)         | High (12)      | High (12)       |
-+------------------------+-------------------+----------------+-----------------+
-| Mitigations            | Validate SMC function ids and arguments before using |
-|                        | them.                                                |
-+------------------------+------------------------------------------------------+
-| Mitigations            | | Yes / Platform specific.                           |
-| implemented?           |                                                      |
-|                        | | For standard services, all input is validated.     |
-|                        |                                                      |
-|                        | | Platforms that implement SiP services must also    |
-|                        |   validate SMC call arguments.                       |
-+------------------------+------------------------------------------------------+
-
-+------------------------+------------------------------------------------------+
-| ID                     | 08                                                   |
-+========================+======================================================+
-| Threat                 | | **Memory corruption due to memory overflows and    |
-|                        |   lack of boundary checking when accessing resources |
-|                        |   could allow an attacker to execute arbitrary code, |
-|                        |   modify some state variable to change the normal    |
-|                        |   flow of the program, or leak sensitive             |
-|                        |   information**                                      |
-|                        |                                                      |
-|                        | | Like in other software, TF-A has multiple points   |
-|                        |   where memory corruption security errors can arise. |
-|                        |                                                      |
-|                        | | Some of the errors include integer overflow,       |
-|                        |   buffer overflow, incorrect array boundary checks,  |
-|                        |   and incorrect error management.                    |
-|                        |   Improper use of asserts instead of proper input    |
-|                        |   validations might also result in these kinds of    |
-|                        |   errors in release builds.                          |
-+------------------------+------------------------------------------------------+
-| Diagram Elements       | DF4, DF5                                             |
-+------------------------+------------------------------------------------------+
-| Affected TF-A          | BL1, BL2, BL31                                       |
-| Components             |                                                      |
-+------------------------+------------------------------------------------------+
-| Assets                 | Code Execution, Sensitive Data                       |
-+------------------------+------------------------------------------------------+
-| Threat Agent           | NSCode, SecCode                                      |
-+------------------------+------------------------------------------------------+
 | Threat Type            | Tampering, Information Disclosure,                   |
 |                        | Elevation of Privilege                               |
 +------------------------+-------------------+-----------------+----------------+
@@ -712,6 +462,380 @@
 |                        |   platforms.                                         |
 +------------------------+------------------------------------------------------+
 
+
++------------------------+----------------------------------------------------+
+| ID                     | 11                                                 |
++========================+====================================================+
+| Threat                 | | **Misconfiguration of the Memory Management Unit |
+|                        |   (MMU) may allow a normal world software to       |
+|                        |   access sensitive data, execute arbitrary         |
+|                        |   code or access otherwise restricted HW           |
+|                        |   interface**                                      |
+|                        |                                                    |
+|                        | | A misconfiguration of the MMU could              |
+|                        |   lead to an open door for software running in the |
+|                        |   normal world to access sensitive data or even    |
+|                        |   execute code if the proper security mechanisms   |
+|                        |   are not in place.                                |
++------------------------+----------------------------------------------------+
+| Diagram Elements       | DF5, DF6                                           |
++------------------------+----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                     |
+| Components             |                                                    |
++------------------------+----------------------------------------------------+
+| Assets                 | Sensitive Data, Code execution                     |
++------------------------+----------------------------------------------------+
+| Threat Agent           | NSCode                                             |
++------------------------+----------------------------------------------------+
+| Threat Type            | Information Disclosure, Elevation of Privilege     |
++------------------------+-----------------+-----------------+----------------+
+| Application            | Server          | IoT             | Mobile         |
++------------------------+-----------------+-----------------+----------------+
+| Impact                 | Critical (5)    | Critical (5)    | Critical (5)   |
++------------------------+-----------------+-----------------+----------------+
+| Likelihood             | High (4)        | High (4)        | High (4)       |
++------------------------+-----------------+-----------------+----------------+
+| Total Risk Rating      | Critical (20)   | Critical (20)   | Critical (20)  |
++------------------------+-----------------+-----------------+----------------+
+| Mitigations            | When configuring access permissions, the           |
+|                        | principle of least privilege ought to be           |
+|                        | enforced. This means we should not grant more      |
+|                        | privileges than strictly needed, e.g. code         |
+|                        | should be read-only executable, read-only data     |
+|                        | should be read-only execute-never, and so on.      |
++------------------------+----------------------------------------------------+
+| Mitigations            | | Platform specific.                               |
+| implemented?           |                                                    |
+|                        | | MMU configuration is platform specific,          |
+|                        |   therefore platforms need to make sure that the   |
+|                        |   correct attributes are assigned to memory        |
+|                        |   regions.                                         |
+|                        |                                                    |
+|                        | | TF-A provides a library which abstracts the      |
+|                        |   low-level details of MMU configuration. It       |
+|                        |   provides well-defined and tested APIs.           |
+|                        |   Platforms are encouraged to use it to limit the  |
+|                        |   risk of misconfiguration.                        |
++------------------------+----------------------------------------------------+
+
+
++------------------------+-----------------------------------------------------+
+| ID                     | 13                                                  |
++========================+=====================================================+
+| Threat                 | | **Leaving sensitive information in the memory,    |
+|                        |   can allow an attacker to retrieve them.**         |
+|                        |                                                     |
+|                        | | Accidentally leaving not-needed sensitive data in |
+|                        |   internal buffers can leak them if an attacker     |
+|                        |   gains access to memory due to a vulnerability.    |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF4, DF5                                            |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                      |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Sensitive Data                                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | NSCode, SecCode                                     |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Information Disclosure                              |
++------------------------+-------------------+----------------+----------------+
+| Application            | Server            | IoT            | Mobile         |
++------------------------+-------------------+----------------+----------------+
+| Impact                 |  Critical (5)     | Critical (5)   | Critical (5)   |
++------------------------+-------------------+----------------+----------------+
+| Likelihood             |  Medium (3)       | Medium (3)     | Medium (3)     |
++------------------------+-------------------+----------------+----------------+
+| Total Risk Rating      |  High (15)        | High (15)      | High (15)      |
++------------------------+-------------------+----------------+----------------+
+| Mitigations            |   Clear the sensitive data from internal buffers as |
+|                        |   soon as they are not needed anymore.              |
++------------------------+-----------------------------------------------------+
+| Mitigations            | | Yes / Platform specific                           |
++------------------------+-----------------------------------------------------+
+
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The boot firmware here refers to the boot ROM (BL1) and the trusted boot
+firmware (BL2). Typically it does not stay resident in memory and it is
+dismissed once execution has reached the runtime EL3 firmware (BL31). Thus, past
+that point in time, the threats below can no longer be exploited.
+
+Note, however, that this is not necessarily true on all platforms. Platform
+vendors should review these threats to make sure they cannot be exploited
+nonetheless once execution has reached the runtime EL3 firmware.
+
++------------------------+----------------------------------------------------+
+| ID                     | 01                                                 |
++========================+====================================================+
+| Threat                 | | **An attacker can mangle firmware images to      |
+|                        |   execute arbitrary code**                         |
+|                        |                                                    |
+|                        | | Some TF-A images are loaded from external        |
+|                        |   storage. It is possible for an attacker to access|
+|                        |   the external flash memory and change its contents|
+|                        |   physically, through the Rich OS, or using the    |
+|                        |   updating mechanism to modify the non-volatile    |
+|                        |   images to execute arbitrary code.                |
++------------------------+----------------------------------------------------+
+| Diagram Elements       | DF1, DF4, DF5                                      |
++------------------------+----------------------------------------------------+
+| Affected TF-A          | BL2, BL31                                          |
+| Components             |                                                    |
++------------------------+----------------------------------------------------+
+| Assets                 | Code Execution                                     |
++------------------------+----------------------------------------------------+
+| Threat Agent           | PhysicalAccess, NSCode, SecCode                    |
++------------------------+----------------------------------------------------+
+| Threat Type            | Tampering, Elevation of Privilege                  |
++------------------------+------------------+-----------------+---------------+
+| Application            | Server           | IoT             | Mobile        |
++------------------------+------------------+-----------------+---------------+
+| Impact                 | Critical (5)     | Critical (5)    | Critical (5)  |
++------------------------+------------------+-----------------+---------------+
+| Likelihood             | Critical (5)     | Critical (5)    | Critical (5)  |
++------------------------+------------------+-----------------+---------------+
+| Total Risk Rating      | Critical (25)    | Critical (25)   | Critical (25) |
++------------------------+------------------+-----------------+---------------+
+| Mitigations            | | 1) Implement the `Trusted Board Boot (TBB)`_     |
+|                        |   feature which prevents malicious firmware from   |
+|                        |   running on the platform by authenticating all    |
+|                        |   firmware images.                                 |
+|                        |                                                    |
+|                        | | 2) Perform extra checks on unauthenticated data, |
+|                        |   such as FIP metadata, prior to use.              |
++------------------------+----------------------------------------------------+
+| Mitigations            | | 1) Yes, provided that the ``TRUSTED_BOARD_BOOT`` |
+| implemented?           |   build option is set to 1.                        |
+|                        |                                                    |
+|                        | | 2) Yes.                                          |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 02                                                 |
++========================+====================================================+
+| Threat                 | | **An attacker may attempt to boot outdated,      |
+|                        |   potentially vulnerable firmware image**          |
+|                        |                                                    |
+|                        | | When updating firmware, an attacker may attempt  |
+|                        |   to rollback to an older version that has unfixed |
+|                        |   vulnerabilities.                                 |
++------------------------+----------------------------------------------------+
+| Diagram Elements       | DF1, DF4, DF5                                      |
++------------------------+----------------------------------------------------+
+| Affected TF-A          | BL2, BL31                                          |
+| Components             |                                                    |
++------------------------+----------------------------------------------------+
+| Assets                 | Code Execution                                     |
++------------------------+----------------------------------------------------+
+| Threat Agent           | PhysicalAccess, NSCode, SecCode                    |
++------------------------+----------------------------------------------------+
+| Threat Type            | Tampering                                          |
++------------------------+------------------+-----------------+---------------+
+| Application            | Server           | IoT             | Mobile        |
++------------------------+------------------+-----------------+---------------+
+| Impact                 | Critical (5)     | Critical (5)    | Critical (5)  |
++------------------------+------------------+-----------------+---------------+
+| Likelihood             | Critical (5)     | Critical (5)    | Critical (5)  |
++------------------------+------------------+-----------------+---------------+
+| Total Risk Rating      | Critical (25)    | Critical (25)   | Critical (25) |
++------------------------+------------------+-----------------+---------------+
+| Mitigations            | Implement anti-rollback protection using           |
+|                        | non-volatile counters (NV counters) as required    |
+|                        | by `TBBR-Client specification`_.                   |
++------------------------+----------------------------------------------------+
+| Mitigations            | | Yes / Platform specific.                         |
+| implemented?           |                                                    |
+|                        | | After a firmware image is validated, the image   |
+|                        |   revision number taken from a certificate         |
+|                        |   extension field is compared with the             |
+|                        |   corresponding NV counter stored in hardware to   |
+|                        |   make sure the new counter value is larger than   |
+|                        |   the current counter value.                       |
+|                        |                                                    |
+|                        | | **Platforms must implement this protection using |
+|                        |   platform specific hardware NV counters.**        |
++------------------------+----------------------------------------------------+
+
+
++------------------------+-------------------------------------------------------+
+| ID                     | 03                                                    |
++========================+=======================================================+
+| Threat                 | | **An attacker can use Time-of-Check-Time-of-Use     |
+|                        |   (TOCTOU) attack to bypass image authentication      |
+|                        |   during the boot process**                           |
+|                        |                                                       |
+|                        | | Time-of-Check-Time-of-Use (TOCTOU) threats occur    |
+|                        |   when the security check is produced before the time |
+|                        |   the resource is accessed. If an attacker is sitting |
+|                        |   in the middle of the off-chip images, they could    |
+|                        |   change the binary containing executable code right  |
+|                        |   after the integrity and authentication check has    |
+|                        |   been performed.                                     |
++------------------------+-------------------------------------------------------+
+| Diagram Elements       | DF1                                                   |
++------------------------+-------------------------------------------------------+
+| Affected TF-A          | BL1, BL2                                              |
+| Components             |                                                       |
++------------------------+-------------------------------------------------------+
+| Assets                 | Code Execution, Sensitive Data                        |
++------------------------+-------------------------------------------------------+
+| Threat Agent           | PhysicalAccess                                        |
++------------------------+-------------------------------------------------------+
+| Threat Type            | Elevation of Privilege                                |
++------------------------+---------------------+-----------------+---------------+
+| Application            | Server              | IoT             | Mobile        |
++------------------------+---------------------+-----------------+---------------+
+| Impact                 | N/A                 | Critical (5)    | Critical (5)  |
++------------------------+---------------------+-----------------+---------------+
+| Likelihood             | N/A                 | Medium (3)      | Medium (3)    |
++------------------------+---------------------+-----------------+---------------+
+| Total Risk Rating      | N/A                 | High (15)       | High (15)     |
++------------------------+---------------------+-----------------+---------------+
+| Mitigations            | Copy image to on-chip memory before authenticating    |
+|                        | it.                                                   |
++------------------------+-------------------------------------------------------+
+| Mitigations            | | Platform specific.                                  |
+| implemented?           |                                                       |
+|                        | | The list of images to load and their location is    |
+|                        |   platform specific. Platforms are responsible for    |
+|                        |   arranging images to be loaded in on-chip memory.    |
++------------------------+-------------------------------------------------------+
+
+
++------------------------+-------------------------------------------------------+
+| ID                     | 04                                                    |
++========================+=======================================================+
+| Threat                 | | **An attacker with physical access can execute      |
+|                        |   arbitrary image by bypassing the signature          |
+|                        |   verification stage using glitching techniques**     |
+|                        |                                                       |
+|                        | | Glitching (Fault injection) attacks attempt to put  |
+|                        |   a hardware into a undefined state by manipulating an|
+|                        |   environmental variable such as power supply.        |
+|                        |                                                       |
+|                        | | TF-A relies on a chain of trust that starts with the|
+|                        |   ROTPK, which is the key stored inside the chip and  |
+|                        |   the root of all validation processes. If an attacker|
+|                        |   can break this chain of trust, they could execute   |
+|                        |   arbitrary code on the device. This could be         |
+|                        |   achieved with physical access to the device by      |
+|                        |   attacking the normal execution flow of the          |
+|                        |   process using glitching techniques that target      |
+|                        |   points where the image is validated against the     |
+|                        |   signature.                                          |
++------------------------+-------------------------------------------------------+
+| Diagram Elements       | DF1                                                   |
++------------------------+-------------------------------------------------------+
+| Affected TF-A          | BL1, BL2                                              |
+| Components             |                                                       |
++------------------------+-------------------------------------------------------+
+| Assets                 | Code Execution                                        |
++------------------------+-------------------------------------------------------+
+| Threat Agent           | PhysicalAccess                                        |
++------------------------+-------------------------------------------------------+
+| Threat Type            | Tampering, Elevation of Privilege                     |
++------------------------+---------------------+-----------------+---------------+
+| Application            | Server              | IoT             | Mobile        |
++------------------------+---------------------+-----------------+---------------+
+| Impact                 | N/A                 | Critical (5)    | Critical (5)  |
++------------------------+---------------------+-----------------+---------------+
+| Likelihood             | N/A                 | Medium (3)      | Medium (3)    |
++------------------------+---------------------+-----------------+---------------+
+| Total Risk Rating      | N/A                 | High (15)       | High (15)     |
++------------------------+---------------------+-----------------+---------------+
+| Mitigations            | Mechanisms to detect clock glitch and power           |
+|                        | variations.                                           |
++------------------------+-------------------------------------------------------+
+| Mitigations            | | No.                                                 |
+| implemented?           |                                                       |
+|                        | | The most effective mitigation is adding glitching   |
+|                        |   detection and mitigation circuit at the hardware    |
+|                        |   level.                                              |
+|                        |                                                       |
+|                        | | However, software techniques, such as adding        |
+|                        |   redundant checks when performing conditional        |
+|                        |   branches that are security sensitive, can be used   |
+|                        |   to harden TF-A against such attacks.                |
+|                        |   **At the moment TF-A doesn't implement such         |
+|                        |   mitigations.**                                      |
++------------------------+-------------------------------------------------------+
+
+.. topic:: Measured Boot Threats (or lack of)
+
+ In the current Measured Boot design, BL1, BL2, and BL31, as well as the
+ secure world components, form the |SRTM|. Measurement data is currently
+ considered an asset to be protected against attack, and this is achieved
+ by storing them in the Secure Memory.
+ Beyond the measurements stored inside the TCG-compliant Event Log buffer,
+ there are no other assets to protect or threats to defend against that
+ could compromise |TF-A| execution environment's security.
+
+ There are general security assets and threats associated with remote/delegated
+ attestation. However, these are outside the |TF-A| security boundary and
+ should be dealt with by the appropriate agent in the platform/system.
+ Since current Measured Boot design does not use local attestation, there would
+ be no further assets to protect(like unsealed keys).
+
+ A limitation of the current Measured Boot design is that it is dependent upon
+ Secure Boot as implementation of Measured Boot does not extend measurements
+ into a discrete |TPM|, where they would be securely stored and protected
+ against tampering. This implies that if Secure-Boot is compromised, Measured
+ Boot may also be compromised.
+
+ Platforms must carefully evaluate the security of the default implementation
+ since the |SRTM| includes all secure world components.
+
+
+Threats to be Mitigated by the Runtime EL3 Firmware
+---------------------------------------------------
+
++------------------------+------------------------------------------------------+
+| ID                     | 07                                                   |
++========================+======================================================+
+| Threat                 | | **An attacker can perform a denial-of-service      |
+|                        |   attack by using a broken SMC call that causes the  |
+|                        |   system to reboot or enter into unknown state.**    |
+|                        |                                                      |
+|                        | | Secure and non-secure clients access TF-A services |
+|                        |   through SMC calls. Malicious code can attempt to   |
+|                        |   place the TF-A runtime into an inconsistent state  |
+|                        |   by calling unimplemented SMC call or by passing    |
+|                        |   invalid arguments.                                 |
++------------------------+------------------------------------------------------+
+| Diagram Elements       | DF4, DF5                                             |
++------------------------+------------------------------------------------------+
+| Affected TF-A          | BL31                                                 |
+| Components             |                                                      |
++------------------------+------------------------------------------------------+
+| Assets                 | Availability                                         |
++------------------------+------------------------------------------------------+
+| Threat Agent           | NSCode, SecCode                                      |
++------------------------+------------------------------------------------------+
+| Threat Type            | Denial of Service                                    |
++------------------------+-------------------+----------------+-----------------+
+| Application            | Server            | IoT            | Mobile          |
++------------------------+-------------------+----------------+-----------------+
+| Impact                 | Medium (3)        | Medium (3)     | Medium (3)      |
++------------------------+-------------------+----------------+-----------------+
+| Likelihood             | High (4)          | High (4)       | High (4)        |
++------------------------+-------------------+----------------+-----------------+
+| Total Risk Rating      | High (12)         | High (12)      | High (12)       |
++------------------------+-------------------+----------------+-----------------+
+| Mitigations            | Validate SMC function ids and arguments before using |
+|                        | them.                                                |
++------------------------+------------------------------------------------------+
+| Mitigations            | | Yes / Platform specific.                           |
+| implemented?           |                                                      |
+|                        | | For standard services, all input is validated.     |
+|                        |                                                      |
+|                        | | Platforms that implement SiP services must also    |
+|                        |   validate SMC call arguments.                       |
++------------------------+------------------------------------------------------+
+
+
 +------------------------+------------------------------------------------------+
 | ID                     | 09                                                   |
 +========================+======================================================+
@@ -795,60 +919,6 @@
 |                        |   attacks.                                          |
 +------------------------+-----------------------------------------------------+
 
-+------------------------+----------------------------------------------------+
-| ID                     | 11                                                 |
-+========================+====================================================+
-| Threat                 | | **Misconfiguration of the Memory Management Unit |
-|                        |   (MMU) may allow a normal world software to       |
-|                        |   access sensitive data, execute arbitrary         |
-|                        |   code or access otherwise restricted HW           |
-|                        |   interface**                                      |
-|                        |                                                    |
-|                        | | A misconfiguration of the MMU could              |
-|                        |   lead to an open door for software running in the |
-|                        |   normal world to access sensitive data or even    |
-|                        |   execute code if the proper security mechanisms   |
-|                        |   are not in place.                                |
-+------------------------+----------------------------------------------------+
-| Diagram Elements       | DF5, DF6                                           |
-+------------------------+----------------------------------------------------+
-| Affected TF-A          | BL1, BL2, BL31                                     |
-| Components             |                                                    |
-+------------------------+----------------------------------------------------+
-| Assets                 | Sensitive Data, Code execution                     |
-+------------------------+----------------------------------------------------+
-| Threat Agent           | NSCode                                             |
-+------------------------+----------------------------------------------------+
-| Threat Type            | Information Disclosure, Elevation of Privilege     |
-+------------------------+-----------------+-----------------+----------------+
-| Application            | Server          | IoT             | Mobile         |
-+------------------------+-----------------+-----------------+----------------+
-| Impact                 | Critical (5)    | Critical (5)    | Critical (5)   |
-+------------------------+-----------------+-----------------+----------------+
-| Likelihood             | High (4)        | High (4)        | High (4)       |
-+------------------------+-----------------+-----------------+----------------+
-| Total Risk Rating      | Critical (20)   | Critical (20)   | Critical (20)  |
-+------------------------+-----------------+-----------------+----------------+
-| Mitigations            | When configuring access permissions, the           |
-|                        | principle of least privilege ought to be           |
-|                        | enforced. This means we should not grant more      |
-|                        | privileges than strictly needed, e.g. code         |
-|                        | should be read-only executable, read-only data     |
-|                        | should be read-only execute-never, and so on.      |
-+------------------------+----------------------------------------------------+
-| Mitigations            | | Platform specific.                               |
-| implemented?           |                                                    |
-|                        | | MMU configuration is platform specific,          |
-|                        |   therefore platforms need to make sure that the   |
-|                        |   correct attributes are assigned to memory        |
-|                        |   regions.                                         |
-|                        |                                                    |
-|                        | | TF-A provides a library which abstracts the      |
-|                        |   low-level details of MMU configuration. It       |
-|                        |   provides well-defined and tested APIs.           |
-|                        |   Platforms are encouraged to use it to limit the  |
-|                        |   risk of misconfiguration.                        |
-+------------------------+----------------------------------------------------+
 
 +------------------------+-----------------------------------------------------+
 | ID                     | 12                                                  |
@@ -905,40 +975,9 @@
 |                        |   mitigated.                                        |
 +------------------------+-----------------------------------------------------+
 
-+------------------------+-----------------------------------------------------+
-| ID                     | 13                                                  |
-+========================+=====================================================+
-| Threat                 | | **Leaving sensitive information in the memory,    |
-|                        |   can allow an attacker to retrieve them.**         |
-|                        |                                                     |
-|                        | | Accidentally leaving not-needed sensitive data in |
-|                        |   internal buffers can leak them if an attacker     |
-|                        |   gains access to memory due to a vulnerability.    |
-+------------------------+-----------------------------------------------------+
-| Diagram Elements       | DF4, DF5                                            |
-+------------------------+-----------------------------------------------------+
-| Affected TF-A          | BL1, BL2, BL31                                      |
-| Components             |                                                     |
-+------------------------+-----------------------------------------------------+
-| Assets                 | Sensitive Data                                      |
-+------------------------+-----------------------------------------------------+
-| Threat Agent           | NSCode, SecCode                                     |
-+------------------------+-----------------------------------------------------+
-| Threat Type            | Information Disclosure                              |
-+------------------------+-------------------+----------------+----------------+
-| Application            | Server            | IoT            | Mobile         |
-+------------------------+-------------------+----------------+----------------+
-| Impact                 |  Critical (5)     | Critical (5)   | Critical (5)   |
-+------------------------+-------------------+----------------+----------------+
-| Likelihood             |  Medium (3)       | Medium (3)     | Medium (3)     |
-+------------------------+-------------------+----------------+----------------+
-| Total Risk Rating      |  High (15)        | High (15)      | High (15)      |
-+------------------------+-------------------+----------------+----------------+
-| Mitigations            |   Clear the sensitive data from internal buffers as |
-|                        |   soon as they are not needed anymore.              |
-+------------------------+-----------------------------------------------------+
-| Mitigations            | | Yes / Platform specific                           |
-+------------------------+-----------------------------------------------------+
+
+Threats to be Mitigated by an External Agent Outside of TF-A
+------------------------------------------------------------
 
 +------------------------+-----------------------------------------------------+
 | ID                     | 14                                                  |
diff --git a/docs/threat_model/threat_model_el3_spm.rst b/docs/threat_model/threat_model_el3_spm.rst
index c3af7a2..8adf3df 100644
--- a/docs/threat_model/threat_model_el3_spm.rst
+++ b/docs/threat_model/threat_model_el3_spm.rst
@@ -4,7 +4,7 @@
 ************
 Introduction
 ************
-This document provides a threat model for the TF-A `EL3 Secure Partition Manager`_
+This document provides a threat model for the TF-A :ref:`EL3 Secure Partition Manager`
 (EL3 SPM) implementation. The EL3 SPM implementation is based on the
 `Arm Firmware Framework for Arm A-profile`_ specification.
 
@@ -13,7 +13,8 @@
 ********************
 In this threat model, the target of evaluation is the ``Secure Partition Manager Core``
 component (SPMC) within the EL3 firmware.
-The monitor and SPMD at EL3 are covered by the `Generic TF-A threat model`_.
+The monitor and SPMD at EL3 are covered by the :ref:`Generic TF-A threat model
+<threat_analysis>`.
 
 The scope for this threat model is:
 
@@ -70,8 +71,8 @@
 Threat Analysis
 ***************
 
-This threat model follows a similar methodology to the `Generic TF-A threat model`_.
-The following sections define:
+This threat model follows a similar methodology to the :ref:`Generic TF-A threat model
+<threat_analysis>`. The following sections define:
 
 - Trust boundaries
 - Assets
@@ -115,7 +116,8 @@
 Threat types
 ============
 
-The following threat categories as exposed in the `Generic TF-A threat model`_
+The following threat categories as exposed in the :ref:`Generic TF-A threat model
+<threat_analysis>`
 are re-used:
 
 - Spoofing
@@ -642,9 +644,7 @@
 
 ---------------
 
-*Copyright (c) 2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
-.. _EL3 Secure Partition Manager: ../components/el3-spmc.html
-.. _Generic TF-A threat model: ./threat_model.html#threat-analysis
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
index 9458a9f..24a115b 100644
--- a/docs/threat_model/threat_model_spm.rst
+++ b/docs/threat_model/threat_model_spm.rst
@@ -4,7 +4,7 @@
 ************************
 Introduction
 ************************
-This document provides a threat model for the TF-A `Secure Partition Manager`_
+This document provides a threat model for the TF-A :ref:`Secure Partition Manager`
 (SPM) implementation or more generally the S-EL2 reference firmware running on
 systems implementing the FEAT_SEL2 (formerly Armv8.4 Secure EL2) architecture
 extension. The SPM implementation is based on the `Arm Firmware Framework for
@@ -28,7 +28,8 @@
 ************************
 In this threat model, the target of evaluation is the S-EL2 firmware or the
 ``Secure Partition Manager Core`` component (SPMC).
-The monitor and SPMD at EL3 are covered by the `Generic TF-A threat model`_.
+The monitor and SPMD at EL3 are covered by the :ref:`Generic TF-A threat model
+<threat_analysis>`.
 
 The scope for this threat model is:
 
@@ -92,7 +93,8 @@
 Threat Analysis
 *********************
 
-This threat model follows a similar methodology to the `Generic TF-A threat model`_.
+This threat model follows a similar methodology to the :ref:`Generic TF-A threat model
+<threat_analysis>`.
 The following sections define:
 
 - Trust boundaries
@@ -141,7 +143,8 @@
 Threat types
 ============================
 
-The following threat categories as exposed in the `Generic TF-A threat model`_
+The following threat categories as exposed in the :ref:`Generic TF-A threat model
+<threat_analysis>`
 are re-used:
 
 - Spoofing
@@ -1333,7 +1336,5 @@
 *Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
-.. _Secure Partition Manager: ../components/secure-partition-manager.html
-.. _Generic TF-A threat model: ./threat_model.html#threat-analysis
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
 
diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c
index 628f5d9..ea48a24 100644
--- a/drivers/arm/ethosn/ethosn_big_fw.c
+++ b/drivers/arm/ethosn/ethosn_big_fw.c
@@ -12,7 +12,7 @@
 #define ETHOSN_BIG_FW_MAGIC	('E' | ('N' << 8) | ('F' << 16) | ('W' << 24))
 
 /* Supported big firmware version */
-#define ETHOSN_BIG_FW_VERSION_MAJOR	11
+#define ETHOSN_BIG_FW_VERSION_MAJOR	12
 
 #define ETHOSN_ARCH_VER_MAJOR_MASK	U(0xF000)
 #define ETHOSN_ARCH_VER_MAJOR_SHIFT	U(0xC)
diff --git a/drivers/arm/ethosn/ethosn_npu.mk b/drivers/arm/ethosn/ethosn_npu.mk
new file mode 100644
index 0000000..4a31b59
--- /dev/null
+++ b/drivers/arm/ethosn/ethosn_npu.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Arm(R) Ethos(TM)-N NPU SiP service
+ETHOSN_NPU_DRIVER			:=	0
+
+$(eval $(call assert_boolean,ETHOSN_NPU_DRIVER))
+$(eval $(call add_define,ETHOSN_NPU_DRIVER))
+
+#Ethos-N NPU TZMP1
+ETHOSN_NPU_TZMP1			:=	0
+$(eval $(call assert_boolean,ETHOSN_NPU_TZMP1))
+$(eval $(call add_define,ETHOSN_NPU_TZMP1))
+ifeq (${ETHOSN_NPU_TZMP1},1)
+  ifeq (${ETHOSN_NPU_DRIVER},0)
+    $(error "ETHOSN_NPU_TZMP1 is only available if ETHOSN_NPU_DRIVER=1)
+  endif
+  ifeq (${PLAT},juno)
+    $(eval $(call add_define,JUNO_ETHOSN_TZMP1))
+  else
+    $(error "ETHOSN_NPU_TZMP1 only supported on Juno platform, not ", ${PLAT})
+  endif
+
+  ifeq (${TRUSTED_BOARD_BOOT},0)
+    # We rely on TRUSTED_BOARD_BOOT to prevent the firmware code from being
+    # tampered with, which is required to protect the confidentiality of protected
+    # inference data.
+    $(error "ETHOSN_NPU_TZMP1 is only available if TRUSTED_BOARD_BOOT is enabled)
+  endif
+
+  # We need the FW certificate and key certificate
+  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_key.crt,--npu-fw-key-cert))
+  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_content.crt,--npu-fw-cert))
+  # We need the firmware to be built into the FIP
+  $(eval $(call TOOL_ADD_IMG,ETHOSN_NPU_FW,--npu-fw))
+
+  # Needed for our OIDs to be available in tbbr_cot_bl2.c
+  $(eval $(call add_define, PLAT_DEF_OID))
+
+  # Needed so that UUIDs from the FIP are available in BL2
+  $(eval $(call add_define,PLAT_DEF_FIP_UUID))
+
+  PLAT_INCLUDES	+=	-I${PLAT_DIR}certificate/include
+  PLAT_INCLUDES	+=	-Iinclude/drivers/arm/
+  PLAT_INCLUDES	+=	-I${PLAT_DIR}fip
+endif
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 85a12c5..42158e4 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -17,9 +17,9 @@
 
 #include <platform_def.h>
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 #include "ethosn_big_fw.h"
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 /*
  * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available
@@ -51,11 +51,11 @@
 #define SEC_AUXCTLR_STASHING_VAL	U(0xA5000000)
 
 #define SEC_DEL_REG			U(0x0004)
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 #define SEC_DEL_VAL			U(0x808)
 #else
 #define SEC_DEL_VAL			U(0x80C)
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 #define SEC_DEL_EXCC_MASK		U(0x20)
 
 #define SEC_SECCTLR_REG			U(0x0010)
@@ -69,7 +69,7 @@
 #define SEC_SYSCTRL0_CPU_WAIT		U(1)
 #define SEC_SYSCTRL0_SLEEPING		U(1U << 4)
 #define SEC_SYSCTRL0_INITVTOR_MASK	U(0x1FFFFF80)
-#define SEC_SYSCTRL0_SOFT_RESET		U(3U << 29)
+#define SEC_SYSCTRL0_SOFT_RESET		U(1U << 29)
 #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
 
 #define SEC_SYSCTRL1_REG		U(0x001C)
@@ -104,8 +104,8 @@
 #define TO_EXTEND_ADDR(addr) \
 	((addr >> SEC_ADDR_EXT_SHIFT) & SEC_ADDR_EXT_MASK)
 
-#if ARM_ETHOSN_NPU_TZMP1
-CASSERT(ARM_ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base);
+#if ETHOSN_NPU_TZMP1
+CASSERT(ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base);
 static const struct ethosn_big_fw *big_fw;
 
 #define FW_INITVTOR_ADDR(big_fw) \
@@ -115,7 +115,7 @@
 #define SYSCTRL0_INITVTOR_ADDR(value) \
 	(value & SEC_SYSCTRL0_INITVTOR_MASK)
 
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 static bool ethosn_get_device_and_core(uintptr_t core_addr,
 				       const struct ethosn_device_t **dev_match,
@@ -142,7 +142,7 @@
 	return false;
 }
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 static uint32_t ethosn_core_read_arch_version(uintptr_t core_addr)
 {
 	uint32_t npu_id = mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr,
@@ -155,23 +155,23 @@
 					  bool is_protected)
 {
 	size_t i;
-	uint32_t streams[9] = {[0 ... 8] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID};
+	uint32_t streams[9] = {[0 ... 8] = ETHOSN_NPU_NS_RO_DATA_NSAID};
 
-	streams[FIRMWARE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
-	streams[PLE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
+	streams[FIRMWARE_STREAM_INDEX] = ETHOSN_NPU_PROT_FW_NSAID;
+	streams[PLE_STREAM_INDEX] = ETHOSN_NPU_PROT_FW_NSAID;
 
-	streams[WORKING_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
+	streams[WORKING_STREAM_INDEX] = ETHOSN_NPU_NS_RW_DATA_NSAID;
 
 	if (is_protected) {
-		streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID;
+		streams[INPUT_STREAM_INDEX] = ETHOSN_NPU_PROT_RO_DATA_NSAID;
 		streams[INTERMEDIATE_STREAM_INDEX] =
-			ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID;
-		streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID;
+			ETHOSN_NPU_PROT_RW_DATA_NSAID;
+		streams[OUTPUT_STREAM_INDEX] = ETHOSN_NPU_PROT_RW_DATA_NSAID;
 	} else {
-		streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID;
+		streams[INPUT_STREAM_INDEX] = ETHOSN_NPU_NS_RO_DATA_NSAID;
 		streams[INTERMEDIATE_STREAM_INDEX] =
-			ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
-		streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID;
+			ETHOSN_NPU_NS_RW_DATA_NSAID;
+		streams[OUTPUT_STREAM_INDEX] = ETHOSN_NPU_NS_RW_DATA_NSAID;
 	}
 
 	for (i = 0U; i < ARRAY_SIZE(streams); ++i) {
@@ -188,7 +188,7 @@
 			FW_INITVTOR_ADDR(big_fw));
 }
 
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 static void ethosn_configure_events(uintptr_t core_addr)
 {
@@ -343,7 +343,7 @@
 
 static int ethosn_core_boot_fw(uintptr_t core_addr)
 {
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 	const uintptr_t sysctrl0_reg = ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG);
 	const uint32_t sysctrl0_val = mmio_read_32(sysctrl0_reg);
 	const bool waiting = (sysctrl0_val & SEC_SYSCTRL0_CPU_WAIT);
@@ -363,7 +363,7 @@
 	return ETHOSN_SUCCESS;
 #else
 	return ETHOSN_NOT_SUPPORTED;
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 }
 
 static int ethosn_core_full_reset(const struct ethosn_device_t *device,
@@ -392,17 +392,17 @@
 	if (!device->has_reserved_memory) {
 		ethosn_configure_smmu_streams(device, core, asset_alloc_idx);
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 		ethosn_configure_stream_nsaid(core, is_protected);
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 	}
 
 	ethosn_configure_stream_addr_extends(device, core->addr);
 	ethosn_configure_stream_attr_ctlr(core->addr);
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 	ethosn_configure_vector_table(core->addr);
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 	ethosn_delegate_to_ns(core->addr);
 
@@ -481,7 +481,7 @@
 static uintptr_t ethosn_smc_fw_prop_handler(u_register_t fw_property,
 					    void *handle)
 {
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 	switch (fw_property) {
 	case ETHOSN_FW_PROP_VERSION:
 		SMC_RET4(handle, ETHOSN_SUCCESS,
@@ -507,7 +507,7 @@
 	}
 #else
 	SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 }
 
 uintptr_t ethosn_smc_handler(uint32_t smc_fid,
@@ -554,17 +554,17 @@
 
 int ethosn_smc_setup(void)
 {
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 	struct ethosn_device_t *dev;
 	uint32_t arch_ver;
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 	if (ETHOSN_NUM_DEVICES == 0U) {
 		ERROR("ETHOSN: No NPU found\n");
 		return ETHOSN_FAILURE;
 	}
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 
 	/* Only one NPU core is supported in the TZMP1 setup */
 	if ((ETHOSN_NUM_DEVICES != 1U) ||
@@ -580,7 +580,7 @@
 	}
 
 	arch_ver = ethosn_core_read_arch_version(dev->cores[0U].addr);
-	big_fw = (struct ethosn_big_fw *)ARM_ETHOSN_NPU_FW_IMAGE_BASE;
+	big_fw = (struct ethosn_big_fw *)ETHOSN_NPU_FW_IMAGE_BASE;
 
 	if (!ethosn_big_fw_verify_header(big_fw, arch_ver)) {
 		return ETHOSN_FAILURE;
@@ -591,7 +591,7 @@
 	       big_fw->fw_ver_patch);
 #else
 	NOTICE("ETHOSN: Setup succeeded\n");
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 	return 0;
 }
diff --git a/drivers/arm/fvp/fvp_pwrc.c b/drivers/arm/fvp/fvp_pwrc.c
index 75a2b66..fb77f77 100644
--- a/drivers/arm/fvp/fvp_pwrc.c
+++ b/drivers/arm/fvp/fvp_pwrc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,22 +10,39 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
+#define FVP_PWRC_ID_MASK U(0x00FFFFFF)
+
 /*
  * TODO: Someday there will be a generic power controller api. At the moment
  * each platform has its own pwrc so just exporting functions is fine.
  */
 ARM_INSTANTIATE_LOCK;
 
+/*
+ * Core ID field is 24 bits wide and extracted from MPIDR.
+ * Bits[23:16] represent Affinity Level 2
+ * Bits[15:8] represent Affinity Level 1
+ * Bits[7:0] represent Affinity Level 0
+ */
+static unsigned int fvp_pwrc_core_id(u_register_t mpidr)
+{
+	return (unsigned int)(mpidr & FVP_PWRC_ID_MASK);
+}
+
 unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr)
 {
-	return PSYSR_WK(fvp_pwrc_read_psysr(mpidr));
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
+	return PSYSR_WK(fvp_pwrc_read_psysr(id));
 }
 
 unsigned int fvp_pwrc_read_psysr(u_register_t mpidr)
 {
 	unsigned int rc;
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
-	mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
+	mmio_write_32(PWRC_BASE + PSYSR_OFF, id);
 	rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
 	arm_lock_release();
 	return rc;
@@ -33,38 +50,47 @@
 
 void fvp_pwrc_write_pponr(u_register_t mpidr)
 {
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
-	mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr);
+	mmio_write_32(PWRC_BASE + PPONR_OFF, id);
 	arm_lock_release();
 }
 
 void fvp_pwrc_write_ppoffr(u_register_t mpidr)
 {
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
-	mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr);
+	mmio_write_32(PWRC_BASE + PPOFFR_OFF, id);
 	arm_lock_release();
 }
 
 void fvp_pwrc_set_wen(u_register_t mpidr)
 {
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
 	mmio_write_32(PWRC_BASE + PWKUPR_OFF,
-		      (unsigned int) (PWKUPR_WEN | mpidr));
+		      (unsigned int) (PWKUPR_WEN | id));
 	arm_lock_release();
 }
 
 void fvp_pwrc_clr_wen(u_register_t mpidr)
 {
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
-	mmio_write_32(PWRC_BASE + PWKUPR_OFF,
-		      (unsigned int) mpidr);
+	mmio_write_32(PWRC_BASE + PWKUPR_OFF, id);
 	arm_lock_release();
 }
 
 void fvp_pwrc_write_pcoffr(u_register_t mpidr)
 {
+	unsigned int id = fvp_pwrc_core_id(mpidr);
+
 	arm_lock_get();
-	mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr);
+	mmio_write_32(PWRC_BASE + PCOFFR_OFF, id);
 	arm_lock_release();
 }
 
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 7a9cca8..105dc05 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -20,6 +20,8 @@
 #include <lib/fconf/fconf_tbbr_getter.h>
 #include <plat/common/platform.h>
 
+#include <tools_share/zero_oid.h>
+
 /* ASN.1 tags */
 #define ASN1_INTEGER                 0x02
 
@@ -148,7 +150,7 @@
 			  const auth_img_desc_t *img_desc,
 			  void *img, unsigned int img_len)
 {
-	void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr;
+	void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr, *pk_oid;
 	unsigned int data_len, pk_len, pk_plat_len, sig_len, sig_alg_len;
 	unsigned int flags = 0;
 	int rc = 0;
@@ -226,6 +228,25 @@
 				return -1;
 			}
 		}
+
+		/*
+		 * Set Zero-OID for ROTPK(subject key) as a the certificate
+		 * does not hold Key-OID information for ROTPK.
+		 */
+		if (param->pk->cookie != NULL) {
+			pk_oid = param->pk->cookie;
+		} else {
+			pk_oid = ZERO_OID;
+		}
+
+		/*
+		 * Public key is verified at this stage, notify platform
+		 * to measure and publish it.
+		 */
+		rc = plat_mboot_measure_key(pk_oid, pk_ptr, pk_len);
+		if (rc != 0) {
+			WARN("Public Key measurement failure = %d\n", rc);
+		}
 	}
 
 	/* Ask the crypto module to verify the signature */
@@ -381,6 +402,7 @@
 			unsigned int img_len)
 {
 	const auth_img_desc_t *img_desc = NULL;
+	const auth_param_type_desc_t *type_desc = NULL;
 	const auth_method_desc_t *auth_method = NULL;
 	void *param_ptr;
 	unsigned int param_len;
@@ -462,6 +484,21 @@
 			/* Copy the parameter for later use */
 			memcpy((void *)img_desc->authenticated_data[i].data.ptr,
 					(void *)param_ptr, param_len);
+
+			/*
+			 * If this is a public key then measure and publicise
+			 * it.
+			 */
+			type_desc = img_desc->authenticated_data[i].type_desc;
+			if (type_desc->type == AUTH_PARAM_PUB_KEY) {
+				rc = plat_mboot_measure_key(type_desc->cookie,
+							    param_ptr,
+							    param_len);
+				if (rc != 0) {
+					WARN("Public Key measurement "
+					     "failure = %d\n", rc);
+				}
+			}
 		}
 	}
 
diff --git a/drivers/cadence/combo_phy/cdns_combo_phy.c b/drivers/cadence/combo_phy/cdns_combo_phy.c
new file mode 100644
index 0000000..f00d0c1
--- /dev/null
+++ b/drivers/cadence/combo_phy/cdns_combo_phy.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
+			uint32_t phy_reg_data, uint32_t phy_reg_data_value)
+{
+	uint32_t data = 0U;
+	uint32_t value = 0U;
+
+	/* Get PHY register address, write HRS04*/
+	value = mmio_read_32(phy_reg_addr);
+	value &= ~PHY_REG_ADDR_MASK;
+	value |= phy_reg_addr_value;
+	mmio_write_32(phy_reg_addr, value);
+	data = mmio_read_32(phy_reg_addr);
+	if ((data & PHY_REG_ADDR_MASK) != phy_reg_addr_value) {
+		ERROR("PHY_REG_ADDR is not set properly\n");
+		return -ENXIO;
+	}
+
+	/* Get PHY register data, write HRS05 */
+	value &= ~PHY_REG_DATA_MASK;
+	value |= phy_reg_data_value;
+	mmio_write_32(phy_reg_data, value);
+	data = mmio_read_32(phy_reg_data);
+	if (data != phy_reg_data_value) {
+		ERROR("PHY_REG_DATA is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_sd_card_detect(void)
+{
+	uint32_t value = 0;
+
+	/* Card detection */
+	do {
+		value = mmio_read_32(SDMMC_CDN(SRS09));
+	/* Wait for card insertion. SRS09.CI = 1 */
+	} while ((value & (1 << SDMMC_CDN_CI)) == 0);
+
+	if ((value & (1 << SDMMC_CDN_CI)) == 0) {
+		ERROR("Card does not detect\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_emmc_card_reset(void)
+{
+	uint32_t _status = 0;
+
+	/* Reset embedded card */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
+	mdelay(68680); /* ~68680us */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
+	udelay(340); /* ~340us */
+
+	/* Turn on supply voltage */
+	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
+	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
+
+	return 0;
+}
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c
new file mode 100644
index 0000000..d2cd4d6
--- /dev/null
+++ b/drivers/cadence/emmc/cdns_sdmmc.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <drivers/mmc.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+/* Card busy and present */
+#define CARD_BUSY					1
+#define CARD_NOT_BUSY					0
+
+/* 500 ms delay to read the RINST register */
+#define DELAY_MS_SRS_READ				500
+#define DELAY_RES					10
+
+/* SRS12 error mask */
+#define SRS12_ERR_MASK					0xFFFF8000
+
+/* Check DV dfi_init val=0 */
+#define IO_MASK_END_DATA				0x0
+
+/* Check DV dfi_init val=2; DDR Mode */
+#define IO_MASK_END_DATA_DDR				0x2
+#define IO_MASK_START_DATA				0x0
+#define DATA_SELECT_OE_END_DATA				0x1
+
+#define TIMEOUT						100000
+
+/* General define */
+#define SDHC_REG_MASK					UINT_MAX
+#define SD_HOST_BLOCK_SIZE				0x200
+#define DTCVVAL_DEFAULT_VAL				0xE
+#define CDMMC_DMA_MAX_BUFFER_SIZE			64*1024
+#define CDNSMMC_ADDRESS_MASK				U(0x0f)
+#define CONFIG_CDNS_DESC_COUNT				8
+
+void cdns_init(void);
+int cdns_send_cmd(struct mmc_cmd *cmd);
+int cdns_set_ios(unsigned int clk, unsigned int width);
+int cdns_prepare(int lba, uintptr_t buf, size_t size);
+int cdns_read(int lba, uintptr_t buf, size_t size);
+int cdns_write(int lba, uintptr_t buf, size_t size);
+
+const struct mmc_ops cdns_sdmmc_ops = {
+	.init			= cdns_init,
+	.send_cmd		= cdns_send_cmd,
+	.set_ios		= cdns_set_ios,
+	.prepare		= cdns_prepare,
+	.read			= cdns_read,
+	.write			= cdns_write,
+};
+
+struct cdns_sdmmc_params cdns_params;
+struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
+struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT];
+#else
+struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT] __aligned(32);
+#endif
+
+bool data_cmd;
+
+int cdns_wait_ics(uint16_t timeout, uint32_t cdn_srs_res)
+{
+	/* Clock for sdmclk and sdclk */
+	uint32_t count = 0;
+	uint32_t data = 0;
+
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(cdn_srs_res);
+		count++;
+		if (count >= timeout) {
+			return -ETIMEDOUT;
+		}
+	} while ((data & (1 << SDMMC_CDN_ICS)) == 0);
+
+	return 0;
+}
+
+int cdns_busy(void)
+{
+	unsigned int data;
+
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
+	return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
+}
+
+int cdns_vol_reset(void)
+{
+	/* Reset embedded card */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	udelay(250);
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
+	udelay(500);
+
+	/* Turn on supply voltage */
+	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	udelay(250);
+	return 0;
+}
+
+void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	/* Values are taken by the reference of cadence IP documents */
+	combo_phy_reg->cp_clk_wr_delay = 0;
+	combo_phy_reg->cp_clk_wrdqs_delay = 0;
+	combo_phy_reg->cp_data_select_oe_end = 0;
+	combo_phy_reg->cp_dll_bypass_mode = 1;
+	combo_phy_reg->cp_dll_locked_mode = 0;
+	combo_phy_reg->cp_dll_start_point = 0;
+	combo_phy_reg->cp_gate_cfg_always_on = 1;
+	combo_phy_reg->cp_io_mask_always_on = 0;
+	combo_phy_reg->cp_io_mask_end = 0;
+	combo_phy_reg->cp_io_mask_start = 0;
+	combo_phy_reg->cp_rd_del_sel = 52;
+	combo_phy_reg->cp_read_dqs_cmd_delay = 0;
+	combo_phy_reg->cp_read_dqs_delay = 0;
+	combo_phy_reg->cp_sw_half_cycle_shift = 0;
+	combo_phy_reg->cp_sync_method = 1;
+	combo_phy_reg->cp_underrun_suppress = 1;
+	combo_phy_reg->cp_use_ext_lpbk_dqs = 1;
+	combo_phy_reg->cp_use_lpbk_dqs = 1;
+	combo_phy_reg->cp_use_phony_dqs = 1;
+	combo_phy_reg->cp_use_phony_dqs_cmd = 1;
+
+	sdhc_reg->sdhc_extended_rd_mode = 1;
+	sdhc_reg->sdhc_extended_wr_mode = 1;
+	sdhc_reg->sdhc_hcsdclkadj = 0;
+	sdhc_reg->sdhc_idelay_val = 0;
+	sdhc_reg->sdhc_rdcmd_en = 1;
+	sdhc_reg->sdhc_rddata_en = 1;
+	sdhc_reg->sdhc_rw_compensate = 9;
+	sdhc_reg->sdhc_sdcfsh = 0;
+	sdhc_reg->sdhc_sdcfsl = 1;
+	sdhc_reg->sdhc_wrcmd0_dly = 1;
+	sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrcmd1_dly = 0;
+	sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrdata0_dly = 1;
+	sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
+	sdhc_reg->sdhc_wrdata1_dly = 0;
+	sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
+}
+
+static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	uint32_t value = 0;
+	int ret = 0;
+
+	/* program PHY_DQS_TIMING_REG */
+	value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
+		(CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
+		(CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
+		(CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
+			SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_GATE_LPBK_CTRL_REG */
+	value = (CP_SYNC_METHOD(combo_phy_reg->cp_sync_method)) |
+		(CP_SW_HALF_CYCLE_SHIFT(combo_phy_reg->cp_sw_half_cycle_shift)) |
+		(CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
+		(CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
+		(CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
+			SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_DLL_MASTER_CTRL_REG */
+	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
+			| (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_DLL_SLAVE_CTRL_REG */
+	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
+		| (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
+		| (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
+		| (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* program PHY_CTRL_REG */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
+			+ PHY_CTRL_REG);
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
+
+	/* phony_dqs_timing=0 */
+	value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
+
+	/* switch off DLL_RESET */
+	do {
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		value |= SDHC_PHY_SW_RESET;
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	/* polling PHY_INIT_COMPLETE */
+	} while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
+
+	/* program PHY_DQ_TIMING_REG */
+	combo_phy_reg->cp_io_mask_end = 0U;
+	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
+		| (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
+		| (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
+		| (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
+
+	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
+			COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
+			+ SDHC_CDNS_HRS05, value);
+	if (ret != 0) {
+		return ret;
+	}
+	return 0;
+}
+
+int cdns_read(int lba, uintptr_t buf, size_t size)
+{
+	inv_dcache_range(buf, size);
+
+	return 0;
+}
+
+void cdns_init(void)
+{
+	/* Dummy function pointer for cdns_init. */
+}
+
+int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
+{
+	data_cmd = true;
+	struct cdns_idmac_desc *desc;
+	uint32_t desc_cnt, i;
+	uint64_t desc_base;
+
+	assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
+			(cdns_params.desc_size > 0) &&
+			((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
+			((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
+			((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
+
+	flush_dcache_range(dma_buff, size);
+
+	desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
+	assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
+
+	if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
+		ERROR("Requested data transfer length %ld is greater than configured length %d",
+				size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
+		return -EINVAL;
+	}
+
+	desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
+	desc_base = (uint64_t)desc;
+	i = 0;
+
+	while ((i + 1) < desc_cnt) {
+		desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
+		desc->reserved = 0;
+		desc->len = MAX_64KB_PAGE;
+		desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
+#endif
+		size -= CDMMC_DMA_MAX_BUFFER_SIZE;
+		desc++;
+		i++;
+	}
+
+	desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
+			ADMA_DESC_ATTR_END;
+	desc->reserved = 0;
+	desc->len = size;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+	desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
+	desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
+#else
+	desc->addr_lo = (dma_buff & UINT_MAX);
+#endif
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
+	flush_dcache_range(cdns_params.desc_base,
+				desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
+			((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
+	return 0;
+}
+
+static void cdns_host_set_clk(int clk)
+{
+	uint32_t ret = 0;
+	uint32_t sdclkfsval = 0;
+	uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
+
+	sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+
+	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
+	if (ret != 0U) {
+		ERROR("Waiting SDMMC_CDN_ICS timeout");
+	}
+
+	/* Enable DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
+			~SDHC_DLL_RESET_MASK);
+	/* Set extended_wr_mode */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
+			& SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
+	/* Release DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | 1);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+
+	do {
+		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+	(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+}
+
+int cdns_set_ios(unsigned int clk, unsigned int width)
+{
+
+	switch (width) {
+	case MMC_BUS_WIDTH_1:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
+		break;
+	case MMC_BUS_WIDTH_4:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
+		break;
+	case MMC_BUS_WIDTH_8:
+		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
+		break;
+	default:
+		assert(0);
+		break;
+	}
+	cdns_host_set_clk(clk);
+
+	return 0;
+}
+
+int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data)
+{
+	uint32_t value = 0;
+
+	value = mmio_read_32(addr);
+	value &= ~SDHC_REG_MASK;
+	value |= data;
+	mmio_write_32(addr, value);
+	value = mmio_read_32(addr);
+	if (value != data) {
+		ERROR("SD host address is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int cdns_write(int lba, uintptr_t buf, size_t size)
+{
+	return 0;
+}
+
+static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+	struct cdns_sdmmc_sdhc *sdhc_reg)
+{
+	uint32_t value = 0;
+	int ret = 0;
+
+	/* program HRS09, register 42 */
+	value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
+		| (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
+		| (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
+		| (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+	if (ret != 0) {
+		ERROR("Program HRS09 failed");
+		return ret;
+	}
+
+	/* program HRS10, register 43 */
+	value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
+	if (ret != 0) {
+		ERROR("Program HRS10 failed");
+		return ret;
+	}
+
+	/* program HRS16, register 48 */
+	value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
+		| (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
+		| (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
+		| (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
+		| (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
+		| (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
+		| (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
+		| (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
+	if (ret != 0) {
+		ERROR("Program HRS16 failed");
+		return ret;
+	}
+
+	/* program HRS07, register 40 */
+	value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
+		| (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
+	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
+	if (ret != 0) {
+		ERROR("Program HRS07 failed");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
+{
+	uint32_t ret = 0;
+	uint32_t dtcvval, sdclkfsval;
+
+	dtcvval = DTC_VAL;
+	sdclkfsval = 0;
+
+	if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
+		sdclkfsval = 4;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
+		sdclkfsval = 2;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
+		sdclkfsval = 1;
+	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
+		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
+		sdclkfsval = 0;
+	}
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
+	if (ret != 0U) {
+		ERROR("Waiting SDMMC_CDN_ICS timeout");
+		return ret;
+	}
+
+	/* Enable DLL reset */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
+	/* Set extended_wr_mode */
+	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
+	(mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &	SDHC_EXTENDED_WR_MODE_MASK) |
+			(1 << EXTENDED_WR_MODE));
+	/* Release DLL reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | 1);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
+			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+	do {
+		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+	return 0;
+}
+
+int cdns_reset(void)
+{
+	uint32_t data = 0;
+	uint32_t count = 0;
+	uint32_t value = 0;
+
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
+	value &= ~(0xFFFF);
+	value |= 0x0;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
+	udelay(500);
+
+	/* Software reset */
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
+		count++;
+		if (count >= 5000) {
+			return -ETIMEDOUT;
+		}
+	/* Wait for HRS00.SWR */
+	} while ((data & 1) == 1);
+
+	/* Step 1, switch on DLL_RESET */
+	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+	value &= ~SDHC_PHY_SW_RESET;
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+
+	return 0;
+}
+
+int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
+struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
+{
+	int ret = 0;
+
+	ret = cdns_reset();
+	if (ret != 0) {
+		ERROR("Program phy reg init failed");
+		return ret;
+	}
+
+	ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (ret != 0) {
+		ERROR("Program phy reg init failed");
+		return ret;
+	}
+
+	ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (ret != 0) {
+		ERROR("Program init for HRS reg is failed");
+		return ret;
+	}
+
+	ret = cdns_sd_card_detect();
+	if (ret != 0) {
+		ERROR("SD card does not detect");
+		return ret;
+	}
+
+	ret = cdns_vol_reset();
+	if (ret != 0) {
+		ERROR("eMMC card reset failed");
+		return ret;
+	}
+
+	ret = cdns_hc_set_clk(&cdns_params);
+	if (ret != 0) {
+		ERROR("hc set clk failed");
+		return ret;
+	}
+
+	return 0;
+}
+
+void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
+{
+	uint32_t data_op = 0U;
+
+	data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
+	mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
+}
+
+void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
+{
+	uint32_t data = 0U;
+
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
+	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
+}
+
+int cdns_send_cmd(struct mmc_cmd *cmd)
+{
+	uint32_t op = 0, ret = 0;
+	uint8_t write_value = 0, prev_val = 0;
+	uint32_t value;
+	int32_t timeout;
+	uint32_t cmd_indx;
+	uint32_t status = 0, srs15_val = 0, srs11_val = 0;
+	uint32_t status_check = 0;
+
+	assert(cmd);
+	cmd_indx = (cmd->cmd_idx) << COM_IDX;
+
+	if (data_cmd) {
+		switch (cmd->cmd_idx) {
+		case SD_SWITCH:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | DT_WIDTH;
+			prev_val = ADMA2_32 | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			srs15_val = BIT_AD_64 | HV4E | V18SE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_WRITE_SINGLE_BLOCK:
+		case SD_READ_SINGLE_BLOCK:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
+			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
+			break;
+
+		case SD_WRITE_MULTIPLE_BLOCK:
+		case SD_READ_MULTIPLE_BLOCK:
+			op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
+			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
+			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
+			break;
+
+		case SD_APP_SEND_SCR:
+			op = DATA_PRESENT;
+			write_value = ADMA2_32 | LEDC;
+			prev_val = LEDC;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = BIT_AD_64 | HV4E | V18SE;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_SEND_IF_COND:
+			op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		default:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			op = 0;
+			break;
+		}
+	} else {
+		switch (cmd->cmd_idx) {
+		case SD_GO_IDLE_STATE:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_ALL_SEND_CID:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E | V18SE;
+			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_SEND_IF_COND:
+			op = CMD_IDX_CHK_ENABLE;
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			srs15_val = HV4E;
+			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
+			cdns_srs11_srs15_config(srs11_val, srs15_val);
+			break;
+
+		case SD_STOP_TRANSMISSION:
+			op = CMD_STOP_ABORT_CMD;
+			break;
+
+		case SD_SEND_STATUS:
+			break;
+
+		case 1:
+			cmd->cmd_arg = 0;
+			break;
+
+		case SD_SELECT_CARD:
+			op = MULTI_BLK_READ;
+			break;
+
+		case SD_APP_CMD:
+		default:
+			write_value = LEDC;
+			prev_val = 0x0;
+			cdns_srs10_value_toggle(write_value, prev_val);
+			op = 0;
+			break;
+		}
+	}
+
+	switch (cmd->resp_type) {
+	case MMC_RESPONSE_NONE:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
+		break;
+
+	case MMC_RESPONSE_R2:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
+			RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
+		break;
+
+	case MMC_RESPONSE_R3:
+		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
+			RES_TYPE_SEL_48;
+		break;
+
+	case MMC_RESPONSE_R1:
+		if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
+			== SD_WRITE_MULTIPLE_BLOCK)) {
+			op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
+			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		} else {
+			op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
+			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		}
+		break;
+
+	default:
+		op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
+			RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+		break;
+	}
+
+	timeout = TIMEOUT;
+	do {
+		udelay(100);
+		ret = cdns_busy();
+		if (--timeout <= 0) {
+			udelay(50);
+			panic();
+		}
+	} while (ret);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
+
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
+	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
+	if (cmd_indx == 1)
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
+	else
+		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
+
+	timeout = TIMEOUT;
+	do {
+		udelay(500);
+		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
+	} while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
+
+	timeout = TIMEOUT;
+
+	if (data_cmd) {
+		data_cmd = false;
+		do {
+			udelay(250);
+		} while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
+	}
+
+	status_check = value & SRS12_ERR_MASK;
+	if (status_check != 0U) {
+		ERROR("SD host controller send command failed, SRS12 = %x", status);
+		return -1;
+	}
+
+	if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
+		cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
+		if (op & RES_TYPE_SEL_136) {
+			cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
+			cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
+			cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/cadence/nand/cdns_nand.c b/drivers/cadence/nand/cdns_nand.c
new file mode 100644
index 0000000..5a66262
--- /dev/null
+++ b/drivers/cadence/nand/cdns_nand.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <platform_def.h>
+
+/* NAND flash device information struct */
+static cnf_dev_info_t dev_info;
+
+/* Scratch buffers for read and write operations */
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+/* Wait for controller to be in idle state */
+static inline void cdns_nand_wait_idle(void)
+{
+	uint32_t reg = 0U;
+
+	do {
+		udelay(CNF_DEF_DELAY_US);
+		reg = mmio_read_32(CNF_CMDREG(CTRL_STATUS));
+	} while (CNF_GET_CTRL_BUSY(reg) != 0U);
+}
+
+/* Wait for given thread to be in ready state */
+static inline void cdns_nand_wait_thread_ready(uint8_t thread_id)
+{
+	uint32_t reg = 0U;
+
+	do {
+		udelay(CNF_DEF_DELAY_US);
+		reg = mmio_read_32(CNF_CMDREG(TRD_STATUS));
+		reg &= (1U << (uint32_t)thread_id);
+	} while (reg != 0U);
+}
+
+/* Check if the last operation/command in selected thread is completed */
+static int cdns_nand_last_opr_status(uint8_t thread_id)
+{
+	uint8_t nthreads = 0U;
+	uint32_t reg = 0U;
+
+	/* Get number of threads */
+	reg = mmio_read_32(CNF_CTRLPARAM(FEATURE));
+	nthreads = CNF_GET_NTHREADS(reg);
+
+	if (thread_id > nthreads) {
+		ERROR("%s: Invalid thread ID\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Select thread */
+	mmio_write_32(CNF_CMDREG(CMD_STAT_PTR), (uint32_t)thread_id);
+
+	uint32_t err_mask = CNF_ECMD | CNF_EECC | CNF_EDEV | CNF_EDQS | CNF_EFAIL |
+				CNF_EBUS | CNF_EDI | CNF_EPAR | CNF_ECTX | CNF_EPRO;
+
+	do {
+		udelay(CNF_DEF_DELAY_US * 2);
+		reg = mmio_read_32(CNF_CMDREG(CMD_STAT));
+	} while ((reg & CNF_CMPLT) == 0U);
+
+	/* last operation is completed, make sure no other error bits are set */
+	if ((reg & err_mask) == 1U) {
+		ERROR("%s, CMD_STATUS:0x%x\n", __func__, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/* Set feature command */
+int cdns_nand_set_feature(uint8_t feat_addr, uint8_t feat_val, uint8_t thread_id)
+{
+	/* Wait for thread to be ready */
+	cdns_nand_wait_thread_ready(thread_id);
+
+	/* Set feature address */
+	mmio_write_32(CNF_CMDREG(CMD_REG1), (uint32_t)feat_addr);
+	/* Set feature volume */
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (uint32_t)feat_val);
+
+	/* Set feature command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (thread_id << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_SET_FEATURE << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	return cdns_nand_last_opr_status(thread_id);
+}
+
+/* Reset command to the selected device */
+int cdns_nand_reset(uint8_t thread_id)
+{
+	/* Operation is executed in selected thread */
+	cdns_nand_wait_thread_ready(thread_id);
+
+	/* Select memory */
+	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Issue reset command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (thread_id << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_RESET_ASYNC << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	return cdns_nand_last_opr_status(thread_id);
+}
+
+/* Set operation work mode */
+static void cdns_nand_set_opr_mode(uint8_t opr_mode)
+{
+	/* Wait for controller to be in idle state */
+	cdns_nand_wait_idle();
+
+	/* Reset DLL PHY */
+	uint32_t reg = mmio_read_32(CNF_MINICTRL(DLL_PHY_CTRL));
+
+	reg &= ~(1 << CNF_DLL_PHY_RST_N);
+	mmio_write_32(CNF_MINICTRL(DLL_PHY_CTRL), reg);
+
+	if (opr_mode == CNF_OPR_WORK_MODE_SDR) {
+		/* Combo PHY Control Timing Block register settings */
+		mmio_write_32(CP_CTB(CTRL_REG), CP_CTRL_REG_SDR);
+		mmio_write_32(CP_CTB(TSEL_REG), CP_TSEL_REG_SDR);
+
+		/* Combo PHY DLL register settings */
+		mmio_write_32(CP_DLL(DQ_TIMING_REG), CP_DQ_TIMING_REG_SDR);
+		mmio_write_32(CP_DLL(DQS_TIMING_REG), CP_DQS_TIMING_REG_SDR);
+		mmio_write_32(CP_DLL(GATE_LPBK_CTRL_REG), CP_GATE_LPBK_CTRL_REG_SDR);
+		mmio_write_32(CP_DLL(MASTER_CTRL_REG), CP_DLL_MASTER_CTRL_REG_SDR);
+
+		/* Async mode timing settings */
+		mmio_write_32(CNF_MINICTRL(ASYNC_TOGGLE_TIMINGS),
+								(2 << CNF_ASYNC_TIMINGS_TRH) |
+								(4 << CNF_ASYNC_TIMINGS_TRP) |
+								(2 << CNF_ASYNC_TIMINGS_TWH) |
+								(4 << CNF_ASYNC_TIMINGS_TWP));
+
+		/* Set extended read and write mode */
+		reg |= (1 << CNF_DLL_PHY_EXT_RD_MODE);
+		reg |= (1 << CNF_DLL_PHY_EXT_WR_MODE);
+
+		/* Set operation work mode in common settings */
+		uint32_t data = mmio_read_32(CNF_MINICTRL(CMN_SETTINGS));
+
+		data |= (CNF_OPR_WORK_MODE_SDR << CNF_CMN_SETTINGS_OPR);
+		mmio_write_32(CNF_MINICTRL(CMN_SETTINGS), data);
+
+	} else if (opr_mode == CNF_OPR_WORK_MODE_NVDDR) {
+		; /* ToDo: add DDR mode settings also once available on SIMICS */
+	} else {
+		;
+	}
+
+	reg |= (1 << CNF_DLL_PHY_RST_N);
+	mmio_write_32(CNF_MINICTRL(DLL_PHY_CTRL), reg);
+}
+
+/* Data transfer configuration */
+static void cdns_nand_transfer_config(void)
+{
+	/* Wait for controller to be in idle state */
+	cdns_nand_wait_idle();
+
+	/* Configure data transfer parameters */
+	mmio_write_32(CNF_CTRLCFG(TRANS_CFG0), 1);
+
+	/* ECC is disabled */
+	mmio_write_32(CNF_CTRLCFG(ECC_CFG0), 0);
+
+	/* DMA burst select */
+	mmio_write_32(CNF_CTRLCFG(DMA_SETTINGS),
+					(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
+					(1 << CNF_DMA_SETTINGS_OTE));
+
+	/* Enable pre-fetching for 1K */
+	mmio_write_32(CNF_CTRLCFG(FIFO_TLEVEL),
+					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
+					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
+
+	/* Select access type */
+	mmio_write_32(CNF_CTRLCFG(MULTIPLANE_CFG), 0);
+	mmio_write_32(CNF_CTRLCFG(CACHE_CFG), 0);
+}
+
+/* Update the nand flash device info */
+static int cdns_nand_update_dev_info(void)
+{
+	uint32_t reg = 0U;
+
+	/* Read the device type and number of LUNs */
+	reg = mmio_read_32(CNF_CTRLPARAM(DEV_PARAMS0));
+	dev_info.type = CNF_GET_DEV_TYPE(reg);
+	if (dev_info.type == CNF_DT_UNKNOWN) {
+		ERROR("%s: device type unknown\n", __func__);
+		return -ENXIO;
+	}
+	dev_info.nluns = CNF_GET_NLUNS(reg);
+
+	/* Pages per block */
+	reg = mmio_read_32(CNF_CTRLCFG(DEV_LAYOUT));
+	dev_info.npages_per_block = CNF_GET_NPAGES_PER_BLOCK(reg);
+
+	/* Sector size and last sector size */
+	reg = mmio_read_32(CNF_CTRLCFG(TRANS_CFG1));
+	dev_info.sector_size = CNF_GET_SCTR_SIZE(reg);
+	dev_info.last_sector_size = CNF_GET_LAST_SCTR_SIZE(reg);
+
+	/* Page size and spare size */
+	reg = mmio_read_32(CNF_CTRLPARAM(DEV_AREA));
+	dev_info.page_size = CNF_GET_PAGE_SIZE(reg);
+	dev_info.spare_size = CNF_GET_SPARE_SIZE(reg);
+
+	/* Device blocks per LUN */
+	dev_info.nblocks_per_lun = mmio_read_32(CNF_CTRLPARAM(DEV_BLOCKS_PLUN));
+
+	/* Calculate block size and total device size */
+	dev_info.block_size = (dev_info.npages_per_block * dev_info.page_size);
+	dev_info.total_size = (dev_info.block_size * dev_info.nblocks_per_lun *
+							dev_info.nluns);
+
+	VERBOSE("CNF params: page %d, spare %d, block %d, total %lld\n",
+				dev_info.page_size, dev_info.spare_size,
+				dev_info.block_size, dev_info.total_size);
+
+	return 0;
+}
+
+/* NAND Flash Controller/Host initialization */
+int cdns_nand_host_init(void)
+{
+	uint32_t reg = 0U;
+	int ret = 0;
+
+	do {
+		/* Read controller status register for init complete */
+		reg = mmio_read_32(CNF_CMDREG(CTRL_STATUS));
+	} while (CNF_GET_INIT_COMP(reg) == 0);
+
+	ret = cdns_nand_update_dev_info();
+	if (ret != 0) {
+		return ret;
+	}
+
+	INFO("CNF: device discovery process completed and device type %d\n",
+			dev_info.type);
+
+	/* Enable data integrity, enable CRC and parity */
+	reg = mmio_read_32(CNF_DI(CONTROL));
+	reg |= (1 << CNF_DI_PAR_EN);
+	reg |= (1 << CNF_DI_CRC_EN);
+	mmio_write_32(CNF_DI(CONTROL), reg);
+
+	/* Status polling mode, device control and status register */
+	cdns_nand_wait_idle();
+	reg = mmio_read_32(CNF_CTRLCFG(DEV_STAT));
+	reg = reg & ~1;
+	mmio_write_32(CNF_CTRLCFG(DEV_STAT), reg);
+
+	/* Set operation work mode */
+	cdns_nand_set_opr_mode(CNF_OPR_WORK_MODE_SDR);
+
+	/* Set data transfer configuration parameters */
+	cdns_nand_transfer_config();
+
+	return 0;
+}
+
+/* erase: Block erase command */
+int cdns_nand_erase(uint32_t offset, uint32_t size)
+{
+	/* Determine the starting block offset i.e row address */
+	uint32_t row_address = dev_info.npages_per_block * offset;
+
+	/* Wait for thread to be in ready state */
+	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
+
+	/*Set row address */
+	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+
+	/* Operation bank number */
+	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Block erase command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (CNF_DEF_TRD << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_CT_ERASE << CNF_CMDREG0_CMD);
+	reg |= (((size-1) & 0xFF) << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	/* Wait for erase operation to complete */
+	return cdns_nand_last_opr_status(CNF_DEF_TRD);
+}
+
+/* io mtd functions */
+int cdns_nand_init_mtd(unsigned long long *size, unsigned int *erase_size)
+{
+	*size = dev_info.total_size;
+	*erase_size = dev_info.block_size;
+
+	return 0;
+}
+
+/* NAND Flash page read */
+static int cdns_nand_read_page(uint32_t block, uint32_t page, uintptr_t buffer)
+{
+	/* Wait for thread to be ready */
+	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
+
+	/* Select device */
+	mmio_write_32(CNF_CMDREG(CMD_REG4),
+					(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+
+	/* Set host memory address for DMA transfers */
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & 0xFFFF));
+	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & 0xFFFF));
+
+	/* Set row address */
+	uint32_t row_address = 0U;
+
+	row_address |= ((page & 0x3F) | (block << 6));
+	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+
+	/* Page read command */
+	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
+
+	reg |= (CNF_DEF_TRD << CNF_CMDREG0_TRD);
+	reg |= (CNF_DEF_VOL_ID << CNF_CMDREG0_VOL);
+	reg |= (CNF_INT_DIS << CNF_CMDREG0_INTR);
+	reg |= (CNF_DMA_MASTER_SEL << CNF_CMDREG0_DMA);
+	reg |= (CNF_CT_PAGE_READ << CNF_CMDREG0_CMD);
+	reg |= (((CNF_READ_SINGLE_PAGE-1) & 0xFF) << CNF_CMDREG0_CMD);
+	mmio_write_32(CNF_CMDREG(CMD_REG0), reg);
+
+	/* Wait for read operation to complete */
+	if (cdns_nand_last_opr_status(CNF_DEF_TRD)) {
+		ERROR("%s: Page read failed\n", __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int cdns_nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+					size_t *out_length)
+{
+	uint32_t block = offset / dev_info.block_size;
+	uint32_t end_block = (offset + length - 1U) / dev_info.block_size;
+	uint32_t page_start = (offset % dev_info.block_size) / dev_info.page_size;
+	uint32_t start_offset = offset % dev_info.page_size;
+	uint32_t nb_pages = dev_info.block_size / dev_info.page_size;
+	uint32_t bytes_read = 0U;
+	uint32_t page = 0U;
+	int result = 0;
+
+	VERBOSE("CNF: block %u-%u, page_start %u, len %zu, offset %u\n",
+				block, end_block, page_start, length, offset);
+
+	if ((offset >= dev_info.total_size) ||
+		(offset + length-1 >= dev_info.total_size) ||
+		(length == 0U)) {
+		ERROR("CNF: Invalid read parameters\n");
+		return -EINVAL;
+	}
+
+	*out_length = 0UL;
+
+	while (block <= end_block) {
+		for (page = page_start; page < nb_pages; page++) {
+			if ((start_offset != 0U) || (length < dev_info.page_size)) {
+				/* Partial page read */
+				result = cdns_nand_read_page(block, page,
+				(uintptr_t)scratch_buff);
+				if (result != 0) {
+					return result;
+				}
+
+				bytes_read = MIN((size_t)(dev_info.page_size - start_offset),
+								length);
+
+				memcpy((uint8_t *)buffer, scratch_buff + start_offset,
+						bytes_read);
+				start_offset = 0U;
+			} else {
+				/* Full page read */
+				result = cdns_nand_read_page(block, page,
+				(uintptr_t)scratch_buff);
+				if (result != 0) {
+					return result;
+				}
+
+				bytes_read = dev_info.page_size;
+				memcpy((uint8_t *)buffer, scratch_buff, bytes_read);
+			}
+
+			length -= bytes_read;
+			buffer += bytes_read;
+			*out_length += bytes_read;
+
+			/* All the bytes have read */
+			if (length == 0U) {
+				break;
+			}
+
+			udelay(CNF_READ_INT_DELAY_US);
+		} /* for */
+
+		page_start = 0U;
+		block++;
+	} /* while */
+
+	return 0;
+}
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index 4c1a80e..1bdaa48 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -197,7 +197,14 @@
 	cmp	x0, #0
 	ASM_ASSERT(ne)
 #endif /* ENABLE_ASSERTIONS */
-	/* Placeholder */
+	/* Loop until the transmit FIFO is empty */
+check_txfifo_empty:
+	ldr     w2, [x0, #R_UART_SR]
+	tbz     w2, #UART_SR_INTR_TEMPTY_BIT, check_txfifo_empty
+	/* Wait until the Transmit is Inactive */
+check_tx_inactive_state:
+	ldr     w2, [x0, #R_UART_SR]
+	tbnz    w2, #UART_SR_INTR_TACTIVE_BIT, check_tx_inactive_state
 	ret
 endfunc console_cdns_core_flush
 
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
index cf545a7..258aa8d 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,39 +32,42 @@
 #  error Invalid Measured Boot algorithm.
 #endif /* MBOOT_ALG_ID */
 
-/* Pointer to struct rss_mboot_metadata */
-static struct rss_mboot_metadata *plat_metadata_ptr;
-
-/* Functions' declarations */
-void rss_measured_boot_init(void)
+#if ENABLE_ASSERTIONS
+static bool null_arr(const uint8_t *signer_id, size_t signer_id_size)
 {
-	/* At this point it is expected that communication channel over MHU
-	 * is already initialised by platform init.
-	 */
-	struct rss_mboot_metadata *metadata_ptr;
+	for (size_t i = 0U; i < signer_id_size; i++) {
+		if (signer_id[i] != 0U) {
+			return false;
+		}
+	}
 
-	/* Get pointer to platform's struct rss_mboot_metadata structure */
-	plat_metadata_ptr = plat_rss_mboot_get_metadata();
-	assert(plat_metadata_ptr != NULL);
+	return true;
+}
+#endif /* ENABLE_ASSERTIONS */
 
-	/* Use a local variable to preserve the value of the global pointer */
-	metadata_ptr = plat_metadata_ptr;
+/* Functions' declarations */
+void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr)
+{
+	assert(metadata_ptr != NULL);
 
 	/* Init the non-const members of the metadata structure */
 	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+		assert(null_arr(metadata_ptr->signer_id, MBOOT_DIGEST_SIZE));
 		metadata_ptr->sw_type_size =
 			strlen((const char *)&metadata_ptr->sw_type) + 1;
 		metadata_ptr++;
 	}
 }
 
-int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id)
 {
 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
 	int rc;
 	psa_status_t ret;
-	const struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
+
+	assert(metadata_ptr != NULL);
 
 	/* Get the metadata associated with this image. */
 	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
@@ -103,35 +106,54 @@
 	return 0;
 }
 
-int rss_mboot_set_signer_id(unsigned int img_id,
+int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+			    const void *pk_oid,
 			    const void *pk_ptr,
 			    size_t pk_len)
 {
 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
-	struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
 	int rc;
+	bool hash_calc_done = false;
 
-	/* Get the metadata associated with this image. */
-	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
-		(metadata_ptr->id != img_id)) {
-		metadata_ptr++;
-	}
+	assert(metadata_ptr != NULL);
 
-	/* If image is not present in metadata array then skip */
-	if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
-		return 0;
-	}
+	/*
+	 * Do an exhaustive search over the platform metadata to find
+	 * all images whose key OID matches the one passed in argument.
+	 *
+	 * Note that it is not an error if do not get any matches.
+	 * The platform may decide not to measure all of the images
+	 * in the system.
+	 */
+	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+		/* Get the metadata associated with this key-oid */
+		if (metadata_ptr->pk_oid == pk_oid) {
+			if (!hash_calc_done) {
+				/* Calculate public key hash */
+				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+							  (void *)pk_ptr,
+							  pk_len, hash_data);
+				if (rc != 0) {
+					return rc;
+				}
 
-	/* Calculate public key hash */
-	rc = crypto_mod_calc_hash(CRYPTO_MD_ID, (void *)pk_ptr,
-				  pk_len, hash_data);
-	if (rc != 0) {
-		return rc;
-	}
+				hash_calc_done = true;
+			}
 
-	/* Update metadata struct with the received signer_id */
-	(void)memcpy(metadata_ptr->signer_id, hash_data, MBOOT_DIGEST_SIZE);
-	metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE;
+			/*
+			 * Fill the signer-ID field with the newly/already
+			 * computed hash of the public key and update its
+			 * signer ID size field with compile-time decided
+			 * digest size.
+			 */
+			(void)memcpy(metadata_ptr->signer_id,
+				     hash_data,
+				     MBOOT_DIGEST_SIZE);
+			metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE;
+		}
+
+		metadata_ptr++;
+	}
 
 	return 0;
 }
diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c
index 98fdc6a..5aaf68c 100644
--- a/drivers/scmi-msg/clock.c
+++ b/drivers/scmi-msg/clock.c
@@ -37,7 +37,8 @@
 int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused,
 				    unsigned int scmi_id __unused,
 				    unsigned long *rates __unused,
-				    size_t *nb_elts __unused)
+				    size_t *nb_elts __unused,
+				    uint32_t start_idx __unused)
 {
 	return SCMI_NOT_SUPPORTED;
 }
@@ -298,7 +299,7 @@
 
 	/* Platform may support array rate description */
 	status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL,
-					     &nb_rates);
+					     &nb_rates, 0);
 	if (status == SCMI_SUCCESS) {
 		/* Currently 12 cells mex, so it's affordable for the stack */
 		unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE];
@@ -307,7 +308,8 @@
 		size_t rem_nb = nb_rates - in_args->rate_index - ret_nb;
 
 		status =  plat_scmi_clock_rates_array(msg->agent_id, clock_id,
-						      plat_rates, &ret_nb);
+						      plat_rates, &ret_nb,
+						      in_args->rate_index);
 		if (status == SCMI_SUCCESS) {
 			write_rate_desc_array_in_buffer(msg->out + sizeof(p2a),
 							plat_rates, ret_nb);
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index d64a6cd..e063941 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -236,7 +236,7 @@
 #endif /* ENABLE_ASSERTIONS */
 	/* Skip flush if UART is not enabled */
 	ldr	r1, [r0, #USART_CR1]
-	ands	r1, r1, #USART_CR1_UE
+	tst	r1, #USART_CR1_UE
 	beq	1f
 	/* Check Transmit Data Register Empty */
 txe_loop_3:
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index b8137c2..5ba5eb0 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -540,6 +540,7 @@
 
 	query_upiu->trans_type = QUERY_REQUEST_UPIU;
 	query_upiu->task_tag = utrd->task_tag;
+	query_upiu->data_segment_len = htobe16(length);
 	query_upiu->ts.desc.opcode = op;
 	query_upiu->ts.desc.idn = idn;
 	query_upiu->ts.desc.index = index;
diff --git a/fdts/juno.dts b/fdts/juno.dts
index 56fe167..8e373e7 100644
--- a/fdts/juno.dts
+++ b/fdts/juno.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
  */
@@ -10,6 +10,6 @@
 
 };
 
-#if ARM_ETHOSN_NPU_DRIVER
+#if ETHOSN_NPU_DRIVER
 	#include "juno-ethosn.dtsi"
 #endif
diff --git a/fdts/morello-coresight.dtsi b/fdts/morello-coresight.dtsi
new file mode 100644
index 0000000..ed3e9e5
--- /dev/null
+++ b/fdts/morello-coresight.dtsi
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	/*
+	 * Morello TRMs specify the size for these coresight components as 64K.
+	 * The actual size is just 4K though 64K is reserved. Access to the
+	 * unmapped reserved region results in a DECERR response.
+	 */
+	cpu_debug0: cpu-debug@402010000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu0>;
+		reg = <0x4 0x02010000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm0: etm@402040000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu0>;
+		reg = <0x4 0x02040000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster0_etm0_out_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	cpu_debug1: cpu-debug@402110000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu1>;
+		reg = <0x4 0x02110000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm1: etm@402140000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu1>;
+		reg = <0x4 0x02140000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster0_etm1_out_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	cpu_debug2: cpu-debug@403010000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu2>;
+		reg = <0x4 0x03010000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm2: etm@403040000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu2>;
+		reg = <0x4 0x03040000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster1_etm0_out_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	cpu_debug3: cpu-debug@403110000 {
+		compatible = "arm,coresight-cpu-debug", "arm,primecell";
+		cpu = <&cpu3>;
+		reg = <0x4 0x03110000 0x0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+	};
+
+	etm3: etm@403140000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		cpu = <&cpu3>;
+		reg = <0x4 0x03140000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster1_etm1_out_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	sfunnel0: funnel@0 { /* cluster0 funnel */
+		compatible = "arm,coresight-static-funnel";
+		out-ports {
+			port {
+				cluster0_static_funnel_out_port: endpoint {
+					remote-endpoint = <&etf0_in_port>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster0_static_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster0_etm0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster0_static_funnel_in_port1: endpoint {
+					remote-endpoint = <&cluster0_etm1_out_port>;
+				};
+			};
+		};
+	};
+
+	sfunnel1: funnel@1 { /* cluster1 funnel */
+		compatible = "arm,coresight-static-funnel";
+		out-ports {
+			port {
+				cluster1_static_funnel_out_port: endpoint {
+					remote-endpoint = <&etf1_in_port>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster1_static_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster1_etm0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster1_static_funnel_in_port1: endpoint {
+					remote-endpoint = <&cluster1_etm1_out_port>;
+				};
+			};
+		};
+	};
+
+	tpiu@400130000 {
+		compatible = "arm,coresight-tpiu", "arm,primecell";
+		reg = <0x4 0x00130000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				tpiu_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port0>;
+				};
+			};
+		};
+	};
+
+	main_funnel: funnel@4000a0000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0x4 0x000a0000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				main_funnel_out_port: endpoint {
+					remote-endpoint = <&replicator_in_port>;
+				};
+			};
+		};
+		main_funnel_in_ports: in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				main_funnel_in_port0: endpoint {
+					remote-endpoint = <&cluster_funnel_out_port>;
+				};
+			};
+			port@5 {
+				reg = <5>;
+				main_funnel_in_port5: endpoint {
+					remote-endpoint = <&etf2_out_port>;
+				};
+			};
+		};
+	};
+
+	etr@400120000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00120000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		arm,scatter-gather;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "etrbufint";
+		in-ports {
+			port {
+				etr_in_port: endpoint {
+					remote-endpoint = <&replicator_out_port1>;
+				};
+			};
+		};
+	};
+
+	replicator@400110000 {
+		compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+		reg = <0x4 0x00110000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			/* replicator output ports */
+			port@0 {
+				reg = <0>;
+				replicator_out_port0: endpoint {
+					remote-endpoint = <&tpiu_in_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				replicator_out_port1: endpoint {
+					remote-endpoint = <&etr_in_port>;
+				};
+			};
+		};
+		in-ports {
+			port {
+				replicator_in_port: endpoint {
+					remote-endpoint = <&main_funnel_out_port>;
+				};
+			};
+		};
+	};
+
+	cluster_funnel: funnel@4000b0000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0x4 0x000b0000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				cluster_funnel_out_port: endpoint {
+					remote-endpoint = <&main_funnel_in_port0>;
+				};
+			};
+		};
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				cluster_funnel_in_port0: endpoint {
+					remote-endpoint = <&etf0_out_port>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				cluster_funnel_in_port1: endpoint {
+					remote-endpoint = <&etf1_out_port>;
+				};
+			};
+		};
+	};
+
+	etf0: etf@400410000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00410000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf0_in_port: endpoint {
+					remote-endpoint = <&cluster0_static_funnel_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf0_out_port: endpoint {
+					remote-endpoint = <&cluster_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	etf1: etf@400420000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00420000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf1_in_port: endpoint {
+					remote-endpoint = <&cluster1_static_funnel_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf1_out_port: endpoint {
+					remote-endpoint = <&cluster_funnel_in_port1>;
+				};
+			};
+		};
+	};
+
+	stm_etf: etf@400010000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x4 0x00010000 0 0x1000>;
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		in-ports {
+			port {
+				etf2_in_port: endpoint {
+					remote-endpoint = <&stm_out_port>;
+				};
+			};
+		};
+		out-ports {
+			port {
+				etf2_out_port: endpoint {
+					remote-endpoint = <&main_funnel_in_port5>;
+				};
+			};
+		};
+	};
+
+	stm@400800000 {
+		compatible = "arm,coresight-stm", "arm,primecell";
+		reg = <4 0x00800000 0 0x1000>,
+		      <0 0x4d000000 0 0x1000000>;
+		reg-names = "stm-base", "stm-stimulus-base";
+		clocks = <&soc_refclk50mhz>;
+		clock-names = "apb_pclk";
+		out-ports {
+			port {
+				stm_out_port: endpoint {
+					remote-endpoint = <&etf2_in_port>;
+				};
+			};
+		};
+	};
+};
diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts
index dc3df41..fda0f55 100644
--- a/fdts/morello-fvp.dts
+++ b/fdts/morello-fvp.dts
@@ -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
  */
@@ -25,6 +25,32 @@
 		};
 	};
 
+	/*
+	 * The timings below are just to demonstrate working cpuidle.
+	 * These values may be inaccurate.
+	 */
+	idle-states {
+		entry-method = "psci";
+
+		cluster_sleep: cluster-sleep {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x40000022>;
+			local-timer-stop;
+			entry-latency-us = <500>;
+			exit-latency-us = <1000>;
+			min-residency-us = <2500>;
+		};
+
+		cpu_sleep: cpu-sleep {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x40000002>;
+			local-timer-stop;
+			entry-latency-us = <150>;
+			exit-latency-us = <300>;
+			min-residency-us = <200>;
+		};
+	};
+
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
@@ -53,6 +79,7 @@
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
 		CPU1: cpu1@100 {
 			compatible = "arm,armv8";
@@ -60,6 +87,7 @@
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
 		CPU2: cpu2@10000 {
 			compatible = "arm,armv8";
@@ -67,6 +95,7 @@
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
 		CPU3: cpu3@10100 {
 			compatible = "arm,armv8";
@@ -74,6 +103,7 @@
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
 	};
 
diff --git a/fdts/morello-soc.dts b/fdts/morello-soc.dts
index e87b617..fba904b 100644
--- a/fdts/morello-soc.dts
+++ b/fdts/morello-soc.dts
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include "morello.dtsi"
+#include "morello-coresight.dtsi"
 
 / {
 	model = "Arm Morello System Development Platform";
@@ -25,36 +26,102 @@
 		};
 	};
 
+	/*
+	 * The timings below are just to demonstrate working cpuidle.
+	 * These values may be inaccurate.
+	 */
+	idle-states {
+		entry-method = "psci";
+
+		cluster_sleep: cluster-sleep {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x40000022>;
+			local-timer-stop;
+			entry-latency-us = <500>;
+			exit-latency-us = <1000>;
+			min-residency-us = <2500>;
+		};
+
+		cpu_sleep: cpu-sleep {
+			compatible = "arm,idle-state";
+			arm,psci-suspend-param = <0x40000002>;
+			local-timer-stop;
+			entry-latency-us = <150>;
+			exit-latency-us = <300>;
+			min-residency-us = <200>;
+		};
+	};
+
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
-		cpu0@0 {
+		cpu0: cpu0@0 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x0>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			operating-points = <
+				/* kHz		uV */
+				2600000		925000
+				2400000		875000
+				2200000		825000
+				2000000		775000
+				1800000		750000
+			>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
-		cpu1@100 {
+		cpu1: cpu1@100 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x100>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
+			operating-points = <
+				/* kHz		uV */
+				2600000		925000
+				2400000		875000
+				2200000		825000
+				2000000		775000
+				1800000		750000
+			>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
-		cpu2@10000 {
+		cpu2: cpu2@10000 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x10000>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
+			operating-points = <
+				/* kHz		uV */
+				2600000		925000
+				2400000		875000
+				2200000		825000
+				2000000		775000
+				1800000		750000
+			>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
-		cpu3@10100 {
+		cpu3: cpu3@10100 {
 			compatible = "arm,armv8";
 			reg = <0x0 0x10100>;
 			device_type = "cpu";
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
+			operating-points = <
+				/* kHz		uV */
+				2600000		925000
+				2400000		875000
+				2200000		825000
+				2000000		775000
+				1800000		750000
+			>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_sleep &cluster_sleep>;
 		};
 	};
 
@@ -193,10 +260,12 @@
 		interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&dpu_aclk>;
 
-		hdmi-transmitter@70 {
+		hdmi_tx: hdmi-transmitter@70 {
 			compatible = "nxp,tda998x";
 			reg = <0x70>;
 			video-ports = <0x234501>;
+			#sound-dai-cells = <0>;
+			audio-ports = <2 0x03>;
 			port {
 				tda998x_0_input: endpoint {
 					remote-endpoint = <&dp_pl0_out0>;
@@ -252,7 +321,139 @@
 				reg = <0x14>;
 				#clock-cells = <1>;
 			};
+			scmi_sensor: protocol@15 {
+				reg = <0x15>;
+				#thermal-sensor-cells = <1>;
+			};
+		};
+	};
+
+	thermal-zones {
+		clus0-thermal {
+			polling-delay-passive = <200>; /* ms */
+			polling-delay = <1000>; /* ms */
+
+			thermal-sensors = <&scmi_sensor 0>;
+
+			trips {
+				clus0_alarm: clus0-alarm {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <1000>; /* millicelsius */
+					type = "passive";
+				};
+				clus0_shutdown: clus0-shutdown {
+					temperature = <90000>; /* millicelsius */
+					hysteresis = <0>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&clus0_alarm>;
+					cooling-device = <&cpu0 4 4>, <&cpu1 4 4>;
+				};
+			};
+		};
+		clus1-thermal {
+			polling-delay-passive = <200>; /* ms */
+			polling-delay = <1000>; /* ms */
+
+			thermal-sensors = <&scmi_sensor 1>;
+			trips {
+				clus1_alarm: clus1-alarm {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <1000>; /* millicelsius */
+					type = "passive";
+				};
+				clus1_shutdown: clus1-shutdown {
+					temperature = <90000>; /* millicelsius */
+					hysteresis = <0>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&clus1_alarm>;
+					cooling-device = <&cpu2 4 4>, <&cpu3 4 4>;
+				};
+			};
 		};
+		sys-thermal {
+			polling-delay-passive = <200>; /* ms */
+			polling-delay = <1000>; /* ms */
+
+			thermal-sensors = <&scmi_sensor 2>;
+			trips {
+				sys_alarm: sys-alarm {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <1000>; /* millicelsius */
+					type = "passive";
+				};
+				sys_shutdown: sys-shutdown {
+					temperature = <90000>; /* millicelsius */
+					hysteresis = <0>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sys_alarm>;
+					cooling-device = <&cpu0 4 4>,
+						<&cpu1 4 4>,
+						<&cpu2 4 4>,
+						<&cpu3 4 4>;
+				};
+			};
+		};
+	};
+
+	iofpga_i2s: xlnx-i2s@1c150000 {
+		#sound-dai-cells = <0>;
+		compatible = "xlnx,i2s-transmitter-1.0";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x0 0x1c150000 0x0 0x10000>;
+		xlnx,dwidth = <0x18>;
+		xlnx,num-channels = <1>;
+	};
+
+	audio_formatter: audio-formatter@1c100000 {
+		compatible = "xlnx,audio-formatter-1.0";
+		reg = <0x0 0x1c000000 0x0 0x10000>;
+		#sound-dai-cells = <0>;
+		interrupt-names = "irq_mm2s";
+		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "s_axi_lite_aclk", "aud_mclk", "m_axis_mm2s_aclk";
+		clocks = <&soc_refclk85mhz>, <&i2s_audclk>, <&soc_refclk85mhz>;
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&audio_master>;
+		simple-audio-card,frame-master = <&audio_master>;
+		audio_master: simple-audio-card,cpu {
+			sound-dai = <&iofpga_i2s>;
+			clocks = <&i2s_audclk>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&hdmi_tx>;
+		};
+
+		simple-audio-card,plat {
+			sound-dai = <&audio_formatter>;
+		};
+	};
+
+	i2s_audclk: i2s_audclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12288000>;
+		clock-output-names = "iofpga:i2s_audclk";
 	};
 };
 
diff --git a/fdts/morello.dtsi b/fdts/morello.dtsi
index 20640c5..7f39d75 100644
--- a/fdts/morello.dtsi
+++ b/fdts/morello.dtsi
@@ -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
  */
@@ -88,6 +88,13 @@
 		clock-output-names = "apb_pclk";
 	};
 
+	soc_refclk85mhz: refclk85mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <85000000>;
+		clock-output-names = "iofpga:aclk";
+	};
+
 	soc_uartclk:  uartclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index dd2c0a6..da4ee7f 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -197,11 +197,11 @@
 #define SDCR_SPD_LEGACY		U(0x0)
 #define SDCR_SPD_DISABLE	U(0x2)
 #define SDCR_SPD_ENABLE		U(0x3)
-#define SDCR_SCCD_BIT		(U(1) << 23)
-#define SDCR_TTRF_BIT		(U(1) << 19)
 #define SDCR_SPME_BIT		(U(1) << 17)
-#define SDCR_RESET_VAL		U(0x0)
+#define SDCR_TTRF_BIT		(U(1) << 19)
+#define SDCR_SCCD_BIT		(U(1) << 23)
 #define SDCR_MTPME_BIT		(U(1) << 28)
+#define SDCR_RESET_VAL		U(0x0)
 
 /* HSCTLR definitions */
 #define HSCTLR_RES1	((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 5dbcd0a..c10102a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -157,6 +157,8 @@
 #define DCCSW			U(0x2)
 #endif
 
+#define ID_REG_FIELD_MASK			ULL(0xf)
+
 /* ID_AA64PFR0_EL1 definitions */
 #define ID_AA64PFR0_EL0_SHIFT			U(0)
 #define ID_AA64PFR0_EL1_SHIFT			U(4)
@@ -275,6 +277,9 @@
 /* ID_AA64ISAR2_EL1 definitions */
 #define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
 
+/* ID_AA64PFR2_EL1 definitions */
+#define ID_AA64PFR2_EL1			S3_0_C0_C4_2
+
 #define ID_AA64ISAR2_GPA3_SHIFT		U(8)
 #define ID_AA64ISAR2_GPA3_MASK		ULL(0xf)
 
@@ -402,6 +407,16 @@
 #define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED	ULL(0x1)
 #define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED	ULL(0x0)
 
+/* ID_AA64PFR2_EL1 definitions */
+#define ID_AA64PFR2_EL1_MTEPERM_SHIFT		U(0)
+#define ID_AA64PFR2_EL1_MTEPERM_MASK		ULL(0xf)
+
+#define ID_AA64PFR2_EL1_MTESTOREONLY_SHIFT	U(4)
+#define ID_AA64PFR2_EL1_MTESTOREONLY_MASK	ULL(0xf)
+
+#define ID_AA64PFR2_EL1_MTEFAR_SHIFT		U(8)
+#define ID_AA64PFR2_EL1_MTEFAR_MASK		ULL(0xf)
+
 #define VDISR_EL2				S3_4_C12_C1_1
 #define VSESR_EL2				S3_4_C5_C2_3
 
@@ -422,6 +437,7 @@
 
 #define ID_AA64PFR1_EL1_SME_SHIFT		U(24)
 #define ID_AA64PFR1_EL1_SME_MASK		ULL(0xf)
+#define ID_AA64PFR1_EL1_SME_WIDTH		U(4)
 #define ID_AA64PFR1_EL1_SME_NOT_SUPPORTED	ULL(0x0)
 #define ID_AA64PFR1_EL1_SME_SUPPORTED		ULL(0x1)
 #define ID_AA64PFR1_EL1_SME2_SUPPORTED		ULL(0x2)
@@ -583,7 +599,7 @@
 #define MDCR_SBRBE_MASK		ULL(0x3)
 #define MDCR_NSTB(x)		((x) << 24)
 #define MDCR_NSTB_EL1		ULL(0x3)
-#define MDCR_NSTBE		(ULL(1) << 26)
+#define MDCR_NSTBE_BIT		(ULL(1) << 26)
 #define MDCR_MTPME_BIT		(ULL(1) << 28)
 #define MDCR_TDCC_BIT		(ULL(1) << 27)
 #define MDCR_SCCD_BIT		(ULL(1) << 23)
@@ -599,6 +615,7 @@
 #define MDCR_SPD32_ENABLE	ULL(0x3)
 #define MDCR_NSPB(x)		((x) << 12)
 #define MDCR_NSPB_EL1		ULL(0x3)
+#define MDCR_NSPBE_BIT		(ULL(1) << 11)
 #define MDCR_TDOSA_BIT		(ULL(1) << 10)
 #define MDCR_TDA_BIT		(ULL(1) << 9)
 #define MDCR_TPM_BIT		(ULL(1) << 6)
@@ -1362,6 +1379,13 @@
 #define HCRX_EL2_INIT_VAL	ULL(0x0)
 
 /*******************************************************************************
+ * FEAT_FGT - Definitions for Fine-Grained Trap registers
+ ******************************************************************************/
+#define HFGITR_EL2_INIT_VAL	ULL(0x180000000000000)
+#define HFGRTR_EL2_INIT_VAL	ULL(0xC4000000000000)
+#define HFGWTR_EL2_INIT_VAL	ULL(0xC4000000000000)
+
+/*******************************************************************************
  * FEAT_TCR2 - Extended Translation Control Register
  ******************************************************************************/
 #define TCR2_EL2		S3_4_C2_C0_3
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 9d71987..bd41fef 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -13,49 +13,37 @@
 #include <common/feat_detect.h>
 
 #define ISOLATE_FIELD(reg, feat)					\
-	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
+	((unsigned int)(((reg) >> (feat)) & ID_REG_FIELD_MASK))
 
-static inline bool is_armv7_gentimer_present(void)
-{
-	/* The Generic Timer is always present in an ARMv8-A implementation */
-	return true;
+#define CREATE_FEATURE_FUNCS_VER(name, read_func, idvalue, guard)	\
+static inline bool is_ ## name ## _supported(void)			\
+{									\
+	if ((guard) == FEAT_STATE_DISABLED) {				\
+		return false;						\
+	}								\
+	if ((guard) == FEAT_STATE_ALWAYS) {				\
+		return true;						\
+	}								\
+	return read_func() >= (idvalue);				\
 }
 
-static inline unsigned int read_feat_pan_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
-}
-
-static inline bool is_feat_pan_supported(void)
-{
-	if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
-		return false;
-	}
+#define CREATE_FEATURE_FUNCS(name, idreg, idfield, guard)		\
+static unsigned int read_ ## name ## _id_field(void)			\
+{									\
+	return ISOLATE_FIELD(read_ ## idreg(), idfield);		\
+}									\
+CREATE_FEATURE_FUNCS_VER(name, read_ ## name ## _id_field, 1U, guard)
 
-	if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_pan_id_field() != 0U;
-}
-
-static inline unsigned int read_feat_vhe_id_field(void)
+static inline bool is_armv7_gentimer_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE);
+	/* The Generic Timer is always present in an ARMv8-A implementation */
+	return true;
 }
 
-static inline bool is_feat_vhe_supported(void)
-{
-	if (ENABLE_FEAT_VHE == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_vhe_id_field() != 0U;
-}
+CREATE_FEATURE_FUNCS(feat_pan, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_PAN_SHIFT,
+		     ENABLE_FEAT_PAN)
+CREATE_FEATURE_FUNCS(feat_vhe, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_VHE_SHIFT,
+		     ENABLE_FEAT_VHE)
 
 static inline bool is_armv8_2_ttcnp_present(void)
 {
@@ -107,260 +95,51 @@
 		ID_AA64PFR1_EL1_MTE_MASK);
 }
 
-static inline unsigned int read_feat_sel2_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2);
-}
-
-static inline bool is_feat_sel2_supported(void)
-{
-	if (ENABLE_FEAT_SEL2 == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_sel2_id_field() != 0U;
-}
-
-static inline unsigned int read_feat_twed_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED);
-}
-
-static inline bool is_feat_twed_supported(void)
-{
-	if (ENABLE_FEAT_TWED == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_twed_id_field() != 0U;
-}
-
-static unsigned int read_feat_fgt_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
-}
-
-static inline bool is_feat_fgt_supported(void)
-{
-	if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_fgt_id_field() != 0U;
-}
-
-static unsigned int read_feat_ecv_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
-}
-
-static inline bool is_feat_ecv_supported(void)
-{
-	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_ecv_id_field() != 0U;
-}
-
-static inline bool is_feat_ecv_v2_supported(void)
-{
-	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
-}
-
-static unsigned int read_feat_rng_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR);
-}
-
-static inline bool is_feat_rng_supported(void)
-{
-	if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_rng_id_field() != 0U;
-}
-
-static unsigned int read_feat_tcrx_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
-}
+CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
+		     ENABLE_FEAT_SEL2)
+CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
+		     ENABLE_FEAT_TWED)
+CREATE_FEATURE_FUNCS(feat_fgt, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
+		     ENABLE_FEAT_FGT)
+CREATE_FEATURE_FUNCS(feat_mte_perm, id_aa64pfr2_el1,
+		     ID_AA64PFR2_EL1_MTEPERM_SHIFT, ENABLE_FEAT_MTE_PERM)
+CREATE_FEATURE_FUNCS(feat_ecv, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
+		     ENABLE_FEAT_ECV)
+CREATE_FEATURE_FUNCS_VER(feat_ecv_v2, read_feat_ecv_id_field,
+			 ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
 
-static inline bool is_feat_tcr2_supported(void)
-{
-	if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_tcrx_id_field() != 0U;
-}
-
-static unsigned int read_feat_s2poe_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
-}
+CREATE_FEATURE_FUNCS(feat_rng, id_aa64isar0_el1, ID_AA64ISAR0_RNDR_SHIFT,
+		     ENABLE_FEAT_RNG)
+CREATE_FEATURE_FUNCS(feat_tcr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_TCRX_SHIFT,
+		     ENABLE_FEAT_TCR2)
 
-static inline bool is_feat_s2poe_supported(void)
-{
-	if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_s2poe_id_field() != 0U;
-}
-
-static unsigned int read_feat_s1poe_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
-}
-
-static inline bool is_feat_s1poe_supported(void)
-{
-	if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_s1poe_id_field() != 0U;
-}
-
+CREATE_FEATURE_FUNCS(feat_s2poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2POE_SHIFT,
+		     ENABLE_FEAT_S2POE)
+CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
+		     ENABLE_FEAT_S1POE)
 static inline bool is_feat_sxpoe_supported(void)
 {
 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
 }
 
-static unsigned int read_feat_s2pie_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
-}
-
-static inline bool is_feat_s2pie_supported(void)
-{
-	if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_s2pie_id_field() != 0U;
-}
-
-static unsigned int read_feat_s1pie_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
-}
-
-static inline bool is_feat_s1pie_supported(void)
-{
-	if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_s1pie_id_field() != 0U;
-}
-
+CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
+		     ENABLE_FEAT_S2PIE)
+CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
+		     ENABLE_FEAT_S1PIE)
 static inline bool is_feat_sxpie_supported(void)
 {
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
 }
 
-static unsigned int read_feat_gcs_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
-}
-
-static inline bool is_feat_gcs_supported(void)
-{
-	if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_gcs_id_field() != 0U;
-}
-
-/*******************************************************************************
- * Functions to identify the presence of the Activity Monitors Extension
- ******************************************************************************/
-static unsigned int read_feat_amu_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
-}
-
-static inline bool is_feat_amu_supported(void)
-{
-	if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
-}
+/* FEAT_GCS: Guarded Control Stack */
+CREATE_FEATURE_FUNCS(feat_gcs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_GCS_SHIFT,
+		     ENABLE_FEAT_GCS)
 
-static inline bool is_feat_amuv1p1_supported(void)
-{
-	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
-}
+/* FEAT_AMU: Activity Monitors Extension */
+CREATE_FEATURE_FUNCS(feat_amu, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
+		     ENABLE_FEAT_AMU)
+CREATE_FEATURE_FUNCS_VER(feat_amuv1p1, read_feat_amu_id_field,
+			 ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
 
 /*
  * Return MPAM version:
@@ -379,36 +158,12 @@
 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
 }
 
-static inline bool is_feat_mpam_supported(void)
-{
-	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+CREATE_FEATURE_FUNCS_VER(feat_mpam, read_feat_mpam_version, 1U,
+			 ENABLE_MPAM_FOR_LOWER_ELS)
 
-	return read_feat_mpam_version() != 0U;
-}
-
-static inline unsigned int read_feat_hcx_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
-}
-
-static inline bool is_feat_hcx_supported(void)
-{
-	if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_hcx_id_field() != 0U;
-}
+/* FEAT_HCX: Extended Hypervisor Configuration Register */
+CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
+		     ENABLE_FEAT_HCX)
 
 static inline bool is_feat_rng_trap_present(void)
 {
@@ -433,251 +188,60 @@
  ********************************************************************************/
 static inline unsigned int read_feat_sb_id_field(void)
 {
-	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
-}
-
-/*********************************************************************************
- * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
- ********************************************************************************/
-static inline unsigned int read_feat_csv2_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
-}
-
-static inline bool is_feat_csv2_2_supported(void)
-{
-	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
-}
-
-/**********************************************************************************
- * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
- *********************************************************************************/
-static inline unsigned int read_feat_spe_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
-}
-
-static inline bool is_feat_spe_supported(void)
-{
-	if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_spe_id_field() != 0U;
-}
-
-/*******************************************************************************
- * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
- ******************************************************************************/
-static inline unsigned int read_feat_sve_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE);
-}
-
-static inline bool is_feat_sve_supported(void)
-{
-	if (ENABLE_SVE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_SVE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED;
-}
-
-static unsigned int read_feat_ras_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS);
-}
-
-static inline bool is_feat_ras_supported(void)
-{
-	if (ENABLE_FEAT_RAS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_ras_id_field() != 0U;
-}
-
-static unsigned int read_feat_dit_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
 }
 
-static inline bool is_feat_dit_supported(void)
-{
-	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_CSV2_2: Cache Speculation Variant 2 */
+CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
+CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
+			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
 
-	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* FEAT_SPE: Statistical Profiling Extension */
+CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
+		     ENABLE_SPE_FOR_NS)
 
-	return read_feat_dit_id_field() != 0U;
-}
+/* FEAT_SVE: Scalable Vector Extension */
+CREATE_FEATURE_FUNCS(feat_sve, id_aa64pfr0_el1, ID_AA64PFR0_SVE_SHIFT,
+		     ENABLE_SVE_FOR_NS)
 
-static inline unsigned int read_feat_tracever_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
-}
+/* FEAT_RAS: Reliability, Accessibility, Serviceability */
+CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1,
+		     ID_AA64PFR0_RAS_SHIFT, ENABLE_FEAT_RAS)
 
-static inline bool is_feat_sys_reg_trace_supported(void)
-{
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_DIT: Data Independent Timing instructions */
+CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1,
+		     ID_AA64PFR0_DIT_SHIFT, ENABLE_FEAT_DIT)
 
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1,
+		     ID_AA64DFR0_TRACEVER_SHIFT, ENABLE_SYS_REG_TRACE_FOR_NS)
 
-	return read_feat_tracever_id_field() != 0U;
-}
+/* FEAT_TRF: TraceFilter */
+CREATE_FEATURE_FUNCS(feat_trf, id_aa64dfr0_el1, ID_AA64DFR0_TRACEFILT_SHIFT,
+		     ENABLE_TRF_FOR_NS)
 
-/*************************************************************************
- * Function to identify the presence of FEAT_TRF (TraceLift)
- ************************************************************************/
-static inline unsigned int read_feat_trf_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
-}
-
-static inline bool is_feat_trf_supported(void)
-{
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_NV2: Enhanced Nested Virtualization */
+CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT, 0)
+CREATE_FEATURE_FUNCS_VER(feat_nv2, read_feat_nv_id_field,
+			 ID_AA64MMFR2_EL1_NV2_SUPPORTED, CTX_INCLUDE_NEVE_REGS)
 
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* FEAT_BRBE: Branch Record Buffer Extension */
+CREATE_FEATURE_FUNCS(feat_brbe, id_aa64dfr0_el1, ID_AA64DFR0_BRBE_SHIFT,
+		     ENABLE_BRBE_FOR_NS)
 
-	return read_feat_trf_id_field() != 0U;
-}
+/* FEAT_TRBE: Trace Buffer Extension */
+CREATE_FEATURE_FUNCS(feat_trbe, id_aa64dfr0_el1, ID_AA64DFR0_TRACEBUFFER_SHIFT,
+		     ENABLE_TRBE_FOR_NS)
 
-/********************************************************************************
- * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
- * Support)
- *******************************************************************************/
-static inline unsigned int read_feat_nv_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV);
-}
-
-static inline bool is_feat_nv2_supported(void)
-{
-	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_nv_id_field() >= ID_AA64MMFR2_EL1_NV2_SUPPORTED;
-}
-
-/*******************************************************************************
- * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
- * Extension)
- ******************************************************************************/
-static inline unsigned int read_feat_brbe_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
-}
-
-static inline bool is_feat_brbe_supported(void)
-{
-	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_brbe_id_field() != 0U;
-}
-
-/*******************************************************************************
- * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
- ******************************************************************************/
-static inline unsigned int read_feat_trbe_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
-}
-
-static inline bool is_feat_trbe_supported(void)
-{
-	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_trbe_id_field() != 0U;
-
-}
-
-/*******************************************************************************
- * Function to identify the presence of FEAT_SMEx (Scalar Matrix Extension)
- ******************************************************************************/
 static inline unsigned int read_feat_sme_fa64_id_field(void)
 {
-	return ISOLATE_FIELD(read_id_aa64smfr0_el1(), ID_AA64SMFR0_EL1_SME_FA64);
+	return ISOLATE_FIELD(read_id_aa64smfr0_el1(),
+			     ID_AA64SMFR0_EL1_SME_FA64_SHIFT);
 }
-
-static inline unsigned int read_feat_sme_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME);
-}
-
-static inline bool is_feat_sme_supported(void)
-{
-	if (ENABLE_SME_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_SME_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME_SUPPORTED;
-}
-
-static inline bool is_feat_sme2_supported(void)
-{
-	if (ENABLE_SME2_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_SME2_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
-}
+/* FEAT_SMEx: Scalar Matrix Extension */
+CREATE_FEATURE_FUNCS(feat_sme, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
+		     ENABLE_SME_FOR_NS)
+CREATE_FEATURE_FUNCS_VER(feat_sme2, read_feat_sme_id_field,
+			 ID_AA64PFR1_EL1_SME2_SUPPORTED, ENABLE_SME2_FOR_NS)
 
 /*******************************************************************************
  * Function to get hardware granularity support
@@ -685,29 +249,30 @@
 
 static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_TGRAN4);
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT);
 }
 
 static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN16);
+			     ID_AA64MMFR0_EL1_TGRAN16_SHIFT);
 }
 
 static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN64);
+			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT);
 }
 
 static inline unsigned int read_feat_pmuv3_id_field(void)
 {
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT);
 }
 
 static inline unsigned int read_feat_mtpmu_id_field(void)
 {
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT);
 }
 
 static inline bool is_feat_mtpmu_supported(void)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 5b3d4c2..6fdc7e8 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -269,6 +269,7 @@
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
 DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1)
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64pfr2_el1, ID_AA64PFR2_EL1)
 DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1)
 DEFINE_IDREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
@@ -486,6 +487,13 @@
 DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
 DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
 
+DEFINE_SYSREG_RW_FUNCS(hacr_el2)
+DEFINE_SYSREG_RW_FUNCS(hpfar_el2)
+DEFINE_SYSREG_RW_FUNCS(tpidr_el2)
+DEFINE_SYSREG_RW_FUNCS(dbgvcr32_el2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ich_hcr_el2, ICH_HCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ich_vmcr_el2, ICH_VMCR_EL2)
+
 DEFINE_SYSREG_READ_FUNC(isr_el1)
 
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
@@ -584,6 +592,7 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el2, TFSR_EL2)
 
 /* Armv8.5 FEAT_RNG Registers */
 DEFINE_RENAME_SYSREG_READ_FUNC(rndr, RNDR)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 6360461..fa9310e 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -115,33 +115,11 @@
 	 * MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
 	 *  debug registers, other than those registers that are controlled by
 	 *  MDCR_EL3.TDOSA.
-	 *
-	 * MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
-	 *  accesses to all Performance Monitors registers do not trap to EL3.
-	 *
-	 * MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer
-	 *  owning security state is Secure state. If FEAT_TRBE is implemented,
-	 *  accesses to Trace Buffer control registers at EL2 and EL1 in any
-	 *  security state generates trap exceptions to EL3.
-	 *  If FEAT_TRBE is not implemented, these bits are RES0.
-	 *
-	 * MDCR_EL3.TTRF: Set to one so that access to trace filter control
-	 *  registers in non-monitor mode generate EL3 trap exception,
-	 *  unless the access generates a higher priority exception when trace
-	 *  filter control(FEAT_TRF) is implemented.
-	 *  When FEAT_TRF is not implemented, this bit is RES0.
-	 * ---------------------------------------------------------------------
 	 */
 	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
 		      MDCR_SPD32(MDCR_SPD32_DISABLE)) & \
-		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT | MDCR_TPM_BIT | \
-		      MDCR_NSTB(MDCR_NSTB_EL1) | MDCR_NSTBE | MDCR_TTRF_BIT))
+		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT))
 
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH
-	cbz	x1, 1f
-	orr	x0, x0, #MDCR_TTRF_BIT
-1:
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
@@ -158,15 +136,6 @@
 	 * CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1,
 	 *  CPTR_EL2, CPACR, or HCPTR do not trap to EL3.
 	 *
-	 * CPTR_EL3.TTA: Set to one so that accesses to the trace system
-	 *  registers trap to EL3 from all exception levels and security
-	 *  states when system register trace is implemented.
-	 *  When system register trace is not implemented, this bit is RES0 and
-	 *  hence set to zero.
-	 *
-	 * CPTR_EL3.TTA: Set to zero so that System register accesses to the
-	 *  trace registers do not trap to EL3.
-	 *
 	 * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
 	 *  by Advanced SIMD, floating-point or SVE instructions (if implemented)
 	 *  do not trap to EL3.
@@ -181,12 +150,7 @@
 	 *  to EL3 by default.
 	 */
 
-	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #ID_AA64DFR0_TRACEVER_SHIFT, #ID_AA64DFR0_TRACEVER_LENGTH
-	cbz	x1, 1f
-	orr	x0, x0, #TTA_BIT
-1:
+	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TFP_BIT))
 	msr	cptr_el3, x0
 
 	/*
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 539280e..4c8a17c 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -85,6 +85,10 @@
 #define __EL3_LP_DESCS_START__		Load$$__EL3_LP_DESCS__$$Base
 #define __EL3_LP_DESCS_END__		Load$$__EL3_LP_DESCS__$$Limit
 #endif
+#if ENABLE_SPMD_LP
+#define __SPMD_LP_DESCS_START__	Load$$__SPMD_LP_DESCS__$$Base
+#define __SPMD_LP_DESCS_END__		Load$$__SPMD_LP_DESCS__$$Limit
+#endif
 #define __RW_START__			Load$$LR$$LR_RW_DATA$$Base
 #define __RW_END__			Load$$LR$$LR_END$$Base
 #define __SPM_SHIM_EXCEPTIONS_START__	Load$$__SPM_SHIM_EXCEPTIONS__$$Base
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index c9bed1a..b6dd0f0 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -49,6 +49,15 @@
 #define EL3_LP_DESCS
 #endif
 
+#if ENABLE_SPMD_LP
+#define SPMD_LP_DESCS					\
+	. = ALIGN(STRUCT_ALIGN);			\
+	__SPMD_LP_DESCS_START__ = .;			\
+	KEEP(*(.spmd_lp_descs))			\
+	__SPMD_LP_DESCS_END__ = .;
+#else
+#define SPMD_LP_DESCS
+#endif
 #define PMF_SVC_DESCS					\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__PMF_SVC_DESCS_START__ = .;			\
@@ -100,7 +109,8 @@
 	CPU_OPS						\
 	GOT						\
 	BASE_XLAT_TABLE_RO				\
-	EL3_LP_DESCS
+	EL3_LP_DESCS					\
+	SPMD_LP_DESCS
 
 /*
  * .data must be placed at a lower address than the stacks if the stack
diff --git a/include/drivers/cadence/cdns_combo_phy.h b/include/drivers/cadence/cdns_combo_phy.h
new file mode 100644
index 0000000..f5dabda
--- /dev/null
+++ b/include/drivers/cadence/cdns_combo_phy.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_COMBOPHY_H
+#define CDN_COMBOPHY_H
+
+/* SRS */
+#define SDMMC_CDN_SRS02			0x8
+#define SDMMC_CDN_SRS03			0xC
+#define SDMMC_CDN_SRS04			0x10
+#define SDMMC_CDN_SRS05			0x14
+#define SDMMC_CDN_SRS06			0x18
+#define SDMMC_CDN_SRS07			0x1C
+#define SDMMC_CDN_SRS09			0x24
+#define SDMMC_CDN_SRS10			0x28
+#define SDMMC_CDN_SRS11			0x2C
+#define SDMMC_CDN_SRS12			0x30
+#define SDMMC_CDN_SRS13			0x34
+#define SDMMC_CDN_SRS14			0x38
+
+/* SRS03 */
+/* Response Type Select
+ * Defines the expected response length.
+ */
+#define SDMMC_CDN_RTS				16
+
+/* Command CRC Check Enable
+ * When set to 1, the host checks if the CRC field of the response is valid.
+ * When 0, the CRC check is disabled and the CRC field of the response is ignored.
+ */
+#define SDMMC_CDN_CRCCE				19
+
+/* Command Index
+ * This field contains a command number (index) of the command to be sent.
+ */
+#define SDMMC_CDN_CIDX				24
+
+/* SRS09 */
+/* Card Inserted
+ * Indicates if the card is inserted inside the slot.
+ */
+#define SDMMC_CDN_CI				16
+
+/* SRS10 */
+/* Data Transfer Width
+ * Bit used to configure DAT bus width to 1 or 4.
+ */
+#define SDMMC_CDN_DTW				1
+
+/* Extended Data Transfer Width
+ * This bit is to enable/disable 8-bit DAT bus width mode.
+ */
+#define SDMMC_CDN_EDTW				5
+
+/* SD Bus Power for VDD1
+ * When set to 1, the VDD1 voltage is supplied to card/device.
+ */
+#define SDMMC_CDN_BP				8
+
+/* SD Bus Voltage Select
+ * This field is used to configure VDD1 voltage level.
+ */
+#define SDMMC_CDN_BVS				9
+
+/* SRS11 */
+/* Internal Clock Enable
+ * This field is designated to controls (enable/disable) external clock generator.
+ */
+#define SDMMC_CDN_ICE				0
+
+/* Internal Clock Stable
+ * When 1, indicates that the clock on sdmclk pin of the host is stable.
+ * When 0, indicates that the clock is not stable .
+ */
+#define SDMMC_CDN_ICS				1
+
+/* SD Clock Enable
+ * When set, SDCLK clock is enabled.
+ * When clear, SDCLK clock is stopped.
+ */
+#define SDMMC_CDN_SDCE				2
+
+/* USDCLK Frequency Select
+ * This is used to calculate frequency of USDCLK clock.
+ */
+#define SDMMC_CDN_USDCLKFS			6
+
+/* SDCLK Frequency Select
+ * This is used to calculate frequency of SDCLK clock.
+ */
+#define SDMMC_CDN_SDCLKFS				8
+
+/* Data Timeout Counter Value
+ * This value determines the interval by which DAT line timeouts are detected
+ */
+#define SDMMC_CDN_DTCV				16
+
+/* SRS12 */
+/* Command Complete
+ * Generated when the end bit of the response is received.
+ */
+#define SDMMC_CDN_CC				0
+
+/* Transfer Complete
+ * Generated when the transfer which uses the DAT line is complete.
+ */
+#define SDMMC_CDN_TC				1
+
+/* Error Interrupt
+ * The software can check for an error by reading this single bit first.
+ */
+#define SDMMC_CDN_EINT				15
+
+/* SRS14 */
+/* Command Complete Interrupt Enable */
+#define SDMMC_CDN_CC_IE				0
+
+/* Transfer Complete Interrupt Enable */
+#define SDMMC_CDN_TC_IE				1
+
+/* DMA Interrupt Enable */
+#define SDMMC_CDN_DMAINT_IE			3
+
+/* Combo PHY DLL registers */
+#define CP_DLL_REG_BASE			(0x10B92000)
+#define CP_DLL_DQ_TIMING_REG		(0x00)
+#define CP_DLL_DQS_TIMING_REG		(0x04)
+#define CP_DLL_GATE_LPBK_CTRL_REG	(0x08)
+#define CP_DLL_MASTER_CTRL_REG		(0x0C)
+#define CP_DLL_SLAVE_CTRL_REG		(0x10)
+#define CP_DLL_IE_TIMING_REG		(0x14)
+
+#define CP_DQ_TIMING_REG_SDR		(0x00000002)
+#define CP_DQS_TIMING_REG_SDR		(0x00100004)
+#define CP_GATE_LPBK_CTRL_REG_SDR	(0x00D80000)
+#define CP_DLL_MASTER_CTRL_REG_SDR	(0x00800000)
+#define CP_DLL_SLAVE_CTRL_REG_SDR	(0x00000000)
+
+#define CP_DLL(_reg)			(CP_DLL_REG_BASE \
+					+ (CP_DLL_##_reg))
+
+/* Control Timing Block registers */
+#define CP_CTB_REG_BASE			(0x10B92080)
+#define CP_CTB_CTRL_REG			(0x00)
+#define CP_CTB_TSEL_REG			(0x04)
+#define CP_CTB_GPIO_CTRL0		(0x08)
+#define CP_CTB_GPIO_CTRL1		(0x0C)
+#define CP_CTB_GPIO_STATUS0		(0x10)
+#define CP_CTB_GPIO_STATUS1		(0x14)
+
+#define CP_CTRL_REG_SDR			(0x00004040)
+#define CP_TSEL_REG_SDR			(0x00000000)
+
+#define CP_CTB(_reg)			(CP_CTB_REG_BASE \
+					+ (CP_CTB_##_reg))
+
+/* Combo PHY */
+#define SDMMC_CDN_REG_BASE		0x10808200
+#define PHY_DQ_TIMING_REG		0x2000
+#define PHY_DQS_TIMING_REG		0x2004
+#define PHY_GATE_LPBK_CTRL_REG		0x2008
+#define PHY_DLL_MASTER_CTRL_REG		0x200C
+#define PHY_DLL_SLAVE_CTRL_REG		0x2010
+#define PHY_CTRL_REG			0x2080
+#define PHY_REG_ADDR_MASK		0xFFFF
+#define PHY_REG_DATA_MASK		0xFFFFFFFF
+
+/* PHY_DQS_TIMING_REG */
+#define CP_USE_EXT_LPBK_DQS(x)		((x) << 22) //0x1
+#define CP_USE_LPBK_DQS(x)		((x) << 21) //0x1
+#define CP_USE_PHONY_DQS(x)		((x) << 20) //0x1
+#define CP_USE_PHONY_DQS_CMD(x)		((x) << 19) //0x1
+
+/* PHY_GATE_LPBK_CTRL_REG */
+#define CP_SYNC_METHOD(x)		((x) << 31) //0x1
+#define CP_SW_HALF_CYCLE_SHIFT(x)	((x) << 28) //0x1
+#define CP_RD_DEL_SEL(x)		((x) << 19) //0x3f
+#define CP_UNDERRUN_SUPPRESS(x)		((x) << 18) //0x1
+#define CP_GATE_CFG_ALWAYS_ON(x)	((x) << 6) //0x1
+
+/* PHY_DLL_MASTER_CTRL_REG */
+#define CP_DLL_BYPASS_MODE(x)		((x) << 23) //0x1
+#define CP_DLL_START_POINT(x)		((x) << 0) //0xff
+
+/* PHY_DLL_SLAVE_CTRL_REG */
+#define CP_READ_DQS_CMD_DELAY(x)	((x) << 24) //0xff
+#define CP_CLK_WRDQS_DELAY(x)		((x) << 16) //0xff
+#define CP_CLK_WR_DELAY(x)		((x) << 8) //0xff
+#define CP_READ_DQS_DELAY(x)		((x) << 0) //0xff
+
+/* PHY_DQ_TIMING_REG */
+#define CP_IO_MASK_ALWAYS_ON(x)		((x) << 31) //0x1
+#define CP_IO_MASK_END(x)		((x) << 27) //0x7
+#define CP_IO_MASK_START(x)		((x) << 24) //0x7
+#define CP_DATA_SELECT_OE_END(x)	((x) << 0) //0x7
+
+/* PHY_CTRL_REG */
+#define CP_PHONY_DQS_TIMING_MASK	0x3F
+#define CP_PHONY_DQS_TIMING_SHIFT	4
+
+/* Shared Macros */
+#define SDMMC_CDN(_reg)			(SDMMC_CDN_REG_BASE + \
+					(SDMMC_CDN_##_reg))
+
+struct cdns_sdmmc_combo_phy {
+	uint32_t	cp_clk_wr_delay;
+	uint32_t	cp_clk_wrdqs_delay;
+	uint32_t	cp_data_select_oe_end;
+	uint32_t	cp_dll_bypass_mode;
+	uint32_t	cp_dll_locked_mode;
+	uint32_t	cp_dll_start_point;
+	uint32_t	cp_gate_cfg_always_on;
+	uint32_t	cp_io_mask_always_on;
+	uint32_t	cp_io_mask_end;
+	uint32_t	cp_io_mask_start;
+	uint32_t	cp_rd_del_sel;
+	uint32_t	cp_read_dqs_cmd_delay;
+	uint32_t	cp_read_dqs_delay;
+	uint32_t	cp_sw_half_cycle_shift;
+	uint32_t	cp_sync_method;
+	uint32_t	cp_underrun_suppress;
+	uint32_t	cp_use_ext_lpbk_dqs;
+	uint32_t	cp_use_lpbk_dqs;
+	uint32_t	cp_use_phony_dqs;
+	uint32_t	cp_use_phony_dqs_cmd;
+};
+
+/* Function Prototype */
+
+int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
+			uint32_t phy_reg_data, uint32_t phy_reg_data_value);
+int cdns_sd_card_detect(void);
+int cdns_emmc_card_reset(void);
+
+#endif
diff --git a/include/drivers/cadence/cdns_nand.h b/include/drivers/cadence/cdns_nand.h
new file mode 100644
index 0000000..64ba267
--- /dev/null
+++ b/include/drivers/cadence/cdns_nand.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_NAND_H
+#define CDN_NAND_H
+
+#include <drivers/cadence/cdns_combo_phy.h>
+
+/* NAND flash device information */
+typedef struct cnf_dev_info {
+	uint8_t type;
+	uint8_t nluns;
+	uint8_t sector_cnt;
+	uint16_t npages_per_block;
+	uint16_t sector_size;
+	uint16_t last_sector_size;
+	uint16_t page_size;
+	uint16_t spare_size;
+	uint32_t nblocks_per_lun;
+	uint32_t block_size;
+	unsigned long long total_size;
+} cnf_dev_info_t;
+
+/* Shared Macros */
+
+/* Default values */
+#define CNF_DEF_VOL_ID					0
+#define CNF_DEF_DEVICE					0
+#define CNF_DEF_TRD					0
+#define CNF_READ_SINGLE_PAGE				1
+#define CNF_DEF_DELAY_US				500
+#define CNF_READ_INT_DELAY_US				10
+
+/* Work modes */
+#define CNF_WORK_MODE_CDMA				0
+#define CNF_WORK_MODE_PIO				1
+
+/* Command types */
+#define CNF_CT_SET_FEATURE				0x0100
+#define CNF_CT_RESET_ASYNC				0x1100
+#define CNF_CT_RESET_SYNC				0x1101
+#define CNF_CT_RESET_LUN				0x1102
+#define CNF_CT_ERASE					0x1000
+#define CNF_CT_PAGE_PROGRAM				0x2100
+#define CNF_CT_PAGE_READ				0x2200
+
+/* Interrupts enable or disable */
+#define CNF_INT_EN					1
+#define CNF_INT_DIS					0
+
+/* Device types */
+#define CNF_DT_UNKNOWN					0x00
+#define CNF_DT_ONFI					0x01
+#define CNF_DT_JEDEC					0x02
+#define CNF_DT_LEGACY					0x03
+
+/* Command and status registers */
+#define CNF_CMDREG_REG_BASE				SOCFPGA_NAND_REG_BASE
+
+/* DMA maximum burst size 0-127*/
+#define CNF_DMA_BURST_SIZE_MAX				127
+
+/* DMA settings register field offsets */
+#define CNF_DMA_SETTINGS_BURST				0
+#define CNF_DMA_SETTINGS_OTE				16
+#define CNF_DMA_SETTINGS_SDMA_ERR			17
+
+#define CNF_DMA_MASTER_SEL				1
+#define CNF_DMA_SLAVE_SEL				0
+
+/* DMA FIFO trigger level register field offsets */
+#define CNF_FIFO_TLEVEL_POS				0
+#define CNF_FIFO_TLEVEL_DMA_SIZE			16
+#define CNF_DMA_PREFETCH_SIZE				(1024 / 8)
+
+#define CNF_GET_CTRL_BUSY(x)				(x & (1 << 8))
+#define CNF_GET_INIT_COMP(x)				(x & (1 << 9))
+
+/* Command register0 field offsets */
+#define CNF_CMDREG0_CT					30
+#define CNF_CMDREG0_TRD					24
+#define CNF_CMDREG0_INTR				20
+#define CNF_CMDREG0_DMA					21
+#define CNF_CMDREG0_VOL					16
+#define CNF_CMDREG0_CMD					0
+#define CNF_CMDREG4_MEM					24
+
+/* Command status register field offsets */
+#define CNF_ECMD					BIT(0)
+#define CNF_EECC					BIT(1)
+#define CNF_EMAX					BIT(2)
+#define CNF_EDEV					BIT(12)
+#define CNF_EDQS					BIT(13)
+#define CNF_EFAIL					BIT(14)
+#define CNF_CMPLT					BIT(15)
+#define CNF_EBUS					BIT(16)
+#define CNF_EDI						BIT(17)
+#define CNF_EPAR					BIT(18)
+#define CNF_ECTX					BIT(19)
+#define CNF_EPRO					BIT(20)
+#define CNF_EIDX					BIT(24)
+
+#define CNF_CMDREG_CMD_REG0				0x00
+#define CNF_CMDREG_CMD_REG1				0x04
+#define CNF_CMDREG_CMD_REG2				0x08
+#define CNF_CMDREG_CMD_REG3				0x0C
+#define CNF_CMDREG_CMD_STAT_PTR				0x10
+#define CNF_CMDREG_CMD_STAT				0x14
+#define CNF_CMDREG_CMD_REG4				0x20
+#define CNF_CMDREG_CTRL_STATUS				0x118
+#define CNF_CMDREG_TRD_STATUS				0x120
+
+#define CNF_CMDREG(_reg)				(CNF_CMDREG_REG_BASE \
+							+ (CNF_CMDREG_##_reg))
+
+/* Controller configuration registers */
+#define CNF_LSB16_MASK					0xFFFF
+#define CNF_GET_NPAGES_PER_BLOCK(x)			(x & CNF_LSB16_MASK)
+
+#define CNF_GET_SCTR_SIZE(x)				(x & CNF_LSB16_MASK)
+#define CNF_GET_LAST_SCTR_SIZE(x)			((x >> 16) & CNF_LSB16_MASK)
+
+#define CNF_GET_PAGE_SIZE(x)				(x & CNF_LSB16_MASK)
+#define CNF_GET_SPARE_SIZE(x)				((x >> 16) & CNF_LSB16_MASK)
+
+#define CNF_CTRLCFG_REG_BASE				0x10B80400
+#define CNF_CTRLCFG_TRANS_CFG0				0x00
+#define CNF_CTRLCFG_TRANS_CFG1				0x04
+#define CNF_CTRLCFG_LONG_POLL				0x08
+#define CNF_CTRLCFG_SHORT_POLL				0x0C
+#define CNF_CTRLCFG_DEV_STAT				0x10
+#define CNF_CTRLCFG_DEV_LAYOUT				0x24
+#define CNF_CTRLCFG_ECC_CFG0				0x28
+#define CNF_CTRLCFG_ECC_CFG1				0x2C
+#define CNF_CTRLCFG_MULTIPLANE_CFG			0x34
+#define CNF_CTRLCFG_CACHE_CFG				0x38
+#define CNF_CTRLCFG_DMA_SETTINGS			0x3C
+#define CNF_CTRLCFG_FIFO_TLEVEL				0x54
+
+#define CNF_CTRLCFG(_reg)				(CNF_CTRLCFG_REG_BASE \
+							+ (CNF_CTRLCFG_##_reg))
+
+/* Data integrity registers */
+#define CNF_DI_PAR_EN					0
+#define CNF_DI_CRC_EN					1
+
+#define CNF_DI_REG_BASE					0x10B80700
+#define CNF_DI_CONTROL					0x00
+#define CNF_DI_INJECT0					0x04
+#define CNF_DI_INJECT1					0x08
+#define CNF_DI_ERR_REG_ADDR				0x0C
+#define CNF_DI_INJECT2					0x10
+
+#define CNF_DI(_reg)					(CNF_DI_REG_BASE \
+							+ (CNF_DI_##_reg))
+
+/* Controller parameter registers */
+#define CNF_NTHREADS_MASK				0x07
+#define CNF_GET_NLUNS(x)				(x & 0xFF)
+#define CNF_GET_DEV_TYPE(x)				((x >> 30) & 0x03)
+#define CNF_GET_NTHREADS(x)				(1 << (x & CNF_NTHREADS_MASK))
+
+#define CNF_CTRLPARAM_REG_BASE				0x10B80800
+#define CNF_CTRLPARAM_VERSION				0x00
+#define CNF_CTRLPARAM_FEATURE				0x04
+#define CNF_CTRLPARAM_MFR_ID				0x08
+#define CNF_CTRLPARAM_DEV_AREA				0x0C
+#define CNF_CTRLPARAM_DEV_PARAMS0			0x10
+#define CNF_CTRLPARAM_DEV_PARAMS1			0x14
+#define CNF_CTRLPARAM_DEV_FEATUERS			0x18
+#define CNF_CTRLPARAM_DEV_BLOCKS_PLUN			0x1C
+
+#define CNF_CTRLPARAM(_reg)				(CNF_CTRLPARAM_REG_BASE \
+							+ (CNF_CTRLPARAM_##_reg))
+
+/* Protection mechanism registers */
+#define CNF_PROT_REG_BASE				0x10B80900
+#define CNF_PROT_CTRL0					0x00
+#define CNF_PROT_DOWN0					0x04
+#define CNF_PROT_UP0					0x08
+#define CNF_PROT_CTRL1					0x10
+#define CNF_PROT_DOWN1					0x14
+#define CNF_PROT_UP1					0x18
+
+#define CNF_PROT(_reg)					(CNF_PROT_REG_BASE \
+							+ (CNF_PROT_##_reg))
+
+/* Mini controller registers */
+#define CNF_MINICTRL_REG_BASE				0x10B81000
+
+/* Operation work modes */
+#define CNF_OPR_WORK_MODE_SDR				0
+#define CNF_OPR_WORK_MODE_NVDDR				1
+#define CNF_OPR_WORK_MODE_TOGGLE_NVDDR2_3		2
+#define CNF_OPR_WORK_MODE_RES				3
+
+/* Mini controller common settings register field offsets */
+#define CNF_CMN_SETTINGS_WR_WUP				20
+#define CNF_CMN_SETTINGS_RD_WUP				16
+#define CNF_CMN_SETTINGS_DEV16				8
+#define CNF_CMN_SETTINGS_OPR				0
+
+/* Async mode register field offsets */
+#define CNF_ASYNC_TIMINGS_TRH				24
+#define CNF_ASYNC_TIMINGS_TRP				16
+#define CNF_ASYNC_TIMINGS_TWH				8
+#define CNF_ASYNC_TIMINGS_TWP				0
+
+/* Mini controller DLL PHY controller register field offsets */
+#define CNF_DLL_PHY_RST_N				24
+#define CNF_DLL_PHY_EXT_WR_MODE				17
+#define CNF_DLL_PHY_EXT_RD_MODE				16
+
+#define CNF_MINICTRL_WP_SETTINGS			0x00
+#define CNF_MINICTRL_RBN_SETTINGS			0x04
+#define CNF_MINICTRL_CMN_SETTINGS			0x08
+#define CNF_MINICTRL_SKIP_BYTES_CFG			0x0C
+#define CNF_MINICTRL_SKIP_BYTES_OFFSET			0x10
+#define CNF_MINICTRL_TOGGLE_TIMINGS0			0x14
+#define CNF_MINICTRL_TOGGLE_TIMINGS1			0x18
+#define CNF_MINICTRL_ASYNC_TOGGLE_TIMINGS		0x1C
+#define CNF_MINICTRL_SYNC_TIMINGS			0x20
+#define CNF_MINICTRL_DLL_PHY_CTRL			0x34
+
+#define CNF_MINICTRL(_reg)				(CNF_MINICTRL_REG_BASE \
+							+ (CNF_MINICTRL_##_reg))
+
+/*
+ * @brief Nand IO MTD initialization routine
+ *
+ * @total_size: [out] Total size of the NAND flash device
+ * @erase_size: [out] Minimum erase size of the NAND flash device
+ * Return: 0 on success, a negative errno on failure
+ */
+int cdns_nand_init_mtd(unsigned long long *total_size,
+						unsigned int *erase_size);
+
+/*
+ * @brief Read bytes from the NAND flash device
+ *
+ * @offset: Byte offset to read from in device
+ * @buffer: [out] Bytes read from device
+ * @length: Number of bytes to read
+ * @out_length: [out] Number of bytes read from device
+ * Return: 0 on success, a negative errno on failure
+ */
+int cdns_nand_read(unsigned int offset, uintptr_t buffer,
+					size_t length, size_t *out_length);
+
+/* NAND Flash Controller/Host initialization */
+int cdns_nand_host_init(void);
+
+#endif
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
new file mode 100644
index 0000000..6452725
--- /dev/null
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDN_MMC_H
+#define CDN_MMC_H
+
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/mmc.h>
+#include "socfpga_plat_def.h"
+
+#if MMC_DEVICE_TYPE == 0
+#define CONFIG_DMA_ADDR_T_64BIT		0
+#endif
+
+#define MMC_REG_BASE			SOCFPGA_MMC_REG_BASE
+#define COMBO_PHY_REG		0x0
+#define SDHC_EXTENDED_WR_MODE_MASK	0xFFFFFFF7
+#define SDHC_DLL_RESET_MASK	0x00000001
+/* HRS09 */
+#define SDHC_PHY_SW_RESET			BIT(0)
+#define SDHC_PHY_INIT_COMPLETE		BIT(1)
+#define SDHC_EXTENDED_RD_MODE(x)	((x) << 2)
+#define EXTENDED_WR_MODE			3
+#define SDHC_EXTENDED_WR_MODE(x)	((x) << 3)
+#define RDCMD_EN					15
+#define SDHC_RDCMD_EN(x)			((x) << 15)
+#define SDHC_RDDATA_EN(x)			((x) << 16)
+
+/* CMD_DATA_OUTPUT */
+#define SDHC_CDNS_HRS16				0x40
+
+/* This value determines the interval by which DAT line timeouts are detected */
+/* The interval can be computed as below: */
+/* • 1111b - Reserved */
+/* • 1110b - t_sdmclk*2(27+2) */
+/* • 1101b - t_sdmclk*2(26+2) */
+#define READ_CLK					0xa << 16
+#define WRITE_CLK					0xe << 16
+#define DTC_VAL						0xE
+
+/* SRS00 */
+/* System Address / Argument 2 / 32-bit block count
+ * This field is used as:
+ * • 32-bit Block Count register
+ * • SDMA system memory address
+ * • Auto CMD23 Argument
+ */
+#define SAAR						(1)
+
+/* SRS01 */
+/* Transfer Block Size
+ * This field defines block size for block data transfers
+ */
+#define BLOCK_SIZE					0
+
+/* SDMA Buffer Boundary
+ * System address boundary can be set for SDMA engine.
+ */
+#define SDMA_BUF					7 << 12
+
+/* Block Count For Current Transfer
+ * To set the number of data blocks can be defined for next transfer
+ */
+#define BLK_COUNT_CT				16
+
+/* SRS03 */
+#define CMD_START					(U(1) << 31)
+#define CMD_USE_HOLD_REG			(1 << 29)
+#define CMD_UPDATE_CLK_ONLY			(1 << 21)
+#define CMD_SEND_INIT				(1 << 15)
+#define CMD_STOP_ABORT_CMD			(4 << 22)
+#define CMD_RESUME_CMD				(2 << 22)
+#define CMD_SUSPEND_CMD				(1 << 22)
+#define DATA_PRESENT				(1 << 21)
+#define CMD_IDX_CHK_ENABLE			(1 << 20)
+#define CMD_WRITE					(0 << 4)
+#define CMD_READ					(1 << 4)
+#define	MULTI_BLK_READ				(1 << 5)
+#define RESP_ERR					(1 << 7)
+#define CMD_CHECK_RESP_CRC			(1 << 19)
+#define RES_TYPE_SEL_48				(2 << 16)
+#define RES_TYPE_SEL_136			(1 << 16)
+#define RES_TYPE_SEL_48_B			(3 << 16)
+#define RES_TYPE_SEL_NO				(0 << 16)
+#define DMA_ENABLED					(1 << 0)
+#define BLK_CNT_EN					(1 << 1)
+#define AUTO_CMD_EN					(2 << 2)
+#define COM_IDX						24
+#define ERROR_INT					(1 << 15)
+#define INT_SBE						(1 << 13)
+#define INT_HLE						(1 << 12)
+#define INT_FRUN					(1 << 11)
+#define INT_DRT						(1 << 9)
+#define INT_RTO						(1 << 8)
+#define INT_DCRC					(1 << 7)
+#define INT_RCRC					(1 << 6)
+#define INT_RXDR					(1 << 5)
+#define INT_TXDR					(1 << 4)
+#define INT_DTO						(1 << 3)
+#define INT_CMD_DONE				(1 << 0)
+#define TRAN_COMP					(1 << 1)
+
+/* SRS09 */
+#define STATUS_DATA_BUSY			BIT(2)
+
+/* SRS10 */
+/* LED Control
+ * State of this bit directly drives led port of the host
+ * in order to control the external LED diode
+ * Default value 0 << 1
+ */
+#define LEDC						BIT(0)
+#define LEDC_OFF					0 << 1
+
+/* Data Transfer Width
+ * Bit used to configure DAT bus width to 1 or 4
+ * Default value 1 << 1
+ */
+#define DT_WIDTH					BIT(1)
+#define DTW_4BIT					1 << 1
+
+/* Extended Data Transfer Width
+ * This bit is to enable/disable 8-bit DAT bus width mode
+ * Default value 1 << 5
+ */
+#define EDTW_8BIT					1 << 5
+
+/* High Speed Enable
+ * Selects operating mode to Default Speed (HSE=0) or High Speed (HSE=1)
+ */
+#define HS_EN						BIT(2)
+
+/* here 0 defines the 64 Kb size */
+#define MAX_64KB_PAGE				0
+#define EMMC_DESC_SIZE		(1<<20)
+
+/* SRS11 */
+/* Software Reset For All
+ * When set to 1, the entire slot is reset
+ * After completing the reset operation, SRFA bit is automatically cleared
+ */
+#define SRFA						BIT(24)
+
+/* Software Reset For CMD Line
+ * When set to 1, resets the logic related to the command generation and response checking
+ */
+#define SRCMD						BIT(25)
+
+/* Software Reset For DAT Line
+ * When set to 1, resets the logic related to the data path,
+ * including data buffers and the DMA logic
+ */
+#define SRDAT						BIT(26)
+
+/* SRS15 */
+/* UHS Mode Select
+ * Used to select one of UHS-I modes.
+ * • 000b - SDR12
+ * • 001b - SDR25
+ * • 010b - SDR50
+ * • 011b - SDR104
+ * • 100b - DDR50
+ */
+#define SDR12_MODE					0 << 16
+#define SDR25_MODE					1 << 16
+#define SDR50_MODE					2 << 16
+#define SDR104_MODE					3 << 16
+#define DDR50_MODE					4 << 16
+/* 1.8V Signaling Enable
+ * • 0 - for Default Speed, High Speed mode
+ * • 1 - for UHS-I mode
+ */
+#define V18SE						BIT(19)
+
+/* CMD23 Enable
+ * In result of Card Identification process,
+ * Host Driver set this bit to 1 if Card supports CMD23
+ */
+#define CMD23_EN					BIT(27)
+
+/* Host Version 4.00 Enable
+ * • 0 - Version 3.00
+ * • 1 - Version 4.00
+ */
+#define HV4E						BIT(28)
+/* Conf depends on SRS15.HV4E */
+#define SDMA						0 << 3
+#define ADMA2_32					2 << 3
+#define ADMA2_64					3 << 3
+
+/* Preset Value Enable
+ * Setting this bit to 1 triggers an automatically update of SRS11
+ */
+#define PVE							BIT(31)
+
+#define BIT_AD_32					0 << 29
+#define BIT_AD_64					1 << 29
+
+/* SW RESET REG*/
+#define SDHC_CDNS_HRS00				(0x00)
+#define SDHC_CDNS_HRS00_SWR			BIT(0)
+
+/* PHY access port */
+#define SDHC_CDNS_HRS04				0x10
+#define SDHC_CDNS_HRS04_ADDR		GENMASK(5, 0)
+
+/* PHY data access port */
+#define SDHC_CDNS_HRS05				0x14
+
+/* eMMC control registers */
+#define SDHC_CDNS_HRS06				0x18
+
+/* SRS */
+#define SDHC_CDNS_SRS_BASE			0x200
+#define SDHC_CDNS_SRS00				0x200
+#define SDHC_CDNS_SRS01				0x204
+#define SDHC_CDNS_SRS02				0x208
+#define SDHC_CDNS_SRS03				0x20c
+#define SDHC_CDNS_SRS04				0x210
+#define SDHC_CDNS_SRS05				0x214
+#define SDHC_CDNS_SRS06				0x218
+#define SDHC_CDNS_SRS07				0x21C
+#define SDHC_CDNS_SRS08				0x220
+#define SDHC_CDNS_SRS09				0x224
+#define SDHC_CDNS_SRS09_CI			BIT(16)
+#define SDHC_CDNS_SRS10				0x228
+#define SDHC_CDNS_SRS11				0x22C
+#define SDHC_CDNS_SRS12				0x230
+#define SDHC_CDNS_SRS13				0x234
+#define SDHC_CDNS_SRS14				0x238
+#define SDHC_CDNS_SRS15				0x23c
+#define SDHC_CDNS_SRS21				0x254
+#define SDHC_CDNS_SRS22				0x258
+#define SDHC_CDNS_SRS23				0x25c
+
+/* HRS07 */
+#define SDHC_CDNS_HRS07				0x1c
+#define SDHC_IDELAY_VAL(x)			((x) << 0)
+#define SDHC_RW_COMPENSATE(x)		((x) << 16)
+
+/* PHY reset port */
+#define SDHC_CDNS_HRS09				0x24
+
+/* HRS10 */
+/* PHY reset port */
+#define SDHC_CDNS_HRS10				0x28
+
+/* HCSDCLKADJ DATA; DDR Mode */
+#define SDHC_HCSDCLKADJ(x)			((x) << 16)
+
+/* Pinmux headers will reomove after ATF driver implementation */
+#define PINMUX_SDMMC_SEL			0x0
+#define PIN0SEL						0x00
+#define PIN1SEL						0x04
+#define PIN2SEL						0x08
+#define PIN3SEL						0x0C
+#define PIN4SEL						0x10
+#define PIN5SEL						0x14
+#define PIN6SEL						0x18
+#define PIN7SEL						0x1C
+#define PIN8SEL						0x20
+#define PIN9SEL						0x24
+#define PIN10SEL					0x28
+
+/* HRS16 */
+#define SDHC_WRCMD0_DLY(x)			((x) << 0)
+#define SDHC_WRCMD1_DLY(x)			((x) << 4)
+#define SDHC_WRDATA0_DLY(x)			((x) << 8)
+#define SDHC_WRDATA1_DLY(x)			((x) << 12)
+#define SDHC_WRCMD0_SDCLK_DLY(x)	((x) << 16)
+#define SDHC_WRCMD1_SDCLK_DLY(x)	((x) << 20)
+#define SDHC_WRDATA0_SDCLK_DLY(x)	((x) << 24)
+#define SDHC_WRDATA1_SDCLK_DLY(x)	((x) << 28)
+
+/* Shared Macros */
+#define SDMMC_CDN(_reg)				(SDMMC_CDN_REG_BASE + \
+								(SDMMC_CDN_##_reg))
+
+/* Refer to atf/tools/cert_create/include/debug.h */
+#define BIT_32(nr)					(U(1) << (nr))
+
+/* MMC Peripheral Definition */
+#define SOCFPGA_MMC_BLOCK_SIZE		U(8192)
+#define SOCFPGA_MMC_BLOCK_MASK		(SOCFPGA_MMC_BLOCK_SIZE - U(1))
+#define SOCFPGA_MMC_BOOT_CLK_RATE	(400 * 1000)
+#define MMC_RESPONSE_NONE			0
+#define SDHC_CDNS_SRS03_VALUE		0x01020013
+
+/* Value randomly chosen for eMMC RCA, it should be > 1 */
+#define MMC_FIX_RCA					6
+#define RCA_SHIFT_OFFSET			16
+
+#define CMD_EXTCSD_PARTITION_CONFIG	179
+#define CMD_EXTCSD_BUS_WIDTH		183
+#define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_SEC_CNT			212
+
+#define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+
+/* Values in EXT CSD register */
+#define MMC_BUS_WIDTH_1				U(0)
+#define MMC_BUS_WIDTH_4				U(1)
+#define MMC_BUS_WIDTH_8				U(2)
+#define MMC_BUS_WIDTH_DDR_4			U(5)
+#define MMC_BUS_WIDTH_DDR_8			U(6)
+#define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
+#define MMC_BOOT_MODE_DDR			(U(2) << 3)
+
+#define EXTCSD_SET_CMD				(U(0) << 24)
+#define EXTCSD_SET_BITS				(U(1) << 24)
+#define EXTCSD_CLR_BITS				(U(2) << 24)
+#define EXTCSD_WRITE_BYTES			(U(3) << 24)
+#define EXTCSD_CMD(x)				(((x) & 0xff) << 16)
+#define EXTCSD_VALUE(x)				(((x) & 0xff) << 8)
+#define EXTCSD_CMD_SET_NORMAL		U(1)
+
+#define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT	3
+
+#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA		BIT(8)
+#define STATUS_SWITCH_ERROR			BIT(7)
+#define MMC_GET_STATE(x)			(((x) >> 9) & 0xf)
+#define MMC_STATE_IDLE				0
+#define MMC_STATE_READY				1
+#define MMC_STATE_IDENT				2
+#define MMC_STATE_STBY				3
+#define MMC_STATE_TRAN				4
+#define MMC_STATE_DATA				5
+#define MMC_STATE_RCV				6
+#define MMC_STATE_PRG				7
+#define MMC_STATE_DIS				8
+#define MMC_STATE_BTST				9
+#define MMC_STATE_SLP				10
+
+#define MMC_FLAG_CMD23				(U(1) << 0)
+
+#define CMD8_CHECK_PATTERN			U(0xAA)
+#define VHS_2_7_3_6_V				BIT(8)
+
+/*ADMA table component*/
+#define ADMA_DESC_ATTR_VALID		BIT(0)
+#define ADMA_DESC_ATTR_END			BIT(1)
+#define ADMA_DESC_ATTR_INT			BIT(2)
+#define ADMA_DESC_ATTR_ACT1			BIT(4)
+#define ADMA_DESC_ATTR_ACT2			BIT(5)
+#define ADMA_DESC_TRANSFER_DATA		ADMA_DESC_ATTR_ACT2
+
+enum sd_opcode {
+	SD_GO_IDLE_STATE = 0,
+	SD_ALL_SEND_CID = 2,
+	SD_SEND_RELATIVE_ADDR = 3,
+	SDIO_SEND_OP_COND = 5, /* SDIO cards only */
+	SD_SWITCH = 6,
+	SD_SELECT_CARD = 7,
+	SD_SEND_IF_COND = 8,
+	SD_SEND_CSD = 9,
+	SD_SEND_CID = 10,
+	SD_VOL_SWITCH = 11,
+	SD_STOP_TRANSMISSION = 12,
+	SD_SEND_STATUS = 13,
+	SD_GO_INACTIVE_STATE = 15,
+	SD_SET_BLOCK_SIZE = 16,
+	SD_READ_SINGLE_BLOCK = 17,
+	SD_READ_MULTIPLE_BLOCK = 18,
+	SD_SEND_TUNING_BLOCK = 19,
+	SD_SET_BLOCK_COUNT = 23,
+	SD_WRITE_SINGLE_BLOCK = 24,
+	SD_WRITE_MULTIPLE_BLOCK = 25,
+	SD_ERASE_BLOCK_START = 32,
+	SD_ERASE_BLOCK_END = 33,
+	SD_ERASE_BLOCK_OPERATION = 38,
+	SD_APP_CMD = 55,
+	SD_SPI_READ_OCR = 58, /* SPI mode only */
+	SD_SPI_CRC_ON_OFF = 59, /* SPI mode only */
+};
+
+enum sd_app_cmd {
+	SD_APP_SET_BUS_WIDTH = 6,
+	SD_APP_SEND_STATUS = 13,
+	SD_APP_SEND_NUM_WRITTEN_BLK = 22,
+	SD_APP_SET_WRITE_BLK_ERASE_CNT = 23,
+	SD_APP_SEND_OP_COND = 41,
+	SD_APP_CLEAR_CARD_DETECT = 42,
+	SD_APP_SEND_SCR = 51,
+};
+
+struct cdns_sdmmc_sdhc {
+	uint32_t	sdhc_extended_rd_mode;
+	uint32_t	sdhc_extended_wr_mode;
+	uint32_t	sdhc_hcsdclkadj;
+	uint32_t	sdhc_idelay_val;
+	uint32_t	sdhc_rdcmd_en;
+	uint32_t	sdhc_rddata_en;
+	uint32_t	sdhc_rw_compensate;
+	uint32_t	sdhc_sdcfsh;
+	uint32_t	sdhc_sdcfsl;
+	uint32_t	sdhc_wrcmd0_dly;
+	uint32_t	sdhc_wrcmd0_sdclk_dly;
+	uint32_t	sdhc_wrcmd1_dly;
+	uint32_t	sdhc_wrcmd1_sdclk_dly;
+	uint32_t	sdhc_wrdata0_dly;
+	uint32_t	sdhc_wrdata0_sdclk_dly;
+	uint32_t	sdhc_wrdata1_dly;
+	uint32_t	sdhc_wrdata1_sdclk_dly;
+};
+
+enum sdmmc_device_mode {
+	SD_DS_ID, /* Identification */
+	SD_DS, /* Default speed */
+	SD_HS, /* High speed */
+	SD_UHS_SDR12, /* Ultra high speed SDR12 */
+	SD_UHS_SDR25, /* Ultra high speed SDR25 */
+	SD_UHS_SDR50, /* Ultra high speed SDR`50 */
+	SD_UHS_SDR104, /* Ultra high speed SDR104 */
+	SD_UHS_DDR50, /* Ultra high speed DDR50 */
+	EMMC_SDR_BC, /* SDR backward compatible */
+	EMMC_SDR, /* SDR */
+	EMMC_DDR, /* DDR */
+	EMMC_HS200, /* High speed 200Mhz in SDR */
+	EMMC_HS400, /* High speed 200Mhz in DDR */
+	EMMC_HS400es, /* High speed 200Mhz in SDR with enhanced strobe*/
+};
+
+struct cdns_sdmmc_params {
+	uintptr_t	reg_base;
+	uintptr_t	reg_pinmux;
+	uintptr_t	reg_phy;
+	uintptr_t	desc_base;
+	size_t		desc_size;
+	int		clk_rate;
+	int		bus_width;
+	unsigned int	flags;
+	enum sdmmc_device_mode	cdn_sdmmc_dev_mode;
+	enum mmc_device_type	cdn_sdmmc_dev_type;
+	uint32_t	combophy;
+};
+
+/* read and write API */
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+
+struct cdns_idmac_desc {
+	/*8 bit attribute*/
+	uint8_t attr;
+	/*reserved bits in desc*/
+	uint8_t reserved;
+	/*page length for the descriptor*/
+	uint16_t len;
+	/*lower 32 bits for buffer (64 bit addressing)*/
+	uint32_t addr_lo;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+	/*higher 32 bits for buffer (64 bit addressing)*/
+	uint32_t addr_hi;
+} __aligned(8);
+#else
+} __packed;
+#endif
+
+
+
+/* Function Prototype */
+int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
+struct cdns_sdmmc_sdhc *mmc_sdhc_reg);
+void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+struct cdns_sdmmc_sdhc *sdhc_reg);
+#endif
diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h
index 30ca910..327c1d9 100644
--- a/include/drivers/cadence/cdns_uart.h
+++ b/include/drivers/cadence/cdns_uart.h
@@ -22,6 +22,7 @@
 #define UART_SR_INTR_REMPTY_BIT	1
 #define UART_SR_INTR_TFUL_BIT	4
 #define UART_SR_INTR_TEMPTY_BIT	3
+#define UART_SR_INTR_TACTIVE_BIT	11
 
 #define R_UART_TX	0x30
 #define R_UART_RX	0x30
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
index fe88576..7ab517c 100644
--- a/include/drivers/measured_boot/rss/rss_measured_boot.h
+++ b/include/drivers/measured_boot/rss/rss_measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,16 +40,18 @@
 	size_t  version_size;
 	uint8_t sw_type[SW_TYPE_MAX_SIZE];
 	size_t  sw_type_size;
+	void    *pk_oid;
 	bool    lock_measurement;
 };
 
 /* Functions' declarations */
-void rss_measured_boot_init(void);
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void);
-int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr);
+int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id);
 
-/* TODO: These metadata are currently not available during TF-A boot */
-int rss_mboot_set_signer_id(unsigned int img_id, const void *pk_ptr, size_t pk_len);
+int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+			    const void *pk_oid, const void *pk_ptr,
+			    size_t pk_len);
 
 #endif /* RSS_MEASURED_BOOT_H */
diff --git a/include/drivers/nuvoton/npcm845x/npcm845x_clock.h b/include/drivers/nuvoton/npcm845x/npcm845x_clock.h
new file mode 100644
index 0000000..3c457d7
--- /dev/null
+++ b/include/drivers/nuvoton/npcm845x/npcm845x_clock.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ARBEL_CLOCK_H_
+#define __ARBEL_CLOCK_H_
+
+struct clk_ctl {
+	unsigned int	clken1;
+	unsigned int	clksel;
+	unsigned int	clkdiv1;
+	unsigned int	pllcon0;
+	unsigned int	pllcon1;
+	unsigned int	swrstr;
+	unsigned char	res1[0x8];
+	unsigned int	ipsrst1;
+	unsigned int	ipsrst2;
+	unsigned int	clken2;
+	unsigned int	clkdiv2;
+	unsigned int	clken3;
+	unsigned int	ipsrst3;
+	unsigned int	wd0rcr;
+	unsigned int	wd1rcr;
+	unsigned int	wd2rcr;
+	unsigned int	swrstc1;
+	unsigned int	swrstc2;
+	unsigned int	swrstc3;
+	unsigned int	tiprstc;
+	unsigned int	pllcon2;
+	unsigned int	clkdiv3;
+	unsigned int	corstc;
+	unsigned int	pllcong;
+	unsigned int	ahbckfi;
+	unsigned int	seccnt;
+	unsigned int	cntr25m;
+	unsigned int	clken4;
+	unsigned int	ipsrst4;
+	unsigned int	busto;
+	unsigned int	clkdiv4;
+	unsigned int	wd0rcrb;
+	unsigned int	wd1rcrb;
+	unsigned int	wd2rcrb;
+	unsigned int	swrstc1b;
+	unsigned int	swrstc2b;
+	unsigned int	swrstc3b;
+	unsigned int	tiprstcb;
+	unsigned int	corstcb;
+	unsigned int	ipsrstdis1;
+	unsigned int	ipsrstdis2;
+	unsigned int	ipsrstdis3;
+	unsigned int	ipsrstdis4;
+	unsigned char	res2[0x10];
+	unsigned int	thrtl_cnt;
+};
+
+#endif /* __ARBEL_CLOCK_H_ */
diff --git a/include/drivers/nuvoton/npcm845x/npcm845x_gcr.h b/include/drivers/nuvoton/npcm845x/npcm845x_gcr.h
new file mode 100644
index 0000000..b9f3048
--- /dev/null
+++ b/include/drivers/nuvoton/npcm845x/npcm845x_gcr.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __NPCM845x_GCR_H_
+#define __NPCM845x_GCR_H_
+
+struct npcm845x_gcr {
+	unsigned int pdid;
+	unsigned int pwron;
+	unsigned int swstrps;
+	unsigned int rsvd1[2];
+	unsigned int miscpe;
+	unsigned int spldcnt;
+	unsigned int rsvd2[1];
+	unsigned int flockr2;
+	unsigned int flockr3;
+	unsigned int rsvd3[3];
+	unsigned int a35_mode;
+	unsigned int spswc;
+	unsigned int intcr;
+	unsigned int intsr;
+	unsigned int obscr1;
+	unsigned int obsdr1;
+	unsigned int rsvd4[1];
+	unsigned int hifcr;
+	unsigned int rsvd5[3];
+	unsigned int intcr2;
+	unsigned int rsvd6[1];
+	unsigned int srcnt;
+	unsigned int ressr;
+	unsigned int rlockr1;
+	unsigned int flockr1;
+	unsigned int dscnt;
+	unsigned int mdlr;
+	unsigned int scrpad_c;
+	unsigned int scrpad_b;
+	unsigned int rsvd7[4];
+	unsigned int daclvlr;
+	unsigned int intcr3;
+	unsigned int pcirctl;
+	unsigned int rsvd8[2];
+	unsigned int vsintr;
+	unsigned int rsvd9[1];
+	unsigned int sd2sur1;
+	unsigned int sd2sur2;
+	unsigned int sd2irv3;
+	unsigned int intcr4;
+	unsigned int obscr2;
+	unsigned int obsdr2;
+	unsigned int rsvd10[5];
+	unsigned int i2csegsel;
+	unsigned int i2csegctl;
+	unsigned int vsrcr;
+	unsigned int mlockr;
+	unsigned int rsvd11[8];
+	unsigned int etsr;
+	unsigned int dft1r;
+	unsigned int dft2r;
+	unsigned int dft3r;
+	unsigned int edffsr;
+	unsigned int rsvd12[1];
+	unsigned int intcrpce3;
+	unsigned int intcrpce2;
+	unsigned int intcrpce0;
+	unsigned int intcrpce1;
+	unsigned int dactest;
+	unsigned int scrpad;
+	unsigned int usb1phyctl;
+	unsigned int usb2phyctl;
+	unsigned int usb3phyctl;
+	unsigned int intsr2;
+	unsigned int intcrpce2b;
+	unsigned int intcrpce0b;
+	unsigned int intcrpce1b;
+	unsigned int intcrpce3b;
+	unsigned int rsvd13[4];
+	unsigned int intcrpce2c;
+	unsigned int intcrpce0c;
+	unsigned int intcrpce1c;
+	unsigned int intcrpce3c;
+	unsigned int rsvd14[40];
+	unsigned int sd2irv4;
+	unsigned int sd2irv5;
+	unsigned int sd2irv6;
+	unsigned int sd2irv7;
+	unsigned int sd2irv8;
+	unsigned int sd2irv9;
+	unsigned int sd2irv10;
+	unsigned int sd2irv11;
+	unsigned int rsvd15[8];
+	unsigned int mfsel1;
+	unsigned int mfsel2;
+	unsigned int mfsel3;
+	unsigned int mfsel4;
+	unsigned int mfsel5;
+	unsigned int mfsel6;
+	unsigned int mfsel7;
+	unsigned int rsvd16[1];
+	unsigned int mfsel_lk1;
+	unsigned int mfsel_lk2;
+	unsigned int mfsel_lk3;
+	unsigned int mfsel_lk4;
+	unsigned int mfsel_lk5;
+	unsigned int mfsel_lk6;
+	unsigned int mfsel_lk7;
+	unsigned int rsvd17[1];
+	unsigned int mfsel_set1;
+	unsigned int mfsel_set2;
+	unsigned int mfsel_set3;
+	unsigned int mfsel_set4;
+	unsigned int mfsel_set5;
+	unsigned int mfsel_set6;
+	unsigned int mfsel_set7;
+	unsigned int rsvd18[1];
+	unsigned int mfsel_clr1;
+	unsigned int mfsel_clr2;
+	unsigned int mfsel_clr3;
+	unsigned int mfsel_clr4;
+	unsigned int mfsel_clr5;
+	unsigned int mfsel_clr6;
+	unsigned int mfsel_clr7;
+};
+
+#endif
diff --git a/include/drivers/nuvoton/npcm845x/npcm845x_lpuart.h b/include/drivers/nuvoton/npcm845x/npcm845x_lpuart.h
new file mode 100644
index 0000000..8962b90
--- /dev/null
+++ b/include/drivers/nuvoton/npcm845x/npcm845x_lpuart.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ASM_ARCH_UART_H_
+#define __ASM_ARCH_UART_H_
+
+#ifndef __ASSEMBLY__
+
+struct npcmX50_uart {
+	union {
+		unsigned int rbr;
+		unsigned int thr;
+		unsigned int dll;
+	};
+	union {
+		unsigned int ier;
+		unsigned int dlm;
+	};
+	union {
+		unsigned int iir;
+		unsigned int fcr;
+	};
+	unsigned int lcr;
+	unsigned int mcr;
+	unsigned int lsr;
+	unsigned int msr;
+	unsigned int tor;
+};
+
+typedef enum {
+	/*
+	 * UART0 is a general UART block without modem-I/O-control
+	 * connection to external signals.
+	 */
+	UART0_DEV = 0,
+	/*
+	 * UART1-3 are each a general UART with modem-I/O-control
+	 * connection to external signals.
+	 */
+	UART1_DEV,
+	UART2_DEV,
+	UART3_DEV,
+} UART_DEV_T;
+
+typedef enum {
+	/*
+	 * 0 0 0: Mode 1:
+	 * HSP1 connected to SI2,
+	 * HSP2 connected to UART2,
+	 * UART1 snoops HSP1,
+	 * UART3 snoops SI2
+	 */
+	UART_MUX_MODE1 = 0,
+	/*
+	 * 0 0 1: Mode 2:
+	 * HSP1 connected to UART1,
+	 * HSP2 connected to SI2,
+	 * UART2 snoops HSP2,
+	 * UART3 snoops SI2
+	 */
+	UART_MUX_MODE2,
+	/*
+	 * 0 1 0: Mode 3:
+	 * HSP1 connected to UART1,
+	 * HSP2 connected to UART2,
+	 * UART3 connected to SI2
+	 */
+	UART_MUX_MODE3,
+	/*
+	 * 0 1 1: Mode 4:
+	 * HSP1 connected to SI1,
+	 * HSP2 connected to SI2,
+	 * UART1 snoops SI1,
+	 * UART3 snoops SI2,
+	 * UART2 snoops HSP1 (default)
+	 */
+	UART_MUX_MODE4,
+	/*
+	 * 1 0 0: Mode 5:
+	 * HSP1 connected to SI1,
+	 * HSP2 connected to UART2,
+	 * UART1 snoops HSP1,
+	 * UART3 snoops SI1
+	 */
+	UART_MUX_MODE5,
+	/*
+	 * 1 0 1: Mode 6:
+	 * HSP1 connected to SI1,
+	 * HSP2 connected to SI2,
+	 * UART1 snoops SI1,
+	 * UART3 snoops SI2,
+	 * UART2 snoops HSP2
+	 */
+	UART_MUX_MODE6,
+	/*
+	 * 1 1 0: Mode 7:
+	 * HSP1 connected to SI1,
+	 * HSP2 connected to UART2,
+	 * UART1 snoops HSP1,
+	 * UART3 connected to SI2
+	 */
+	UART_MUX_MODE7,
+	/* Skip UART mode configuration. */
+	UART_MUX_RESERVED,
+	/*
+	 * A SW option to allow config of UART
+	 * without touching the UART mux.
+	 */
+	UART_MUX_SKIP_CONFIG
+} UART_MUX_T;
+
+/*---------------------------------------------------------------------------*/
+/* Common baudrate definitions                                               */
+/*---------------------------------------------------------------------------*/
+typedef enum {
+	UART_BAUDRATE_110 = 110,
+	UART_BAUDRATE_300 = 300,
+	UART_BAUDRATE_600 = 600,
+	UART_BAUDRATE_1200 = 1200,
+	UART_BAUDRATE_2400 = 2400,
+	UART_BAUDRATE_4800 = 4800,
+	UART_BAUDRATE_9600 = 9600,
+	UART_BAUDRATE_14400 = 14400,
+	UART_BAUDRATE_19200 = 19200,
+	UART_BAUDRATE_38400 = 38400,
+	UART_BAUDRATE_57600 = 57600,
+	UART_BAUDRATE_115200 = 115200,
+	UART_BAUDRATE_230400 = 230400,
+	UART_BAUDRATE_380400 = 380400,
+	UART_BAUDRATE_460800 = 460800,
+} UART_BAUDRATE_T;
+
+/*---------------------------------------------------------------------------*/
+/* UART parity types                                                         */
+/*---------------------------------------------------------------------------*/
+typedef enum {
+	UART_PARITY_NONE = 0,
+	UART_PARITY_EVEN,
+	UART_PARITY_ODD,
+} UART_PARITY_T;
+
+/*---------------------------------------------------------------------------*/
+/* Uart stop bits                                                            */
+/*---------------------------------------------------------------------------*/
+typedef enum {
+	UART_STOPBIT_1 = 0x00,
+	UART_STOPBIT_DYNAMIC,
+} UART_STOPBIT_T;
+
+enum FCR_RFITL_TYPE {
+	FCR_RFITL_1B = 0x0,
+	FCR_RFITL_4B = 0x4,
+	FCR_RFITL_8B = 0x8,
+	FCR_RFITL_14B = 0xC,
+};
+
+enum LCR_WLS_TYPE {
+	LCR_WLS_5bit = 0x0,
+	LCR_WLS_6bit = 0x1,
+	LCR_WLS_7bit = 0x2,
+	LCR_WLS_8bit = 0x3,
+};
+
+#define IER_DBGACK (1 << 4)
+#define IER_MSIE (1 << 3)
+#define IER_RLSE (1 << 2)
+#define IER_THREIE (1 << 1)
+#define IER_RDAIE (1 << 0)
+
+#define IIR_FMES (1 << 7)
+#define IIR_RFTLS (1 << 5)
+#define IIR_DMS (1 << 4)
+#define IIR_IID (1 << 1)
+#define IIR_NIP (1 << 0)
+
+#define FCR_RFITL_1B (0 << 4)
+#define FCR_RFITL_4B (4 << 4)
+#define FCR_RFITL_8B (8 << 4)
+#define FCR_RFITL_14B (12 << 4)
+#define FCR_DMS (1 << 3)
+#define FCR_TFR (1 << 2)
+#define FCR_RFR (1 << 1)
+#define FCR_FME (1 << 0)
+
+#define LCR_DLAB (1 << 7)
+#define LCR_BCB (1 << 6)
+#define LCR_SPE (1 << 5)
+#define LCR_EPS (1 << 4)
+#define LCR_PBE (1 << 3)
+#define LCR_NSB (1 << 2)
+#define LCR_WLS_8b (3 << 0)
+#define LCR_WLS_7b (2 << 0)
+#define LCR_WLS_6b (1 << 0)
+#define LCR_WLS_5b (0 << 0)
+
+#define MCR_LBME (1 << 4)
+#define MCR_OUT2 (1 << 3)
+#define MCR_RTS (1 << 1)
+#define MCR_DTR (1 << 0)
+
+#define LSR_ERR_RX (1 << 7)
+#define LSR_TE (1 << 6)
+#define LSR_THRE (1 << 5)
+#define LSR_BII (1 << 4)
+#define LSR_FEI (1 << 3)
+#define LSR_PEI (1 << 2)
+#define LSR_OEI (1 << 1)
+#define LSR_RFDR (1 << 0)
+
+#define MSR_DCD (1 << 7)
+#define MSR_RI (1 << 6)
+#define MSR_DSR (1 << 5)
+#define MSR_CTS (1 << 4)
+#define MSR_DDCD (1 << 3)
+#define MSR_DRI (1 << 2)
+#define MSR_DDSR (1 << 1)
+#define MSR_DCTS (1 << 0)
+
+#endif /* __ASSEMBLY__ */
+
+uintptr_t npcm845x_get_base_uart(UART_DEV_T dev);
+void CLK_ResetUART(void);
+int UART_Init(UART_DEV_T devNum, UART_BAUDRATE_T baudRate);
+
+#endif /* __ASM_ARCH_UART_H_ */
diff --git a/include/drivers/scmi-msg.h b/include/drivers/scmi-msg.h
index eb90859..c93c455 100644
--- a/include/drivers/scmi-msg.h
+++ b/include/drivers/scmi-msg.h
@@ -113,10 +113,12 @@
  * @scmi_id: SCMI clock ID
  * @rates: If NULL, function returns, else output rates array
  * @nb_elts: Array size of @rates.
+ * @start_idx: Start index of rates array
  * Return an SCMI compliant error code
  */
 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
-				    unsigned long *rates, size_t *nb_elts);
+				    unsigned long *rates, size_t *nb_elts,
+				    uint32_t start_idx);
 
 /*
  * Get clock possible rate as range with regular steps in Hertz
diff --git a/include/export/lib/bl_aux_params/bl_aux_params_exp.h b/include/export/lib/bl_aux_params/bl_aux_params_exp.h
index 7391dec..5ae1d64 100644
--- a/include/export/lib/bl_aux_params/bl_aux_params_exp.h
+++ b/include/export/lib/bl_aux_params/bl_aux_params_exp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/export/lib/utils_def_exp.h b/include/export/lib/utils_def_exp.h
index 2ee5769..8c58cbb 100644
--- a/include/export/lib/utils_def_exp.h
+++ b/include/export/lib/utils_def_exp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/bakery_lock.h b/include/lib/bakery_lock.h
index 2cf2b44..5d165c9 100644
--- a/include/lib/bakery_lock.h
+++ b/include/lib/bakery_lock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/bl_aux_params/bl_aux_params.h b/include/lib/bl_aux_params/bl_aux_params.h
index 072a29d..c2da96c 100644
--- a/include/lib/bl_aux_params/bl_aux_params.h
+++ b/include/lib/bl_aux_params/bl_aux_params.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/bootmarker_capture.h b/include/lib/bootmarker_capture.h
new file mode 100644
index 0000000..31fe048
--- /dev/null
+++ b/include/lib/bootmarker_capture.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOOTMARKER_CAPTURE_H
+#define BOOTMARKER_CAPTURE_H
+
+#define BL1_ENTRY	U(0)
+#define BL1_EXIT	U(1)
+#define BL2_ENTRY	U(2)
+#define BL2_EXIT	U(3)
+#define BL31_ENTRY	U(4)
+#define BL31_EXIT	U(5)
+#define BL_TOTAL_IDS	U(6)
+
+#ifdef __ASSEMBLER__
+PMF_DECLARE_CAPTURE_TIMESTAMP(bl_svc)
+#endif  /*__ASSEMBLER__*/
+
+#endif  /*BOOTMARKER_CAPTURE_H*/
diff --git a/include/lib/cassert.h b/include/lib/cassert.h
index bbfdfdb..512a2ad 100644
--- a/include/lib/cassert.h
+++ b/include/lib/cassert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h
index 42d4149..c8e1b2d 100644
--- a/include/lib/coreboot.h
+++ b/include/lib/coreboot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/aem_generic.h b/include/lib/cpus/aarch32/aem_generic.h
index 1d40cec..f631f26 100644
--- a/include/lib/cpus/aarch32/aem_generic.h
+++ b/include/lib/cpus/aarch32/aem_generic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a12.h b/include/lib/cpus/aarch32/cortex_a12.h
index abacdba..789b4cf 100644
--- a/include/lib/cpus/aarch32/cortex_a12.h
+++ b/include/lib/cpus/aarch32/cortex_a12.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a15.h b/include/lib/cpus/aarch32/cortex_a15.h
index 9526a9c..aca4d34 100644
--- a/include/lib/cpus/aarch32/cortex_a15.h
+++ b/include/lib/cpus/aarch32/cortex_a15.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a17.h b/include/lib/cpus/aarch32/cortex_a17.h
index 89a8eb6..b9e754a 100644
--- a/include/lib/cpus/aarch32/cortex_a17.h
+++ b/include/lib/cpus/aarch32/cortex_a17.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a32.h b/include/lib/cpus/aarch32/cortex_a32.h
index 6ddd533..841898a 100644
--- a/include/lib/cpus/aarch32/cortex_a32.h
+++ b/include/lib/cpus/aarch32/cortex_a32.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a5.h b/include/lib/cpus/aarch32/cortex_a5.h
index 76703b7..c0763f9 100644
--- a/include/lib/cpus/aarch32/cortex_a5.h
+++ b/include/lib/cpus/aarch32/cortex_a5.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a53.h b/include/lib/cpus/aarch32/cortex_a53.h
index 8dd0192..b9bb310 100644
--- a/include/lib/cpus/aarch32/cortex_a53.h
+++ b/include/lib/cpus/aarch32/cortex_a53.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a57.h b/include/lib/cpus/aarch32/cortex_a57.h
index ffabd61..bb977ff 100644
--- a/include/lib/cpus/aarch32/cortex_a57.h
+++ b/include/lib/cpus/aarch32/cortex_a57.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a7.h b/include/lib/cpus/aarch32/cortex_a7.h
index 730fdb5..16fbfaa 100644
--- a/include/lib/cpus/aarch32/cortex_a7.h
+++ b/include/lib/cpus/aarch32/cortex_a7.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a72.h b/include/lib/cpus/aarch32/cortex_a72.h
index 954f736..0a3a23a 100644
--- a/include/lib/cpus/aarch32/cortex_a72.h
+++ b/include/lib/cpus/aarch32/cortex_a72.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch32/cortex_a9.h b/include/lib/cpus/aarch32/cortex_a9.h
index a8c978a..337bad9 100644
--- a/include/lib/cpus/aarch32/cortex_a9.h
+++ b/include/lib/cpus/aarch32/cortex_a9.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/aem_generic.h b/include/lib/cpus/aarch64/aem_generic.h
index 6bb30a2..acb6adb 100644
--- a/include/lib/cpus/aarch64/aem_generic.h
+++ b/include/lib/cpus/aarch64/aem_generic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a35.h b/include/lib/cpus/aarch64/cortex_a35.h
index 5421478..cef2960 100644
--- a/include/lib/cpus/aarch64/cortex_a35.h
+++ b/include/lib/cpus/aarch64/cortex_a35.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
index 6af85a8..337aac3 100644
--- a/include/lib/cpus/aarch64/cortex_a510.h
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,11 +14,13 @@
  ******************************************************************************/
 #define CORTEX_A510_CPUECTLR_EL1				S3_0_C15_C1_4
 #define CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT		U(19)
+#define CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_WIDTH		U(1)
 #define CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE	U(1)
 #define CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT			U(23)
 #define CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT			U(46)
 #define CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR		U(2)
-#define CORTEX_A510_CPUECTLR_EL1_ATOM				U(38)
+#define CORTEX_A510_CPUECTLR_EL1_ATOM_SHIFT			U(38)
+#define CORTEX_A510_CPUECTLR_EL1_ATOM_WIDTH			U(3)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
@@ -30,6 +32,12 @@
  * Complex auxiliary control register specific definitions
  ******************************************************************************/
 #define CORTEX_A510_CMPXACTLR_EL1				S3_0_C15_C1_3
+#define CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_DISABLE	U(1)
+#define CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_SHIFT		U(25)
+#define CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_WIDTH		U(1)
+#define CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_DISABLE	U(3)
+#define CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_SHIFT		U(10)
+#define CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_WIDTH		U(2)
 
 /*******************************************************************************
  * Auxiliary control register specific definitions
@@ -37,5 +45,11 @@
 #define CORTEX_A510_CPUACTLR_EL1				S3_0_C15_C1_0
 #define CORTEX_A510_CPUACTLR_EL1_BIT_17				(ULL(1) << 17)
 #define CORTEX_A510_CPUACTLR_EL1_BIT_38				(ULL(1) << 38)
+#define CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_DISABLE	U(1)
+#define CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_SHIFT		U(18)
+#define CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_WIDTH		U(1)
+#define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_DISABLE		U(1)
+#define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT		U(18)
+#define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH		U(1)
 
-#endif /* CORTEX_A510_H */
\ No newline at end of file
+#endif /* CORTEX_A510_H */
diff --git a/include/lib/cpus/aarch64/cortex_a53.h b/include/lib/cpus/aarch64/cortex_a53.h
index 54e646c..18796ee 100644
--- a/include/lib/cpus/aarch64/cortex_a53.h
+++ b/include/lib/cpus/aarch64/cortex_a53.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a55.h b/include/lib/cpus/aarch64/cortex_a55.h
index 60ed957..0a1593a 100644
--- a/include/lib/cpus/aarch64/cortex_a55.h
+++ b/include/lib/cpus/aarch64/cortex_a55.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a57.h b/include/lib/cpus/aarch64/cortex_a57.h
index dc40e31..19ac513 100644
--- a/include/lib/cpus/aarch64/cortex_a57.h
+++ b/include/lib/cpus/aarch64/cortex_a57.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index bef9337..a00f6d6 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a73.h b/include/lib/cpus/aarch64/cortex_a73.h
index 271a333..ede76d1 100644
--- a/include/lib/cpus/aarch64/cortex_a73.h
+++ b/include/lib/cpus/aarch64/cortex_a73.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a75.h b/include/lib/cpus/aarch64/cortex_a75.h
index e5ca1ba..ca79991 100644
--- a/include/lib/cpus/aarch64/cortex_a75.h
+++ b/include/lib/cpus/aarch64/cortex_a75.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h
index 74fb6e9..b2ec8aa 100644
--- a/include/lib/cpus/aarch64/cortex_a76.h
+++ b/include/lib/cpus/aarch64/cortex_a76.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,7 @@
 #define CORTEX_A76_CPUACTLR2_EL1				S3_0_C15_C1_1
 
 #define CORTEX_A76_CPUACTLR2_EL1_BIT_2				(ULL(1) << 2)
+#define CORTEX_A76_CPUACTLR2_EL1_BIT_59 			(ULL(1) << 59)
 
 #define CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE	(ULL(1) << 16)
 
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index a9b4546..39717a3 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index 66f565d..2984f82 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index b68ec1e..4ada845 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/cpus/aarch64/cortex_gelas.h b/include/lib/cpus/aarch64/cortex_gelas.h
new file mode 100644
index 0000000..90bb78f
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_gelas.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_GELAS_H
+#define CORTEX_GELAS_H
+
+#include <lib/utils_def.h>
+
+#define CORTEX_GELAS_MIDR				U(0x410FD8B0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_GELAS_IMP_CPUECTLR_EL1			S3_0_C15_C1_5
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_GELAS_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_GELAS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define CORTEX_GELAS_SVCRSM				S0_3_C4_C2_3
+#define CORTEX_GELAS_SVCRZA				S0_3_C4_C4_3
+
+#endif /* CORTEX_GELAS_H */
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index ceafe66..e648734 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,4 +31,11 @@
 #define CORTEX_X3_CPUACTLR2_EL1			S3_0_C15_C1_1
 #define CORTEX_X3_CPUACTLR2_EL1_BIT_36		(ULL(1) << 36)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR5_EL1			S3_0_C15_C8_0
+#define CORTEX_X3_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
+#define CORTEX_X3_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
+
 #endif /* CORTEX_X3_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 404b7f9..6faef5d 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -444,6 +444,19 @@
 .endm
 
 /*
+ * BFI : Inserts bitfield into a system register.
+ *
+ * BFI{cond} Rd, Rn, #lsb, #width
+ */
+.macro sysreg_bitfield_insert _reg:req, _src:req, _lsb:req, _width:req
+	/* Source value for BFI */
+	mov	x1, #\_src
+	mrs	x0, \_reg
+	bfi	x0, x1, #\_lsb, #\_width
+	msr	\_reg, x0
+.endm
+
+/*
  * Apply erratum
  *
  * _cpu:
@@ -459,15 +472,25 @@
  * _chosen:
  *	Compile time flag on whether the erratum is included
  *
+ * _get_rev:
+ *	Optional parameter that determines whether to insert a call to the CPU revision fetching
+ *	procedure. Stores the result of this in the temporary register x10.
+ *
- * clobbers: x0-x9 (PCS compliant)
+ * clobbers: x0-x10 (PCS compliant)
  */
-.macro apply_erratum _cpu:req, _cve:req, _id:req, _chosen:req
-	.if \_chosen
+.macro apply_erratum _cpu:req, _cve:req, _id:req, _chosen:req, _get_rev=GET_CPU_REV
+	.if (\_chosen & \_get_rev)
 		mov	x9, x30
 		bl	cpu_get_rev_var
+		mov	x10, x0
+	.elseif (\_chosen)
+		mov	x9, x30
+		mov	x0, x10
+	.endif
+
+	.if \_chosen
 		bl	erratum_\_cpu\()_\_id\()_wa
 		mov	x30, x9
-
 	.endif
 .endm
 
diff --git a/include/lib/cpus/aarch64/cpuamu.h b/include/lib/cpus/aarch64/cpuamu.h
index 463f890..cb004bf 100644
--- a/include/lib/cpus/aarch64/cpuamu.h
+++ b/include/lib/cpus/aarch64/cpuamu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h
index 24b6a87..84ab6bb 100644
--- a/include/lib/cpus/aarch64/denver.h
+++ b/include/lib/cpus/aarch64/denver.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/neoverse_e1.h b/include/lib/cpus/aarch64/neoverse_e1.h
index 96b4661..6e784f6 100644
--- a/include/lib/cpus/aarch64/neoverse_e1.h
+++ b/include/lib/cpus/aarch64/neoverse_e1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h
index b6b8d8d..0ba5ad1 100644
--- a/include/lib/cpus/aarch64/neoverse_n1.h
+++ b/include/lib/cpus/aarch64/neoverse_n1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index cb1be5b..0d50854 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -43,9 +43,17 @@
 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_40		(ULL(1) << 40)
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR3_EL1			S3_0_C15_C1_2
+#define NEOVERSE_N2_CPUACTLR3_EL1_BIT_47		(ULL(1) << 47)
+
+/*******************************************************************************
  * CPU Auxiliary Control register 5 specific definitions.
  ******************************************************************************/
 #define NEOVERSE_N2_CPUACTLR5_EL1			S3_0_C15_C8_0
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44		(ULL(1) << 44)
 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_13		(ULL(1) << 13)
 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_17		(ULL(1) << 17)
diff --git a/include/lib/cpus/aarch64/neoverse_poseidon.h b/include/lib/cpus/aarch64/neoverse_poseidon.h
index 798ecd1..202ef5c 100644
--- a/include/lib/cpus/aarch64/neoverse_poseidon.h
+++ b/include/lib/cpus/aarch64/neoverse_poseidon.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index 3d48623..d618994 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,7 +42,10 @@
 #define NEOVERSE_V1_ACTLR2_EL1_BIT_40				(ULL(1) << 40)
 
 #define NEOVERSE_V1_ACTLR3_EL1					S3_0_C15_C1_2
+#define NEOVERSE_V1_ACTLR3_EL1_BIT_47				(ULL(1) << 47)
 
 #define NEOVERSE_V1_ACTLR5_EL1					S3_0_C15_C9_0
+#define NEOVERSE_V1_ACTLR5_EL1_BIT_55				(ULL(1) << 55)
+#define NEOVERSE_V1_ACTLR5_EL1_BIT_56				(ULL(1) << 56)
 
 #endif /* NEOVERSE_V1_H */
diff --git a/include/lib/cpus/aarch64/nevis.h b/include/lib/cpus/aarch64/nevis.h
new file mode 100644
index 0000000..7006a29
--- /dev/null
+++ b/include/lib/cpus/aarch64/nevis.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEVIS_H
+#define NEVIS_H
+
+#define NEVIS_MIDR					U(0x410FD8A0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEVIS_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEVIS_IMP_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+#endif /* NEVIS_H */
diff --git a/include/lib/cpus/aarch64/qemu_max.h b/include/lib/cpus/aarch64/qemu_max.h
index 14da170..58923d2 100644
--- a/include/lib/cpus/aarch64/qemu_max.h
+++ b/include/lib/cpus/aarch64/qemu_max.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index b280435..2080898 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -66,6 +66,9 @@
 #define NO_ASSERT		0
 #define NO_APPLY_AT_RESET	0
 #define APPLY_AT_RESET		1
+#define GET_CPU_REV		1
+#define NO_GET_CPU_REV		0
+
 /* useful for errata that end up always being worked around */
 #define ERRATUM_ALWAYS_CHOSEN	1
 
diff --git a/include/lib/cpus/wa_cve_2017_5715.h b/include/lib/cpus/wa_cve_2017_5715.h
index 940fc65..2ad56e1 100644
--- a/include/lib/cpus/wa_cve_2017_5715.h
+++ b/include/lib/cpus/wa_cve_2017_5715.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/wa_cve_2018_3639.h b/include/lib/cpus/wa_cve_2018_3639.h
index e37db37..5a7c9bf 100644
--- a/include/lib/cpus/wa_cve_2018_3639.h
+++ b/include/lib/cpus/wa_cve_2018_3639.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/cpus/wa_cve_2022_23960.h b/include/lib/cpus/wa_cve_2022_23960.h
index 35b3fd8..50c0f76 100644
--- a/include/lib/cpus/wa_cve_2022_23960.h
+++ b/include/lib/cpus/wa_cve_2022_23960.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/el3_runtime/aarch32/context.h b/include/lib/el3_runtime/aarch32/context.h
index df77c0f..3b698e3 100644
--- a/include/lib/el3_runtime/aarch32/context.h
+++ b/include/lib/el3_runtime/aarch32/context.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index e6af43e..ebd0e30 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -516,15 +516,6 @@
 void el1_sysregs_context_save(el1_sysregs_t *regs);
 void el1_sysregs_context_restore(el1_sysregs_t *regs);
 
-#if CTX_INCLUDE_EL2_REGS
-void el2_sysregs_context_save_common(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_common(el2_sysregs_t *regs);
-#if CTX_INCLUDE_MTE_REGS
-void el2_sysregs_context_save_mte(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_mte(el2_sysregs_t *regs);
-#endif /* CTX_INCLUDE_MTE_REGS */
-#endif /* CTX_INCLUDE_EL2_REGS */
-
 #if CTX_INCLUDE_FPREGS
 void fpregs_context_save(fp_regs_t *regs);
 void fpregs_context_restore(fp_regs_t *regs);
diff --git a/include/lib/el3_runtime/pubsub_events.h b/include/lib/el3_runtime/pubsub_events.h
index 5012082..d0c0502 100644
--- a/include/lib/el3_runtime/pubsub_events.h
+++ b/include/lib/el3_runtime/pubsub_events.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index de476e4..09d8dee 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,13 +16,21 @@
 
 #if ENABLE_FEAT_AMU
 #if __aarch64__
-void amu_enable(bool el2_unused, cpu_context_t *ctx);
+void amu_enable(cpu_context_t *ctx);
+void amu_init_el3(void);
+void amu_init_el2_unused(void);
 #else
 void amu_enable(bool el2_unused);
 #endif
 #else
 #if __aarch64__
-static inline void amu_enable(bool el2_unused, cpu_context_t *ctx)
+void amu_enable(cpu_context_t *ctx)
+{
+}
+void amu_init_el3(void)
+{
+}
+void amu_init_el2_unused(void)
 {
 }
 #else
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
index 9ee2444..194efba 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.h
@@ -8,9 +8,9 @@
 #define BRBE_H
 
 #if ENABLE_BRBE_FOR_NS
-void brbe_enable(void);
+void brbe_init_el3(void);
 #else
-static inline void brbe_enable(void)
+static inline void brbe_init_el3(void)
 {
 }
 #endif /* ENABLE_BRBE_FOR_NS */
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
index 4327278..e5438ce 100644
--- a/include/lib/extensions/mpam.h
+++ b/include/lib/extensions/mpam.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,11 +10,15 @@
 #include <stdbool.h>
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
-void mpam_enable(bool el2_unused);
+void mpam_init_el3(void);
+void mpam_init_el2_unused(void);
 #else
-static inline void mpam_enable(bool el2_unused)
+static inline void mpam_init_el3(void)
 {
 }
-#endif
+static inline void mpam_init_el2_unused(void)
+{
+}
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
 #endif /* MPAM_H */
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
index 2e780de..dbc2226 100644
--- a/include/lib/extensions/pauth.h
+++ b/include/lib/extensions/pauth.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/extensions/pmuv3.h b/include/lib/extensions/pmuv3.h
index 5d5d055..62fee7b 100644
--- a/include/lib/extensions/pmuv3.h
+++ b/include/lib/extensions/pmuv3.h
@@ -9,7 +9,7 @@
 
 #include <context.h>
 
-void pmuv3_disable_el3(void);
+void pmuv3_init_el3(void);
 
 #ifdef __aarch64__
 void pmuv3_enable(cpu_context_t *ctx);
diff --git a/include/lib/extensions/ras.h b/include/lib/extensions/ras.h
index 793ab9f..6997da0 100644
--- a/include/lib/extensions/ras.h
+++ b/include/lib/extensions/ras.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/extensions/ras_arch.h b/include/lib/extensions/ras_arch.h
index 55760b0..e0aee50 100644
--- a/include/lib/extensions/ras_arch.h
+++ b/include/lib/extensions/ras_arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
index 0e9c4b9..dbefdfc 100644
--- a/include/lib/extensions/sme.h
+++ b/include/lib/extensions/sme.h
@@ -22,11 +22,19 @@
 
 #if ENABLE_SME_FOR_NS
 void sme_enable(cpu_context_t *context);
+void sme_init_el3(void);
+void sme_init_el2_unused(void);
 void sme_disable(cpu_context_t *context);
 #else
 static inline void sme_enable(cpu_context_t *context)
 {
 }
+static inline void sme_init_el3(void)
+{
+}
+static inline void sme_init_el2_unused(void)
+{
+}
 static inline void sme_disable(cpu_context_t *context)
 {
 }
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 02fccae..7b39037 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,15 +10,19 @@
 #include <stdbool.h>
 
 #if ENABLE_SPE_FOR_NS
-void spe_enable(bool el2_unused);
+void spe_init_el3(void);
+void spe_init_el2_unused(void);
 void spe_disable(void);
 #else
-static inline void spe_enable(bool el2_unused)
+static inline void spe_init_el3(void)
 {
 }
+static inline void spe_init_el2_unused(void)
+{
+}
 static inline void spe_disable(void)
 {
 }
-#endif
+#endif /* ENABLE_SPE_FOR_NS */
 
 #endif /* SPE_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 1faed2d..fc76a16 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -11,11 +11,15 @@
 
 #if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS)
 void sve_enable(cpu_context_t *context);
+void sve_init_el2_unused(void);
 void sve_disable(cpu_context_t *context);
 #else
 static inline void sve_enable(cpu_context_t *context)
 {
 }
+static inline void sve_init_el2_unused(void)
+{
+}
 static inline void sve_disable(cpu_context_t *context)
 {
 }
diff --git a/include/lib/extensions/sys_reg_trace.h b/include/lib/extensions/sys_reg_trace.h
index 5915c55..beda88a 100644
--- a/include/lib/extensions/sys_reg_trace.h
+++ b/include/lib/extensions/sys_reg_trace.h
@@ -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
  */
@@ -10,10 +10,13 @@
 #include <context.h>
 
 #if ENABLE_SYS_REG_TRACE_FOR_NS
+
 #if __aarch64__
 void sys_reg_trace_enable(cpu_context_t *context);
+void sys_reg_trace_disable(cpu_context_t *context);
+void sys_reg_trace_init_el2_unused(void);
 #else
-void sys_reg_trace_enable(void);
+void sys_reg_trace_init_el3(void);
 #endif /* __aarch64__ */
 
 #else /* !ENABLE_SYS_REG_TRACE_FOR_NS */
@@ -22,11 +25,18 @@
 static inline void sys_reg_trace_enable(cpu_context_t *context)
 {
 }
+static inline void sys_reg_trace_disable(cpu_context_t *context)
+{
+}
+static inline void sys_reg_trace_init_el2_unused(void)
+{
+}
 #else
-static inline void sys_reg_trace_enable(void)
+static inline void sys_reg_trace_init_el3(void)
 {
 }
 #endif /* __aarch64__ */
+
 #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
 
 #endif /* SYS_REG_TRACE_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 861a4ad..0bed433 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -8,9 +8,13 @@
 #define TRBE_H
 
 #if ENABLE_TRBE_FOR_NS
-void trbe_enable(void);
+void trbe_init_el3(void);
+void trbe_init_el2_unused(void);
 #else
-static inline void trbe_enable(void)
+static inline void trbe_init_el3(void)
+{
+}
+static inline void trbe_init_el2_unused(void)
 {
 }
 #endif /* ENABLE_TRBE_FOR_NS */
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index 91a9615..1ac7cda 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -8,9 +8,13 @@
 #define TRF_H
 
 #if ENABLE_TRF_FOR_NS
-void trf_enable(void);
+void trf_init_el3(void);
+void trf_init_el2_unused(void);
 #else
-static inline void trf_enable(void)
+static inline void trf_init_el3(void)
+{
+}
+static inline void trf_init_el2_unused(void)
 {
 }
 #endif /* ENABLE_TRF_FOR_NS */
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index 3762021..5b54c04 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h
index db98b68..541a396 100644
--- a/include/lib/fconf/fconf_tbbr_getter.h
+++ b/include/lib/fconf/fconf_tbbr_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch32/endian_.h b/include/lib/libc/aarch32/endian_.h
index 0cf2c75..edca496 100644
--- a/include/lib/libc/aarch32/endian_.h
+++ b/include/lib/libc/aarch32/endian_.h
@@ -32,7 +32,7 @@
  * $FreeBSD$
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch32/inttypes_.h b/include/lib/libc/aarch32/inttypes_.h
index ef3fb8f..0888bf0 100644
--- a/include/lib/libc/aarch32/inttypes_.h
+++ b/include/lib/libc/aarch32/inttypes_.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch32/limits_.h b/include/lib/libc/aarch32/limits_.h
index a67ec53..5b0516a 100644
--- a/include/lib/libc/aarch32/limits_.h
+++ b/include/lib/libc/aarch32/limits_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch32/stddef_.h b/include/lib/libc/aarch32/stddef_.h
index 36dc20b..14ed094 100644
--- a/include/lib/libc/aarch32/stddef_.h
+++ b/include/lib/libc/aarch32/stddef_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h
index dafe142..6e2deed 100644
--- a/include/lib/libc/aarch32/stdint_.h
+++ b/include/lib/libc/aarch32/stdint_.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch32/stdio_.h b/include/lib/libc/aarch32/stdio_.h
index 5e49425..7042664 100644
--- a/include/lib/libc/aarch32/stdio_.h
+++ b/include/lib/libc/aarch32/stdio_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch64/endian_.h b/include/lib/libc/aarch64/endian_.h
index 7c79fd4..58273d7 100644
--- a/include/lib/libc/aarch64/endian_.h
+++ b/include/lib/libc/aarch64/endian_.h
@@ -32,7 +32,7 @@
  * $FreeBSD$
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch64/inttypes_.h b/include/lib/libc/aarch64/inttypes_.h
index f25882f..6109084 100644
--- a/include/lib/libc/aarch64/inttypes_.h
+++ b/include/lib/libc/aarch64/inttypes_.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch64/limits_.h b/include/lib/libc/aarch64/limits_.h
index 1bb0681..834439e 100644
--- a/include/lib/libc/aarch64/limits_.h
+++ b/include/lib/libc/aarch64/limits_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch64/setjmp_.h b/include/lib/libc/aarch64/setjmp_.h
index f880a17..a7d0b5c 100644
--- a/include/lib/libc/aarch64/setjmp_.h
+++ b/include/lib/libc/aarch64/setjmp_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch64/stddef_.h b/include/lib/libc/aarch64/stddef_.h
index 6ecc606..963048e 100644
--- a/include/lib/libc/aarch64/stddef_.h
+++ b/include/lib/libc/aarch64/stddef_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h
index 56e9f1b..34a75ec 100644
--- a/include/lib/libc/aarch64/stdint_.h
+++ b/include/lib/libc/aarch64/stdint_.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/aarch64/stdio_.h b/include/lib/libc/aarch64/stdio_.h
index afaeadc..331bcaa 100644
--- a/include/lib/libc/aarch64/stdio_.h
+++ b/include/lib/libc/aarch64/stdio_.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/arm_acle.h b/include/lib/libc/arm_acle.h
index eb08552..d1bc0f9 100644
--- a/include/lib/libc/arm_acle.h
+++ b/include/lib/libc/arm_acle.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 ARM Limited
+ * Copyright (c) 2021 Arm Limited
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
diff --git a/include/lib/libc/assert.h b/include/lib/libc/assert.h
index 462bb43..acfd147 100644
--- a/include/lib/libc/assert.h
+++ b/include/lib/libc/assert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
index 2423f38..b11d072 100644
--- a/include/lib/libc/cdefs.h
+++ b/include/lib/libc/cdefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/endian.h b/include/lib/libc/endian.h
index 4100f57..9c9fd58 100644
--- a/include/lib/libc/endian.h
+++ b/include/lib/libc/endian.h
@@ -28,7 +28,7 @@
  * $FreeBSD$
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/errno.h b/include/lib/libc/errno.h
index 029912f..b536fe9 100644
--- a/include/lib/libc/errno.h
+++ b/include/lib/libc/errno.h
@@ -37,7 +37,7 @@
  * $FreeBSD$
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/inttypes.h b/include/lib/libc/inttypes.h
index 6ad1c9e..344b71c 100644
--- a/include/lib/libc/inttypes.h
+++ b/include/lib/libc/inttypes.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/limits.h b/include/lib/libc/limits.h
index 41bb658..c5c8764 100644
--- a/include/lib/libc/limits.h
+++ b/include/lib/libc/limits.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/setjmp.h b/include/lib/libc/setjmp.h
index be8e2c0..871c868 100644
--- a/include/lib/libc/setjmp.h
+++ b/include/lib/libc/setjmp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/stdarg.h b/include/lib/libc/stdarg.h
index e260b9b..2d1f785 100644
--- a/include/lib/libc/stdarg.h
+++ b/include/lib/libc/stdarg.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/stdbool.h b/include/lib/libc/stdbool.h
index b58334c..c2c9b22 100644
--- a/include/lib/libc/stdbool.h
+++ b/include/lib/libc/stdbool.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/libc/stddef.h b/include/lib/libc/stddef.h
index 58a519e..aaad673 100644
--- a/include/lib/libc/stddef.h
+++ b/include/lib/libc/stddef.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h
index e96a25c..88502e7 100644
--- a/include/lib/libc/stdint.h
+++ b/include/lib/libc/stdint.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h
index ba13683..5ceaf68 100644
--- a/include/lib/libc/stdio.h
+++ b/include/lib/libc/stdio.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h
index 4641e56..4e5a824 100644
--- a/include/lib/libc/stdlib.h
+++ b/include/lib/libc/stdlib.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 7ddeed9..8129404 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2020, Arm Limited and Contributors.
  * Portions copyright (c) 2023, Intel Corporation. All rights reserved.
  * All rights reserved.
  */
diff --git a/include/lib/libc/time.h b/include/lib/libc/time.h
index c1c95e5..e1eb2a5 100644
--- a/include/lib/libc/time.h
+++ b/include/lib/libc/time.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/include/lib/mmio.h b/include/lib/mmio.h
index 3242a7c..591d7b6 100644
--- a/include/lib/mmio.h
+++ b/include/lib/mmio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2014, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/object_pool.h b/include/lib/object_pool.h
index 66e8c47..49584eb 100644
--- a/include/lib/object_pool.h
+++ b/include/lib/object_pool.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h
index 8224d50..e1e9d80 100644
--- a/include/lib/optee_utils.h
+++ b/include/lib/optee_utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/pmf/aarch64/pmf_asm_macros.S b/include/lib/pmf/aarch64/pmf_asm_macros.S
index 5f3e6b7..792ede9 100644
--- a/include/lib/pmf/aarch64/pmf_asm_macros.S
+++ b/include/lib/pmf/aarch64/pmf_asm_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index fa990d2..9d901e2 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index 01cc179..f5f040b 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index be78bae..7183112 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -8,6 +8,9 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
+/******** RSS_SP_CRYPTO ********/
+#define RSS_CRYPTO_HANDLE				(0x40000100U)
+
 /******** RSS_SP_PLATFORM ********/
 #define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
 
diff --git a/include/lib/psa/rss_crypto_defs.h b/include/lib/psa/rss_crypto_defs.h
new file mode 100644
index 0000000..b8c7426
--- /dev/null
+++ b/include/lib/psa/rss_crypto_defs.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSS_CRYPTO_DEFS_H
+#define RSS_CRYPTO_DEFS_H
+
+/* Declares types that encode errors, algorithms, key types, policies, etc. */
+#include "psa/crypto_types.h"
+
+/*
+ * Value identifying export public key function API, used to dispatch the request
+ * to the corresponding API implementation in the Crypto service backend.
+ *
+ */
+#define RSS_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x701)
+
+/*
+ * The persistent key identifiers for RSS builtin keys.
+ */
+enum rss_key_id_builtin_t {
+	RSS_BUILTIN_KEY_ID_HOST_S_ROTPK = 0x7FFF816Cu,
+	RSS_BUILTIN_KEY_ID_HOST_NS_ROTPK,
+	RSS_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
+};
+
+/*
+ * This type is used to overcome a limitation within RSS firmware in the number of maximum
+ * IOVECs it can use especially in psa_aead_encrypt and psa_aead_decrypt.
+ */
+#define RSS_CRYPTO_MAX_NONCE_LENGTH (16u)
+struct rss_crypto_aead_pack_input {
+	uint8_t nonce[RSS_CRYPTO_MAX_NONCE_LENGTH];
+	uint32_t nonce_length;
+};
+
+/*
+ * Structure used to pack non-pointer types in a call
+ */
+struct rss_crypto_pack_iovec {
+	psa_key_id_t key_id;	/* Key id */
+	psa_algorithm_t alg;	/* Algorithm */
+	uint32_t op_handle;	/* Frontend context handle associated
+				   to a multipart operation */
+	uint32_t capacity;	/* Key derivation capacity */
+	uint32_t ad_length;	/* Additional Data length for multipart AEAD */
+	uint32_t plaintext_length;	/* Plaintext length for multipart AEAD */
+	struct rss_crypto_aead_pack_input aead_in;	/* Packs AEAD-related inputs */
+	uint16_t function_id;	/* Used to identify the function in the API dispatcher
+				   to the service backend. See rss_crypto_func_sid for
+				   detail */
+	uint16_t step;		/* Key derivation step */
+};
+
+#endif /* RSS_CRYPTO_DEFS_H */
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rss_platform_api.h
index 1dd7d05..8f74a51 100644
--- a/include/lib/psa/rss_platform_api.h
+++ b/include/lib/psa/rss_platform_api.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include "psa/error.h"
+#include <rss_crypto_defs.h>
 
 #define RSS_PLATFORM_API_ID_NV_READ       (1010)
 #define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
@@ -41,4 +42,19 @@
 rss_platform_nv_counter_read(uint32_t counter_id,
 		uint32_t size, uint8_t *val);
 
+/*
+ * Reads the public key or the public part of a key pair in binary format.
+ *
+ * key		Identifier of the key to export.
+ * data		Buffer where the key data is to be written.
+ * data_size	Size of the data buffer in bytes.
+ * data_length	On success, the number of bytes that make up the key data.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_key_read(enum rss_key_id_builtin_t key, uint8_t *data,
+		size_t data_size, size_t *data_length);
+
 #endif /* RSS_PLATFORM_API_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 01dc3cb..c40f955 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/runtime_instr.h b/include/lib/runtime_instr.h
index 303f27e..65fafa7 100644
--- a/include/lib/runtime_instr.h
+++ b/include/lib/runtime_instr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/semihosting.h b/include/lib/semihosting.h
index 24b030c..5c72e8b 100644
--- a/include/lib/semihosting.h
+++ b/include/lib/semihosting.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2014, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index fb2b3a2..8fd6093 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h
index 0bf3ee0..9fd3fc6 100644
--- a/include/lib/spinlock.h
+++ b/include/lib/spinlock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/utils.h b/include/lib/utils.h
index 17ee936..ce76de2 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 63eda63..ba52bc6 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/include/lib/xlat_mpu/xlat_mpu.h b/include/lib/xlat_mpu/xlat_mpu.h
index 252b92c..3a470ad 100644
--- a/include/lib/xlat_mpu/xlat_mpu.h
+++ b/include/lib/xlat_mpu/xlat_mpu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
index 30eb5e9..42a48f4 100644
--- a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
index 3014c8f..6c0d73b 100644
--- a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h
index 269afd2..fabc494 100644
--- a/include/lib/xlat_tables/xlat_mmu_helpers.h
+++ b/include/lib/xlat_tables/xlat_mmu_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_tables.h b/include/lib/xlat_tables/xlat_tables.h
index a156969..24f833c 100644
--- a/include/lib/xlat_tables/xlat_tables.h
+++ b/include/lib/xlat_tables/xlat_tables.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
index 0ce0cac..46e058c 100644
--- a/include/lib/xlat_tables/xlat_tables_arch.h
+++ b/include/lib/xlat_tables/xlat_tables_arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_tables_compat.h b/include/lib/xlat_tables/xlat_tables_compat.h
index 5f28195..3877c91 100644
--- a/include/lib/xlat_tables/xlat_tables_compat.h
+++ b/include/lib/xlat_tables/xlat_tables_compat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 4d16ced..64fe5ef 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index 62f853d..992c94e 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/lib/zlib/tf_gunzip.h b/include/lib/zlib/tf_gunzip.h
index 741ba50..9435860 100644
--- a/include/lib/zlib/tf_gunzip.h
+++ b/include/lib/zlib/tf_gunzip.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index bf1f93a..9426ac7 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -782,6 +782,9 @@
 #define PLAT_SDEI_CRITICAL_PRI		0x60
 #define PLAT_SDEI_NORMAL_PRI		0x70
 
+/* CPU Fault Handling Interrupt(FHI) PPI interrupt ID */
+#define PLAT_CORE_FAULT_IRQ		17
+
 /* ARM platforms use 3 upper bits of secure interrupt priority */
 #define PLAT_PRI_BITS			3
 
diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h
index cafbc3e..d45c269 100644
--- a/include/plat/arm/common/fconf_ethosn_getter.h
+++ b/include/plat/arm/common/fconf_ethosn_getter.h
@@ -57,8 +57,6 @@
 	struct ethosn_device_t devices[ETHOSN_DEV_NUM_MAX];
 };
 
-int fconf_populate_arm_ethosn(uintptr_t config);
-
 extern struct ethosn_config_t ethosn_config;
 
 #endif /* FCONF_ETHOSN_GETTER_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index e8461f5..2fdbfb7 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -39,6 +39,20 @@
  *   - Region 1 with secure access only;
  *   - the remaining DRAM regions access from the given Non-Secure masters.
  ******************************************************************************/
+
+#if ENABLE_RME
+#define ARM_TZC_RME_REGIONS_DEF						    \
+	{ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},\
+	{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0},	    \
+	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS,	    \
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				    \
+	/* Realm and Shared area share the same PAS */		    \
+	{ARM_REALM_BASE, ARM_EL3_RMM_SHARED_END, ARM_TZC_NS_DRAM_S_ACCESS,  \
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				    \
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	    \
+		PLAT_ARM_TZC_NS_DEV_ACCESS}
+#endif
+
 #if SPM_MM
 #define ARM_TZC_REGIONS_DEF						\
 	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
@@ -52,16 +66,16 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #elif ENABLE_RME
-#define ARM_TZC_REGIONS_DEF						    \
-	{ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},\
-	{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0},	    \
-	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS,	    \
-		PLAT_ARM_TZC_NS_DEV_ACCESS},				    \
-	/* Realm and Shared area share the same PAS */		    \
-	{ARM_REALM_BASE, ARM_EL3_RMM_SHARED_END, ARM_TZC_NS_DRAM_S_ACCESS,  \
-		PLAT_ARM_TZC_NS_DEV_ACCESS},				    \
-	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	    \
-		PLAT_ARM_TZC_NS_DEV_ACCESS}
+#if (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) &&  \
+MEASURED_BOOT
+#define ARM_TZC_REGIONS_DEF					        \
+	ARM_TZC_RME_REGIONS_DEF,					\
+	{ARM_EVENT_LOG_DRAM1_BASE, ARM_EVENT_LOG_DRAM1_END,             \
+		TZC_REGION_S_RDWR, 0}
+#else
+#define ARM_TZC_REGIONS_DEF					        \
+	ARM_TZC_RME_REGIONS_DEF
+#endif
 
 #else
 #define ARM_TZC_REGIONS_DEF						\
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index d146a29..e024d91 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -146,6 +146,8 @@
 int plat_mboot_measure_critical_data(unsigned int critical_data_id,
 				     const void *base,
 				     size_t size);
+int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+			   size_t pk_len);
 #else
 static inline int plat_mboot_measure_image(unsigned int image_id __unused,
 					   image_info_t *image_data __unused)
@@ -159,6 +161,12 @@
 {
 	return 0;
 }
+static inline int plat_mboot_measure_key(const void *pk_oid __unused,
+					 const void *pk_ptr __unused,
+					 size_t pk_len __unused)
+{
+	return 0;
+}
 #endif /* MEASURED_BOOT */
 
 /*******************************************************************************
diff --git a/include/plat/nuvoton/common/npcm845x_arm_def.h b/include/plat/nuvoton/common/npcm845x_arm_def.h
new file mode 100644
index 0000000..faddb88
--- /dev/null
+++ b/include/plat/nuvoton/common/npcm845x_arm_def.h
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2017-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NPCM845x_ARM_DEF_H
+#define NPCM845x_ARM_DEF_H
+
+#include <arch.h>
+#include <common/interrupt_props.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+/* This flag will add zones to the MMU so that it will be possible to debug */
+#ifdef NPCM845X_DEBUG
+#define ALLOW_DEBUG_MMU
+#undef ALLOW_DEBUG_MMU
+#endif /* NPCM845X_DEBUG */
+
+#undef CONFIG_TARGET_ARBEL_PALLADIUM
+/******************************************************************************
+ * Definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Root of trust key hash lengths
+ */
+#define ARM_ROTPK_HEADER_LEN		19
+#define ARM_ROTPK_HASH_LEN		32
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
+
+/* No need for system because we have only one cluster */
+#define ARM_SYSTEM_COUNT		U(0)
+
+#define ARM_CACHE_WRITEBACK_SHIFT	6
+
+/*
+ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels.
+ * The power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+/* In NPCM845x - refers to cores */
+#define ARM_PWR_LVL0		MPIDR_AFFLVL0
+
+/* In NPCM845x - refers to cluster */
+#define ARM_PWR_LVL1		MPIDR_AFFLVL1
+
+/* No need for additional settings because the platform doesn't have system */
+
+/*
+ * Macros for local power states in ARM platforms encoded by State-ID field
+ * within the power-state parameter.
+ */
+#define NPCM845x_PLAT_PRIMARY_CPU		U(0x0)
+#define NPCM845x_CLUSTER_COUNT		U(1)
+
+#ifdef SECONDARY_BRINGUP
+#define NPCM845x_MAX_CPU_PER_CLUSTER	U(2)
+#define NPCM845x_PLATFORM_CORE_COUNT	U(2)
+#define NPCM845x_PLATFORM_CLUSTER0_CORE_COUNT	U(2)
+#else
+#define NPCM845x_MAX_CPU_PER_CLUSTER	U(4)
+#define NPCM845x_PLATFORM_CORE_COUNT	U(4)
+#define NPCM845x_PLATFORM_CLUSTER0_CORE_COUNT	U(4)
+#endif /* SECONDARY_BRINGUP */
+
+#define NPCM845x_SYSTEM_COUNT					U(0)
+
+/* Memory mapping for NPCM845x */
+#define NPCM845x_REG_BASE			0xf0000000
+#define NPCM845x_REG_SIZE			0x0ff16000
+
+/*
+ *				DRAM
+ *	0x3fffffff +-------------+
+ *	           |     BL33    | (non-secure)
+ *	0x06200000 +-------------+
+ *	           | BL32 SHARED | (non-secure)
+ *	0x06000000 +-------------+
+ *	           |     BL32    | (secure)
+ *	0x02100000 +-------------+
+ *	           |     BL31    | (secure)
+ *	0x02000000 +-------------+
+ *	           |             | (non-secure)
+ *	0x00000000 +-------------+
+ *
+ *				 Trusted ROM
+ *	0xfff50000 +-------------+
+ *	           |  BL1 (ro)   |
+ *	0xfff40000 +-------------+
+ */
+
+#define ARM_DRAM1_BASE			ULL(0x00000000)
+#ifndef CONFIG_TARGET_ARBEL_PALLADIUM
+/*
+ * Although npcm845x is 4G,
+ * consider only 2G Trusted Firmware memory allocation
+ */
+#define ARM_DRAM1_SIZE			ULL(0x37000000)
+#else
+#define ARM_DRAM1_SIZE			ULL(0x10000000)
+#define ARM_DRAM1_END			(ARM_DRAM1_BASE + ARM_DRAM1_SIZE - 1U)
+#endif /* CONFIG_TARGET_ARBEL_PALLADIUM */
+
+/*
+ * The top 16MB of DRAM1 is configured as secure access only using the TZC
+ *	- SCP TZC DRAM: If present, DRAM reserved for SCP use
+ *	- AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
+ */
+
+/* Check for redundancy */
+#ifdef NPCM845X_DEBUG
+#define PLAT_ARM_NS_IMAGE_BASE	0x0
+#endif /* NPCM845X_DEBUG */
+
+#define ARM_TZC_DRAM1_SIZE		UL(0x01000000)
+#define ARM_SCP_TZC_DRAM1_SIZE		PLAT_ARM_SCP_TZC_DRAM1_SIZE
+#define ARM_SCP_TZC_DRAM1_END		(ARM_SCP_TZC_DRAM1_BASE +	\
+					ARM_SCP_TZC_DRAM1_SIZE - 1U)
+
+/*
+ * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime
+ * firmware. This region is meant to be NOLOAD and will not be zero
+ * initialized. Data sections with the attribute `arm_el3_tzc_dram`
+ * will be placed here.
+ *
+ * NPCM845x - Currently the platform doesn't have EL3 implementation
+ * on secured DRAM.
+ */
+#define ARM_EL3_TZC_DRAM1_BASE		(ARM_SCP_TZC_DRAM1_BASE -	\
+			ARM_EL3_TZC_DRAM1_SIZE)
+#define ARM_EL3_TZC_DRAM1_SIZE		UL(0x00200000)	/* 2 MB */
+#define ARM_EL3_TZC_DRAM1_END		(ARM_EL3_TZC_DRAM1_BASE +	\
+			ARM_EL3_TZC_DRAM1_SIZE - 1U)
+
+#define ARM_AP_TZC_DRAM1_BASE		0x02100000
+#define ARM_AP_TZC_DRAM1_SIZE		(ARM_TZC_DRAM1_SIZE -	\
+			(ARM_SCP_TZC_DRAM1_SIZE + \
+			ARM_EL3_TZC_DRAM1_SIZE))
+#define ARM_AP_TZC_DRAM1_END		(ARM_AP_TZC_DRAM1_BASE +	\
+			ARM_AP_TZC_DRAM1_SIZE - 1U)
+
+/* Define the Access permissions for Secure peripherals to NS_DRAM */
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Allow Secure peripheral to read NS DRAM when integrated with CryptoCell.
+ * This is required by CryptoCell to authenticate BL33 which is loaded
+ * into the Non Secure DDR.
+ */
+#define ARM_TZC_NS_DRAM_S_ACCESS	TZC_REGION_S_RD
+#else
+#define ARM_TZC_NS_DRAM_S_ACCESS	TZC_REGION_S_NONE
+#endif /* ARM_CRYPTOCELL_INTEG */
+
+#ifdef SPD_opteed
+/*
+ * BL2 needs to map 4MB at the end of TZC_DRAM1 in order to
+ * load/authenticate the trusted os extra image. The first 512KB of
+ * TZC_DRAM1 are reserved for trusted os (OPTEE). The extra image loading
+ * for OPTEE is paged image which only include the paging part using
+ * virtual memory but without "init" data. OPTEE will copy the "init" data
+ * (from pager image) to the first 512KB of TZC_DRAM, and then copy the
+ * extra image behind the "init" data.
+ */
+#define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
+#define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
+#define BL32_BASE			ARM_AP_TZC_DRAM1_BASE
+#define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+									ARM_AP_TZC_DRAM1_SIZE)
+
+#define ARM_OPTEE_PAGEABLE_LOAD_BASE	(	\
+			ARM_AP_TZC_DRAM1_BASE + ARM_AP_TZC_DRAM1_SIZE -	\
+			ARM_OPTEE_PAGEABLE_LOAD_SIZE)
+#define ARM_OPTEE_PAGEABLE_LOAD_SIZE	UL(0x400000)
+#define ARM_OPTEE_PAGEABLE_LOAD_MEM	MAP_REGION_FLAT(	\
+			ARM_OPTEE_PAGEABLE_LOAD_BASE,	\
+			ARM_OPTEE_PAGEABLE_LOAD_SIZE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * Map the memory for the OP-TEE core (also known as OP-TEE pager
+ * when paging support is enabled).
+ */
+#define ARM_MAP_OPTEE_CORE_MEM		MAP_REGION_FLAT(	\
+			BL32_BASE, BL32_LIMIT - BL32_BASE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* SPD_opteed */
+
+#define ARM_NS_DRAM1_BASE		ARM_DRAM1_BASE
+#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -	\
+			ARM_TZC_DRAM1_SIZE)
+#define ARM_NS_DRAM1_END		(ARM_NS_DRAM1_BASE + \
+			ARM_NS_DRAM1_SIZE - 1U)
+
+/* The platform doesn't use DRAM2 but it has to have a value for calculation */
+#define ARM_DRAM2_BASE			0	/* PLAT_ARM_DRAM_BASE */
+#define ARM_DRAM2_SIZE			1	/* PLAT_ARM_DRAM_SIZE */
+#define ARM_DRAM2_END			(ARM_DRAM2_BASE + ARM_DRAM2_SIZE - 1U)
+
+#define FIRST_EXT_INTERRUPT_NUM	U(32)
+#define ARM_IRQ_SEC_PHY_TIMER	(U(29) + FIRST_EXT_INTERRUPT_NUM)
+
+#define ARM_IRQ_SEC_SGI_0		8
+#define ARM_IRQ_SEC_SGI_1		9
+#define ARM_IRQ_SEC_SGI_2		10
+#define ARM_IRQ_SEC_SGI_3		11
+#define ARM_IRQ_SEC_SGI_4		12
+#define ARM_IRQ_SEC_SGI_5		13
+#define ARM_IRQ_SEC_SGI_6		14
+#define ARM_IRQ_SEC_SGI_7		15
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties
+ * as per GICv3 terminology. On a GICv2 system or mode,
+ * the lists will be merged and treated as Group 0 interrupts.
+ */
+#define ARM_G1S_IRQ_PROPS(grp)	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE)
+
+#define ARM_G0_IRQ_PROPS(grp) \
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0,	\
+			PLAT_SDEI_NORMAL_PRI, (grp), GIC_INTR_CFG_EDGE),	\
+			INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6,	\
+			GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_EDGE)
+
+#define ARM_MAP_SHARED_RAM		MAP_REGION_FLAT(	\
+			ARM_SHARED_RAM_BASE, ARM_SHARED_RAM_SIZE,	\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#ifdef ALLOW_DEBUG_MMU
+/* In order to be able to debug,
+ * the platform needs to add BL33 and BL32 to MMU as well.
+ */
+#define ARM_MAP_NS_DRAM1		MAP_REGION_FLAT(	\
+			ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE,	\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#ifdef BL32_BASE
+#define ARM_MAP_BL32_CORE_MEM		MAP_REGION_FLAT(	\
+			BL32_BASE, BL32_LIMIT - BL32_BASE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* BL32_BASE */
+
+#ifdef NPCM845X_DEBUG
+#define ARM_MAP_SEC_BB_MEM		MAP_REGION_FLAT(	\
+			0xFFFB0000, 0x20000,	\
+			MT_MEMORY | MT_RW | MT_NS)
+#endif /* NPCM845X_DEBUG */
+#endif /* BL32_BASE */
+
+#define ARM_MAP_DRAM2			MAP_REGION_FLAT(	\
+			ARM_DRAM2_BASE, ARM_DRAM2_SIZE,	\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#define ARM_MAP_TSP_SEC_MEM		MAP_REGION_FLAT(	\
+			TSP_SEC_MEM_BASE, TSP_SEC_MEM_SIZE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+
+#if ARM_BL31_IN_DRAM
+#define ARM_MAP_BL31_SEC_DRAM		MAP_REGION_FLAT(	\
+			BL31_BASE, PLAT_ARM_MAX_BL31_SIZE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* ARM_BL31_IN_DRAM */
+
+/* Currently the platform doesn't have EL3 implementation on secured DRAM. */
+#define ARM_MAP_EL3_TZC_DRAM		MAP_REGION_FLAT(	\
+			ARM_EL3_TZC_DRAM1_BASE,	\
+			ARM_EL3_TZC_DRAM1_SIZE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+
+#if defined(SPD_spmd)
+#define ARM_MAP_TRUSTED_DRAM		MAP_REGION_FLAT(	\
+			PLAT_ARM_TRUSTED_DRAM_BASE,	\
+			PLAT_ARM_TRUSTED_DRAM_SIZE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* SPD_spmd */
+
+/*
+ * Mapping for the BL1 RW region. This mapping is needed by BL2
+ * in order to share the Mbed TLS heap. Since the heap is allocated
+ * inside BL1, it resides in the BL1 RW region. Hence, BL2 needs access
+ * to the BL1 RW region in order to be able to access the heap.
+ */
+#define ARM_MAP_BL1_RW		MAP_REGION_FLAT(	\
+			BL1_RW_BASE, BL1_RW_LIMIT - BL1_RW_BASE,	\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+/*
+ * If SEPARATE_CODE_AND_RODATA=1 the platform will define a region
+ * for each section, otherwise one region containing both sections
+ * is defined.
+ */
+#if SEPARATE_CODE_AND_RODATA
+#define ARM_MAP_BL_RO		MAP_REGION_FLAT(	\
+			BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,	\
+			MT_CODE | EL3_PAS),	\
+			MAP_REGION_FLAT(BL_RO_DATA_BASE,	\
+			BL_RO_DATA_END - BL_RO_DATA_BASE,	\
+			MT_RO_DATA | EL3_PAS)
+#else
+#define ARM_MAP_BL_RO		MAP_REGION_FLAT(	\
+			BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,	\
+			MT_CODE | EL3_PAS)
+#endif /* SEPARATE_CODE_AND_RODATA */
+
+#if USE_COHERENT_MEM
+#define ARM_MAP_BL_COHERENT_RAM		MAP_REGION_FLAT(	\
+			BL_COHERENT_RAM_BASE,	\
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \
+			MT_DEVICE | MT_RW | EL3_PAS)
+#endif /* USE_COHERENT_MEM */
+
+#if USE_ROMLIB
+#define ARM_MAP_ROMLIB_CODE		MAP_REGION_FLAT(	\
+			ROMLIB_RO_BASE,	\
+			ROMLIB_RO_LIMIT - ROMLIB_RO_BASE,	\
+			MT_CODE | MT_SECURE)
+
+#define ARM_MAP_ROMLIB_DATA		MAP_REGION_FLAT(	\
+			ROMLIB_RW_BASE,	\
+			ROMLIB_RW_END - ROMLIB_RW_BASE,	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* USE_ROMLIB */
+
+/*
+ * Map mem_protect flash region with read and write permissions
+ */
+#define ARM_V2M_MAP_MEM_PROTECT		MAP_REGION_FLAT(	\
+			PLAT_ARM_MEM_PROT_ADDR,	\
+			V2M_FLASH_BLOCK_SIZE,	\
+			MT_DEVICE | MT_RW | MT_SECURE)
+/*
+ * Map the region for device tree configuration with read and write permissions
+ */
+#define ARM_MAP_BL_CONFIG_REGION	MAP_REGION_FLAT(	\
+			ARM_BL_RAM_BASE,	\
+			(ARM_FW_CONFIGS_LIMIT - ARM_BL_RAM_BASE),	\
+			MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * The max number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+#define ARM_BL_REGIONS			10
+
+#define MAX_MMAP_REGIONS		(	\
+			PLAT_ARM_MMAP_ENTRIES + ARM_BL_REGIONS)
+
+/* Memory mapped Generic timer interfaces  */
+#define ARM_SYS_CNTCTL_BASE			UL(0XF07FC000)
+
+#define ARM_CONSOLE_BAUDRATE		115200
+
+/*
+ * The TBBR document specifies a watchdog timeout of 256 seconds. SP805
+ * asserts reset after two consecutive countdowns (2 x 128 = 256 sec)
+ */
+#define ARM_TWDG_TIMEOUT_SEC		128
+#define ARM_TWDG_LOAD_VAL		(ARM_SP805_TWDG_CLK_HZ * \
+			ARM_TWDG_TIMEOUT_SEC)
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches (64 on Arbel).
+ */
+#define CACHE_WRITEBACK_GRANULE		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
+ * and limit. Leave enough space of BL2 meminfo.
+ */
+#define ARM_FW_CONFIG_BASE		(ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT		(	\
+			(ARM_BL_RAM_BASE + PAGE_SIZE) + (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE		(ARM_FW_CONFIG_LIMIT)
+#define ARM_BL2_MEM_DESC_LIMIT		(	\
+			ARM_BL2_MEM_DESC_BASE + (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need
+ * two sets of addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE			PLAT_ARM_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT			(PLAT_ARM_TRUSTED_ROM_BASE +	\
+			(PLAT_ARM_TRUSTED_ROM_SIZE - PLAT_ARM_MAX_ROMLIB_RO_SIZE))
+/*
+ * Put BL1 RW at the top of the Trusted SRAM.
+ */
+#define BL1_RW_BASE			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE -	\
+			(PLAT_ARM_MAX_BL1_RW_SIZE + PLAT_ARM_MAX_ROMLIB_RW_SIZE))
+#define BL1_RW_LIMIT			(ARM_BL_RAM_BASE +	\
+			(ARM_BL_RAM_SIZE - PLAT_ARM_MAX_ROMLIB_RW_SIZE))
+
+#define ROMLIB_RO_BASE			BL1_RO_LIMIT
+#define ROMLIB_RO_LIMIT			(	\
+			PLAT_ARM_TRUSTED_ROM_BASE + PLAT_ARM_TRUSTED_ROM_SIZE)
+
+#define ROMLIB_RW_BASE			(BL1_RW_BASE + PLAT_ARM_MAX_BL1_RW_SIZE)
+#define ROMLIB_RW_END			(	\
+			ROMLIB_RW_BASE + PLAT_ARM_MAX_ROMLIB_RW_SIZE)
+
+/******************************************************************************
+ * BL2 specific defines.
+ *****************************************************************************/
+#if BL2_AT_EL3
+/* Put BL2 towards the middle of the Trusted SRAM */
+#define BL2_BASE			(ARM_TRUSTED_SRAM_BASE +	\
+			PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + 0x2000)
+#define BL2_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+#else
+/*
+ * Put BL2 just below BL1.
+ */
+#define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL1_RW_BASE
+#endif /* BL2_AT_EL3 */
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+#if ARM_BL31_IN_DRAM || SEPARATE_NOBITS_REGION
+/*
+ * Put BL31 at the bottom of TZC secured DRAM
+ */
+#define BL31_BASE			ARM_AP_TZC_DRAM1_BASE
+#define BL31_LIMIT			(	\
+			ARM_AP_TZC_DRAM1_BASE + PLAT_ARM_MAX_BL31_SIZE)
+
+/*
+ * For SEPARATE_NOBITS_REGION, BL31 PROGBITS are loaded in TZC secured DRAM.
+ * And BL31 NOBITS are loaded in Trusted SRAM such that BL2 is overwritten.
+ */
+#if SEPARATE_NOBITS_REGION
+#define BL31_NOBITS_BASE		BL2_BASE
+#define BL31_NOBITS_LIMIT		BL2_LIMIT
+#endif /* SEPARATE_NOBITS_REGION */
+#elif (RESET_TO_BL31)
+/* Ensure Position Independent support (PIE) is enabled for this config.*/
+#if !ENABLE_PIE
+#error "BL31 must be a PIE if RESET_TO_BL31=1."
+#endif /* !ENABLE_PIE */
+/*
+ * Since this is PIE, we can define BL31_BASE to 0x0 since this macro is solely
+ * used for building BL31 and not used for loading BL31.
+ */
+#define NEW_SRAM_ALLOCATION
+
+#ifdef NEW_SRAM_ALLOCATION
+	#define BL31_BASE				0x20001000
+#else
+	#define BL31_BASE				0x20001000
+#endif /* NEW_SRAM_ALLOCATION */
+
+#define BL31_LIMIT			BL2_BASE	/* PLAT_ARM_MAX_BL31_SIZE */
+#else
+/* Put BL31 below BL2 in the Trusted SRAM.*/
+#define BL31_BASE			((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) -	\
+			PLAT_ARM_MAX_BL31_SIZE)
+#define BL31_PROGBITS_LIMIT		BL2_BASE
+
+/*
+ * For BL2_AT_EL3 make sure the BL31 can grow up until BL2_BASE.
+ * This is because in the BL2_AT_EL3 configuration, BL2 is always resident.
+ */
+#if BL2_AT_EL3
+#define BL31_LIMIT			BL2_BASE
+#else
+#define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+#endif /* BL2_AT_EL3 */
+#endif /* ARM_BL31_IN_DRAM || SEPARATE_NOBITS_REGION */
+
+/*
+ * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is
+ * no SPD and no SPM-MM, as they are the only ones that can be used as BL32.
+ */
+#if defined(SPD_none) && !SPM_MM
+#undef BL32_BASE
+#endif /* SPD_none && !SPM_MM */
+
+/******************************************************************************
+ * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
+ *****************************************************************************/
+#define BL2U_BASE			BL2_BASE
+#define BL2U_LIMIT			BL2_LIMIT
+
+#define NS_BL2U_BASE			ARM_NS_DRAM1_BASE
+#define NS_BL1U_BASE			(PLAT_ARM_NVM_BASE + UL(0x03EB8000))
+
+/*
+ * ID of the secure physical generic timer interrupt used by the TSP.
+ */
+#define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
+
+/* Priority levels for ARM platforms */
+#define PLAT_RAS_PRI			0x10
+#define PLAT_SDEI_CRITICAL_PRI		0x60
+#define PLAT_SDEI_NORMAL_PRI		0x70
+
+/* ARM platforms use 3 upper bits of secure interrupt priority */
+#define ARM_PRI_BITS			3
+
+/* SGI used for SDEI signalling */
+#define ARM_SDEI_SGI			ARM_IRQ_SEC_SGI_0
+
+#if SDEI_IN_FCONF
+/* ARM SDEI dynamic private event max count */
+#define ARM_SDEI_DP_EVENT_MAX_CNT	3
+
+/* ARM SDEI dynamic shared event max count */
+#define ARM_SDEI_DS_EVENT_MAX_CNT	3
+#else
+/* ARM SDEI dynamic private event numbers */
+#define ARM_SDEI_DP_EVENT_0		1000
+#define ARM_SDEI_DP_EVENT_1		1001
+#define ARM_SDEI_DP_EVENT_2		1002
+
+/* ARM SDEI dynamic shared event numbers */
+#define ARM_SDEI_DS_EVENT_0		2000
+#define ARM_SDEI_DS_EVENT_1		2001
+#define ARM_SDEI_DS_EVENT_2		2002
+
+#define ARM_SDEI_PRIVATE_EVENTS \
+	SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI), \
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+
+#define ARM_SDEI_SHARED_EVENTS \
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+#endif /* SDEI_IN_FCONF */
+
+#endif /* ARM_DEF_H */
diff --git a/include/plat/nuvoton/common/plat_macros.S b/include/plat/nuvoton/common/plat_macros.S
new file mode 100644
index 0000000..08f9feb
--- /dev/null
+++ b/include/plat/nuvoton/common/plat_macros.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (c) 2017-2023 Nuvoton Technology Corp.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+#include <cci_macros.S>
+#include <platform_def.h>
+
+/*
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception is
+ * taken in BL3-1.
+ * Clobbers: x0 - x10, x16, x17, sp
+ */
+.macro plat_print_gic_regs
+mov_imm	x17, BASE_GICC_BASE
+mov_imm	x16, BASE_GICD_BASE
+arm_print_gic_regs
+.endm
+
+/*
+ * the below macros print out relevant interconnect
+ * registers whenever an unhandled exception is
+ * taken in BL3-1
+ */
+.macro plat_print_interconnect_regs
+	/* TODO */
+.endm
+
+/*
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ */
+.macro plat_crash_print_regs
+	/* TODO */
+.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/include/plat/nuvoton/common/plat_npcm845x.h b/include/plat/nuvoton/common/plat_npcm845x.h
new file mode 100644
index 0000000..d90952a
--- /dev/null
+++ b/include/plat/nuvoton/common/plat_npcm845x.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (c) 2017-2023 Nuvoton Technology Corp.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_NPCM845X_H
+#define PLAT_NPCM845X_H
+
+#include <drivers/arm/gicv2.h>
+#include <lib/psci/psci.h>
+
+unsigned int plat_calc_core_pos(uint64_t mpidr);
+void npcm845x_mailbox_init(uintptr_t base_addr);
+void plat_gic_driver_init(void);
+void plat_gic_init(void);
+void plat_gic_cpuif_enable(void);
+void plat_gic_cpuif_disable(void);
+void plat_gic_pcpu_init(void);
+
+void __dead2 npcm845x_system_off(void);
+void __dead2 npcm845x_system_reset(void);
+void npcm845x_pwr_domain_on_finish(const psci_power_state_t *target_state);
+bool npcm845x_is_wakeup_src_irqsteer(void);
+void __dead2 npcm845x_pwr_down_wfi(const psci_power_state_t *target_state);
+void npcm845x_cpu_standby(plat_local_state_t cpu_state);
+int npcm845x_validate_ns_entrypoint(uintptr_t entrypoint);
+int npcm845x_pwr_domain_on(u_register_t mpidr);
+int npcm845x_validate_power_state(unsigned int power_state,
+				  psci_power_state_t *req_state);
+
+#if !ARM_BL31_IN_DRAM
+void npcm845x_get_sys_suspend_power_state(psci_power_state_t *req_state);
+#endif
+
+void __dead2 npcm845x_pwr_domain_pwr_down_wfi(
+	const psci_power_state_t *target_state);
+void npcm845x_pwr_domain_suspend_finish(const psci_power_state_t *target_state);
+void npcm845x_pwr_domain_suspend(const psci_power_state_t *target_state);
+void npcm845x_pwr_domain_off(const psci_power_state_t *target_state);
+void __init npcm845x_bl31_plat_arch_setup(void);
+
+#endif /* PLAT_NPCM845X_H */
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
new file mode 100644
index 0000000..09da36b
--- /dev/null
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (c) 2017-2023 Nuvoton Technology Corp.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/interrupt_props.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <npcm845x_arm_def.h>
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+#define VALUE_TO_STRING(x) #x
+#define VALUE(x) VALUE_TO_STRING(x)
+#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE 0x400
+
+#define PLATFORM_CORE_COUNT NPCM845x_PLATFORM_CORE_COUNT
+#define PLATFORM_CLUSTER_COUNT NPCM845x_CLUSTER_COUNT
+#define PLATFORM_MAX_CPU_PER_CLUSTER NPCM845x_MAX_CPU_PER_CLUSTER
+#define PLAT_PRIMARY_CPU NPCM845x_PLAT_PRIMARY_CPU
+#define PLATFORM_SYSTEM_COUNT NPCM845x_SYSTEM_COUNT
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF U(2)
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE PLAT_LOCAL_STATE_OFF
+#define PLAT_MAX_RET_STATE PLAT_LOCAL_STATE_RET
+
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + PLATFORM_CORE_COUNT)
+#define NPCM845x_MAX_PWR_LVL ARM_PWR_LVL1
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Required ARM standard platform porting definitions
+ */
+#define PLAT_ARM_CLUSTER_COUNT PLATFORM_CLUSTER_COUNT
+
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + PLATFORM_CORE_COUNT)
+#define PLAT_MAX_PWR_LVL NPCM845x_MAX_PWR_LVL
+
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+#ifdef BL32_BASE
+
+#ifndef CONFIG_TARGET_ARBEL_PALLADIUM
+#define PLAT_ARM_TRUSTED_DRAM_BASE BL32_BASE
+#else
+#define PLAT_ARM_TRUSTED_DRAM_BASE BL32_BASE
+#endif /* CONFIG_TARGET_ARBEL_PALLADIUM */
+
+#define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */
+#endif /* BL32_BASE */
+
+#define PWR_DOMAIN_AT_MAX_LVL U(1)
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#define MAX_XLAT_TABLES 16
+#define PLAT_ARM_MMAP_ENTRIES 17
+
+#ifdef NPCM845X_DEBUG
+#define MAX_MMAP_REGIONS 8
+#define NPCM845X_TZ1_BASE 0xFFFB0000
+#endif /* NPCM845X_DEBUG */
+
+#define FIQ_SMP_CALL_SGI 10
+
+/* (0x00040000) 128  KB, the rest 128K if it is non secured */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00020000)
+
+#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */
+
+/* UL(0xfffCE000) add calc ARM_TRUSTED_SRAM_BASE */
+#define ARM_SHARED_RAM_BASE (BL31_BASE + 0x00020000 - ARM_SHARED_RAM_SIZE)
+
+/* The remaining Trusted SRAM is used to load the BL images */
+#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE)
+
+/*
+ * PLAT_ARM_TRUSTED_SRAM_SIZE is taken from platform_def.h 0x20000
+ * because only half is secured in this specific implementation
+ */
+#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE)
+
+#if RESET_TO_BL31
+/* Size of Trusted SRAM - the first 4KB of shared memory */
+#define PLAT_ARM_MAX_BL31_SIZE                                                 \
+	(PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE)
+#else
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE
+ * is calculated using the current BL31 PROGBITS debug size plus the sizes
+ * of BL2 and BL1-RW
+ */
+#define PLAT_ARM_MAX_BL31_SIZE                                                 \
+	(PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE)
+#endif /* RESET_TO_BL31 */
+/*
+ * Load address of BL33 for this platform port
+ */
+#define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x6208000))
+
+#ifdef NPCM845X_DEBUG
+#define COUNTER_FREQUENCY 0x07735940 /* f/4 = 125MHz */
+#endif /* NPCM845X_DEBUG */
+
+#define COUNTER_FREQUENCY 0x0EE6B280 /* f/2 = 250MHz */
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+
+/* GIC parameters */
+
+/* Base  compatible GIC memory map */
+#define NT_GIC_BASE (0xDFFF8000)
+#define BASE_GICD_BASE (NT_GIC_BASE + 0x1000)
+#define BASE_GICC_BASE (NT_GIC_BASE + 0x2000)
+#define BASE_GICR_BASE (NT_GIC_BASE + 0x200000)
+#define BASE_GICH_BASE (NT_GIC_BASE + 0x4000)
+#define BASE_GICV_BASE (NT_GIC_BASE + 0x6000)
+
+#define DEVICE1_BASE BASE_GICD_BASE
+#define DEVICE1_SIZE 0x7000
+
+#ifdef NPCM845X_DEBUG
+/* ((BASE_GICR_BASE - BASE_GICD_BASE) +	 (PLATFORM_CORE_COUNT * 0x20000)) */
+#define ARM_CPU_START_ADDRESS(m) UL(0xf0800e00 + 0x10 + m * 4)
+#endif /* NPCM845X_DEBUG */
+
+#define PLAT_REG_BASE NPCM845x_REG_BASE
+#define PLAT_REG_SIZE NPCM845x_REG_SIZE
+
+/* MMU entry for internal (register) space access */
+#define MAP_DEVICE0                                                            \
+	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, MT_DEVICE | MT_RW | MT_NS)
+
+#define MAP_DEVICE1                                                            \
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE,                            \
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties
+ * as per GICv3 terminology. On a GICv2 system or mode,
+ * the lists will be merged and treated as Group 0 interrupts.
+ */
+#define PLAT_ARM_GICD_BASE BASE_GICD_BASE
+#define PLAT_ARM_GICC_BASE BASE_GICC_BASE
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)                                            \
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp,   \
+		       GIC_INTR_CFG_LEVEL),                                    \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE),                        \
+		INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,    \
+			       grp, GIC_INTR_CFG_EDGE)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp)
+
+/* Required for compilation: */
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE 0 /* UL(0xB000) */
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000)
+#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0x6000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0)
+#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0)
+#endif /* USE_ROMLIB */
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size
+ * plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) * FVP_BL2_ROMLIB_OPTIMIZATION)
+#else
+/* (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION) */
+#define PLAT_ARM_MAX_BL2_SIZE 0
+#endif /* TRUSTED_BOARD_BOOT */
+
+#undef NPCM_PRINT_ONCE
+#ifdef NPCM_PRINT_ONCE
+#define PRINT_ONLY_ONCE
+#pragma message(VAR_NAME_VALUE(ARM_AP_TZC_DRAM1_BASE))
+#pragma message(VAR_NAME_VALUE(BL31_BASE))
+#pragma message(VAR_NAME_VALUE(BL31_LIMIT))
+#pragma message(VAR_NAME_VALUE(PLAT_ARM_MAX_BL31_SIZE))
+#pragma message(VAR_NAME_VALUE(BL32_BASE))
+#pragma message(VAR_NAME_VALUE(BL32_LIMIT))
+#pragma message(VAR_NAME_VALUE(PLAT_ARM_MAX_BL32_SIZE)
+#pragma message(VAR_NAME_VALUE(SPMD_SPM_AT_SEL2_KKO))
+#endif /* NPCM_PRINT_ONCE */
+
+#define MAX_IO_DEVICES 4
+#define MAX_IO_HANDLES 4
+
+#define PLAT_ARM_FIP_BASE 0x0
+#define PLAT_ARM_FIP_MAX_SIZE PLAT_ARM_MAX_BL31_SIZE
+
+#define PLAT_ARM_BOOT_UART_BASE 0xF0000000
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ 115200
+#define PLAT_ARM_RUN_UART_BASE 0xF0000000
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ 115200
+#define PLAT_ARM_CRASH_UART_BASE 0xF0000000
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ 115200
+
+/*
+ * Mailbox to control the secondary cores.All secondary cores are held in a wait
+ * loop in cold boot. To release them perform the following steps (plus any
+ * additional barriers that may be needed):
+ *
+ *     uint64_t *entrypoint = (uint64_t *)PLAT_NPCM_TM_ENTRYPOINT;
+ *     *entrypoint = ADDRESS_TO_JUMP_TO;
+ *
+ *     uint64_t *mbox_entry = (uint64_t *)PLAT_NPCM_TM_HOLD_BASE;
+ *     mbox_entry[cpu_id] = PLAT_NPCM_TM_HOLD_BASE;
+ *
+ *     sev();
+ */
+#define PLAT_NPCM_TRUSTED_MAILBOX_BASE ARM_SHARED_RAM_BASE
+
+/* The secure entry point to be used on warm reset by all CPUs. */
+#define PLAT_NPCM_TM_ENTRYPOINT PLAT_NPCM_TRUSTED_MAILBOX_BASE
+#define PLAT_NPCM_TM_ENTRYPOINT_SIZE ULL(8)
+
+/* Hold entries for each CPU. */
+#define PLAT_NPCM_TM_HOLD_BASE                                                 \
+	(PLAT_NPCM_TM_ENTRYPOINT + PLAT_NPCM_TM_ENTRYPOINT_SIZE)
+#define PLAT_NPCM_TM_HOLD_ENTRY_SIZE ULL(8)
+#define PLAT_NPCM_TM_HOLD_SIZE                                                 \
+	(PLAT_NPCM_TM_HOLD_ENTRY_SIZE * PLATFORM_CORE_COUNT)
+#define PLAT_NPCM_TRUSTED_NOTIFICATION_BASE                                    \
+	(PLAT_NPCM_TM_ENTRYPOINT_SIZE + PLAT_NPCM_TM_HOLD_SIZE)
+
+#define PLAT_NPCM_TRUSTED_NOTIFICATION_ENTRY_SIZE ULL(8)
+
+#define PLAT_NPCM_TRUSTED_NOTIFICATION_SIZE                                    \
+	(PLAT_NPCM_TRUSTED_NOTIFICATION_ENTRY_SIZE * PLATFORM_CORE_COUNT)
+
+#define PLAT_NPCM_TRUSTED_MAILBOX_SIZE                                         \
+	(PLAT_NPCM_TM_ENTRYPOINT_SIZE + PLAT_NPCM_TM_HOLD_SIZE +               \
+	 PLAT_NPCM_TRUSTED_NOTIFICATION_ENTRY_SIZE)
+
+#define PLAT_NPCM_TM_HOLD_STATE_WAIT ULL(0)
+#define PLAT_NPCM_TM_HOLD_STATE_GO ULL(1)
+#define PLAT_NPCM_TM_HOLD_STATE_BSP_OFF ULL(2)
+
+#define PLAT_NPCM_TM_NOTIFICATION_START ULL(0xAA)
+#define PLAT_NPCM_TM_NOTIFICATION_BR ULL(0xCC)
+
+#ifdef NPCM845X_DEBUG
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE 0xfffB0000
+#endif /* NPCM845X_DEBUG */
+
+#endif /* PLATFORM_DEF_H */
diff --git a/include/services/el3_spmd_logical_sp.h b/include/services/el3_spmd_logical_sp.h
new file mode 100644
index 0000000..1f9ef0d
--- /dev/null
+++ b/include/services/el3_spmd_logical_sp.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef EL3_SPMD_LOGICAL_SP_H
+#define EL3_SPMD_LOGICAL_SP_H
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+#include <services/ffa_svc.h>
+
+/*******************************************************************************
+ * Structure definition, typedefs & constants for the SPMD Logical Partitions.
+ ******************************************************************************/
+typedef struct spmd_spm_core_context spmd_spm_core_context_t;
+
+/* Prototype for SPMD logical partition initializing function. */
+typedef int32_t (*ffa_spmd_lp_init_t)(void);
+
+/* SPMD Logical Partition Descriptor. */
+struct spmd_lp_desc {
+	ffa_spmd_lp_init_t init;
+	uint16_t sp_id;
+	uint32_t properties;
+	uint32_t uuid[4];  /* Little Endian. */
+	const char *debug_name;
+};
+
+struct ffa_value {
+	uint64_t func;
+	uint64_t arg1;
+	uint64_t arg2;
+	uint64_t arg3;
+	uint64_t arg4;
+	uint64_t arg5;
+	uint64_t arg6;
+	uint64_t arg7;
+	uint64_t arg8;
+	uint64_t arg9;
+	uint64_t arg10;
+	uint64_t arg11;
+	uint64_t arg12;
+	uint64_t arg13;
+	uint64_t arg14;
+	uint64_t arg15;
+	uint64_t arg16;
+	uint64_t arg17;
+};
+
+/* Convenience macro to declare a SPMD logical partition descriptor. */
+#define DECLARE_SPMD_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties) \
+	static const struct spmd_lp_desc __partition_desc_ ## _name	    \
+		__section(".spmd_lp_descs") __used = {			    \
+			.debug_name = #_name,				    \
+			.init = (_init),				    \
+			.sp_id = (_sp_id),				    \
+			.uuid = _uuid,					    \
+			.properties = (_properties),			    \
+		}
+
+IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_START__,	SPMD_LP_DESCS_START);
+IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_END__,	SPMD_LP_DESCS_END);
+
+#define SPMD_LP_DESCS_COUNT ((SPMD_LP_DESCS_END - SPMD_LP_DESCS_START) \
+			  / sizeof(struct spmd_lp_desc))
+CASSERT(sizeof(struct spmd_lp_desc) == 40, assert_spmd_lp_desc_size_mismatch);
+
+/*
+ * Reserve 63 IDs for SPMD Logical Partitions. Currently, 0xFFC0 to 0xFFFE
+ * is reserved.
+ */
+#define SPMD_LP_ID_END		(SPMD_DIRECT_MSG_ENDPOINT_ID - 1)
+#define SPMD_LP_ID_START	(SPMD_LP_ID_END - 62)
+
+/*
+ * TODO: Arbitrary number. Can make this platform specific in the future,
+ * no known use cases for more LPs at this point.
+ */
+#define EL3_SPMD_MAX_NUM_LP	U(5)
+
+static inline bool is_spmd_lp_id(unsigned int id)
+{
+#if ENABLE_SPMD_LP
+	return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END);
+#else
+	return false;
+#endif
+}
+
+static inline bool is_ffa_error(struct ffa_value *retval)
+{
+	return retval->func == FFA_ERROR;
+}
+
+static inline bool is_ffa_success(struct ffa_value *retval)
+{
+	return (retval->func == FFA_SUCCESS_SMC32) ||
+		(retval->func == FFA_SUCCESS_SMC64);
+}
+
+static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval)
+{
+	return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
+		(retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64);
+}
+
+static inline uint16_t ffa_partition_info_regs_get_last_idx(
+	struct ffa_value args)
+{
+	return (uint16_t)(args.arg2 & 0xFFFFU);
+}
+
+static inline uint16_t ffa_partition_info_regs_get_curr_idx(
+	struct ffa_value args)
+{
+	return (uint16_t)((args.arg2 >> 16) & 0xFFFFU);
+}
+
+static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value args)
+{
+	return (uint16_t)((args.arg2 >> 32) & 0xFFFFU);
+}
+
+static inline uint16_t ffa_partition_info_regs_get_desc_size(
+	struct ffa_value args)
+{
+	return (uint16_t)(args.arg2 >> 48);
+}
+
+uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
+						  uint64_t x2, uint64_t x3);
+
+bool ffa_partition_info_regs_get_part_info(
+	struct ffa_value args, uint8_t idx,
+	struct ffa_partition_info_v1_1 *partition_info);
+
+bool spmd_el3_invoke_partition_info_get(
+				const uint32_t target_uuid[4],
+				const uint16_t start_index,
+				const uint16_t tag,
+				struct ffa_value *retval);
+void spmd_logical_sp_set_spmc_initialized(void);
+void spmc_logical_sp_set_spmc_failure(void);
+
+int32_t spmd_logical_sp_init(void);
+bool is_spmd_logical_sp_dir_req_in_progress(
+		spmd_spm_core_context_t *ctx);
+
+bool is_spmd_logical_sp_info_regs_req_in_progress(
+		spmd_spm_core_context_t *ctx);
+
+bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *handle,
+				 struct ffa_value *retval);
+
+uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
+		u_register_t x1,
+		u_register_t x2,
+		u_register_t x3,
+		u_register_t x4,
+		void *cookie,
+		void *handle,
+		u_register_t flags);
+
+#endif /* EL3_SPMD_LOGICAL_SP_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 64af437..de56638 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -343,4 +343,28 @@
 	uint64_t reserved;
 };
 
+/* FF-A Partition Info Get related macros. */
+#define FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK	U(0x7)
+#define FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT		U(8)
+#define FFA_PARTITION_INFO_GET_AARCH32_STATE		U(0)
+#define FFA_PARTITION_INFO_GET_AARCH64_STATE		U(1)
+
+/**
+ * Holds information returned for each partition by the FFA_PARTITION_INFO_GET
+ * interface.
+ */
+struct ffa_partition_info_v1_0 {
+	uint16_t ep_id;
+	uint16_t execution_ctx_count;
+	uint32_t properties;
+};
+
+/* Extended structure for FF-A v1.1. */
+struct ffa_partition_info_v1_1 {
+	uint16_t ep_id;
+	uint16_t execution_ctx_count;
+	uint32_t properties;
+	uint32_t uuid[4];
+};
+
 #endif /* FFA_SVC_H */
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index 2ca12c9..8c53ef9 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.h
@@ -28,4 +28,17 @@
 /* CCAFirmwareNVCounter - Non-volatile counter extension */
 #define CCA_FW_NVCOUNTER_OID			"1.3.6.1.4.1.4128.2100.3"
 
+/*
+ * First undef previous definitions from tbbr_oid.h.
+ * CCA ROTPK authenticates BL31 and its configuration image in
+ * CCA CoT.
+ **/
+#undef BL31_IMAGE_KEY_OID
+#undef SOC_FW_CONFIG_KEY_OID
+#undef HW_CONFIG_KEY_OID
+#define BL31_IMAGE_KEY_OID			ZERO_OID
+#define SOC_FW_CONFIG_KEY_OID			ZERO_OID
+#define HW_CONFIG_KEY_OID			ZERO_OID
+#define RMM_IMAGE_KEY_OID			ZERO_OID
+
 #endif /* CCA_OID_H */
diff --git a/include/tools_share/dualroot_oid.h b/include/tools_share/dualroot_oid.h
index 3e88a6d..3762c79 100644
--- a/include/tools_share/dualroot_oid.h
+++ b/include/tools_share/dualroot_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 52b43ab..9881d1a 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #ifndef TBBR_OID_H
 #define TBBR_OID_H
 
+#include "zero_oid.h"
+
 #define	MAX_OID_NAME_LEN	30
 
 /*
@@ -160,6 +162,14 @@
 #define SP_PKG7_HASH_OID			"1.3.6.1.4.1.4128.2100.1307"
 #define SP_PKG8_HASH_OID			"1.3.6.1.4.1.4128.2100.1308"
 
+/*
+ * Public Keys present in SOC FW content certificates authenticate BL31 and
+ * its configuration.
+ */
+#define BL31_IMAGE_KEY_OID			SOC_FW_CONTENT_CERT_PK_OID
+#define SOC_FW_CONFIG_KEY_OID			SOC_FW_CONTENT_CERT_PK_OID
+#define HW_CONFIG_KEY_OID			ZERO_OID
+
 #ifdef PLAT_DEF_OID
 #include <platform_oid.h>
 #endif
diff --git a/include/tools_share/zero_oid.h b/include/tools_share/zero_oid.h
new file mode 100644
index 0000000..9b83094
--- /dev/null
+++ b/include/tools_share/zero_oid.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ZERO_OID_H
+#define ZERO_OID_H
+
+#define ZERO_OID                              "0.0.0.0.0.0.0.0.0"
+
+#endif /* ZERO_OID_H */
diff --git a/lib/aarch32/arm32_aeabi_divmod.c b/lib/aarch32/arm32_aeabi_divmod.c
index ea8e2bb..89a9033 100644
--- a/lib/aarch32/arm32_aeabi_divmod.c
+++ b/lib/aarch32/arm32_aeabi_divmod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/aarch32/arm32_aeabi_divmod_a32.S b/lib/aarch32/arm32_aeabi_divmod_a32.S
index 6915dcd..9155100 100644
--- a/lib/aarch32/arm32_aeabi_divmod_a32.S
+++ b/lib/aarch32/arm32_aeabi_divmod_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/aarch32/armclang_printf.S b/lib/aarch32/armclang_printf.S
index 2b87bf7..e736a11 100644
--- a/lib/aarch32/armclang_printf.S
+++ b/lib/aarch32/armclang_printf.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/aarch32/misc_helpers.S b/lib/aarch32/misc_helpers.S
index 59e15bd..c010cbc 100644
--- a/lib/aarch32/misc_helpers.S
+++ b/lib/aarch32/misc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/aarch64/armclang_printf.S b/lib/aarch64/armclang_printf.S
index 52a6976..f9326fd 100644
--- a/lib/aarch64/armclang_printf.S
+++ b/lib/aarch64/armclang_printf.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/bl_aux_params/bl_aux_params.c b/lib/bl_aux_params/bl_aux_params.c
index 7f357b7..6e30ecf 100644
--- a/lib/bl_aux_params/bl_aux_params.c
+++ b/lib/bl_aux_params/bl_aux_params.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index b41c4d0..2b16504 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
diff --git a/lib/coreboot/coreboot.mk b/lib/coreboot/coreboot.mk
index 4201823..e07d28c 100644
--- a/lib/coreboot/coreboot.mk
+++ b/lib/coreboot/coreboot.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c
index 43e9835..c954e97 100644
--- a/lib/coreboot/coreboot_table.c
+++ b/lib/coreboot/coreboot_table.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S
index 7bd586a..9f45e38 100644
--- a/lib/cpus/aarch32/aem_generic.S
+++ b/lib/cpus/aarch32/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
index 5300fe0..8eec27c 100644
--- a/lib/cpus/aarch32/cortex_a12.S
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,19 +64,16 @@
 
 	bl	plat_disable_acp
 
+	/* Flush L2 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level2
+
 	/* Exit cluster coherency */
 	pop	{r12, lr}
 	b	cortex_a12_disable_smp
 endfunc cortex_a12_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A12. Must follow AAPCS.
- */
-func cortex_a12_errata_report
-	bx	lr
-endfunc cortex_a12_errata_report
-#endif
+errata_report_shim cortex_a12
 
 declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
 	cortex_a12_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index 1143e9b..b41676d 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,6 +62,7 @@
 	bx	lr
 endfunc check_errata_816470
 
+add_erratum_entry cortex_a15, ERRATUM(816470), ERRATA_A15_816470
 	/* ----------------------------------------------------
 	 * Errata Workaround for Cortex A15 Errata #827671.
 	 * This applies only to revision >= r3p0 of Cortex A15.
@@ -91,6 +92,8 @@
 	b	cpu_rev_var_hs
 endfunc check_errata_827671
 
+add_erratum_entry cortex_a15, ERRATUM(827671), ERRATA_A15_827671
+
 func check_errata_cve_2017_5715
 #if WORKAROUND_CVE_2017_5715
 	mov	r0, #ERRATA_APPLIES
@@ -100,6 +103,8 @@
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
+add_erratum_entry cortex_a15, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	r0, #ERRATA_APPLIES
@@ -109,29 +114,7 @@
 	bx	lr
 endfunc check_errata_cve_2022_23960
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A15. Must follow AAPCS.
- */
-func cortex_a15_errata_report
-	push	{r12, lr}
-
-	bl	cpu_get_rev_var
-	mov	r4, r0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A15_816470, cortex_a15, 816470
-	report_errata ERRATA_A15_827671, cortex_a15, 827671
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a15, cve_2017_5715
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a15, cve_2022_23960
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a15_errata_report
-#endif
+add_erratum_entry cortex_a15, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
 func cortex_a15_reset_func
 	mov	r5, lr
@@ -180,11 +163,17 @@
 
 	bl	plat_disable_acp
 
+	/* Flush L2 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level2
+
 	/* Exit cluster coherency */
 	pop	{r12, lr}
 	b	cortex_a15_disable_smp
 endfunc cortex_a15_cluster_pwr_dwn
 
+errata_report_shim cortex_a15
+
 declare_cpu_ops cortex_a15, CORTEX_A15_MIDR, \
 	cortex_a15_reset_func, \
 	cortex_a15_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a17.S b/lib/cpus/aarch32/cortex_a17.S
index b8abd33..1877570 100644
--- a/lib/cpus/aarch32/cortex_a17.S
+++ b/lib/cpus/aarch32/cortex_a17.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,6 +63,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_852421
 
+add_erratum_entry cortex_a17, ERRATUM(852421), ERRATA_A17_852421
+
 	/* ----------------------------------------------------
 	 * Errata Workaround for Cortex A17 Errata #852423.
 	 * This applies only to revision <= r1p2 of Cortex A17.
@@ -91,6 +93,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_852423
 
+add_erratum_entry cortex_a17, ERRATUM(852423), ERRATA_A17_852423
+
 func check_errata_cve_2017_5715
 #if WORKAROUND_CVE_2017_5715
 	mov	r0, #ERRATA_APPLIES
@@ -100,28 +104,9 @@
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A17. Must follow AAPCS.
- */
-func cortex_a17_errata_report
-	push	{r12, lr}
+add_erratum_entry cortex_a17, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-	bl	cpu_get_rev_var
-	mov	r4, r0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A17_852421, cortex_a17, 852421
-	report_errata ERRATA_A17_852423, cortex_a17, 852423
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a17, cve_2017_5715
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a17_errata_report
-#endif
+errata_report_shim cortex_a17
 
 func cortex_a17_reset_func
 	mov	r5, lr
@@ -139,7 +124,7 @@
 #endif
 
 #if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
-	ldr	r0, =workaround_bpiall_runtime_exceptions
+	ldr	r0, =wa_cve_2017_5715_bpiall_vbar
 	stcopr	r0, VBAR
 	stcopr	r0, MVBAR
 	/* isb will be applied in the course of the reset func */
@@ -174,6 +159,10 @@
 
 	bl	plat_disable_acp
 
+	/* Flush L2 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level2
+
 	/* Exit cluster coherency */
 	pop	{r12, lr}
 	b	cortex_a17_disable_smp
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index dfa159f..d08b4ff 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
index 8abb66f..625ea7b 100644
--- a/lib/cpus/aarch32/cortex_a5.S
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,14 +69,7 @@
 	b	cortex_a5_disable_smp
 endfunc cortex_a5_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A5. Must follow AAPCS.
- */
-func cortex_a5_errata_report
-	bx	lr
-endfunc cortex_a5_errata_report
-#endif
+errata_report_shim cortex_a5
 
 declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
 	cortex_a5_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a53.S b/lib/cpus/aarch32/cortex_a53.S
index 6e3ff81..89b238a 100644
--- a/lib/cpus/aarch32/cortex_a53.S
+++ b/lib/cpus/aarch32/cortex_a53.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,6 +44,8 @@
 	bx	lr
 endfunc check_errata_819472
 
+add_erratum_entry cortex_a53, ERRATUM(819472), ERRATA_A53_819472
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #824069.
 	 * This applies only to revision <= r0p2 of Cortex A53.
@@ -59,6 +61,8 @@
 	bx	lr
 endfunc check_errata_824069
 
+add_erratum_entry cortex_a53, ERRATUM(824069), ERRATA_A53_824069
+
 	/* --------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #826319.
 	 * This applies only to revision <= r0p2 of Cortex A53.
@@ -89,6 +93,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_826319
 
+add_erratum_entry cortex_a53, ERRATUM(826319), ERRATA_A53_826319
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #827319.
 	 * This applies only to revision <= r0p2 of Cortex A53.
@@ -104,6 +110,8 @@
 	bx	lr
 endfunc check_errata_827319
 
+add_erratum_entry cortex_a53, ERRATUM(827319), ERRATA_A53_827319
+
 	/* ---------------------------------------------------------------------
 	 * Disable the cache non-temporal hint.
 	 *
@@ -142,6 +150,9 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_disable_non_temporal_hint
 
+add_erratum_entry cortex_a53, ERRATUM(836870), ERRATA_A53_836870 | A53_DISABLE_NON_TEMPORAL_HINT, \
+	disable_non_temporal_hint
+
 	/* --------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #855873.
 	 *
@@ -176,6 +187,8 @@
 	b	cpu_rev_var_hs
 endfunc check_errata_855873
 
+add_erratum_entry cortex_a53, ERRATUM(855873), ERRATA_A53_855873
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A53.
 	 * Shall clobber: r0-r6
@@ -284,31 +297,7 @@
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A53. Must follow AAPCS.
- */
-func cortex_a53_errata_report
-	push	{r12, lr}
-
-	bl	cpu_get_rev_var
-	mov	r4, r0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A53_819472, cortex_a53, 819472
-	report_errata ERRATA_A53_824069, cortex_a53, 824069
-	report_errata ERRATA_A53_826319, cortex_a53, 826319
-	report_errata ERRATA_A53_827319, cortex_a53, 827319
-	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
-	report_errata ERRATA_A53_855873, cortex_a53, 855873
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a53_errata_report
-#endif
+errata_report_shim cortex_a53
 
 declare_cpu_ops cortex_a53, CORTEX_A53_MIDR, \
 	cortex_a53_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a57.S b/lib/cpus/aarch32/cortex_a57.S
index 18ee1f9..1e5377b 100644
--- a/lib/cpus/aarch32/cortex_a57.S
+++ b/lib/cpus/aarch32/cortex_a57.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -86,6 +86,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_806969
 
+add_erratum_entry cortex_a57, ERRATUM(806969), ERRATA_A57_806969
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #813419.
 	 * This applies only to revision r0p0 of Cortex A57.
@@ -101,6 +103,8 @@
 	bx	lr
 endfunc check_errata_813419
 
+add_erratum_entry cortex_a57, ERRATUM(813419), ERRATA_A57_813419
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #813420.
 	 * This applies only to revision r0p0 of Cortex A57.
@@ -130,6 +134,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_813420
 
+add_erratum_entry cortex_a57, ERRATUM(813420), ERRATA_A57_813420
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #814670.
 	 * This applies only to revision r0p0 of Cortex A57.
@@ -159,6 +165,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_814670
 
+add_erratum_entry cortex_a57, ERRATUM(814670), ERRATA_A57_814670
+
 	/* ----------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #817169.
 	 * This applies only to revision <= r0p1 of Cortex A57.
@@ -173,6 +181,8 @@
 	bx	lr
 endfunc check_errata_817169
 
+add_erratum_entry cortex_a57, ERRATUM(817169), ERRATA_A57_817169
+
 	/* --------------------------------------------------------------------
 	 * Disable the over-read from the LDNP instruction.
 	 *
@@ -205,6 +215,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_disable_ldnp_overread
 
+add_erratum_entry cortex_a57, ERRATUM(1), A57_DISABLE_NON_TEMPORAL_HINT, disable_ldnp_overread
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #826974.
 	 * This applies only to revision <= r1p1 of Cortex A57.
@@ -234,6 +246,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_826974
 
+add_erratum_entry cortex_a57, ERRATUM(826974), ERRATA_A57_826974
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #826977.
 	 * This applies only to revision <= r1p1 of Cortex A57.
@@ -263,6 +277,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_826977
 
+add_erratum_entry cortex_a57, ERRATUM(826977), ERRATA_A57_826977
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #828024.
 	 * This applies only to revision <= r1p1 of Cortex A57.
@@ -298,6 +314,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_828024
 
+add_erratum_entry cortex_a57, ERRATUM(828024), ERRATA_A57_828024
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #829520.
 	 * This applies only to revision <= r1p2 of Cortex A57.
@@ -327,6 +345,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_829520
 
+add_erratum_entry cortex_a57, ERRATUM(829520), ERRATA_A57_829520
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #833471.
 	 * This applies only to revision <= r1p2 of Cortex A57.
@@ -356,6 +376,8 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_833471
 
+add_erratum_entry cortex_a57, ERRATUM(833471), ERRATA_A57_833471
+
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A57 Errata #859972.
 	 * This applies only to revision <= r1p3 of Cortex A57.
@@ -382,11 +404,15 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_859972
 
+add_erratum_entry cortex_a57, ERRATUM(859972), ERRATA_A57_859972
+
 func check_errata_cve_2017_5715
 	mov	r0, #ERRATA_MISSING
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
+add_erratum_entry cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+
 func check_errata_cve_2018_3639
 #if WORKAROUND_CVE_2018_3639
 	mov	r0, #ERRATA_APPLIES
@@ -396,11 +422,15 @@
 	bx	lr
 endfunc check_errata_cve_2018_3639
 
+add_erratum_entry cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+
 func check_errata_cve_2022_23960
 	mov	r0, #ERRATA_MISSING
 	bx	lr
 endfunc check_errata_cve_2022_23960
 
+add_erratum_entry cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A57.
 	 * Shall clobber: r0-r6
@@ -576,41 +606,7 @@
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A57. Must follow AAPCS.
- */
-func cortex_a57_errata_report
-	push	{r12, lr}
-
-	bl	cpu_get_rev_var
-	mov	r4, r0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A57_806969, cortex_a57, 806969
-	report_errata ERRATA_A57_813419, cortex_a57, 813419
-	report_errata ERRATA_A57_813420, cortex_a57, 813420
-	report_errata ERRATA_A57_814670, cortex_a57, 814670
-	report_errata ERRATA_A57_817169, cortex_a57, 817169
-	report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
-		disable_ldnp_overread
-	report_errata ERRATA_A57_826974, cortex_a57, 826974
-	report_errata ERRATA_A57_826977, cortex_a57, 826977
-	report_errata ERRATA_A57_828024, cortex_a57, 828024
-	report_errata ERRATA_A57_829520, cortex_a57, 829520
-	report_errata ERRATA_A57_833471, cortex_a57, 833471
-	report_errata ERRATA_A57_859972, cortex_a57, 859972
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a57, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a57, cve_2018_3639
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a57, cve_2022_23960
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a57_errata_report
-#endif
+errata_report_shim cortex_a57
 
 declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
 	cortex_a57_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
index 4d4bb77..4842ca6 100644
--- a/lib/cpus/aarch32/cortex_a7.S
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,19 +64,16 @@
 
 	bl	plat_disable_acp
 
+	/* Flush L2 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level2
+
 	/* Exit cluster coherency */
 	pop	{r12, lr}
 	b	cortex_a7_disable_smp
 endfunc cortex_a7_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A7. Must follow AAPCS.
- */
-func cortex_a7_errata_report
-	bx	lr
-endfunc cortex_a7_errata_report
-#endif
+errata_report_shim cortex_a7
 
 declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
 	cortex_a7_reset_func, \
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
index 7200343..1e9757a 100644
--- a/lib/cpus/aarch32/cortex_a9.S
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,14 +35,16 @@
 	bx	lr
 endfunc cortex_a9_enable_smp
 
-func check_errata_a9_794073
+func check_errata_794073
 #if ERRATA_A9_794073
 	mov	r0, #ERRATA_APPLIES
 #else
 	mov	r0, #ERRATA_MISSING
 #endif
 	bx	lr
-endfunc check_errata_cve_2017_5715
+endfunc check_errata_794073
+
+add_erratum_entry cortex_a9, ERRATUM(794073), ERRATA_A9_794073
 
 func check_errata_cve_2017_5715
 #if WORKAROUND_CVE_2017_5715
@@ -53,31 +55,13 @@
 	bx	lr
 endfunc check_errata_cve_2017_5715
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A9. Must follow AAPCS.
- */
-func cortex_a9_errata_report
-	push	{r12, lr}
-
-	bl	cpu_get_rev_var
-	mov	r4, r0
+add_erratum_entry cortex_a9, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a9, cve_2017_5715
-	report_errata ERRATA_A9_794073, cortex_a9, a9_79407
-
-	pop	{r12, lr}
-	bx	lr
-endfunc cortex_a9_errata_report
-#endif
+errata_report_shim cortex_a9
 
 func cortex_a9_reset_func
 #if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
-	ldr	r0, =workaround_bpiall_runtime_exceptions
+	ldr	r0, =wa_cve_2017_5715_bpiall_vbar
 	stcopr	r0, VBAR
 	stcopr	r0, MVBAR
 	/* isb will be applied in the course of the reset func */
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index 05bc5d9..83e3e49 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S
index 6291e43..d47279a 100644
--- a/lib/cpus/aarch64/aem_generic.S
+++ b/lib/cpus/aarch64/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S
index be3c652..6ffb944 100644
--- a/lib/cpus/aarch64/cortex_a35.S
+++ b/lib/cpus/aarch64/cortex_a35.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,9 +16,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a35_disable_dcache
-	mrs	x1, sctlr_el3
-	bic	x1, x1, #SCTLR_C_BIT
-	msr	sctlr_el3, x1
+	sysreg_bit_clear sctlr_el3, SCTLR_C_BIT
 	isb
 	ret
 endfunc cortex_a35_disable_dcache
@@ -28,65 +26,29 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a35_disable_smp
-	mrs	x0, CORTEX_A35_CPUECTLR_EL1
-	bic	x0, x0, #CORTEX_A35_CPUECTLR_SMPEN_BIT
-	msr	CORTEX_A35_CPUECTLR_EL1, x0
+	sysreg_bit_clear CORTEX_A35_CPUECTLR_EL1, CORTEX_A35_CPUECTLR_SMPEN_BIT
 	isb
 	dsb	sy
 	ret
 endfunc cortex_a35_disable_smp
 
-	 /* ---------------------------------------------------
-	 * Errata Workaround for Cortex A35 Errata #855472.
-	 * This applies to revisions r0p0 of Cortex A35.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a35_855472_wa
-	 /*
-	  * Compare x0 against revision r0p0
-	  */
-	 mov	x17, x30
-	 bl	check_errata_855472
-	 cbz	x0, 1f
-	 mrs	x1, CORTEX_A35_CPUACTLR_EL1
-	 orr	x1, x1, #CORTEX_A35_CPUACTLR_EL1_ENDCCASCI
-	 msr	CORTEX_A35_CPUACTLR_EL1, x1
-	 isb
-1:
-	ret	x17
-endfunc errata_a35_855472_wa
+workaround_reset_start cortex_a35, ERRATUM(855472), ERRATA_A35_855472
+	sysreg_bit_set CORTEX_A35_CPUACTLR_EL1, CORTEX_A35_CPUACTLR_EL1_ENDCCASCI
+workaround_reset_end cortex_a35, ERRATUM(855472)
 
-func check_errata_855472
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_855472
+check_erratum_ls cortex_a35, ERRATUM(855472), CPU_REV(0, 0)
 
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A35.
-	 * Clobbers: x0
 	 * -------------------------------------------------
 	 */
-func cortex_a35_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-
-#if ERRATA_A35_855472
-	bl	errata_a35_855472_wa
-#endif
-
+cpu_reset_func_start cortex_a35
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A35_CPUECTLR_EL1
-	orr	x0, x0, #CORTEX_A35_CPUECTLR_SMPEN_BIT
-	msr	CORTEX_A35_CPUECTLR_EL1, x0
-	isb
-	ret	x19
-endfunc cortex_a35_reset_func
+	sysreg_bit_set CORTEX_A35_CPUECTLR_EL1, CORTEX_A35_CPUECTLR_SMPEN_BIT
+cpu_reset_func_end cortex_a35
 
 func cortex_a35_core_pwr_dwn
 	mov	x18, x30
@@ -149,27 +111,7 @@
 	b	cortex_a35_disable_smp
 endfunc cortex_a35_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A35. Must follow AAPCS.
- */
-func cortex_a35_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A35_855472, cortex_a35, 855472
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a35_errata_report
-#endif
-
+errata_report_shim cortex_a35
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a35 specific
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index e10ebb0..6fce24e 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -21,110 +21,15 @@
 #error "Cortex-A510 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #1922240.
-	 * This applies only to revision r0p0 (fixed in r0p1)
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_1922240_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1922240
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a510, ERRATUM(1922240), ERRATA_A510_1922240
 	/* Apply the workaround by setting IMP_CMPXACTLR_EL1[11:10] = 0b11. */
-	mrs	x0, CORTEX_A510_CMPXACTLR_EL1
-	mov	x1, #3
-	bfi	x0, x1, #10, #2
-	msr	CORTEX_A510_CMPXACTLR_EL1, x0
-
-1:
-	ret	x17
-endfunc errata_cortex_a510_1922240_wa
-
-func check_errata_1922240
-	/* Applies to r0p0 only */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1922240
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2288014.
-	 * This applies only to revisions r0p0, r0p1, r0p2,
-	 * r0p3 and r1p0. (fixed in r1p1)
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_2288014_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2288014
-	cbz	x0, 1f
-
-	/* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */
-	mrs	x0, CORTEX_A510_CPUACTLR_EL1
-	mov	x1, #1
-	bfi	x0, x1, #18, #1
-	msr	CORTEX_A510_CPUACTLR_EL1, x0
-
-1:
-	ret	x17
-endfunc errata_cortex_a510_2288014_wa
-
-func check_errata_2288014
-	/* Applies to r1p0 and below */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_2288014
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2042739.
-	 * This applies only to revisions r0p0, r0p1 and r0p2.
-	 * (fixed in r0p3)
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_2042739_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2042739
-	cbz	x0, 1f
-
-	/* Apply the workaround by disabling ReadPreferUnique. */
-	mrs	x0, CORTEX_A510_CPUECTLR_EL1
-	mov	x1, #CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE
-	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT, #1
-	msr	CORTEX_A510_CPUECTLR_EL1, x0
-
-1:
-	ret	x17
-endfunc errata_cortex_a510_2042739_wa
+	sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_DISABLE, \
+	CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_WIDTH
+workaround_reset_end cortex_a510, ERRATUM(1922240)
 
-func check_errata_2042739
-	/* Applies to revisions r0p0 - r0p2 */
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-endfunc check_errata_2042739
+check_erratum_ls cortex_a510, ERRATUM(1922240), CPU_REV(0, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2041909.
-	 * This applies only to revision r0p2 and it is fixed in
-	 * r0p3. The issue is also present in r0p0 and r0p1 but
-	 * there is no workaround in those revisions.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x2, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_2041909_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2041909
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a510, ERRATUM(2041909), ERRATA_A510_2041909
 	/* Apply workaround */
 	mov	x0, xzr
 	msr	S3_6_C15_C4_0, x0
@@ -140,39 +45,55 @@
 	mov	x0, #0x3F1
 	movk	x0, #0x110, lsl #16
 	msr	S3_6_C15_C4_1, x0
-	isb
+workaround_reset_end cortex_a510, ERRATUM(2041909)
+
+check_erratum_range cortex_a510, ERRATUM(2041909), CPU_REV(0, 2), CPU_REV(0, 2)
+
+workaround_reset_start cortex_a510, ERRATUM(2042739), ERRATA_A510_2042739
+	/* Apply the workaround by disabling ReadPreferUnique. */
+	sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE, \
+		CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_WIDTH
+workaround_reset_end cortex_a510, ERRATUM(2042739)
 
-1:
-	ret	x17
-endfunc errata_cortex_a510_2041909_wa
+check_erratum_ls cortex_a510, ERRATUM(2042739), CPU_REV(0, 2)
 
-func check_errata_2041909
-	/* Applies only to revision r0p2 */
-	mov	x1, #0x02
-	mov	x2, #0x02
-	b	cpu_rev_var_range
-endfunc check_errata_2041909
+workaround_reset_start cortex_a510, ERRATUM(2172148), ERRATA_A510_2172148
+	/*
+	 * Force L2 allocation of transient lines by setting
+	 * CPUECTLR_EL1.RSCTL=0b01 and CPUECTLR_EL1.NTCTL=0b01.
+	 */
+	mrs	x0, CORTEX_A510_CPUECTLR_EL1
+	mov	x1, #1
+	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT, #2
+	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT, #2
+	msr	CORTEX_A510_CPUECTLR_EL1, x0
+workaround_reset_end cortex_a510, ERRATUM(2172148)
+
+check_erratum_ls cortex_a510, ERRATUM(2172148), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a510, ERRATUM(2218950), ERRATA_A510_2218950
+	/* Set bit 18 in CPUACTLR_EL1 */
+	sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \
+	CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_WIDTH
+
+	/* Set bit 25 in CMPXACTLR_EL1 */
+	sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \
+	CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_WIDTH
+
+workaround_reset_end cortex_a510, ERRATUM(2218950)
+
+check_erratum_ls cortex_a510, ERRATUM(2218950), CPU_REV(1, 0)
 
 	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2250311.
-	 * This applies only to revisions r0p0, r0p1, r0p2,
-	 * r0p3 and r1p0, and is fixed in r1p1.
 	 * This workaround is not a typical errata fix. MPMM
 	 * is disabled here, but this conflicts with the BL31
 	 * MPMM support. So in addition to simply disabling
 	 * the feature, a flag is set in the MPMM library
 	 * indicating that it should not be enabled even if
 	 * ENABLE_MPMM=1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
 	 * --------------------------------------------------
 	 */
-func errata_cortex_a510_2250311_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2250311
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a510, ERRATUM(2250311), ERRATA_A510_2250311
 	/* Disable MPMM */
 	mrs	x0, CPUMPMMCR_EL3
 	bfm	x0, xzr, #0, #0 /* bfc instruction does not work in GCC */
@@ -182,227 +103,68 @@
 	/* If ENABLE_MPMM is set, tell the runtime lib to skip enabling it. */
 	bl mpmm_errata_disable
 #endif
-
-1:
-	ret x17
-endfunc errata_cortex_a510_2250311_wa
-
-func check_errata_2250311
-	/* Applies to r1p0 and lower */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_2250311
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2218950.
-	 * This applies only to revisions r0p0, r0p1, r0p2,
-	 * r0p3 and r1p0, and is fixed in r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_2218950_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2218950
-	cbz	x0, 1f
-
-	/* Source register for BFI */
-	mov	x1, #1
-
-	/* Set bit 18 in CPUACTLR_EL1 */
-	mrs	x0, CORTEX_A510_CPUACTLR_EL1
-	bfi	x0, x1, #18, #1
-	msr	CORTEX_A510_CPUACTLR_EL1, x0
-
-	/* Set bit 25 in CMPXACTLR_EL1 */
-	mrs	x0, CORTEX_A510_CMPXACTLR_EL1
-	bfi	x0, x1, #25, #1
-	msr	CORTEX_A510_CMPXACTLR_EL1, x0
-
-1:
-	ret x17
-endfunc errata_cortex_a510_2218950_wa
+workaround_reset_end cortex_a510, ERRATUM(2250311)
 
-func check_errata_2218950
-	/* Applies to r1p0 and lower */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_2218950
+check_erratum_ls cortex_a510, ERRATUM(2250311), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2172148.
-	 * This applies only to revisions r0p0, r0p1, r0p2,
-	 * r0p3 and r1p0, and is fixed in r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_a510_2172148_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2172148
-	cbz	x0, 1f
-
-	/*
-	 * Force L2 allocation of transient lines by setting
-	 * CPUECTLR_EL1.RSCTL=0b01 and CPUECTLR_EL1.NTCTL=0b01.
-	 */
-	mrs	x0, CORTEX_A510_CPUECTLR_EL1
-	mov	x1, #1
-	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT, #2
-	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT, #2
-	msr	CORTEX_A510_CPUECTLR_EL1, x0
-
-1:
-	ret x17
-endfunc errata_cortex_a510_2172148_wa
-
-func check_errata_2172148
-	/* Applies to r1p0 and lower */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_2172148
+workaround_reset_start cortex_a510, ERRATUM(2288014), ERRATA_A510_2288014
+	/* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */
+	sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_DISABLE, \
+	CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH
+workaround_reset_end cortex_a510, ERRATUM(2288014)
 
-	/* ----------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2347730.
-	 * This applies to revisions r0p0 - r0p3, r1p0, r1p1.
-	 * It is fixed in r1p2.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x1, x17
-	 * ----------------------------------------------------
-	 */
-func errata_cortex_a510_2347730_wa
-	mov	x17, x30
-	bl	check_errata_2347730
-	cbz	x0, 1f
+check_erratum_ls cortex_a510, ERRATUM(2288014), CPU_REV(1, 0)
 
+workaround_reset_start cortex_a510, ERRATUM(2347730), ERRATA_A510_2347730
 	/*
 	 * Set CPUACTLR_EL1[17] to 1'b1, which disables
 	 * specific microarchitectural clock gating
 	 * behaviour.
 	 */
-	mrs	x1, CORTEX_A510_CPUACTLR_EL1
-	orr	x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_17
-	msr	CORTEX_A510_CPUACTLR_EL1, x1
-1:
-	ret x17
-endfunc errata_cortex_a510_2347730_wa
-
-func check_errata_2347730
-	/* Applies to revisions r1p1 and lower. */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2347730
+	sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_17
+workaround_reset_end cortex_a510, ERRATUM(2347730)
 
-	/*---------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2371937.
-	 * This applies to revisions r1p1 and lower, and is
-	 * fixed in r1p2.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 *---------------------------------------------------
-	 */
-func errata_cortex_a510_2371937_wa
-	mov	x17, x30
-	bl	check_errata_2371937
-	cbz	x0, 1f
+check_erratum_ls cortex_a510, ERRATUM(2347730), CPU_REV(1, 1)
 
+workaround_reset_start cortex_a510, ERRATUM(2371937), ERRATA_A510_2371937
 	/*
 	 * Cacheable atomic operations can be forced
 	 * to be executed near by setting
 	 * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found
 	 * in [40:38] of CPUECTLR_EL1.
 	 */
-	mrs 	x0, CORTEX_A510_CPUECTLR_EL1
-	mov 	x1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR
-	bfi 	x0, x1, CORTEX_A510_CPUECTLR_EL1_ATOM, #3
-	msr 	CORTEX_A510_CPUECTLR_EL1, x0
-1:
-	ret 	x17
-endfunc errata_cortex_a510_2371937_wa
-
-func check_errata_2371937
-	/* Applies to r1p1 and lower */
-	mov 	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2371937
-
-	/* ------------------------------------------------------
-	 * Errata Workaround for Cortex-A510 Errata #2666669
-	 * This applies to revisions r1p1 and lower, and is fixed
-	 * in r1p2.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * ------------------------------------------------------
-	 */
-func errata_cortex_a510_2666669_wa
-	mov	x17, x30
-	bl	check_errata_2666669
-	cbz	x0, 1f
-
-	/*
-	 * Workaround will set IMP_CPUACTLR_EL1[38]
-	 * to 0b1.
-	 */
-	mrs	x1, CORTEX_A510_CPUACTLR_EL1
-	orr	x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_38
-	msr	CORTEX_A510_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_cortex_a510_2666669_wa
+	sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR, \
+		CORTEX_A510_CPUECTLR_EL1_ATOM_SHIFT, CORTEX_A510_CPUECTLR_EL1_ATOM_WIDTH
+workaround_reset_end cortex_a510, ERRATUM(2371937)
 
-func check_errata_2666669
-	/* Applies to r1p1 and lower */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2666669
+check_erratum_ls cortex_a510, ERRATUM(2371937), CPU_REV(1, 1)
 
-/* ------------------------------------------------------
- * Errata Workaround for Cortex-A510 Erratum 2684597.
- * This erratum applies to revision r0p0, r0p1, r0p2,
- * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
- * is fixed in r1p3.
- * Shall clobber: x0-x17
- * ------------------------------------------------------
- */
-	.globl	errata_cortex_a510_2684597_wa
-func errata_cortex_a510_2684597_wa
-	mov	x17, x30
-	/* Ensure this errata is only applied to Cortex-A510 cores */
-	jump_if_cpu_midr	CORTEX_A510_MIDR,	1f
-	b	2f
+workaround_reset_start cortex_a510, ERRATUM(2666669), ERRATA_A510_2666669
+	sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_38
+workaround_reset_end cortex_a510, ERRATUM(2666669)
 
-1:
-	/* Check workaround compatibility. */
-	mov	x0, x18
-	bl	check_errata_2684597
-	cbz	x0, 2f
+check_erratum_ls cortex_a510, ERRATUM(2666669), CPU_REV(1, 1)
 
+.global erratum_cortex_a510_2684597_wa
+workaround_runtime_start cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, CORTEX_A510_MIDR
 	/*
 	 * Many assemblers do not yet understand the "tsb csync" mnemonic,
 	 * so use the equivalent hint instruction.
 	 */
 	hint	#18			/* tsb csync */
-2:
-	ret	x17
-endfunc errata_cortex_a510_2684597_wa
-/* ------------------------------------------------------
- * Errata Workaround for Cortex-A510 Erratum 2684597.
- * This erratum applies to revision r0p0, r0p1, r0p2,
- * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
- * is fixed in r1p3.
- * Shall clobber: x0-x17
- * ------------------------------------------------------
+workaround_runtime_end cortex_a510, ERRATUM(2684597)
+
+check_erratum_ls cortex_a510, ERRATUM(2684597), CPU_REV(1, 2)
+
+/*
+ * ERRATA_DSU_2313941 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_a510
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
  */
-func check_errata_2684597
-	/* Applies to revision < r1p3 */
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_2684597
+.equ check_erratum_cortex_a510_2313941, check_errata_dsu_2313941
+.equ erratum_cortex_a510_2313941_wa, errata_dsu_2313941_wa
+add_erratum_entry cortex_a510, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -413,112 +175,17 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A510_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A510_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A510_CPUPWRCTLR_EL1, CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_a510_core_pwr_dwn
 
-	/*
-	 * Errata printing function for Cortex-A510. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_a510_errata_report
-	stp	x8, x30, [sp, #-16]!
+errata_report_shim cortex_a510
 
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A510_1922240, cortex_a510, 1922240
-	report_errata ERRATA_A510_2041909, cortex_a510, 2041909
-	report_errata ERRATA_A510_2042739, cortex_a510, 2042739
-	report_errata ERRATA_A510_2172148, cortex_a510, 2172148
-	report_errata ERRATA_A510_2218950, cortex_a510, 2218950
-	report_errata ERRATA_A510_2250311, cortex_a510, 2250311
-	report_errata ERRATA_A510_2288014, cortex_a510, 2288014
-	report_errata ERRATA_A510_2347730, cortex_a510, 2347730
-	report_errata ERRATA_A510_2371937, cortex_a510, 2371937
-	report_errata ERRATA_A510_2666669, cortex_a510, 2666669
-	report_errata ERRATA_A510_2684597, cortex_a510, 2684597
-	report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a510_errata_report
-#endif
-
-func cortex_a510_reset_func
-	mov	x19, x30
-
+cpu_reset_func_start cortex_a510
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-
-	/* Get the CPU revision and stash it in x18. */
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_DSU_2313941
-	bl	errata_dsu_2313941_wa
-#endif
-
-#if ERRATA_A510_1922240
-	mov	x0, x18
-	bl	errata_cortex_a510_1922240_wa
-#endif
-
-#if ERRATA_A510_2288014
-	mov	x0, x18
-	bl	errata_cortex_a510_2288014_wa
-#endif
-
-#if ERRATA_A510_2042739
-	mov	x0, x18
-	bl	errata_cortex_a510_2042739_wa
-#endif
-
-#if ERRATA_A510_2041909
-	mov	x0, x18
-	bl	errata_cortex_a510_2041909_wa
-#endif
-
-#if ERRATA_A510_2250311
-	mov	x0, x18
-	bl	errata_cortex_a510_2250311_wa
-#endif
-
-#if ERRATA_A510_2218950
-	mov	x0, x18
-	bl	errata_cortex_a510_2218950_wa
-#endif
-
-#if ERRATA_A510_2371937
-	mov 	x0, x18
-	bl	errata_cortex_a510_2371937_wa
-#endif
-
-#if ERRATA_A510_2172148
-	mov	x0, x18
-	bl	errata_cortex_a510_2172148_wa
-#endif
-
-#if ERRATA_A510_2347730
-	mov	x0, x18
-	bl	errata_cortex_a510_2347730_wa
-#endif
-
-#if ERRATA_A510_2666669
-	mov	x0, x18
-	bl	errata_cortex_a510_2666669_wa
-#endif
-
-	isb
-	ret	x19
-endfunc cortex_a510_reset_func
+cpu_reset_func_end cortex_a510
 
 	/* ---------------------------------------------
 	 * This function provides Cortex-A510 specific
diff --git a/lib/cpus/aarch64/cortex_a520.S b/lib/cpus/aarch64/cortex_a520.S
index 5bbe862..6c2f33e 100644
--- a/lib/cpus/aarch64/cortex_a520.S
+++ b/lib/cpus/aarch64/cortex_a520.S
@@ -30,28 +30,17 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A520_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A520_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A520_CPUPWRCTLR_EL1, CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_a520_core_pwr_dwn
 
-	/*
-	 * Errata printing function for Cortex A520. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_a520_errata_report
-	ret
-endfunc cortex_a520_errata_report
-#endif
+errata_report_shim cortex_a520
 
-func cortex_a520_reset_func
+cpu_reset_func_start cortex_a520
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_a520_reset_func
+cpu_reset_func_end cortex_a520
 
 	/* ---------------------------------------------
 	 * This function provides Cortex A520 specific
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index ecaf422..e6fb08a 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,19 +12,12 @@
 #include <plat_macros.S>
 #include <lib/cpus/errata.h>
 
-#if A53_DISABLE_NON_TEMPORAL_HINT
-#undef ERRATA_A53_836870
-#define ERRATA_A53_836870	1
-#endif
-
 	/* ---------------------------------------------
 	 * Disable L1 data cache and unified L2 cache
 	 * ---------------------------------------------
 	 */
 func cortex_a53_disable_dcache
-	mrs	x1, sctlr_el3
-	bic	x1, x1, #SCTLR_C_BIT
-	msr	sctlr_el3, x1
+	sysreg_bit_clear sctlr_el3, SCTLR_C_BIT
 	isb
 	ret
 endfunc cortex_a53_disable_dcache
@@ -34,169 +27,38 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a53_disable_smp
-	mrs	x0, CORTEX_A53_ECTLR_EL1
-	bic	x0, x0, #CORTEX_A53_ECTLR_SMP_BIT
-	msr	CORTEX_A53_ECTLR_EL1, x0
+	sysreg_bit_clear CORTEX_A53_ECTLR_EL1, CORTEX_A53_ECTLR_SMP_BIT
 	isb
 	dsb	sy
 	ret
 endfunc cortex_a53_disable_smp
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A53 Errata #819472.
-	 * This applies only to revision <= r0p1 of Cortex A53.
-	 * Due to the nature of the errata it is applied unconditionally
-	 * when built in, report it as applicable in this case
-	 * ---------------------------------------------------
-	 */
-func check_errata_819472
-#if ERRATA_A53_819472
-	mov x0, #ERRATA_APPLIES
-	ret
-#else
-	mov	x1, #0x01
-	b	cpu_rev_var_ls
-#endif
-endfunc check_errata_819472
+/* Due to the nature of the errata it is applied unconditionally when chosen */
+check_erratum_ls cortex_a53, ERRATUM(819472), CPU_REV(0, 1)
+/* erratum workaround is interleaved with generic code */
+add_erratum_entry cortex_a53, ERRATUM(819472), ERRATUM_ALWAYS_CHOSEN, NO_APPLY_AT_RESET
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A53 Errata #824069.
-	 * This applies only to revision <= r0p2 of Cortex A53.
-	 * Due to the nature of the errata it is applied unconditionally
-	 * when built in, report it as applicable in this case
-	 * ---------------------------------------------------
-	 */
-func check_errata_824069
-#if ERRATA_A53_824069
-	mov x0, #ERRATA_APPLIES
-	ret
-#else
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-#endif
-endfunc check_errata_824069
+/* Due to the nature of the errata it is applied unconditionally when chosen */
+check_erratum_ls cortex_a53, ERRATUM(824069), CPU_REV(0, 2)
+/* erratum workaround is interleaved with generic code */
+add_erratum_entry cortex_a53, ERRATUM(824069), ERRATUM_ALWAYS_CHOSEN, NO_APPLY_AT_RESET
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A53 Errata #826319.
-	 * This applies only to revision <= r0p2 of Cortex A53.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a53_826319_wa
-	/*
-	 * Compare x0 against revision r0p2
-	 */
-	mov	x17, x30
-	bl	check_errata_826319
-	cbz	x0, 1f
+workaround_reset_start cortex_a53, ERRATUM(826319), ERRATA_A53_826319
 	mrs	x1, CORTEX_A53_L2ACTLR_EL1
 	bic	x1, x1, #CORTEX_A53_L2ACTLR_ENABLE_UNIQUECLEAN
 	orr	x1, x1, #CORTEX_A53_L2ACTLR_DISABLE_CLEAN_PUSH
 	msr	CORTEX_A53_L2ACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a53_826319_wa
-
-func check_errata_826319
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-endfunc check_errata_826319
-
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A53 Errata #827319.
-	 * This applies only to revision <= r0p2 of Cortex A53.
-	 * Due to the nature of the errata it is applied unconditionally
-	 * when built in, report it as applicable in this case
-	 * ---------------------------------------------------
-	 */
-func check_errata_827319
-#if ERRATA_A53_827319
-	mov x0, #ERRATA_APPLIES
-	ret
-#else
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-#endif
-endfunc check_errata_827319
-
-	/* ---------------------------------------------------------------------
-	 * Disable the cache non-temporal hint.
-	 *
-	 * This ignores the Transient allocation hint in the MAIR and treats
-	 * allocations the same as non-transient allocation types. As a result,
-	 * the LDNP and STNP instructions in AArch64 behave the same as the
-	 * equivalent LDP and STP instructions.
-	 *
-	 * This is relevant only for revisions <= r0p3 of Cortex-A53.
-	 * From r0p4 and onwards, the bit to disable the hint is enabled by
-	 * default at reset.
-	 *
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------------------------
-	 */
-func a53_disable_non_temporal_hint
-	/*
-	 * Compare x0 against revision r0p3
-	 */
-	mov	x17, x30
-	bl	check_errata_disable_non_temporal_hint
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A53_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A53_CPUACTLR_EL1_DTAH
-	msr	CORTEX_A53_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc a53_disable_non_temporal_hint
-
-func check_errata_disable_non_temporal_hint
-	mov	x1, #0x03
-	b	cpu_rev_var_ls
-endfunc check_errata_disable_non_temporal_hint
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A53 Errata #855873.
-	 *
-	 * This applies only to revisions >= r0p3 of Cortex A53.
-	 * Earlier revisions of the core are affected as well, but don't
-	 * have the chicken bit in the CPUACTLR register. It is expected that
-	 * the rich OS takes care of that, especially as the workaround is
-	 * shared with other erratas in those revisions of the CPU.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a53_855873_wa
-	/*
-	 * Compare x0 against revision r0p3 and higher
-	 */
-        mov     x17, x30
-        bl      check_errata_855873
-        cbz     x0, 1f
+workaround_reset_end cortex_a53, ERRATUM(826319)
 
-	mrs	x1, CORTEX_A53_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A53_CPUACTLR_EL1_ENDCCASCI
-	msr	CORTEX_A53_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a53_855873_wa
+check_erratum_ls cortex_a53, ERRATUM(826319), CPU_REV(0, 2)
 
-func check_errata_855873
-	mov	x1, #0x03
-	b	cpu_rev_var_hs
-endfunc check_errata_855873
+/* Due to the nature of the errata it is applied unconditionally when chosen */
+check_erratum_ls cortex_a53, ERRATUM(827319), CPU_REV(0, 2)
+/* erratum workaround is interleaved with generic code */
+add_erratum_entry cortex_a53, ERRATUM(827319), ERRATUM_ALWAYS_CHOSEN, NO_APPLY_AT_RESET
 
-/*
- * Errata workaround for Cortex A53 Errata #835769.
- * This applies to revisions <= r0p4 of Cortex A53.
- * This workaround is statically enabled at build time.
- */
-func check_errata_835769
-	cmp	x0, #0x04
+check_erratum_custom_start cortex_a53, ERRATUM(835769)
+	cmp	x0, CPU_REV(0, 4)
 	b.hi	errata_not_applies
 	/*
 	 * Fix potentially available for revisions r0p2, r0p3 and r0p4.
@@ -213,17 +75,29 @@
 	mov	x0, #ERRATA_NOT_APPLIES
 exit_check_errata_835769:
 	ret
-endfunc check_errata_835769
+check_erratum_custom_end cortex_a53, ERRATUM(835769)
 
-/*
- * Errata workaround for Cortex A53 Errata #843419.
- * This applies to revisions <= r0p4 of Cortex A53.
- * This workaround is statically enabled at build time.
- */
-func check_errata_843419
+/* workaround at build time */
+add_erratum_entry cortex_a53, ERRATUM(835769), ERRATA_A53_835769, NO_APPLY_AT_RESET
+
+	/*
+	 * Disable the cache non-temporal hint.
+	 *
+	 * This ignores the Transient allocation hint in the MAIR and treats
+	 * allocations the same as non-transient allocation types. As a result,
+	 * the LDNP and STNP instructions in AArch64 behave the same as the
+	 * equivalent LDP and STP instructions.
+	 */
+workaround_reset_start cortex_a53, ERRATUM(836870), ERRATA_A53_836870 | A53_DISABLE_NON_TEMPORAL_HINT
+	sysreg_bit_set CORTEX_A53_CPUACTLR_EL1, CORTEX_A53_CPUACTLR_EL1_DTAH
+workaround_reset_end cortex_a53, ERRATUM(836870)
+
+check_erratum_ls cortex_a53, ERRATUM(836870), CPU_REV(0, 3)
+
+check_erratum_custom_start cortex_a53, ERRATUM(843419)
 	mov	x1, #ERRATA_APPLIES
 	mov	x2, #ERRATA_NOT_APPLIES
-	cmp	x0, #0x04
+	cmp	x0, CPU_REV(0, 4)
 	csel	x0, x1, x2, ls
 	/*
 	 * Fix potentially available for revision r0p4.
@@ -237,58 +111,32 @@
 	mov	x0, x2
 exit_check_errata_843419:
 	ret
-endfunc check_errata_843419
+check_erratum_custom_end cortex_a53, ERRATUM(843419)
 
-	/* --------------------------------------------------
-	 * Errata workaround for Cortex A53 Errata #1530924.
-	 * This applies to all revisions of Cortex A53.
-	 * --------------------------------------------------
-	 */
-func check_errata_1530924
-#if ERRATA_A53_1530924
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_1530924
+/* workaround at build time */
+add_erratum_entry cortex_a53, ERRATUM(843419), ERRATA_A53_843419, NO_APPLY_AT_RESET
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A53.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
+	/*
+	 * Earlier revisions of the core are affected as well, but don't
+	 * have the chicken bit in the CPUACTLR register. It is expected that
+	 * the rich OS takes care of that, especially as the workaround is
+	 * shared with other erratas in those revisions of the CPU.
 	 */
-func cortex_a53_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+workaround_reset_start cortex_a53, ERRATUM(855873), ERRATA_A53_855873
+	sysreg_bit_set CORTEX_A53_CPUACTLR_EL1, CORTEX_A53_CPUACTLR_EL1_ENDCCASCI
+workaround_reset_end cortex_a53, ERRATUM(855873)
 
+check_erratum_hs cortex_a53, ERRATUM(855873), CPU_REV(0, 3)
 
-#if ERRATA_A53_826319
-	mov	x0, x18
-	bl	errata_a53_826319_wa
-#endif
+check_erratum_chosen cortex_a53, ERRATUM(1530924), ERRATA_A53_1530924
 
-#if ERRATA_A53_836870
-	mov	x0, x18
-	bl	a53_disable_non_temporal_hint
-#endif
+/* erratum has no workaround in the cpu. Generic code must take care */
+add_erratum_entry cortex_a53, ERRATUM(1530924), ERRATA_A53_1530924, NO_APPLY_AT_RESET
 
-#if ERRATA_A53_855873
-	mov	x0, x18
-	bl	errata_a53_855873_wa
-#endif
-
-	/* ---------------------------------------------
-	 * Enable the SMP bit.
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_A53_ECTLR_EL1
-	orr	x0, x0, #CORTEX_A53_ECTLR_SMP_BIT
-	msr	CORTEX_A53_ECTLR_EL1, x0
-	isb
-	ret	x19
-endfunc cortex_a53_reset_func
+cpu_reset_func_start cortex_a53
+	/* Enable the SMP bit. */
+	sysreg_bit_set CORTEX_A53_ECTLR_EL1, CORTEX_A53_ECTLR_SMP_BIT
+cpu_reset_func_end cortex_a53
 
 func cortex_a53_core_pwr_dwn
 	mov	x18, x30
@@ -351,34 +199,7 @@
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A53. Must follow AAPCS.
- */
-func cortex_a53_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A53_819472, cortex_a53, 819472
-	report_errata ERRATA_A53_824069, cortex_a53, 824069
-	report_errata ERRATA_A53_826319, cortex_a53, 826319
-	report_errata ERRATA_A53_827319, cortex_a53, 827319
-	report_errata ERRATA_A53_835769, cortex_a53, 835769
-	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
-	report_errata ERRATA_A53_843419, cortex_a53, 843419
-	report_errata ERRATA_A53_855873, cortex_a53, 855873
-	report_errata ERRATA_A53_1530924, cortex_a53, 1530924
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a53_errata_report
-#endif
+errata_report_shim cortex_a53
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a53 specific
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 0e0388b..712b6e0 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,63 +18,37 @@
 
 	.globl cortex_a55_reset_func
 	.globl cortex_a55_core_pwr_dwn
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #768277.
-	 * This applies only to revision r0p0 of Cortex A55.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a55_768277_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_768277
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A55_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
-	msr	CORTEX_A55_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a55_768277_wa
 
-func check_errata_768277
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_768277
+/* ERRATA_DSU_798953:
+ * The errata is defined in dsu_helpers.S but applies to cortex_a55
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a55_798953, check_errata_dsu_798953
+.equ erratum_cortex_a55_798953_wa, errata_dsu_798953_wa
+add_erratum_entry cortex_a55, ERRATUM(798953), ERRATA_DSU_798953, APPLY_AT_RESET
 
-	/* ------------------------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #778703.
-	 * This applies only to revision r0p0 of Cortex A55 where L2 cache is
-	 * not configured.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ------------------------------------------------------------------
-	 */
-func errata_a55_778703_wa
-	/*
-	 * Compare x0 against revision r0p0 and check that no private L2 cache
-	 * is configured
-	 */
-	mov	x17, x30
-	bl	check_errata_778703
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A55_CPUECTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUECTLR_EL1_L1WSCTL
-	msr	CORTEX_A55_CPUECTLR_EL1, x1
-	mrs	x1, CORTEX_A55_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_WRITE_STREAMING
-	msr	CORTEX_A55_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a55_778703_wa
+/* ERRATA_DSU_936184:
+ * The errata is defined in dsu_helpers.S but applies to cortex_a55
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a55_936184, check_errata_dsu_936184
+.equ erratum_cortex_a55_936184_wa, errata_dsu_936184_wa
+add_erratum_entry cortex_a55, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
+
+workaround_reset_start cortex_a55, ERRATUM(768277), ERRATA_A55_768277
+	sysreg_bit_set CORTEX_A55_CPUACTLR_EL1, CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
+workaround_reset_end cortex_a55, ERRATUM(768277)
 
-func check_errata_778703
+check_erratum_ls cortex_a55, ERRATUM(768277), CPU_REV(0, 0)
+
+workaround_reset_start cortex_a55, ERRATUM(778703), ERRATA_A55_778703
+	sysreg_bit_set CORTEX_A55_CPUECTLR_EL1, CORTEX_A55_CPUECTLR_EL1_L1WSCTL
+	sysreg_bit_set CORTEX_A55_CPUACTLR_EL1, CORTEX_A55_CPUACTLR_EL1_DISABLE_WRITE_STREAMING
+workaround_reset_end cortex_a55, ERRATUM(778703)
+
+check_erratum_custom_start cortex_a55, ERRATUM(778703)
 	mov	x16, x30
 	mov	x1, #0x00
 	bl	cpu_rev_var_ls
@@ -87,111 +61,27 @@
 	mov	x2, #ERRATA_NOT_APPLIES
 	csel	x0, x0, x2, eq
 	ret	x16
-endfunc check_errata_778703
+check_erratum_custom_end cortex_a55, ERRATUM(778703)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #798797.
-	 * This applies only to revision r0p0 of Cortex A55.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a55_798797_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_798797
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A55_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
-	msr	CORTEX_A55_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a55_798797_wa
+workaround_reset_start cortex_a55, ERRATUM(798797), ERRATA_A55_798797
+	sysreg_bit_set CORTEX_A55_CPUACTLR_EL1, CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
+workaround_reset_end cortex_a55, ERRATUM(798797)
 
-func check_errata_798797
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_798797
+check_erratum_ls cortex_a55, ERRATUM(798797), CPU_REV(0, 0)
 
-	/* --------------------------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #846532.
-	 * This applies only to revisions <= r0p1 of Cortex A55.
-	 * Disabling dual-issue has a small impact on performance. Disabling a
-	 * power optimization feature is an alternate workaround with no impact
-	 * on performance but with an increase in power consumption (see errata
-	 * notice).
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------------------------
-	 */
-func errata_a55_846532_wa
-	/*
-	 * Compare x0 against revision r0p1
-	 */
-	mov	x17, x30
-	bl	check_errata_846532
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A55_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
-	msr	CORTEX_A55_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a55_846532_wa
+workaround_reset_start cortex_a55, ERRATUM(846532), ERRATA_A55_846532
+	sysreg_bit_set CORTEX_A55_CPUACTLR_EL1, CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
+workaround_reset_end cortex_a55, ERRATUM(846532)
 
-func check_errata_846532
-	mov	x1, #0x01
-	b	cpu_rev_var_ls
-endfunc check_errata_846532
+check_erratum_ls cortex_a55, ERRATUM(846532), CPU_REV(0, 1)
 
-	/* -----------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #903758.
-	 * This applies only to revisions <= r0p1 of Cortex A55.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * -----------------------------------------------------
-	 */
-func errata_a55_903758_wa
-	/*
-	 * Compare x0 against revision r0p1
-	 */
-	mov	x17, x30
-	bl	check_errata_903758
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A55_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
-	msr	CORTEX_A55_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a55_903758_wa
+workaround_reset_start cortex_a55, ERRATUM(903758), ERRATA_A55_903758
+	sysreg_bit_set CORTEX_A55_CPUACTLR_EL1, CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
+workaround_reset_end cortex_a55, ERRATUM(903758)
 
-func check_errata_903758
-	mov	x1, #0x01
-	b	cpu_rev_var_ls
-endfunc check_errata_903758
+check_erratum_ls cortex_a55, ERRATUM(903758), CPU_REV(0, 1)
 
-	/* -----------------------------------------------------
-	 * Errata Workaround for Cortex A55 Errata #1221012.
-	 * This applies only to revisions <= r1p0 of Cortex A55.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * -----------------------------------------------------
-	 */
-func errata_a55_1221012_wa
-	/*
-	 * Compare x0 against revision r1p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1221012
-	cbz	x0, 1f
+workaround_reset_start cortex_a55, ERRATUM(1221012), ERRATA_A55_1221012
 	mov	x0, #0x0020
 	movk	x0, #0x0850, lsl #16
 	msr	CPUPOR_EL3, x0
@@ -214,121 +104,30 @@
 	mov	x0, #0x03fd
 	movk	x0, #0x0110, lsl #16
 	msr	CPUPCR_EL3, x0
-	isb
-1:
-	ret	x17
-endfunc errata_a55_1221012_wa
+workaround_reset_end cortex_a55, ERRATUM(1221012)
 
-func check_errata_1221012
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1221012
+check_erratum_ls cortex_a55, ERRATUM(1221012), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata workaround for Cortex A55 Errata #1530923.
-	 * This applies to all revisions of Cortex A55.
-	 * --------------------------------------------------
-	 */
-func check_errata_1530923
-#if ERRATA_A55_1530923
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_1530923
-
-func cortex_a55_reset_func
-	mov	x19, x30
-
-#if ERRATA_DSU_798953
-	bl	errata_dsu_798953_wa
-#endif
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
-#endif
-
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A55_768277
-	mov	x0, x18
-	bl	errata_a55_768277_wa
-#endif
-
-#if ERRATA_A55_778703
-	mov	x0, x18
-	bl	errata_a55_778703_wa
-#endif
-
-#if ERRATA_A55_798797
-	mov	x0, x18
-	bl	errata_a55_798797_wa
-#endif
+check_erratum_chosen cortex_a55, ERRATUM(1530923), ERRATA_A55_1530923
 
-#if ERRATA_A55_846532
-	mov	x0, x18
-	bl	errata_a55_846532_wa
-#endif
-
-#if ERRATA_A55_903758
-	mov	x0, x18
-	bl	errata_a55_903758_wa
-#endif
+/* erratum has no workaround in the cpu. Generic code must take care */
+add_erratum_entry cortex_a55, ERRATUM(1530923), ERRATA_A55_1530923, NO_APPLY_AT_RESET
 
-#if ERRATA_A55_1221012
-	mov	x0, x18
-	bl	errata_a55_1221012_wa
-#endif
+cpu_reset_func_start cortex_a55
+cpu_reset_func_end cortex_a55
 
-	ret	x19
-endfunc cortex_a55_reset_func
+errata_report_shim cortex_a55
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
 	 */
 func cortex_a55_core_pwr_dwn
-	/* ---------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_A55_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A55_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A55_CPUPWRCTLR_EL1, CORTEX_A55_CORE_PWRDN_EN_MASK
 	isb
 	ret
 endfunc cortex_a55_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A55. Must follow AAPCS & can use stack.
- */
-func cortex_a55_errata_report
-	stp	x8, x30, [sp, #-16]!
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision variant information is at x8, where
-	 * "report_errata" is expecting it and it doesn't corrupt it.
-	 */
-	report_errata ERRATA_DSU_798953, cortex_a55, dsu_798953
-	report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184
-	report_errata ERRATA_A55_768277, cortex_a55, 768277
-	report_errata ERRATA_A55_778703, cortex_a55, 778703
-	report_errata ERRATA_A55_798797, cortex_a55, 798797
-	report_errata ERRATA_A55_846532, cortex_a55, 846532
-	report_errata ERRATA_A55_903758, cortex_a55, 903758
-	report_errata ERRATA_A55_1221012, cortex_a55, 1221012
-	report_errata ERRATA_A55_1530923, cortex_a55, 1530923
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a55_errata_report
-#endif
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a55 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 3766ec7..8fafaca 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -18,9 +18,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a57_disable_dcache
-	mrs	x1, sctlr_el3
-	bic	x1, x1, #SCTLR_C_BIT
-	msr	sctlr_el3, x1
+	sysreg_bit_clear sctlr_el3, SCTLR_C_BIT
 	isb
 	ret
 endfunc cortex_a57_disable_dcache
@@ -46,9 +44,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a57_disable_smp
-	mrs	x0, CORTEX_A57_ECTLR_EL1
-	bic	x0, x0, #CORTEX_A57_ECTLR_SMP_BIT
-	msr	CORTEX_A57_ECTLR_EL1, x0
+	sysreg_bit_clear CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT
 	ret
 endfunc cortex_a57_disable_smp
 
@@ -60,227 +56,66 @@
 	mov	x0, #1
 	msr	osdlr_el1, x0
 	isb
-#if ERRATA_A57_817169
-	/*
-	 * Invalidate any TLB address
-	 */
-	mov	x0, #0
-	tlbi	vae3, x0
-#endif
+
+	apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169
+
 	dsb	sy
 	ret
 endfunc cortex_a57_disable_ext_debug
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #806969.
-	 * This applies only to revision r0p0 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a57_806969_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_806969
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_806969_wa
+/*
+ * Disable the over-read from the LDNP/STNP instruction. The SDEN doesn't
+ * provide and erratum number, so assign it an obvious 1
+ */
+workaround_reset_start cortex_a57, ERRATUM(1), A57_DISABLE_NON_TEMPORAL_HINT
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD
+workaround_reset_end cortex_a57, ERRATUM(1)
 
-func check_errata_806969
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_806969
+check_erratum_ls cortex_a57, ERRATUM(1), CPU_REV(1, 2)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #813419.
-	 * This applies only to revision r0p0 of Cortex A57.
-	 * ---------------------------------------------------
-	 */
-func check_errata_813419
-	/*
-	 * Even though this is only needed for revision r0p0, it
-	 * is always applied due to limitations of the current
-	 * errata framework.
-	 */
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_errata_813419
+workaround_reset_start cortex_a57, ERRATUM(806969), ERRATA_A57_806969
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA
+workaround_reset_end cortex_a57, ERRATUM(806969)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #813420.
-	 * This applies only to revision r0p0 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_813420_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_813420
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DCC_AS_DCCI
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_813420_wa
+check_erratum_ls cortex_a57, ERRATUM(806969), CPU_REV(0, 0)
 
-func check_errata_813420
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_813420
+/* erratum always worked around, but report it correctly */
+check_erratum_ls cortex_a57, ERRATUM(813419), CPU_REV(0, 0)
+add_erratum_entry cortex_a57, ERRATUM(813419), ERRATUM_ALWAYS_CHOSEN, NO_APPLY_AT_RESET
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #814670.
-	 * This applies only to revision r0p0 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_814670_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_814670
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DIS_DMB_NULLIFICATION
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a57_814670_wa
+workaround_reset_start cortex_a57, ERRATUM(813420), ERRATA_A57_813420
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DCC_AS_DCCI
+workaround_reset_end cortex_a57, ERRATUM(813420)
 
-func check_errata_814670
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_814670
+check_erratum_ls cortex_a57, ERRATUM(813420), CPU_REV(0, 0)
 
-	/* ----------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #817169.
-	 * This applies only to revision <= r0p1 of Cortex A57.
-	 * ----------------------------------------------------
-	 */
-func check_errata_817169
-	/*
-	 * Even though this is only needed for revision <= r0p1, it
-	 * is always applied because of the low cost of the workaround.
-	 */
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_errata_817169
+workaround_reset_start cortex_a57, ERRATUM(814670), ERRATA_A57_814670
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_DMB_NULLIFICATION
+workaround_reset_end cortex_a57, ERRATUM(814670)
 
-	/* --------------------------------------------------------------------
-	 * Disable the over-read from the LDNP instruction.
-	 *
-	 * This applies to all revisions <= r1p2. The performance degradation
-	 * observed with LDNP/STNP has been fixed on r1p3 and onwards.
-	 *
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------------------------
-	 */
-func a57_disable_ldnp_overread
-	/*
-	 * Compare x0 against revision r1p2
-	 */
-	mov	x17, x30
-	bl	check_errata_disable_ldnp_overread
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc a57_disable_ldnp_overread
+check_erratum_ls cortex_a57, ERRATUM(814670), CPU_REV(0, 0)
 
-func check_errata_disable_ldnp_overread
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_disable_ldnp_overread
+workaround_runtime_start cortex_a57, ERRATUM(817169), ERRATA_A57_817169, CORTEX_A57_MIDR
+	/* Invalidate any TLB address */
+	mov	x0, #0
+	tlbi	vae3, x0
+workaround_runtime_end cortex_a57, ERRATUM(817169), NO_ISB
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #826974.
-	 * This applies only to revision <= r1p1 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_826974_wa
-	/*
-	 * Compare x0 against revision r1p1
-	 */
-	mov	x17, x30
-	bl	check_errata_826974
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_DMB
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_826974_wa
+check_erratum_ls cortex_a57, ERRATUM(817169), CPU_REV(0, 1)
 
-func check_errata_826974
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_826974
+workaround_reset_start cortex_a57, ERRATUM(826974), ERRATA_A57_826974
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_DMB
+workaround_reset_end cortex_a57, ERRATUM(826974)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #826977.
-	 * This applies only to revision <= r1p1 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_826977_wa
-	/*
-	 * Compare x0 against revision r1p1
-	 */
-	mov	x17, x30
-	bl	check_errata_826977
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_GRE_NGRE_AS_NGNRE
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_826977_wa
+check_erratum_ls cortex_a57, ERRATUM(826974), CPU_REV(1, 1)
 
-func check_errata_826977
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_826977
+workaround_reset_start cortex_a57, ERRATUM(826977), ERRATA_A57_826977
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_GRE_NGRE_AS_NGNRE
+workaround_reset_end cortex_a57, ERRATUM(826977)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #828024.
-	 * This applies only to revision <= r1p1 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_828024_wa
-	/*
-	 * Compare x0 against revision r1p1
-	 */
-	mov	x17, x30
-	bl	check_errata_828024
-	cbz	x0, 1f
+check_erratum_ls cortex_a57, ERRATUM(826977), CPU_REV(1, 1)
+
+workaround_reset_start cortex_a57, ERRATUM(828024), ERRATA_A57_828024
 	mrs	x1, CORTEX_A57_CPUACTLR_EL1
 	/*
 	 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
@@ -291,234 +126,64 @@
 	orr	x1, x1, #(CORTEX_A57_CPUACTLR_EL1_DIS_L1_STREAMING | \
 			  CORTEX_A57_CPUACTLR_EL1_DIS_STREAMING)
 	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_828024_wa
-
-func check_errata_828024
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_828024
-
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #829520.
-	 * This applies only to revision <= r1p2 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_829520_wa
-	/*
-	 * Compare x0 against revision r1p2
-	 */
-	mov	x17, x30
-	bl	check_errata_829520
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_829520_wa
-
-func check_errata_829520
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_829520
-
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #833471.
-	 * This applies only to revision <= r1p2 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a57_833471_wa
-	/*
-	 * Compare x0 against revision r1p2
-	 */
-	mov	x17, x30
-	bl	check_errata_833471
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_833471_wa
-
-func check_errata_833471
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_833471
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A57 Errata #859972.
-	 * This applies only to revision <= r1p3 of Cortex A57.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber:
-	 * --------------------------------------------------
-	 */
-func errata_a57_859972_wa
-	mov	x17, x30
-	bl	check_errata_859972
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A57_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH
-	msr	CORTEX_A57_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a57_859972_wa
-
-func check_errata_859972
-	mov	x1, #0x13
-	b	cpu_rev_var_ls
-endfunc check_errata_859972
-
-func check_errata_cve_2017_5715
-#if WORKAROUND_CVE_2017_5715
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2017_5715
+workaround_reset_end cortex_a57, ERRATUM(828024)
 
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
+check_erratum_ls cortex_a57, ERRATUM(828024), CPU_REV(1, 1)
 
-	/* --------------------------------------------------
-	 * Errata workaround for Cortex A57 Errata #1319537.
-	 * This applies to all revisions of Cortex A57.
-	 * --------------------------------------------------
-	 */
-func check_errata_1319537
-#if ERRATA_A57_1319537
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_1319537
+workaround_reset_start cortex_a57, ERRATUM(829520), ERRATA_A57_829520
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR
+workaround_reset_end cortex_a57, ERRATUM(829520)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A57.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
-	 */
-func cortex_a57_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+check_erratum_ls cortex_a57, ERRATUM(829520), CPU_REV(1, 2)
 
-#if ERRATA_A57_806969
-	mov	x0, x18
-	bl	errata_a57_806969_wa
-#endif
+workaround_reset_start cortex_a57, ERRATUM(833471), ERRATA_A57_833471
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH
+workaround_reset_end cortex_a57, ERRATUM(833471)
 
-#if ERRATA_A57_813420
-	mov	x0, x18
-	bl	errata_a57_813420_wa
-#endif
+check_erratum_ls cortex_a57, ERRATUM(833471), CPU_REV(1, 2)
 
-#if ERRATA_A57_814670
-	mov	x0, x18
-	bl	errata_a57_814670_wa
-#endif
+workaround_reset_start cortex_a57, ERRATUM(859972), ERRATA_A57_859972
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH
+workaround_reset_end cortex_a57, ERRATUM(859972)
 
-#if A57_DISABLE_NON_TEMPORAL_HINT
-	mov	x0, x18
-	bl	a57_disable_ldnp_overread
-#endif
+check_erratum_ls cortex_a57, ERRATUM(859972), CPU_REV(1, 3)
 
-#if ERRATA_A57_826974
-	mov	x0, x18
-	bl	errata_a57_826974_wa
-#endif
+check_erratum_chosen cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537
+/* erratum has no workaround in the cpu. Generic code must take care */
+add_erratum_entry cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537, NO_APPLY_AT_RESET
 
-#if ERRATA_A57_826977
-	mov	x0, x18
-	bl	errata_a57_826977_wa
+workaround_reset_start cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+#if IMAGE_BL31
+	override_vector_table wa_cve_2017_5715_mmu_vbar
 #endif
+workaround_reset_end cortex_a57, CVE(2017, 5715)
 
-#if ERRATA_A57_828024
-	mov	x0, x18
-	bl	errata_a57_828024_wa
-#endif
+check_erratum_chosen cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-#if ERRATA_A57_829520
-	mov	x0, x18
-	bl	errata_a57_829520_wa
-#endif
-
-#if ERRATA_A57_833471
-	mov	x0, x18
-	bl	errata_a57_833471_wa
-#endif
-
-#if ERRATA_A57_859972
-	mov	x0, x18
-	bl	errata_a57_859972_wa
-#endif
-
-#if IMAGE_BL31 && ( WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960 )
-	/* ---------------------------------------------------------------
-	 * Override vector table & enable existing workaround if either of
-	 * the build flags are enabled
-	 * ---------------------------------------------------------------
-	 */
-	adr	x0, wa_cve_2017_5715_mmu_vbar
-	msr	vbar_el3, x0
-	/* isb will be performed before returning from this function */
-#endif
-
-#if WORKAROUND_CVE_2018_3639
-	mrs	x0, CORTEX_A57_CPUACTLR_EL1
-	orr	x0, x0, #CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_STORE
-	msr	CORTEX_A57_CPUACTLR_EL1, x0
+workaround_reset_start cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_STORE
 	isb
 	dsb	sy
-#endif
+workaround_reset_end cortex_a57, CVE(2018, 3639)
 
-#if A57_ENABLE_NONCACHEABLE_LOAD_FWD
-	/* ---------------------------------------------
-	 * Enable higher performance non-cacheable load
-	 * forwarding
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_A57_CPUACTLR_EL1
-	orr	x0, x0, #CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD
-	msr	CORTEX_A57_CPUACTLR_EL1, x0
+check_erratum_chosen cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+
+workaround_reset_start cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	override_vector_table wa_cve_2017_5715_mmu_vbar
 #endif
+workaround_reset_end cortex_a57, CVE(2022, 23960)
 
-	/* ---------------------------------------------
-	 * Enable the SMP bit.
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_A57_ECTLR_EL1
-	orr	x0, x0, #CORTEX_A57_ECTLR_SMP_BIT
-	msr	CORTEX_A57_ECTLR_EL1, x0
-	isb
-	ret	x19
-endfunc cortex_a57_reset_func
+check_erratum_chosen cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
+cpu_reset_func_start cortex_a57
+#if A57_ENABLE_NONCACHEABLE_LOAD_FWD
+	/* Enable higher performance non-cacheable load forwarding */
+	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD
 #endif
-	ret
-endfunc check_errata_cve_2022_23960
+	/* Enable the SMP bit. */
+	sysreg_bit_set CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT
+cpu_reset_func_end cortex_a57
 
 func check_smccc_arch_workaround_3
 	mov	x0, #ERRATA_APPLIES
@@ -619,42 +284,7 @@
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A57. Must follow AAPCS.
- */
-func cortex_a57_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A57_806969, cortex_a57, 806969
-	report_errata ERRATA_A57_813419, cortex_a57, 813419
-	report_errata ERRATA_A57_813420, cortex_a57, 813420
-	report_errata ERRATA_A57_814670, cortex_a57, 814670
-	report_errata ERRATA_A57_817169, cortex_a57, 817169
-	report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
-		disable_ldnp_overread
-	report_errata ERRATA_A57_826974, cortex_a57, 826974
-	report_errata ERRATA_A57_826977, cortex_a57, 826977
-	report_errata ERRATA_A57_828024, cortex_a57, 828024
-	report_errata ERRATA_A57_829520, cortex_a57, 829520
-	report_errata ERRATA_A57_833471, cortex_a57, 833471
-	report_errata ERRATA_A57_859972, cortex_a57, 859972
-	report_errata ERRATA_A57_1319537, cortex_a57, 1319537
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a57, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a57, cve_2018_3639
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a57, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a57_errata_report
-#endif
+errata_report_shim cortex_a57
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a57 specific
@@ -679,7 +309,7 @@
 
 declare_cpu_ops_wa cortex_a57, CORTEX_A57_MIDR, \
 	cortex_a57_reset_func, \
-	check_errata_cve_2017_5715, \
+	check_erratum_cortex_a57_5715, \
 	CPU_NO_EXTRA2_FUNC, \
 	check_smccc_arch_workaround_3, \
 	cortex_a57_core_pwr_dwn, \
diff --git a/lib/cpus/aarch64/cortex_a65ae.S b/lib/cpus/aarch64/cortex_a65ae.S
index ac6583e..85d1894 100644
--- a/lib/cpus/aarch64/cortex_a65ae.S
+++ b/lib/cpus/aarch64/cortex_a65ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,49 +22,26 @@
 #error "Cortex-A65AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-/* -------------------------------------------------
- * The CPU Ops reset function for Cortex-A65.
- * Shall clobber: x0-x19
- * -------------------------------------------------
- */
-func cortex_a65ae_reset_func
-	mov	x19, x30
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
-#endif
+ /*
+  * ERRATA_DSU_936184 :
+  * The errata is defined in dsu_helpers.S but applies to cortex_a65ae
+  * as well. Henceforth creating symbolic names to the already existing errata
+  * workaround functions to get them registered under the Errata Framework.
+  */
+.equ check_erratum_cortex_a65ae_936184, check_errata_dsu_936184
+.equ erratum_cortex_a65ae_936184_wa, errata_dsu_936184_wa
+add_erratum_entry cortex_a65ae, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
 
-	ret	x19
-endfunc cortex_a65ae_reset_func
+cpu_reset_func_start cortex_a65ae
+cpu_reset_func_end cortex_a65ae
 
 func cortex_a65ae_cpu_pwr_dwn
-	mrs	x0, CORTEX_A65AE_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A65AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A65AE_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A65AE_CPUPWRCTLR_EL1, CORTEX_A65AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_a65ae_cpu_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A65AE. Must follow AAPCS.
- */
-func cortex_a65ae_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_DSU_936184, cortex_a65ae, dsu_936184
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a65ae_errata_report
-#endif
+errata_report_shim cortex_a65ae
 
 .section .rodata.cortex_a65ae_regs, "aS"
 cortex_a65ae_regs:  /* The ascii list of register names to be reported */
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index cebd6f0..eab5ada 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,22 +26,7 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A710_BHB_LOOP_COUNT, cortex_a710
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 1987031.
- * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710. It is still
- * open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a710_1987031_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_1987031
-	cbz	x0, 1f
-
-	/* Apply instruction patching sequence */
+workaround_reset_start cortex_a710, ERRATUM(1987031), ERRATA_A710_1987031
 	ldr x0,=0x6
 	msr S3_6_c15_c8_0,x0
 	ldr x0,=0xF3A08002
@@ -58,33 +43,53 @@
 	msr S3_6_c15_c8_3,x0
 	ldr x0,=0x40000001003f3
 	msr S3_6_c15_c8_1,x0
-	isb
-1:
-	ret	x17
-endfunc errata_a710_1987031_wa
+workaround_reset_end cortex_a710, ERRATUM(1987031)
 
-func check_errata_1987031
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1987031
+check_erratum_ls cortex_a710, ERRATUM(1987031), CPU_REV(2, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2081180.
- * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710.
- * It is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a710_2081180_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2081180
-	cbz	x0, 1f
+workaround_runtime_start cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768
+	/* Stash ERRSELR_EL1 in x2 */
+	mrs	x2, ERRSELR_EL1
+
+	/* Select error record 0 and clear ED bit */
+	msr	ERRSELR_EL1, xzr
+	mrs	x1, ERXCTLR_EL1
+	bfi	x1, xzr, #ERXCTLR_ED_SHIFT, #1
+	msr	ERXCTLR_EL1, x1
 
-	/* Apply instruction patching sequence */
+	/* Select error record 1 and clear ED bit */
+	mov	x0, #1
+	msr	ERRSELR_EL1, x0
+	mrs	x1, ERXCTLR_EL1
+	bfi	x1, xzr, #ERXCTLR_ED_SHIFT, #1
+	msr	ERXCTLR_EL1, x1
+
+	/* Restore ERRSELR_EL1 from x2 */
+	msr	ERRSELR_EL1, x2
+workaround_runtime_end cortex_a710, ERRATUM(2008768), NO_ISB
+
+check_erratum_ls cortex_a710, ERRATUM(2008768), CPU_REV(2, 0)
+
+workaround_reset_start cortex_a710, ERRATUM(2017096), ERRATA_A710_2017096
+	sysreg_bit_set	CORTEX_A710_CPUECTLR_EL1, CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT
+workaround_reset_end cortex_a710, ERRATUM(2017096)
+
+check_erratum_ls cortex_a710, ERRATUM(2017096), CPU_REV(2, 0)
+
+workaround_reset_start cortex_a710, ERRATUM(2055002), ERRATA_A710_2055002
+	sysreg_bit_set	CORTEX_A710_CPUACTLR_EL1, CORTEX_A710_CPUACTLR_EL1_BIT_46
+workaround_reset_end cortex_a710, ERRATUM(2055002)
+
+check_erratum_ls cortex_a710, ERRATUM(2055002), CPU_REV(2, 0)
+
+workaround_reset_start cortex_a710, ERRATUM(2058056), ERRATA_A710_2058056
+	sysreg_bitfield_insert CORTEX_A710_CPUECTLR2_EL1, CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV, \
+		CPUECTLR2_EL1_PF_MODE_LSB, CPUECTLR2_EL1_PF_MODE_WIDTH
+workaround_reset_end cortex_a710, ERRATUM(2058056)
+
+check_erratum_ls cortex_a710, ERRATUM(2058056), CPU_REV(2, 0)
+
+workaround_reset_start cortex_a710, ERRATUM(2081180), ERRATA_A710_2081180
 	ldr	x0,=0x3
 	msr	S3_6_c15_c8_0,x0
 	ldr	x0,=0xF3A08002
@@ -101,238 +106,30 @@
 	msr	S3_6_c15_c8_3,x0
 	ldr	x0,=0x10002001003F3
 	msr	S3_6_c15_c8_1,x0
-	isb
-1:
-	ret	x17
-endfunc errata_a710_2081180_wa
-
-func check_errata_2081180
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2081180
-
-/* ---------------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2055002.
- * This applies to revision r1p0, r2p0 of Cortex-A710 and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------------
- */
-func errata_a710_2055002_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_2055002
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A710_CPUACTLR_EL1
-	orr	x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_46
-	msr	CORTEX_A710_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2055002_wa
-
-func check_errata_2055002
-	/* Applies to r1p0, r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2055002
-
-/* -------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2017096.
- * This applies to revisions r0p0, r1p0 and r2p0 of Cortex-A710.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * -------------------------------------------------------------
- */
-func errata_a710_2017096_wa
-	/* Compare x0 against revision r0p0 to r2p0 */
-	mov     x17, x30
-	bl      check_errata_2017096
-	cbz     x0, 1f
-	mrs     x1, CORTEX_A710_CPUECTLR_EL1
-	orr     x1, x1, CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT
-	msr     CORTEX_A710_CPUECTLR_EL1, x1
-
-1:
-	ret     x17
-endfunc errata_a710_2017096_wa
-
-func check_errata_2017096
-	/* Applies to r0p0, r1p0, r2p0 */
-	mov     x1, #0x20
-	b       cpu_rev_var_ls
-endfunc check_errata_2017096
-
-
-/* ---------------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2083908.
- * This applies to revision r2p0 of Cortex-A710 and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------------
- */
-func errata_a710_2083908_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_2083908
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A710_CPUACTLR5_EL1
-	orr	x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_13
-	msr	CORTEX_A710_CPUACTLR5_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2083908_wa
-
-func check_errata_2083908
-	/* Applies to r2p0 */
-	mov	x1, #CPU_REV(2, 0)
-	mov	x2, #CPU_REV(2, 0)
-	b	cpu_rev_var_range
-endfunc check_errata_2083908
-
-/* ---------------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2058056.
- * This applies to revisions r0p0, r1p0 and r2p0 of Cortex-A710 and is still
- * open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------------
- */
-func errata_a710_2058056_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_2058056
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A710_CPUECTLR2_EL1
-	mov	x0, #CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH
-	msr	CORTEX_A710_CPUECTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2058056_wa
+workaround_reset_end cortex_a710, ERRATUM(2081180)
 
-func check_errata_2058056
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2058056
+check_erratum_ls cortex_a710, ERRATUM(2081180), CPU_REV(2, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2267065.
- * This applies to revisions r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_a710_2267065_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_2267065
-	cbz	x0, 1f
-
-	/* Apply instruction patching sequence */
-	mrs	x1, CORTEX_A710_CPUACTLR_EL1
-	orr	x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_22
-	msr	CORTEX_A710_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2267065_wa
+workaround_reset_start cortex_a710, ERRATUM(2083908), ERRATA_A710_2083908
+	sysreg_bit_set	CORTEX_A710_CPUACTLR5_EL1, CORTEX_A710_CPUACTLR5_EL1_BIT_13
+workaround_reset_end cortex_a710, ERRATUM(2083908)
 
-func check_errata_2267065
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2267065
+check_erratum_range cortex_a710, ERRATUM(2083908), CPU_REV(2, 0), CPU_REV(2, 0)
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2136059.
- * This applies to revision r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------
- */
-func errata_a710_2136059_wa
-	/* Compare x0 against revision r2p0 */
-	mov     x17, x30
-	bl      check_errata_2136059
-	cbz     x0, 1f
+workaround_reset_start cortex_a710, ERRATUM(2136059), ERRATA_A710_2136059
+	sysreg_bit_set	CORTEX_A710_CPUACTLR5_EL1, CORTEX_A710_CPUACTLR5_EL1_BIT_44
+workaround_reset_end cortex_a710, ERRATUM(2136059)
 
-	/* Apply the workaround */
-	mrs     x1, CORTEX_A710_CPUACTLR5_EL1
-	orr     x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_44
-	msr     CORTEX_A710_CPUACTLR5_EL1, x1
+check_erratum_ls cortex_a710, ERRATUM(2136059), CPU_REV(2, 0)
 
-1:
-	ret     x17
-endfunc errata_a710_2136059_wa
+workaround_reset_start cortex_a710, ERRATUM(2147715), ERRATA_A710_2147715
+	sysreg_bit_set	CORTEX_A710_CPUACTLR_EL1, CORTEX_A710_CPUACTLR_EL1_BIT_22
+workaround_reset_end cortex_a710, ERRATUM(2147715)
 
-func check_errata_2136059
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov     x1, #0x20
-	b       cpu_rev_var_ls
-endfunc check_errata_2136059
+check_erratum_range cortex_a710, ERRATUM(2147715), CPU_REV(2, 0), CPU_REV(2, 0)
 
-/* ----------------------------------------------------------------
- * Errata workaround for Cortex-A710 Erratum 2147715.
- * This applies to revision r2p0, and is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0, x1, x17
- * ----------------------------------------------------------------
- */
-func errata_a710_2147715_wa
-	mov 	x17, x30
-	bl 	check_errata_2147715
-	cbz	x0, 1f
-
-	/* Apply workaround; set CPUACTLR_EL1[22]
-	 * to 1, which will cause the CFP instruction
-	 * to invalidate all branch predictor resources
-	 * regardless of context.
-	 */
-	mrs 	x1, CORTEX_A710_CPUACTLR_EL1
-	orr	x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_22
-	msr 	CORTEX_A710_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2147715_wa
-
-func check_errata_2147715
-	mov 	x1, #0x20
-	mov 	x2, #0x20
-	b 	cpu_rev_var_range
-endfunc check_errata_2147715
-
-/* ---------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2216384.
- * This applies to revision r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------
- */
-func errata_a710_2216384_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_2216384
-	cbz	x0, 1f
-
-	/* Apply workaround: set CPUACTLR5_EL1[17]
-	 * to 1 and the following instruction
-	 * patching sequence.
-	 */
-	mrs	x1, CORTEX_A710_CPUACTLR5_EL1
-	orr	x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_17
-	msr	CORTEX_A710_CPUACTLR5_EL1, x1
+workaround_reset_start cortex_a710, ERRATUM(2216384), ERRATA_A710_2216384
+	sysreg_bit_set	CORTEX_A710_CPUACTLR5_EL1, CORTEX_A710_CPUACTLR5_EL1_BIT_17
 
 	ldr	x0,=0x5
 	msr	CORTEX_A710_CPUPSELR_EL3, x0
@@ -342,338 +139,88 @@
 	msr	CORTEX_A710_CPUPMR_EL3, x0
 	ldr	x0,=0x80000000003FF
 	msr	CORTEX_A710_CPUPCR_EL3, x0
-	isb
-1:
-	ret 	x17
-endfunc errata_a710_2216384_wa
+workaround_reset_end cortex_a710, ERRATUM(2216384)
 
-func check_errata_2216384
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2216384
+check_erratum_ls cortex_a710, ERRATUM(2216384), CPU_REV(2, 0)
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2282622.
- * This applies to revision r0p0, r1p0, r2p0 and r2p1.
- * It is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0, x1, x17
- * ---------------------------------------------------------------
- */
-func errata_a710_2282622_wa
-	/* Compare x0 against revision r2p1 */
-	mov     x17, x30
-	bl      check_errata_2282622
-	cbz     x0, 1f
+workaround_reset_start cortex_a710, ERRATUM(2267065), ERRATA_A710_2267065
+	sysreg_bit_set	CORTEX_A710_CPUACTLR_EL1, CORTEX_A710_CPUACTLR_EL1_BIT_22
+workaround_reset_end cortex_a710, ERRATUM(2267065)
 
-	/* Apply the workaround */
-	mrs     x1, CORTEX_A710_CPUACTLR2_EL1
-	orr     x1, x1, #BIT(0)
-	msr     CORTEX_A710_CPUACTLR2_EL1, x1
+check_erratum_ls cortex_a710, ERRATUM(2267065), CPU_REV(2, 0)
 
-1:
-	ret     x17
-endfunc errata_a710_2282622_wa
+workaround_reset_start cortex_a710, ERRATUM(2282622), ERRATA_A710_2282622
+	sysreg_bit_set	CORTEX_A710_CPUACTLR2_EL1, BIT(0)
+workaround_reset_end cortex_a710, ERRATUM(2282622)
 
-func check_errata_2282622
-	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
-	mov     x1, #0x21
-	b       cpu_rev_var_ls
-endfunc check_errata_2282622
+check_erratum_ls cortex_a710, ERRATUM(2282622), CPU_REV(2, 1)
 
-/* ------------------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2291219 on power down request.
- * This applies to revision <= r2p0 and is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * ------------------------------------------------------------------------
- */
-func errata_a710_2291219_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2291219
-	cbz	x0, 1f
-
+workaround_runtime_start cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219
 	/* Set bit 36 in ACTLR2_EL1 */
-	mrs	x1, CORTEX_A710_CPUACTLR2_EL1
-	orr	x1, x1, #CORTEX_A710_CPUACTLR2_EL1_BIT_36
-	msr	CORTEX_A710_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a710_2291219_wa
+	sysreg_bit_set CORTEX_A710_CPUACTLR2_EL1, CORTEX_A710_CPUACTLR2_EL1_BIT_36
+workaround_runtime_end cortex_a710, ERRATUM(2291219), NO_ISB
 
-func check_errata_2291219
-	/* Applies to <= r2p0. */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2291219
+check_erratum_ls cortex_a710, ERRATUM(2291219), CPU_REV(2, 0)
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2008768.
- * This applies to revision r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0, x1, x2, x17
- * ---------------------------------------------------------------
+/*
+ * ERRATA_DSU_2313941 is defined in dsu_helpers.S but applies to Cortex-A710 as
+ * well. Create a symbollic link to existing errata workaround to get them
+ * registered under the Errata Framework.
  */
-func errata_a710_2008768_wa
-	mov     x17, x30
-	bl      check_errata_2008768
-	cbz     x0, 1f
-
-	/* Stash ERRSELR_EL1 in x2 */
-	mrs	x2, ERRSELR_EL1
+.equ check_erratum_cortex_a710_2313941, check_errata_dsu_2313941
+.equ erratum_cortex_a710_2313941_wa, errata_dsu_2313941_wa
+add_erratum_entry cortex_a710, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
 
-	/* Select error record 0 and clear ED bit */
-	msr	ERRSELR_EL1, xzr
-	mrs	x1, ERXCTLR_EL1
-	bfi	x1, xzr, #ERXCTLR_ED_SHIFT, #1
-	msr	ERXCTLR_EL1, x1
-
-	/* Select error record 1 and clear ED bit */
-	mov	x0, #1
-	msr	ERRSELR_EL1, x0
-	mrs	x1, ERXCTLR_EL1
-	bfi	x1, xzr, #ERXCTLR_ED_SHIFT, #1
-	msr	ERXCTLR_EL1, x1
-
-	/* Restore ERRSELR_EL1 from x2 */
-	msr	ERRSELR_EL1, x2
-
-1:
-	ret     x17
-endfunc errata_a710_2008768_wa
-
-func check_errata_2008768
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov     x1, #0x20
-	b       cpu_rev_var_ls
-endfunc check_errata_2008768
-
-/* -------------------------------------------------------
- * Errata Workaround for Cortex-A710 Erratum 2371105.
- * This applies to revisions <= r2p0 and is fixed in r2p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * -------------------------------------------------------
- */
-func errata_a710_2371105_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2371105
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a710, ERRATUM(2371105), ERRATA_A710_2371105
 	/* Set bit 40 in CPUACTLR2_EL1 */
-	mrs	x1, CORTEX_A710_CPUACTLR2_EL1
-	orr	x1, x1, #CORTEX_A710_CPUACTLR2_EL1_BIT_40
-	msr	CORTEX_A710_CPUACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a710_2371105_wa
+	sysreg_bit_set CORTEX_A710_CPUACTLR2_EL1, CORTEX_A710_CPUACTLR2_EL1_BIT_40
+workaround_reset_end cortex_a710, ERRATUM(2371105)
 
-func check_errata_2371105
-	/* Applies to <= r2p0. */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2371105
+check_erratum_ls cortex_a710, ERRATUM(2371105), CPU_REV(2, 0)
 
-/* ----------------------------------------------------
- * Errata Workaround for Cortex-A710 Errata #2768515
- * This applies to revisions <= r2p1 and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------
- */
-func errata_a710_2768515_wa
-	mov	x17, x30
-	bl	check_errata_2768515
-	cbz	x0, 1f
-
+workaround_runtime_start cortex_a710, ERRATUM(2768515), ERRATA_A710_2768515
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_a710_2768515_wa
+workaround_runtime_end cortex_a710, ERRATUM(2768515), NO_ISB
 
-func check_errata_2768515
-	/* Applies to all revisions <= r2p1 */
-	mov	x1, #0x21
-	b	cpu_rev_var_ls
-endfunc check_errata_2768515
+check_erratum_ls cortex_a710, ERRATUM(2768515), CPU_REV(2, 1)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+workaround_reset_start cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Cortex-A710 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_cortex_a710
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a710, CVE(2022, 23960)
+
+check_erratum_chosen cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
 func cortex_a710_core_pwr_dwn
-
-#if ERRATA_A710_2008768
-	mov	x4, x30
-	bl	cpu_get_rev_var
-	bl	errata_a710_2008768_wa
-	mov	x30, x4
-#endif
-
-#if ERRATA_A710_2291219
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a710_2291219_wa
-	mov	x30, x15
-#endif /* ERRATA_A710_2291219 */
+	apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768
+	apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A710_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A710_CPUPWRCTLR_EL1, x0
-#if ERRATA_A710_2768515
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a710_2768515_wa
-	mov	x30, x15
-#endif /* ERRATA_A710_2768515 */
+	sysreg_bit_set CORTEX_A710_CPUPWRCTLR_EL1, CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	apply_erratum cortex_a710, ERRATUM(2768515), ERRATA_A710_2768515, NO_GET_CPU_REV
 	isb
 	ret
 endfunc cortex_a710_core_pwr_dwn
 
-#if REPORT_ERRATA
-	/*
-	 * Errata printing function for Cortex-A710. Must follow AAPCS.
-	 */
-func cortex_a710_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A710_1987031, cortex_a710, 1987031
-	report_errata ERRATA_A710_2081180, cortex_a710, 2081180
-	report_errata ERRATA_A710_2055002, cortex_a710, 2055002
-	report_errata ERRATA_A710_2017096, cortex_a710, 2017096
-	report_errata ERRATA_A710_2083908, cortex_a710, 2083908
-	report_errata ERRATA_A710_2058056, cortex_a710, 2058056
-	report_errata ERRATA_A710_2267065, cortex_a710, 2267065
-	report_errata ERRATA_A710_2136059, cortex_a710, 2136059
-	report_errata ERRATA_A710_2282622, cortex_a710, 2282622
-	report_errata ERRATA_A710_2008768, cortex_a710, 2008768
-	report_errata ERRATA_A710_2147715, cortex_a710, 2147715
-	report_errata ERRATA_A710_2216384, cortex_a710, 2216384
-	report_errata ERRATA_A710_2291219, cortex_a710, 2291219
-	report_errata ERRATA_A710_2371105, cortex_a710, 2371105
-	report_errata ERRATA_A710_2768515, cortex_a710, 2768515
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a710, cve_2022_23960
-	report_errata ERRATA_DSU_2313941, cortex_a710, dsu_2313941
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a710_errata_report
-#endif
+errata_report_shim cortex_a710
 
-func cortex_a710_reset_func
-	mov	x19, x30
-
+cpu_reset_func_start cortex_a710
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_DSU_2313941
-	bl	errata_dsu_2313941_wa
-#endif
-
-#if ERRATA_A710_1987031
-	mov	x0, x18
-	bl	errata_a710_1987031_wa
-#endif
-
-#if ERRATA_A710_2081180
-	mov	x0, x18
-	bl	errata_a710_2081180_wa
-#endif
-
-#if ERRATA_A710_2055002
-	mov	x0, x18
-	bl	errata_a710_2055002_wa
-#endif
-
-#if ERRATA_A710_2017096
-	mov	x0, x18
-	bl	errata_a710_2017096_wa
-#endif
-
-#if ERRATA_A710_2083908
-	mov	x0, x18
-	bl	errata_a710_2083908_wa
-#endif
-
-#if ERRATA_A710_2058056
-	mov	x0, x18
-	bl	errata_a710_2058056_wa
-#endif
-
-#if ERRATA_A710_2267065
-	mov	x0, x18
-	bl	errata_a710_2267065_wa
-#endif
-
-#if ERRATA_A710_2136059
-	mov	x0, x18
-	bl	errata_a710_2136059_wa
-#endif
-
-#if ERRATA_A710_2147715
-	mov	x0, x18
-	bl 	errata_a710_2147715_wa
-#endif
-
-#if ERRATA_A710_2216384
-	mov	x0, x18
-	bl 	errata_a710_2216384_wa
-#endif /* ERRATA_A710_2216384 */
-
-#if ERRATA_A710_2282622
-	mov	x0, x18
-	bl	errata_a710_2282622_wa
-#endif
-
-#if ERRATA_A710_2371105
-	mov	x0, x18
-	bl	errata_a710_2371105_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex-A710 generic vectors are overridden to apply errata
-	 * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_cortex_a710
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc cortex_a710_reset_func
+cpu_reset_func_end cortex_a710
 
 	/* ---------------------------------------------
 	 * This function provides Cortex-A710 specific
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 12d969f..dd4c307 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -26,31 +26,22 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A715_BHB_LOOP_COUNT, cortex_a715
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov     x0, #ERRATA_APPLIES
-#else
-	mov     x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_a715_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex-A715 generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-        adr	x0, wa_cve_vbar_cortex_a715
-        msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	override_vector_table wa_cve_vbar_cortex_a715
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a715, CVE(2022, 23960)
 
-	isb
-	ret
-endfunc cortex_a715_reset_func
+check_erratum_chosen cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+cpu_reset_func_start cortex_a715
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_a715
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -68,26 +59,7 @@
 	ret
 endfunc cortex_a715_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A715. Must follow AAPCS.
- */
-func cortex_a715_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a715, cve_2022_23960
-
-	ldp     x8, x30, [sp], #16
-	ret
-endfunc cortex_a715_errata_report
-#endif
+errata_report_shim cortex_a715
 
 	/* ---------------------------------------------
 	 * This function provides Cortex-A715 specific
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index de2d36e..997f261 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,9 +47,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a72_disable_hw_prefetcher
-	mrs	x0, CORTEX_A72_CPUACTLR_EL1
-	orr	x0, x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
-	msr	CORTEX_A72_CPUACTLR_EL1, x0
+	sysreg_bit_set CORTEX_A72_CPUACTLR_EL1, CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
 	isb
 	dsb	ish
 	ret
@@ -60,9 +58,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a72_disable_smp
-	mrs	x0, CORTEX_A72_ECTLR_EL1
-	bic	x0, x0, #CORTEX_A72_ECTLR_SMP_BIT
-	msr	CORTEX_A72_ECTLR_EL1, x0
+	sysreg_bit_clear CORTEX_A72_ECTLR_EL1, CORTEX_A72_ECTLR_SMP_BIT
 	ret
 endfunc cortex_a72_disable_smp
 
@@ -78,139 +74,95 @@
 	ret
 endfunc cortex_a72_disable_ext_debug
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A72 Errata #859971.
-	 * This applies only to revision <= r0p3 of Cortex A72.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber:
-	 * --------------------------------------------------
-	 */
-func errata_a72_859971_wa
-	mov	x17,x30
-	bl	check_errata_859971
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A72_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A72_CPUACTLR_EL1_DIS_INSTR_PREFETCH
-	msr	CORTEX_A72_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a72_859971_wa
-
-func check_errata_859971
-	mov	x1, #0x03
-	b	cpu_rev_var_ls
-endfunc check_errata_859971
-
-func check_errata_cve_2017_5715
+func check_smccc_arch_workaround_3
 	cpu_check_csv2	x0, 1f
-#if WORKAROUND_CVE_2017_5715
 	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
 	ret
 1:
 	mov	x0, #ERRATA_NOT_APPLIES
 	ret
-endfunc check_errata_cve_2017_5715
+endfunc check_smccc_arch_workaround_3
 
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
+workaround_reset_start cortex_a72, ERRATUM(859971), ERRATA_A72_859971
+	sysreg_bit_set CORTEX_A72_CPUACTLR_EL1, CORTEX_A72_CPUACTLR_EL1_DIS_INSTR_PREFETCH
+workaround_reset_end cortex_a72, ERRATUM(859971)
 
-	/* --------------------------------------------------
-	 * Errata workaround for Cortex A72 Errata #1319367.
-	 * This applies to all revisions of Cortex A72.
-	 * --------------------------------------------------
-	 */
-func check_errata_1319367
-#if ERRATA_A72_1319367
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
+check_erratum_ls cortex_a72, ERRATUM(859971), CPU_REV(0, 3)
+
+/* Due to the nature of the errata it is applied unconditionally when chosen */
+check_erratum_chosen cortex_a72, ERRATUM(1319367), ERRATA_A72_1319367
+/* erratum workaround is interleaved with generic code */
+add_erratum_entry cortex_a72, ERRATUM(1319367), ERRATA_A72_1319367, NO_APPLY_AT_RESET
+
+workaround_reset_start cortex_a72, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+#if IMAGE_BL31
+	override_vector_table wa_cve_2017_5715_mmu_vbar
 #endif
-	ret
-endfunc check_errata_1319367
+workaround_reset_end cortex_a72, CVE(2017, 5715)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
+check_erratum_custom_start cortex_a72, CVE(2017, 5715)
+	cpu_check_csv2	x0, 1f
+#if WORKAROUND_CVE_2017_5715
 	mov	x0, #ERRATA_APPLIES
 #else
 	mov	x0, #ERRATA_MISSING
 #endif
 	ret
-endfunc check_errata_cve_2022_23960
-
-func check_smccc_arch_workaround_3
-	cpu_check_csv2	x0, 1f
-	mov	x0, #ERRATA_APPLIES
-	ret
 1:
 	mov	x0, #ERRATA_NOT_APPLIES
 	ret
-endfunc check_smccc_arch_workaround_3
-
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A72.
-	 * -------------------------------------------------
-	 */
-func cortex_a72_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A72_859971
-	mov	x0, x18
-	bl	errata_a72_859971_wa
-#endif
+check_erratum_custom_end cortex_a72, CVE(2017, 5715)
 
-#if IMAGE_BL31 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
-	cpu_check_csv2	x0, 1f
-	adr	x0, wa_cve_2017_5715_mmu_vbar
-	msr	vbar_el3, x0
-	/* isb will be performed before returning from this function */
+workaround_reset_start cortex_a72, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+	sysreg_bit_set CORTEX_A72_CPUACTLR_EL1, CORTEX_A72_CPUACTLR_EL1_DIS_LOAD_PASS_STORE
+	isb
+	dsb	sy
+workaround_reset_end cortex_a72, CVE(2018, 3639)
+check_erratum_chosen cortex_a72, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
 
-	/* Skip CVE_2022_23960 mitigation if cve_2017_5715 mitigation applied */
-	b	2f
-1:
-#if WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a72, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/* Skip installing vector table again if already done for CVE(2017, 5715) */
 	/*
 	 * The Cortex-A72 generic vectors are overridden to apply the
-         * mitigation on exception entry from lower ELs for revisions >= r1p0
+	 * mitigation on exception entry from lower ELs for revisions >= r1p0
 	 * which has CSV2 implemented.
 	 */
 	adr	x0, wa_cve_vbar_cortex_a72
+	mrs	x1, vbar_el3
+	cmp	x0, x1
+	b.eq	1f
 	msr	vbar_el3, x0
+1:
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a72, CVE(2022, 23960)
 
-	/* isb will be performed before returning from this function */
+check_erratum_custom_start cortex_a72, CVE(2022, 23960)
+#if WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960
+	cpu_check_csv2	x0, 1f
+	mov	x0, #ERRATA_APPLIES
+	ret
+1:
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
 #endif /* WORKAROUND_CVE_2022_23960 */
-2:
-#endif /* IMAGE_BL31 &&  (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960) */
+	ret
+#endif /* WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960 */
+	mov	x0, #ERRATA_MISSING
+	ret
+check_erratum_custom_end cortex_a72, CVE(2022, 23960)
 
-#if WORKAROUND_CVE_2018_3639
-	mrs	x0, CORTEX_A72_CPUACTLR_EL1
-	orr	x0, x0, #CORTEX_A72_CPUACTLR_EL1_DIS_LOAD_PASS_STORE
-	msr	CORTEX_A72_CPUACTLR_EL1, x0
-	isb
-	dsb	sy
-#endif
+cpu_reset_func_start cortex_a72
 
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A72_ECTLR_EL1
-	orr	x0, x0, #CORTEX_A72_ECTLR_SMP_BIT
-	msr	CORTEX_A72_ECTLR_EL1, x0
-	isb
-	ret x19
-endfunc cortex_a72_reset_func
+	sysreg_bit_set CORTEX_A72_ECTLR_EL1, CORTEX_A72_ECTLR_SMP_BIT
+
+cpu_reset_func_end cortex_a72
 
 	/* ----------------------------------------------------
 	 * The CPU Ops core power down function for Cortex-A72.
@@ -319,30 +271,7 @@
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A72. Must follow AAPCS.
- */
-func cortex_a72_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A72_859971, cortex_a72, 859971
-	report_errata ERRATA_A72_1319367, cortex_a72, 1319367
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a72, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a72, cve_2018_3639
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a72, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a72_errata_report
-#endif
+errata_report_shim cortex_a72
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a72 specific
@@ -367,7 +296,7 @@
 
 declare_cpu_ops_wa cortex_a72, CORTEX_A72_MIDR, \
 	cortex_a72_reset_func, \
-	check_errata_cve_2017_5715, \
+	check_erratum_cortex_a72_5715, \
 	CPU_NO_EXTRA2_FUNC, \
 	check_smccc_arch_workaround_3, \
 	cortex_a72_core_pwr_dwn, \
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 529ab50..4b28fdb 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -26,31 +26,22 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_a720_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a720, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex A720 generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-	adr	x0, wa_cve_vbar_cortex_a720
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	override_vector_table wa_cve_vbar_cortex_a720
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a720, CVE(2022, 23960)
 
-	isb
-	ret
-endfunc cortex_a720_reset_func
+check_erratum_chosen cortex_a720, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+cpu_reset_func_start cortex_a720
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_a720
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -61,33 +52,13 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A720_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A720_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A720_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A720_CPUPWRCTLR_EL1, CORTEX_A720_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
 	isb
 	ret
 endfunc cortex_a720_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A720. Must follow AAPCS.
- */
-func cortex_a720_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a720, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a720_errata_report
-#endif
+errata_report_shim cortex_a720
 
 	/* ---------------------------------------------
 	 * This function provides Cortex A720-specific
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index edcd1f5..3a6b922 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,9 +15,7 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a73_disable_dcache
-	mrs	x1, sctlr_el3
-	bic	x1, x1, #SCTLR_C_BIT
-	msr	sctlr_el3, x1
+	sysreg_bit_clear sctlr_el3, SCTLR_C_BIT
 	isb
 	ret
 endfunc cortex_a73_disable_dcache
@@ -27,124 +25,97 @@
 	 * ---------------------------------------------
 	 */
 func cortex_a73_disable_smp
-	mrs	x0, CORTEX_A73_CPUECTLR_EL1
-	bic	x0, x0, #CORTEX_A73_CPUECTLR_SMP_BIT
-	msr	CORTEX_A73_CPUECTLR_EL1, x0
+	sysreg_bit_clear CORTEX_A73_CPUECTLR_EL1, CORTEX_A73_CPUECTLR_SMP_BIT
 	isb
 	dsb	sy
 	ret
 endfunc cortex_a73_disable_smp
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A73 Errata #852427.
-	 * This applies only to revision r0p0 of Cortex A73.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a73_852427_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_852427
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A73_DIAGNOSTIC_REGISTER
-	orr	x1, x1, #(1 << 12)
-	msr	CORTEX_A73_DIAGNOSTIC_REGISTER, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a73_852427_wa
+func check_smccc_arch_workaround_3
+	mov	x0, #ERRATA_APPLIES
+	ret
+endfunc check_smccc_arch_workaround_3
 
-func check_errata_852427
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_852427
+workaround_reset_start cortex_a73, ERRATUM(852427), ERRATA_A73_852427
+	sysreg_bit_set CORTEX_A73_DIAGNOSTIC_REGISTER, BIT(12)
+workaround_reset_end cortex_a73, ERRATUM(852427)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A73 Errata #855423.
-	 * This applies only to revision <= r0p1 of Cortex A73.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ---------------------------------------------------
-	 */
-func errata_a73_855423_wa
-	/*
-	 * Compare x0 against revision r0p1
-	 */
-	mov	x17, x30
-	bl	check_errata_855423
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A73_IMP_DEF_REG2
-	orr	x1, x1, #(1 << 7)
-	msr	CORTEX_A73_IMP_DEF_REG2, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a73_855423_wa
+check_erratum_ls cortex_a73, ERRATUM(852427), CPU_REV(0, 0)
 
-func check_errata_855423
-	mov	x1, #0x01
-	b	cpu_rev_var_ls
-endfunc check_errata_855423
+workaround_reset_start cortex_a73, ERRATUM(855423), ERRATA_A73_855423
+	sysreg_bit_set CORTEX_A73_IMP_DEF_REG2, BIT(7)
+workaround_reset_end cortex_a73, ERRATUM(855423)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A73.
-	 * -------------------------------------------------
-	 */
+check_erratum_ls cortex_a73, ERRATUM(855423), CPU_REV(0, 1)
 
-func cortex_a73_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+workaround_reset_start cortex_a73, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+#if IMAGE_BL31
+	override_vector_table wa_cve_2017_5715_bpiall_vbar
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a73, CVE(2017, 5715)
 
-#if ERRATA_A73_852427
-	mov	x0, x18
-	bl	errata_a73_852427_wa
+check_erratum_custom_start cortex_a73, CVE(2017, 5715)
+	cpu_check_csv2	x0, 1f
+#if WORKAROUND_CVE_2017_5715
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
 #endif
+	ret
+1:
+	mov	x0, #ERRATA_NOT_APPLIES
+	ret
+check_erratum_custom_end cortex_a73, CVE(2017, 5715)
 
-#if ERRATA_A73_855423
-	mov	x0, x18
-	bl	errata_a73_855423_wa
-#endif
+workaround_reset_start cortex_a73, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+	sysreg_bit_set CORTEX_A73_IMP_DEF_REG1, CORTEX_A73_IMP_DEF_REG1_DISABLE_LOAD_PASS_STORE
+workaround_reset_end cortex_a73, CVE(2018, 3639)
 
-#if IMAGE_BL31 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
-	cpu_check_csv2	x0, 1f
-	adr	x0, wa_cve_2017_5715_bpiall_vbar
-	msr	vbar_el3, x0
-	isb
+check_erratum_chosen cortex_a73, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+
+workaround_reset_start cortex_a73, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/* Skip installing vector table again for CVE_2022_23960 */
-        b       2f
+	adr	x0, wa_cve_2017_5715_bpiall_vbar
+	mrs	x1, vbar_el3
+
+	cmp	x0, x1
+	b.eq	1f
+	msr     vbar_el3, x0
 1:
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a73, CVE(2022, 23960)
+
+check_erratum_custom_start cortex_a73, CVE(2022, 23960)
+#if WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960
+	cpu_check_csv2  x0, 1f
+	mov	x0, #ERRATA_APPLIES
+	ret
+ 1:
 #if WORKAROUND_CVE_2022_23960
-	adr	x0, wa_cve_2017_5715_bpiall_vbar
-	msr	vbar_el3, x0
-	isb
-#endif
-2:
-#endif /* IMAGE_BL31 &&  (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960) */
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif /* WORKAROUND_CVE_2022_23960 */
+	ret
+#endif /* WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960 */
+	mov	x0, #ERRATA_MISSING
+	ret
+check_erratum_custom_end cortex_a73, CVE(2022, 23960)
 
-#if WORKAROUND_CVE_2018_3639
-	mrs	x0, CORTEX_A73_IMP_DEF_REG1
-	orr	x0, x0, #CORTEX_A73_IMP_DEF_REG1_DISABLE_LOAD_PASS_STORE
-	msr	CORTEX_A73_IMP_DEF_REG1, x0
-	isb
-#endif
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A73.
+	 * -------------------------------------------------
+	 */
 
+cpu_reset_func_start cortex_a73
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * Clobbers : x0
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A73_CPUECTLR_EL1
-	orr	x0, x0, #CORTEX_A73_CPUECTLR_SMP_BIT
-	msr	CORTEX_A73_CPUECTLR_EL1, x0
-	isb
-	ret	x19
-endfunc cortex_a73_reset_func
+	sysreg_bit_set CORTEX_A73_CPUECTLR_EL1, CORTEX_A73_CPUECTLR_SMP_BIT
+cpu_reset_func_end cortex_a73
 
 func cortex_a73_core_pwr_dwn
 	mov	x18, x30
@@ -207,74 +178,8 @@
 	b	cortex_a73_disable_smp
 endfunc cortex_a73_cluster_pwr_dwn
 
-func check_errata_cve_2017_5715
-	cpu_check_csv2	x0, 1f
-#if WORKAROUND_CVE_2017_5715
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-1:
-	mov	x0, #ERRATA_NOT_APPLIES
-	ret
-endfunc check_errata_cve_2017_5715
-
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960
-	cpu_check_csv2	x0, 1f
-	mov	x0, #ERRATA_APPLIES
-	ret
- 1:
-# if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-# else
-	mov	x0, #ERRATA_MISSING
-# endif /* WORKAROUND_CVE_2022_23960 */
-	ret
-#endif /* WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960 */
-	mov	x0, #ERRATA_MISSING
-	ret
-endfunc check_errata_cve_2022_23960
-
-func check_smccc_arch_workaround_3
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_smccc_arch_workaround_3
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A75. Must follow AAPCS.
- */
-func cortex_a73_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A73_852427, cortex_a73, 852427
-	report_errata ERRATA_A73_855423, cortex_a73, 855423
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a73, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a73, cve_2018_3639
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a73, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a73_errata_report
-#endif
+errata_report_shim cortex_a73
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a73 specific
@@ -298,7 +203,7 @@
 
 declare_cpu_ops_wa cortex_a73, CORTEX_A73_MIDR, \
 	cortex_a73_reset_func, \
-	check_errata_cve_2017_5715, \
+	check_erratum_cortex_a73_5715, \
 	CPU_NO_EXTRA2_FUNC, \
 	check_smccc_arch_workaround_3, \
 	cortex_a73_core_pwr_dwn, \
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index e22c828..c90be67 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,139 +15,43 @@
 #error "Cortex-A75 must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A75 Errata #764081.
-	 * This applies only to revision r0p0 of Cortex A75.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a75_764081_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_764081
-	cbz	x0, 1f
-	mrs	x1, sctlr_el3
-	orr	x1, x1 ,#SCTLR_IESB_BIT
-	msr	sctlr_el3, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a75_764081_wa
+workaround_reset_start cortex_a75, ERRATUM(764081), ERRATA_A75_764081
+	sysreg_bit_set sctlr_el3, SCTLR_IESB_BIT
+workaround_reset_end cortex_a75, ERRATUM(764081)
 
-func check_errata_764081
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_764081
+check_erratum_ls cortex_a75, ERRATUM(764081), CPU_REV(0, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A75 Errata #790748.
-	 * This applies only to revision r0p0 of Cortex A75.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a75_790748_wa
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	mov	x17, x30
-	bl	check_errata_790748
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A75_CPUACTLR_EL1
-	orr	x1, x1 ,#(1 << 13)
-	msr	CORTEX_A75_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a75_790748_wa
+workaround_reset_start cortex_a75, ERRATUM(790748), ERRATA_A75_790748
+	sysreg_bit_set CORTEX_A75_CPUACTLR_EL1, (1 << 13)
+workaround_reset_end cortex_a75, ERRATUM(790748)
 
-func check_errata_790748
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_790748
+check_erratum_ls cortex_a75, ERRATUM(790748), CPU_REV(0, 0)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A75.
-	 * -------------------------------------------------
-	 */
-func cortex_a75_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A75_764081
-	mov	x0, x18
-	bl	errata_a75_764081_wa
-#endif
-
-#if ERRATA_A75_790748
-	mov	x0, x18
-	bl	errata_a75_790748_wa
-#endif
-
-#if IMAGE_BL31 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
-	cpu_check_csv2	x0, 1f
-	adr	x0, wa_cve_2017_5715_bpiall_vbar
-	msr	vbar_el3, x0
-	isb
-	/* Skip installing vector table again for CVE_2022_23960 */
-        b       2f
-1:
-#if WORKAROUND_CVE_2022_23960
-	adr	x0, wa_cve_2017_5715_bpiall_vbar
-	msr	vbar_el3, x0
-	isb
-#endif
-2:
-#endif /* IMAGE_BL31 &&  (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960) */
-
-#if WORKAROUND_CVE_2018_3639
-	mrs	x0, CORTEX_A75_CPUACTLR_EL1
-	orr	x0, x0, #CORTEX_A75_CPUACTLR_EL1_DISABLE_LOAD_PASS_STORE
-	msr	CORTEX_A75_CPUACTLR_EL1, x0
-	isb
-#endif
-
-#if ERRATA_DSU_798953
-	bl	errata_dsu_798953_wa
-#endif
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
-#endif
-
-#if ENABLE_FEAT_AMU
-	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, actlr_el3
-	orr	x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
-	msr	actlr_el3, x0
-	isb
-
-	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	mrs	x0, actlr_el2
-	orr	x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
-	msr	actlr_el2, x0
-	isb
+/* ERRATA_DSU_798953 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_a75
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a75_798953, check_errata_dsu_798953
+.equ erratum_cortex_a75_798953_wa, errata_dsu_798953_wa
+add_erratum_entry cortex_a75, ERRATUM(798953), ERRATA_DSU_798953, APPLY_AT_RESET
 
-	/* Enable group0 counters */
-	mov	x0, #CORTEX_A75_AMU_GROUP0_MASK
-	msr	CPUAMCNTENSET_EL0, x0
-	isb
+/* ERRATA_DSU_936184 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_a75
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a75_936184, check_errata_dsu_936184
+.equ erratum_cortex_a75_936184_wa, errata_dsu_936184_wa
+add_erratum_entry cortex_a75, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
 
-	/* Enable group1 counters */
-	mov	x0, #CORTEX_A75_AMU_GROUP1_MASK
-	msr	CPUAMCNTENSET_EL0, x0
-	isb
-#endif
-	ret	x19
-endfunc cortex_a75_reset_func
+workaround_reset_start cortex_a75, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+#if IMAGE_BL31
+	override_vector_table wa_cve_2017_5715_bpiall_vbar
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a75, CVE(2017, 5715)
 
-func check_errata_cve_2017_5715
+check_erratum_custom_start cortex_a75, CVE(2017, 5715)
 	cpu_check_csv2	x0, 1f
 #if WORKAROUND_CVE_2017_5715
 	mov	x0, #ERRATA_APPLIES
@@ -158,18 +62,27 @@
 1:
 	mov	x0, #ERRATA_NOT_APPLIES
 	ret
-endfunc check_errata_cve_2017_5715
+check_erratum_custom_end cortex_a75, CVE(2017, 5715)
 
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
+workaround_reset_start cortex_a75, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+	sysreg_bit_set CORTEX_A75_CPUACTLR_EL1, CORTEX_A75_CPUACTLR_EL1_DISABLE_LOAD_PASS_STORE
+workaround_reset_end cortex_a75, CVE(2018, 3639)
 
-func check_errata_cve_2022_23960
+check_erratum_chosen cortex_a75, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
+
+workaround_reset_start cortex_a75, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/* Skip installing vector table again if already done for CVE(2017, 5715) */
+	adr	x0, wa_cve_2017_5715_bpiall_vbar
+	mrs	x1, vbar_el3
+	cmp	x0, x1
+	b.eq	1f
+	msr	vbar_el3, x0
+1:
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a75, CVE(2022, 23960)
+
+check_erratum_custom_start cortex_a75, CVE(2022, 23960)
 #if WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960
 	cpu_check_csv2	x0, 1f
 	mov	x0, #ERRATA_APPLIES
@@ -184,7 +97,34 @@
 #endif /* WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960 */
 	mov	x0, #ERRATA_MISSING
 	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_custom_end cortex_a75, CVE(2022, 23960)
+
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A75.
+	 * -------------------------------------------------
+	 */
+
+cpu_reset_func_start cortex_a75
+#if ENABLE_FEAT_AMU
+	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
+	sysreg_bit_set actlr_el3, CORTEX_A75_ACTLR_AMEN_BIT
+	isb
+
+	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
+	sysreg_bit_set actlr_el2, CORTEX_A75_ACTLR_AMEN_BIT
+	isb
+
+	/* Enable group0 counters */
+	mov	x0, #CORTEX_A75_AMU_GROUP0_MASK
+	msr	CPUAMCNTENSET_EL0, x0
+	isb
+
+	/* Enable group1 counters */
+	mov	x0, #CORTEX_A75_AMU_GROUP1_MASK
+	msr	CPUAMCNTENSET_EL0, x0
+	/* isb included in cpu_reset_func_end macro */
+#endif
+cpu_reset_func_end cortex_a75
 
 func check_smccc_arch_workaround_3
 	mov	x0, #ERRATA_APPLIES
@@ -200,39 +140,13 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A75_CPUPWRCTLR_EL1, \
+		CORTEX_A75_CORE_PWRDN_EN_MASK
 	isb
 	ret
 endfunc cortex_a75_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A75. Must follow AAPCS.
- */
-func cortex_a75_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A75_764081, cortex_a75, 764081
-	report_errata ERRATA_A75_790748, cortex_a75, 790748
-	report_errata WORKAROUND_CVE_2017_5715, cortex_a75, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a75, cve_2018_3639
-	report_errata ERRATA_DSU_798953, cortex_a75, dsu_798953
-	report_errata ERRATA_DSU_936184, cortex_a75, dsu_936184
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a75, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a75_errata_report
-#endif
+errata_report_shim cortex_a75
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a75 specific
@@ -255,7 +169,7 @@
 
 declare_cpu_ops_wa cortex_a75, CORTEX_A75_MIDR, \
 	cortex_a75_reset_func, \
-	check_errata_cve_2017_5715, \
+	check_erratum_cortex_a75_5715, \
 	CPU_NO_EXTRA2_FUNC, \
 	check_smccc_arch_workaround_3, \
 	cortex_a75_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75_pubsub.c b/lib/cpus/aarch64/cortex_a75_pubsub.c
index bd2c697..11190c8 100644
--- a/lib/cpus/aarch64/cortex_a75_pubsub.c
+++ b/lib/cpus/aarch64/cortex_a75_pubsub.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 36507de..8b3d730 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -298,154 +298,50 @@
 endfunc apply_cve_2018_3639_sync_wa
 #endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1073348.
-	 * This applies only to revision <= r1p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1073348_wa
-	/*
-	 * Compare x0 against revision r1p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1073348
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUACTLR_EL1
-	orr	x1, x1 ,#CORTEX_A76_CPUACTLR_EL1_DISABLE_STATIC_PREDICTION
-	msr	CORTEX_A76_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1073348_wa
+workaround_reset_start cortex_a76, ERRATUM(1073348), ERRATA_A76_1073348
+	sysreg_bit_set CORTEX_A76_CPUACTLR_EL1 ,CORTEX_A76_CPUACTLR_EL1_DISABLE_STATIC_PREDICTION
+workaround_reset_end cortex_a76, ERRATUM(1073348)
 
-func check_errata_1073348
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1073348
+check_erratum_ls cortex_a76, ERRATUM(1073348), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1130799.
-	 * This applies only to revision <= r2p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1130799_wa
-	/*
-	 * Compare x0 against revision r2p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1130799
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUACTLR2_EL1
-	orr	x1, x1 ,#(1 << 59)
+workaround_reset_start cortex_a76, ERRATUM(1130799), ERRATA_A76_1130799
+	sysreg_bit_set CORTEX_A76_CPUACTLR2_EL1, CORTEX_A76_CPUACTLR2_EL1_BIT_59
 	msr	CORTEX_A76_CPUACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1130799_wa
+workaround_reset_end cortex_a76, ERRATUM(1130799)
 
-func check_errata_1130799
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1130799
+check_erratum_ls cortex_a76, ERRATUM(1130799), CPU_REV(2, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1220197.
-	 * This applies only to revision <= r2p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1220197_wa
-/*
- * Compare x0 against revision r2p0
- */
-	mov	x17, x30
-	bl	check_errata_1220197
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUECTLR_EL1
-	orr	x1, x1, #CORTEX_A76_CPUECTLR_EL1_WS_THR_L2
-	msr	CORTEX_A76_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1220197_wa
+workaround_reset_start cortex_a76, ERRATUM(1220197), ERRATA_A76_1220197
+	sysreg_bit_set CORTEX_A76_CPUECTLR_EL1, CORTEX_A76_CPUECTLR_EL1_WS_THR_L2
+workaround_reset_end cortex_a76, ERRATUM(1220197)
 
-func check_errata_1220197
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1220197
+check_erratum_ls cortex_a76, ERRATUM(1220197), CPU_REV(2, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1257314.
-	 * This applies only to revision <= r3p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1257314_wa
-	/*
-	 * Compare x0 against revision r3p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1257314
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUACTLR3_EL1
-	orr	x1, x1, CORTEX_A76_CPUACTLR3_EL1_BIT_10
-	msr	CORTEX_A76_CPUACTLR3_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1257314_wa
+workaround_reset_start cortex_a76, ERRATUM(1257314), ERRATA_A76_1257314
+	sysreg_bit_set CORTEX_A76_CPUACTLR3_EL1, CORTEX_A76_CPUACTLR3_EL1_BIT_10
+workaround_reset_end cortex_a76, ERRATUM(1257314)
 
-func check_errata_1257314
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1257314
+check_erratum_ls cortex_a76, ERRATUM(1257314), CPU_REV(3, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1262888.
-	 * This applies only to revision <= r3p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1262888_wa
-	/*
-	 * Compare x0 against revision r3p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1262888
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUECTLR_EL1
-	orr	x1, x1, CORTEX_A76_CPUECTLR_EL1_BIT_51
-	msr	CORTEX_A76_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1262888_wa
+workaround_reset_start cortex_a76, ERRATUM(1262606), ERRATA_A76_1262606
+	sysreg_bit_set CORTEX_A76_CPUACTLR_EL1, CORTEX_A76_CPUACTLR_EL1_BIT_13
+workaround_reset_end cortex_a76, ERRATUM(1262606)
 
-func check_errata_1262888
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1262888
+check_erratum_ls cortex_a76, ERRATUM(1262606), CPU_REV(3, 0)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1286807.
-	 * This applies only to revision <= r3p0 of Cortex A76.
-	 * Due to the nature of the errata it is applied unconditionally
-	 * when built in, report it as applicable in this case
-	 * ---------------------------------------------------
-	 */
-func check_errata_1286807
+workaround_reset_start cortex_a76, ERRATUM(1262888), ERRATA_A76_1262888
+	sysreg_bit_set CORTEX_A76_CPUECTLR_EL1, CORTEX_A76_CPUECTLR_EL1_BIT_51
+workaround_reset_end cortex_a76, ERRATUM(1262888)
+
+check_erratum_ls cortex_a76, ERRATUM(1262888), CPU_REV(3, 0)
+
+workaround_reset_start cortex_a76, ERRATUM(1275112), ERRATA_A76_1275112
+	sysreg_bit_set CORTEX_A76_CPUACTLR_EL1, CORTEX_A76_CPUACTLR_EL1_BIT_13
+workaround_reset_end cortex_a76, ERRATUM(1275112)
+
+check_erratum_ls cortex_a76, ERRATUM(1275112), CPU_REV(3, 0)
+
+check_erratum_custom_start cortex_a76, ERRATUM(1286807)
 #if ERRATA_A76_1286807
 	mov x0, #ERRATA_APPLIES
 	ret
@@ -453,100 +349,21 @@
 	mov	x1, #0x30
 	b	cpu_rev_var_ls
 #endif
-endfunc check_errata_1286807
-
-	/* --------------------------------------------------
-	 * Errata workaround for Cortex A76 Errata #1791580.
-	 * This applies to revisions <= r4p0 of Cortex A76.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a76_1791580_wa
-	/* Compare x0 against revision r4p0 */
-	mov	x17, x30
-	bl	check_errata_1791580
-	cbz	x0, 1f
-	mrs	x1, CORTEX_A76_CPUACTLR2_EL1
-	orr	x1, x1, CORTEX_A76_CPUACTLR2_EL1_BIT_2
-	msr	CORTEX_A76_CPUACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1791580_wa
-
-func check_errata_1791580
-	/* Applies to everything <=r4p0. */
-	mov	x1, #0x40
-	b	cpu_rev_var_ls
-endfunc check_errata_1791580
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1262606,
-	 * #1275112, and #1868343.  #1262606 and #1275112
-	 * apply to revisions <= r3p0 and #1868343 applies to
-	 * revisions <= r4p0.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
+check_erratum_custom_end cortex_a76, ERRATUM(1286807)
 
-func errata_a76_1262606_1275112_1868343_wa
-	mov	x17, x30
+workaround_reset_start cortex_a76, ERRATUM(1791580), ERRATA_A76_1791580
+	sysreg_bit_set CORTEX_A76_CPUACTLR2_EL1, CORTEX_A76_CPUACTLR2_EL1_BIT_2
+workaround_reset_end cortex_a76, ERRATUM(1791580)
 
-/* Check for <= r3p0 cases and branch if check passes. */
-#if ERRATA_A76_1262606 || ERRATA_A76_1275112
-	bl	check_errata_1262606
-	cbnz	x0, 1f
-#endif
-
-/* Check for <= r4p0 cases and branch if check fails. */
-#if ERRATA_A76_1868343
-	bl	check_errata_1868343
-	cbz	x0, 2f
-#endif
-1:
-	mrs	x1, CORTEX_A76_CPUACTLR_EL1
-	orr	x1, x1, #CORTEX_A76_CPUACTLR_EL1_BIT_13
-	msr	CORTEX_A76_CPUACTLR_EL1, x1
-	isb
-2:
-	ret	x17
-endfunc errata_a76_1262606_1275112_1868343_wa
+check_erratum_ls cortex_a76, ERRATUM(1791580), CPU_REV(4, 0)
 
-func check_errata_1262606
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1262606
+workaround_reset_start cortex_a76, ERRATUM(1868343), ERRATA_A76_1868343
+	sysreg_bit_set CORTEX_A76_CPUACTLR_EL1, CORTEX_A76_CPUACTLR_EL1_BIT_13
+workaround_reset_end cortex_a76, ERRATUM(1868343)
 
-func check_errata_1275112
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1275112
+check_erratum_ls cortex_a76, ERRATUM(1868343), CPU_REV(4, 0)
 
-func check_errata_1868343
-	mov	x1, #0x40
-	b	cpu_rev_var_ls
-endfunc check_errata_1868343
-
-/* --------------------------------------------------
- * Errata Workaround for A76 Erratum 1946160.
- * This applies to revisions r3p0 - r4p1 of A76.
- * It also exists in r0p0 - r2p0 but there is no fix
- * in those revisions.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a76_1946160_wa
-	/* Compare x0 against revisions r3p0 - r4p1 */
-	mov	x17, x30
-	bl	check_errata_1946160
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a76, ERRATUM(1946160), ERRATA_A76_1946160
 	mov	x0, #3
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0x10E3900002
@@ -573,68 +390,33 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_C15_C8_1, x0
-
-	isb
-1:
-	ret	x17
-endfunc errata_a76_1946160_wa
+workaround_reset_end cortex_a76, ERRATUM(1946160)
 
-func check_errata_1946160
-	/* Applies to revisions r3p0 - r4p1. */
-	mov	x1, #0x30
-	mov	x2, #0x41
-	b	cpu_rev_var_range
-endfunc check_errata_1946160
-
-	/* ----------------------------------------------------
-	 * Errata Workaround for Cortex-A76 Errata #2743102
-	 * This applies to revisions <= r4p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ----------------------------------------------------
-	 */
-func errata_a76_2743102_wa
-	mov	x17, x30
-	bl	check_errata_2743102
-	cbz	x0, 1f
+check_erratum_range cortex_a76, ERRATUM(1946160), CPU_REV(3, 0), CPU_REV(4, 1)
 
+workaround_runtime_start cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_a76_2743102_wa
+workaround_runtime_end cortex_a76, ERRATUM(2743102)
 
-func check_errata_2743102
-	/* Applies to all revisions <= r4p1 */
-	mov	x1, #0x41
-	b	cpu_rev_var_ls
-endfunc check_errata_2743102
+check_erratum_ls cortex_a76, ERRATUM(2743102), CPU_REV(4, 1)
 
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
+check_erratum_chosen cortex_a76, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
 
 func cortex_a76_disable_wa_cve_2018_3639
-	mrs	x0, CORTEX_A76_CPUACTLR2_EL1
-	bic	x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
-	msr	CORTEX_A76_CPUACTLR2_EL1, x0
+	sysreg_bit_clear CORTEX_A76_CPUACTLR2_EL1, CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
 	isb
 	ret
 endfunc cortex_a76_disable_wa_cve_2018_3639
 
-	/* --------------------------------------------------------------
-	 * Errata Workaround for Cortex A76 Errata #1165522.
-	 * This applies only to revisions <= r3p0 of Cortex A76.
-	 * Due to the nature of the errata it is applied unconditionally
-	 * when built in, report it as applicable in this case
-	 * --------------------------------------------------------------
-	 */
-func check_errata_1165522
+/* --------------------------------------------------------------
+ * Errata Workaround for Cortex A76 Errata #1165522.
+ * This applies only to revisions <= r3p0 of Cortex A76.
+ * Due to the nature of the errata it is applied unconditionally
+ * when built in, report it as applicable in this case
+ * --------------------------------------------------------------
+ */
+check_erratum_custom_start cortex_a76, ERRATUM(1165522)
 #if ERRATA_A76_1165522
 	mov	x0, #ERRATA_APPLIES
 	ret
@@ -642,66 +424,32 @@
 	mov	x1, #0x30
 	b	cpu_rev_var_ls
 #endif
-endfunc check_errata_1165522
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif /* WORKAROUND_CVE_2022_23960 */
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_custom_end cortex_a76, ERRATUM(1165522)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A76.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
-	 */
-func cortex_a76_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+check_erratum_chosen cortex_a76, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if ERRATA_A76_1073348
-	mov	x0, x18
-	bl	errata_a76_1073348_wa
-#endif
+/* erratum has no workaround in the cpu. Generic code must take care */
+add_erratum_entry cortex_a76, CVE(2022, 23960), WORKAROUND_CVE_2022_23960, NO_APPLY_AT_RESET
 
-#if ERRATA_A76_1130799
-	mov	x0, x18
-	bl	errata_a76_1130799_wa
-#endif
-
-#if ERRATA_A76_1220197
-	mov	x0, x18
-	bl	errata_a76_1220197_wa
-#endif
-
-#if ERRATA_A76_1257314
-	mov	x0, x18
-	bl	errata_a76_1257314_wa
-#endif
-
-#if ERRATA_A76_1262606 || ERRATA_A76_1275112 || ERRATA_A76_1868343
-	mov	x0, x18
-	bl	errata_a76_1262606_1275112_1868343_wa
-#endif
-
-#if ERRATA_A76_1262888
-	mov	x0, x18
-	bl	errata_a76_1262888_wa
-#endif
+/* ERRATA_DSU_798953 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_a76
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a76_798953, check_errata_dsu_798953
+.equ erratum_cortex_a76_798953_wa, errata_dsu_798953_wa
+add_erratum_entry cortex_a76, ERRATUM(798953), ERRATA_DSU_798953, APPLY_AT_RESET
 
-#if ERRATA_A76_1791580
-	mov	x0, x18
-	bl	errata_a76_1791580_wa
-#endif
+/* ERRATA_DSU_936184 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_a76
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_a76_936184, check_errata_dsu_936184
+.equ erratum_cortex_a76_936184_wa, errata_dsu_936184_wa
+add_erratum_entry cortex_a76, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
 
-#if ERRATA_A76_1946160
-	mov	x0, x18
-	bl	errata_a76_1946160_wa
-#endif
+cpu_reset_func_start cortex_a76
 
 #if WORKAROUND_CVE_2018_3639
 	/* If the PE implements SSBS, we don't need the dynamic workaround */
@@ -714,9 +462,7 @@
 #endif
 #if DYNAMIC_WORKAROUND_CVE_2018_3639
 	cbnz	x0, 1f
-	mrs	x0, CORTEX_A76_CPUACTLR2_EL1
-	orr	x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
-	msr	CORTEX_A76_CPUACTLR2_EL1, x0
+	sysreg_bit_set CORTEX_A76_CPUACTLR2_EL1, CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
 	isb
 
 #ifdef IMAGE_BL31
@@ -727,8 +473,7 @@
 	 * If the below vector table is used, skip overriding it again for
 	 *  CVE_2022_23960 as both use the same vbar.
 	 */
-	adr	x0, cortex_a76_wa_cve_vbar
-	msr	vbar_el3, x0
+	override_vector_table cortex_a76_wa_cve_vbar
 	isb
 	b	2f
 #endif /* IMAGE_BL31 */
@@ -743,22 +488,11 @@
 	 * mitigation on exception entry from lower ELs. This will be bypassed
 	 * if DYNAMIC_WORKAROUND_CVE_2018_3639 has overridden the vectors.
 	 */
-	adr	x0, cortex_a76_wa_cve_vbar
-	msr	vbar_el3, x0
+	override_vector_table cortex_a76_wa_cve_vbar
 	isb
 #endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 2:
-
-#if ERRATA_DSU_798953
-	bl	errata_dsu_798953_wa
-#endif
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
-#endif
-
-	ret	x19
-endfunc cortex_a76_reset_func
+cpu_reset_func_end cortex_a76
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -769,55 +503,15 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A76_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A76_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A76_CPUPWRCTLR_EL1, x0
-#if ERRATA_A76_2743102
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a76_2743102_wa
-	mov	x30, x15
-#endif /* ERRATA_A76_2743102 */
+	sysreg_bit_set CORTEX_A76_CPUPWRCTLR_EL1, CORTEX_A76_CORE_PWRDN_EN_MASK
+
+	apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102
+
 	isb
 	ret
 endfunc cortex_a76_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A76. Must follow AAPCS.
- */
-func cortex_a76_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A76_1073348, cortex_a76, 1073348
-	report_errata ERRATA_A76_1130799, cortex_a76, 1130799
-	report_errata ERRATA_A76_1165522, cortex_a76, 1165522
-	report_errata ERRATA_A76_1220197, cortex_a76, 1220197
-	report_errata ERRATA_A76_1257314, cortex_a76, 1257314
-	report_errata ERRATA_A76_1262606, cortex_a76, 1262606
-	report_errata ERRATA_A76_1262888, cortex_a76, 1262888
-	report_errata ERRATA_A76_1275112, cortex_a76, 1275112
-	report_errata ERRATA_A76_1286807, cortex_a76, 1286807
-	report_errata ERRATA_A76_1791580, cortex_a76, 1791580
-	report_errata ERRATA_A76_1868343, cortex_a76, 1868343
-	report_errata ERRATA_A76_1946160, cortex_a76, 1946160
-	report_errata ERRATA_A76_2743102, cortex_a76, 2743102
-	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
-	report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
-	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a76, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a76_errata_report
-#endif
+errata_report_shim cortex_a76
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a76 specific
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 5c19548..08a6ef9 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,71 +25,34 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A76AE_BHB_LOOP_COUNT, cortex_a76ae
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif /* WORKAROUND_CVE_2022_23960 */
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_chosen cortex_a76ae, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-	/* --------------------------------------------
-	 * The CPU Ops reset function for Cortex-A76AE.
-	 * Shall clobber: x0-x19
-	 * --------------------------------------------
-	 */
-func cortex_a76ae_reset_func
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a76ae, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex-A76ae generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-	adr	x0, wa_cve_vbar_cortex_a76ae
-	msr	vbar_el3, x0
+	override_vector_table wa_cve_vbar_cortex_a76ae
 	isb
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a76ae, CVE(2022, 23960)
 
-	ret
-endfunc cortex_a76ae_reset_func
+cpu_reset_func_start cortex_a76ae
+cpu_reset_func_end cortex_a76ae
+
+errata_report_shim cortex_a76ae
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
 func cortex_a76ae_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_A76AE_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
-	msr	CORTEX_A76AE_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A76AE_CPUPWRCTLR_EL1, CORTEX_A76AE_CORE_PWRDN_EN_MASK
 	isb
 	ret
 endfunc cortex_a76ae_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A76AE. Must follow AAPCS.
- */
-func cortex_a76ae_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a76ae, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a76ae_errata_report
-#endif	/* REPORT_ERRATA */
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a76ae specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 2882df7..86c2561 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,26 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A77_BHB_LOOP_COUNT, cortex_a77
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #1508412.
-	 * This applies only to revision <= r1p0 of Cortex A77.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_1508412_wa
-	/*
-	 * Compare x0 against revision r1p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1508412
-	cbz	x0, 3f
-	/*
-	 * Compare x0 against revision r0p0
-	 */
-	bl	check_errata_1508412_0
+workaround_reset_start cortex_a77, ERRATUM(1508412), ERRATA_A77_1508412
+	/* move cpu revision in again and compare against r0p0 */
+	mov	x0, x7
+	mov	x1, #CPU_REV(0, 0)
+	bl	cpu_rev_var_ls
 	cbz	x0, 1f
+
 	ldr	x0, =0x0
 	msr	CORTEX_A77_CPUPSELR_EL3, x0
 	ldr 	x0, =0x00E8400000
@@ -75,64 +62,30 @@
 2:
 	ldr	x0, =0x04004003FF
 	msr	CORTEX_A77_CPUPCR_EL3, x0
-	isb
-3:
-	ret	x17
-endfunc errata_a77_1508412_wa
+workaround_reset_end cortex_a77, ERRATUM(1508412)
 
-func check_errata_1508412
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1508412
+check_erratum_ls cortex_a77, ERRATUM(1508412), CPU_REV(1, 0)
 
-func check_errata_1508412_0
-	mov	x1, #0x0
-	b	cpu_rev_var_ls
-endfunc check_errata_1508412_0
+workaround_reset_start cortex_a77, ERRATUM(1791578), ERRATA_A77_1791578
+	sysreg_bit_set CORTEX_A77_ACTLR2_EL1, CORTEX_A77_ACTLR2_EL1_BIT_2
+workaround_reset_end cortex_a77, ERRATUM(1791578)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #1925769.
-	 * This applies to revision <= r1p1 of Cortex A77.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_1925769_wa
-	/* Compare x0 against revision <= r1p1 */
-	mov	x17, x30
-	bl	check_errata_1925769
-	cbz	x0, 1f
+check_erratum_ls cortex_a77, ERRATUM(1791578), CPU_REV(1, 1)
 
-	/* Set bit 8 in ECTLR_EL1 */
-	mrs	x1, CORTEX_A77_CPUECTLR_EL1
-	orr	x1, x1, #CORTEX_A77_CPUECTLR_EL1_BIT_8
-	msr	CORTEX_A77_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a77_1925769_wa
+workaround_reset_start cortex_a77, ERRATUM(1800714), ERRATA_A77_1800714
+	/* Disable allocation of splintered pages in the L2 TLB */
+	sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, CORTEX_A77_CPUECTLR_EL1_BIT_53
+workaround_reset_end cortex_a77, ERRATUM(1800714)
 
-func check_errata_1925769
-	/* Applies to everything <= r1p1 */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1925769
+check_erratum_ls cortex_a77, ERRATUM(1800714), CPU_REV(1, 1)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #1946167.
-	 * This applies to revision <= r1p1 of Cortex A77.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_1946167_wa
-	/* Compare x0 against revision <= r1p1 */
-	mov	x17, x30
-	bl	check_errata_1946167
-	cbz	x0, 1f
+workaround_reset_start cortex_a77, ERRATUM(1925769), ERRATA_A77_1925769
+	sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, CORTEX_A77_CPUECTLR_EL1_BIT_8
+workaround_reset_end cortex_a77, ERRATUM(1925769)
+
+check_erratum_ls cortex_a77, ERRATUM(1925769), CPU_REV(1, 1)
 
+workaround_reset_start cortex_a77, ERRATUM(1946167), ERRATA_A77_1946167
 	ldr	x0,=0x4
 	msr	CORTEX_A77_CPUPSELR_EL3,x0
 	ldr	x0,=0x10E3900002
@@ -159,188 +112,42 @@
 	msr	CORTEX_A77_CPUPMR_EL3,x0
 	ldr	x0,=0x2001003FF
 	msr	CORTEX_A77_CPUPCR_EL3,x0
+workaround_reset_end cortex_a77, ERRATUM(1946167)
 
-	isb
-1:
-	ret	x17
-endfunc errata_a77_1946167_wa
+check_erratum_ls cortex_a77, ERRATUM(1946167), CPU_REV(1, 1)
 
-func check_errata_1946167
-	/* Applies to everything <= r1p1 */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1946167
+workaround_reset_start cortex_a77, ERRATUM(2356587), ERRATA_A77_2356587
+	sysreg_bit_set CORTEX_A77_ACTLR2_EL1, CORTEX_A77_ACTLR2_EL1_BIT_0
+workaround_reset_end cortex_a77, ERRATUM(2356587)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #1791578.
-	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_1791578_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1791578
-	cbz	x0, 1f
+check_erratum_ls cortex_a77, ERRATUM(2356587), CPU_REV(1, 1)
 
-	/* Set bit 2 in ACTLR2_EL1 */
-	mrs     x1, CORTEX_A77_ACTLR2_EL1
-	orr	x1, x1, #CORTEX_A77_ACTLR2_EL1_BIT_2
-	msr     CORTEX_A77_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a77_1791578_wa
-
-func check_errata_1791578
-	/* Applies to r0p0, r1p0, and r1p1 right now */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1791578
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #2356587.
-	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_2356587_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2356587
-	cbz	x0, 1f
-
-	/* Set bit 0 in ACTLR2_EL1 */
-	mrs	x1, CORTEX_A77_ACTLR2_EL1
-	orr	x1, x1, #CORTEX_A77_ACTLR2_EL1_BIT_0
-	msr	CORTEX_A77_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a77_2356587_wa
-
-func check_errata_2356587
-	/* Applies to r0p0, r1p0, and r1p1 right now */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2356587
-
-	/* -----------------------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #2743100
-	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * -----------------------------------------------------------------
-	 */
-func errata_a77_2743100_wa
-	mov	x17, x30
-	bl	check_errata_2743100
-	cbz	x0, 1f
-
+workaround_runtime_start cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_a77_2743100_wa
+workaround_runtime_end cortex_a77, ERRATUM(2743100), NO_ISB
 
-func check_errata_2743100
-	/* Applies to r0p0, r1p0, and r1p1 right now */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2743100
+check_erratum_ls cortex_a77, ERRATUM(2743100), CPU_REV(1, 1)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex A77 Errata #1800714.
-	 * This applies to revision <= r1p1 of Cortex A77.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_a77_1800714_wa
-	/* Compare x0 against revision <= r1p1 */
-	mov	x17, x30
-	bl	check_errata_1800714
-	cbz	x0, 1f
-
-	/* Disable allocation of splintered pages in the L2 TLB */
-	mrs	x1, CORTEX_A77_CPUECTLR_EL1
-	orr	x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53
-	msr	CORTEX_A77_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a77_1800714_wa
-
-func check_errata_1800714
-	/* Applies to everything <= r1p1 */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1800714
-
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A77.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
-	 */
-func cortex_a77_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A77_1508412
-	mov	x0, x18
-	bl	errata_a77_1508412_wa
-#endif
-
-#if ERRATA_A77_1925769
-	mov	x0, x18
-	bl	errata_a77_1925769_wa
-#endif
-
-#if ERRATA_A77_1946167
-	mov	x0, x18
-	bl	errata_a77_1946167_wa
-#endif
-
-#if ERRATA_A77_1791578
-	mov	x0, x18
-	bl	errata_a77_1791578_wa
-#endif
-
-#if ERRATA_A77_2356587
-	mov	x0, x18
-	bl	errata_a77_2356587_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a77, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex-A77 generic vectors are overridden to apply errata
          * mitigation on exception entry from lower ELs.
 	 */
 	adr	x0, wa_cve_vbar_cortex_a77
 	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a77, CVE(2022, 23960)
 
-#if ERRATA_A77_1800714
-	mov	x0, x18
-	bl	errata_a77_1800714_wa
-#endif
+check_erratum_chosen cortex_a77, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-	isb
-	ret	x19
-endfunc cortex_a77_reset_func
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A77. Must follow AAPCS.
+	 * -------------------------------------------------
+	 */
+cpu_reset_func_start cortex_a77
+cpu_reset_func_end cortex_a77
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -351,48 +158,16 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, CORTEX_A77_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_A77_CPUPWRCTLR_EL1, x0
-#if ERRATA_A77_2743100
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a77_2743100_wa
-	mov	x30, x15
-#endif /* ERRATA_A77_2743100 */
-	isb
-	ret
-endfunc cortex_a77_core_pwr_dwn
+	sysreg_bit_set CORTEX_A77_CPUPWRCTLR_EL1, \
+		CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A77. Must follow AAPCS.
- */
-func cortex_a77_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A77_1508412, cortex_a77, 1508412
-	report_errata ERRATA_A77_1791578, cortex_a77, 1791578
-	report_errata ERRATA_A77_1800714, cortex_a77, 1800714
-	report_errata ERRATA_A77_1925769, cortex_a77, 1925769
-	report_errata ERRATA_A77_1946167, cortex_a77, 1946167
-	report_errata ERRATA_A77_2356587, cortex_a77, 2356587
-	report_errata ERRATA_A77_2743100, cortex_a77, 2743100
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a77, cve_2022_23960
+	apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100
 
-	ldp	x8, x30, [sp], #16
+	isb
 	ret
-endfunc cortex_a77_errata_report
-#endif
-
+endfunc cortex_a77_core_pwr_dwn
 
+errata_report_shim cortex_a77
 	/* ---------------------------------------------
 	 * This function provides Cortex-A77 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 69d7ab0..b5c24e1 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,77 +24,25 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for A78 Erratum 1688305.
- * This applies to revision r0p0 and r1p0 of A78.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_1688305_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1688305
-	cbz	x0, 1f
-	mrs     x1, CORTEX_A78_ACTLR2_EL1
-	orr	x1, x1, #CORTEX_A78_ACTLR2_EL1_BIT_1
-	msr     CORTEX_A78_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a78_1688305_wa
+workaround_reset_start cortex_a78, ERRATUM(1688305), ERRATA_A78_1688305
+	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_1
+workaround_reset_end cortex_a78, ERRATUM(1688305)
 
-func check_errata_1688305
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1688305
+check_erratum_ls cortex_a78, ERRATUM(1688305), CPU_REV(1, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata #1941498.
- * This applies to revisions r0p0, r1p0, and r1p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_1941498_wa
-	/* Compare x0 against revision <= r1p1 */
-	mov	x17, x30
-	bl	check_errata_1941498
-	cbz	x0, 1f
+workaround_reset_start cortex_a78, ERRATUM(1821534), ERRATA_A78_1821534
+	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_2
+workaround_reset_end cortex_a78, ERRATUM(1821534)
 
-	/* Set bit 8 in ECTLR_EL1 */
-	mrs	x1, CORTEX_A78_CPUECTLR_EL1
-	orr	x1, x1, #CORTEX_A78_CPUECTLR_EL1_BIT_8
-	msr	CORTEX_A78_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a78_1941498_wa
+check_erratum_ls cortex_a78, ERRATUM(1821534), CPU_REV(1, 0)
 
-func check_errata_1941498
-	/* Check for revision <= r1p1, might need to be updated later. */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1941498
+workaround_reset_start cortex_a78, ERRATUM(1941498), ERRATA_A78_1941498
+	sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, CORTEX_A78_CPUECTLR_EL1_BIT_8
+workaround_reset_end cortex_a78, ERRATUM(1941498)
 
-/* --------------------------------------------------
- * Errata Workaround for A78 Erratum 1951500.
- * This applies to revisions r1p0 and r1p1 of A78.
- * The issue also exists in r0p0 but there is no fix
- * in that revision.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_1951500_wa
-	/* Compare x0 against revisions r1p0 - r1p1 */
-	mov	x17, x30
-	bl	check_errata_1951500
-	cbz	x0, 1f
+check_erratum_ls cortex_a78, ERRATUM(1941498), CPU_REV(1, 1)
 
+workaround_reset_start cortex_a78, ERRATUM(1951500), ERRATA_A78_1951500
 	msr	S3_6_c15_c8_0, xzr
 	ldr	x0, =0x10E3900002
 	msr	S3_6_c15_c8_2, x0
@@ -120,60 +68,11 @@
 	msr	S3_6_c15_c8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_c15_c8_1, x0
-
-	isb
-1:
-	ret	x17
-endfunc errata_a78_1951500_wa
-
-func check_errata_1951500
-	/* Applies to revisions r1p0 and r1p1. */
-	mov	x1, #CPU_REV(1, 0)
-	mov	x2, #CPU_REV(1, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_1951500
-
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata #1821534.
- * This applies to revisions r0p0 and r1p0.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_1821534_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_1821534
-	cbz	x0, 1f
-
-	/* Set bit 2 in ACTLR2_EL1 */
-	mrs     x1, CORTEX_A78_ACTLR2_EL1
-	orr	x1, x1, #CORTEX_A78_ACTLR2_EL1_BIT_2
-	msr     CORTEX_A78_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_a78_1821534_wa
+workaround_reset_end cortex_a78, ERRATUM(1951500)
 
-func check_errata_1821534
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1821534
+check_erratum_range cortex_a78, ERRATUM(1951500), CPU_REV(1, 0), CPU_REV(1, 1)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 1952683.
- * This applies to revision r0p0.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_1952683_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_1952683
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78, ERRATUM(1952683), ERRATA_A78_1952683
 	ldr	x0,=0x5
 	msr	S3_6_c15_c8_0,x0
 	ldr	x0,=0xEEE10A10
@@ -194,61 +93,21 @@
 	msr	S3_6_c15_c8_3,x0
 	ldr	x0,=0x40000080023ff
 	msr	S3_6_c15_c8_1,x0
-	isb
-1:
-	ret	x17
-endfunc errata_a78_1952683_wa
+workaround_reset_end cortex_a78, ERRATUM(1952683)
 
-func check_errata_1952683
-	/* Applies to r0p0 only */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1952683
+check_erratum_ls cortex_a78, ERRATUM(1952683), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 2132060.
- * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_a78_2132060_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2132060
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78, ERRATUM(2132060), ERRATA_A78_2132060
 	/* Apply the workaround. */
 	mrs	x1, CORTEX_A78_CPUECTLR_EL1
 	mov	x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV
 	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
 	msr	CORTEX_A78_CPUECTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78_2132060_wa
+workaround_reset_end cortex_a78, ERRATUM(2132060)
 
-func check_errata_2132060
-	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_2132060
+check_erratum_ls cortex_a78, ERRATUM(2132060), CPU_REV(1, 2)
 
-/* --------------------------------------------------------------------
- * Errata Workaround for A78 Erratum 2242635.
- * This applies to revisions r1p0, r1p1, and r1p2 of the Cortex A78
- * processor and is still open.
- * The issue also exists in r0p0 but there is no fix in that revision.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------------------------
- */
-func errata_a78_2242635_wa
-	/* Compare x0 against revisions r1p0 - r1p2 */
-	mov	x17, x30
-	bl	check_errata_2242635
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78, ERRATUM(2242635), ERRATA_A78_2242635
 	ldr	x0, =0x5
 	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
 	ldr	x0, =0x10F600E000
@@ -257,242 +116,64 @@
 	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
 	ldr	x0, =0x80000000003FF
 	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+workaround_reset_end cortex_a78, ERRATUM(2242635)
 
-	isb
-1:
-	ret	x17
-endfunc errata_a78_2242635_wa
+check_erratum_range cortex_a78, ERRATUM(2242635), CPU_REV(1, 0), CPU_REV(1, 2)
 
-func check_errata_2242635
-	/* Applies to revisions r1p0 through r1p2. */
-	mov	x1, #CPU_REV(1, 0)
-	mov	x2, #CPU_REV(1, 2)
-	b	cpu_rev_var_range
-endfunc check_errata_2242635
+workaround_reset_start cortex_a78, ERRATUM(2376745), ERRATA_A78_2376745
+	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, BIT(0)
+workaround_reset_end cortex_a78, ERRATUM(2376745)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 2376745.
- * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_a78_2376745_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2376745
-	cbz	x0, 1f
-
-	/* Apply the workaround. */
-	mrs	x1, CORTEX_A78_ACTLR2_EL1
-	orr	x1, x1, #BIT(0)
-	msr	CORTEX_A78_ACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78_2376745_wa
+check_erratum_ls cortex_a78, ERRATUM(2376745), CPU_REV(1, 2)
 
-func check_errata_2376745
-	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
-	mov	x1, #CPU_REV(1, 2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2376745
+workaround_reset_start cortex_a78, ERRATUM(2395406), ERRATA_A78_2395406
+	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, BIT(40)
+workaround_reset_end cortex_a78, ERRATUM(2395406)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 2395406.
- * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_a78_2395406_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2395406
-	cbz	x0, 1f
-
-	/* Apply the workaround. */
-	mrs	x1, CORTEX_A78_ACTLR2_EL1
-	orr	x1, x1, #BIT(40)
-	msr	CORTEX_A78_ACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78_2395406_wa
+check_erratum_ls cortex_a78, ERRATUM(2395406), CPU_REV(1, 2)
 
-func check_errata_2395406
-	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
-	mov	x1, #CPU_REV(1, 2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2395406
-
-/* ----------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 2742426.
- * This applies to revisions r0p0, r1p0, r1p1 and r1p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * ----------------------------------------------------
- */
-func errata_a78_2742426_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2742426
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78, ERRATUM(2742426), ERRATA_A78_2742426
 	/* Apply the workaround */
 	mrs	x1, CORTEX_A78_ACTLR5_EL1
 	bic	x1, x1, #BIT(56)
 	orr	x1, x1, #BIT(55)
 	msr	CORTEX_A78_ACTLR5_EL1, x1
+workaround_reset_end cortex_a78, ERRATUM(2742426)
 
-1:
-	ret	x17
-endfunc errata_a78_2742426_wa
+check_erratum_ls cortex_a78, ERRATUM(2742426), CPU_REV(1, 2)
 
-func check_errata_2742426
-	/* Applies to r0p0, r1p0, r1p1, r1p2 */
-	mov	x1, #CPU_REV(1, 2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2742426
-
-/* ----------------------------------------------------
- * Errata Workaround for Cortex-A78 Errata 2772019
- * This applies to revisions <= r1p2 and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------
- */
-func errata_a78_2772019_wa
-	mov	x17, x30
-	bl	check_errata_2772019
-	cbz	x0, 1f
-
-
+workaround_runtime_start cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_a78_2772019_wa
-
-func check_errata_2772019
-	/* Applies to all revisions <= r1p2 */
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_2772019
-
-/* ----------------------------------------------------
- * Errata Workaround for Cortex A78 Errata 2779479.
- * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * ----------------------------------------------------
- */
-func errata_a78_2779479_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2779479
-	cbz	x0, 1f
+workaround_runtime_end cortex_a78, ERRATUM(2772019)
 
-	/* Apply the workaround */
-	mrs	x1, CORTEX_A78_ACTLR3_EL1
-	orr	x1, x1, #BIT(47)
-	msr	CORTEX_A78_ACTLR3_EL1, x1
-
-1:
-	ret	x17
-endfunc errata_a78_2779479_wa
+check_erratum_ls cortex_a78, ERRATUM(2772019), CPU_REV(1, 2)
 
-func check_errata_2779479
-	/* Applies to r0p0, r1p0, r1p1, r1p2 */
-	mov	x1, #CPU_REV(1, 2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2779479
+workaround_reset_start cortex_a78, ERRATUM(2779479), ERRATA_A78_2779479
+	sysreg_bit_set CORTEX_A78_ACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_a78, ERRATUM(2779479)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_ls cortex_a78, ERRATUM(2779479), CPU_REV(1, 2)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A78
-	 * -------------------------------------------------
+workaround_reset_start cortex_a78, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Cortex-X1 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
 	 */
-func cortex_a78_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A78_1688305
-	mov     x0, x18
-	bl	errata_a78_1688305_wa
-#endif
-
-#if ERRATA_A78_1941498
-	mov     x0, x18
-	bl	errata_a78_1941498_wa
-#endif
-
-#if ERRATA_A78_1951500
-	mov	x0, x18
-	bl	errata_a78_1951500_wa
-#endif
-
-#if ERRATA_A78_1821534
-	mov	x0, x18
-	bl	errata_a78_1821534_wa
-#endif
-
-#if ERRATA_A78_1952683
-	mov	x0, x18
-	bl	errata_a78_1952683_wa
-#endif
-
-#if ERRATA_A78_2132060
-	mov	x0, x18
-	bl	errata_a78_2132060_wa
-#endif
+	override_vector_table wa_cve_vbar_cortex_a78
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a78, CVE(2022, 23960)
 
-#if ERRATA_A78_2242635
-	mov	x0, x18
-	bl	errata_a78_2242635_wa
-#endif
-
-#if ERRATA_A78_2376745
-	mov	x0, x18
-	bl	errata_a78_2376745_wa
-#endif
+check_erratum_chosen cortex_a78, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if ERRATA_A78_2395406
-	mov	x0, x18
-	bl	errata_a78_2395406_wa
-#endif
-
-#if ERRATA_A78_2742426
-	mov	x0, x18
-	bl	errata_a78_2742426_wa
-#endif
-
-#if ERRATA_A78_2779479
-	mov	x0, x18
-	bl	errata_a78_2779479_wa
-#endif
-
+cpu_reset_func_start cortex_a78
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, actlr_el3
-	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
-	msr	actlr_el3, x0
+	sysreg_bit_clear actlr_el3, CORTEX_A78_ACTLR_TAM_BIT
 
 	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
-	mrs	x0, actlr_el2
-	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
-	msr	actlr_el2, x0
+	sysreg_bit_clear actlr_el2, CORTEX_A78_ACTLR_TAM_BIT
 
 	/* Enable group0 counters */
 	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
@@ -502,74 +183,22 @@
 	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
 	msr	CPUAMCNTENSET1_EL0, x0
 #endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex-A78 generic vectors are overridden to apply errata
-	 * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_cortex_a78
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc cortex_a78_reset_func
+cpu_reset_func_end cortex_a78
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
 	 */
 func cortex_a78_core_pwr_dwn
-	/* ---------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
-	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
-#if ERRATA_A78_2772019
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a78_2772019_wa
-	mov	x30, x15
-#endif /* ERRATA_A78_2772019 */
+	sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+
+	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
+
 	isb
 	ret
 endfunc cortex_a78_core_pwr_dwn
 
-	/*
-	 * Errata printing function for cortex_a78. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_a78_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A78_1688305, cortex_a78, 1688305
-	report_errata ERRATA_A78_1941498, cortex_a78, 1941498
-	report_errata ERRATA_A78_1951500, cortex_a78, 1951500
-	report_errata ERRATA_A78_1821534, cortex_a78, 1821534
-	report_errata ERRATA_A78_1952683, cortex_a78, 1952683
-	report_errata ERRATA_A78_2132060, cortex_a78, 2132060
-	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
-	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
-	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
-	report_errata ERRATA_A78_2742426, cortex_a78, 2742426
-	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
-	report_errata ERRATA_A78_2779479, cortex_a78, 2779479
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a78_errata_report
-#endif
+errata_report_shim cortex_a78
 
 	/* ---------------------------------------------
 	 * This function provides cortex_a78 specific
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index d56f835..9f729c1 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -22,50 +22,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for A78 AE Erratum 1941500.
- * This applies to revisions r0p0 and r0p1 of A78 AE.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_ae_1941500_wa
-	/* Compare x0 against revisions r0p0 - r0p1 */
-	mov	x17, x30
-	bl	check_errata_1941500
-	cbz	x0, 1f
-
-	/* Set bit 8 in ECTLR_EL1 */
-	mrs	x0, CORTEX_A78_AE_CPUECTLR_EL1
-	bic	x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
-	msr	CORTEX_A78_AE_CPUECTLR_EL1, x0
-	isb
-1:
-	ret	x17
-endfunc errata_a78_ae_1941500_wa
+workaround_reset_start cortex_a78_ae, ERRATUM(1941500), ERRATA_A78_AE_1941500
+	sysreg_bit_clear CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
+workaround_reset_end cortex_a78_ae, ERRATUM(1941500)
 
-func check_errata_1941500
-	/* Applies to revisions r0p0 and r0p1. */
-	mov	x1, #CPU_REV(0, 0)
-	mov	x2, #CPU_REV(0, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_1941500
+check_erratum_ls cortex_a78_ae, ERRATUM(1941500), CPU_REV(0, 1)
 
-/* --------------------------------------------------
- * Errata Workaround for A78 AE Erratum 1951502.
- * This applies to revisions r0p0 and r0p1 of A78 AE.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_ae_1951502_wa
-	/* Compare x0 against revisions r0p0 - r0p1 */
-	mov	x17, x30
-	bl	check_errata_1951502
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78_ae, ERRATUM(1951502), ERRATA_A78_AE_1951502
 	msr	S3_6_c15_c8_0, xzr
 	ldr	x0, =0x10E3900002
 	msr	S3_6_c15_c8_2, x0
@@ -91,33 +54,11 @@
 	msr	S3_6_c15_c8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_c15_c8_1, x0
+workaround_reset_end cortex_a78_ae, ERRATUM(1951502)
 
-	isb
-1:
-	ret	x17
-endfunc errata_a78_ae_1951502_wa
+check_erratum_ls cortex_a78_ae, ERRATUM(1951502), CPU_REV(0, 1)
 
-func check_errata_1951502
-	/* Applies to revisions r0p0 and r0p1. */
-	mov	x1, #CPU_REV(0, 0)
-	mov	x2, #CPU_REV(0, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_1951502
-
-/* --------------------------------------------------
- * Errata Workaround for A78 AE Erratum 2376748.
- * This applies to revisions r0p0 and r0p1 of A78 AE.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_ae_2376748_wa
-	/* Compare x0 against revisions r0p0 - r0p1 */
-	mov	x17, x30
-	bl	check_errata_2376748
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78_ae, ERRATUM(2376748), ERRATA_A78_AE_2376748
 	/* -------------------------------------------------------
 	 * Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM ST to
 	 * behave like PLD/PRFM LD and not cause invalidations to
@@ -126,104 +67,42 @@
 	 * that share data.
 	 * -------------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A78_AE_ACTLR2_EL1
-	orr	x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_0
-	msr	CORTEX_A78_AE_ACTLR2_EL1, x0
-	isb
-1:
-	ret	x17
-endfunc errata_a78_ae_2376748_wa
-
-func check_errata_2376748
-	/* Applies to revisions r0p0 and r0p1. */
-	mov	x1, #CPU_REV(0, 0)
-	mov	x2, #CPU_REV(0, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_2376748
+	sysreg_bit_set CORTEX_A78_AE_ACTLR2_EL1, CORTEX_A78_AE_ACTLR2_EL1_BIT_0
+workaround_reset_end cortex_a78_ae, ERRATUM(2376748)
 
-/* --------------------------------------------------
- * Errata Workaround for A78 AE Erratum 2395408.
- * This applies to revisions r0p0 and r0p1 of A78 AE.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78_ae_2395408_wa
-	/* Compare x0 against revisions r0p0 - r0p1 */
-	mov	x17, x30
-	bl	check_errata_2395408
-	cbz	x0, 1f
+check_erratum_ls cortex_a78_ae, ERRATUM(2376748), CPU_REV(0, 1)
 
+workaround_reset_start cortex_a78_ae, ERRATUM(2395408), ERRATA_A78_AE_2395408
 	/* --------------------------------------------------------
 	 * Disable folding of demand requests into older prefetches
 	 * with L2 miss requests outstanding by setting the
 	 * CPUACTLR2_EL1[40] to 1.
 	 * --------------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A78_AE_ACTLR2_EL1
-	orr	x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_40
-	msr	CORTEX_A78_AE_ACTLR2_EL1, x0
-	isb
-1:
-	ret	x17
-endfunc errata_a78_ae_2395408_wa
-
-func check_errata_2395408
-	/* Applies to revisions r0p0 and r0p1. */
-	mov	x1, #CPU_REV(0, 0)
-	mov	x2, #CPU_REV(0, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_2395408
+	sysreg_bit_set CORTEX_A78_AE_ACTLR2_EL1, CORTEX_A78_AE_ACTLR2_EL1_BIT_40
+workaround_reset_end cortex_a78_ae, ERRATUM(2395408)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_ls cortex_a78_ae, ERRATUM(2395408), CPU_REV(0, 1)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A78-AE
-	 * -------------------------------------------------
+workaround_reset_start cortex_a78_ae, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Cortex-A78AE generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
 	 */
-func cortex_a78_ae_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+	override_vector_table wa_cve_vbar_cortex_a78_ae
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a78_ae, CVE(2022, 23960)
 
-#if ERRATA_A78_AE_1941500
-	mov	x0, x18
-	bl	errata_a78_ae_1941500_wa
-#endif
+check_erratum_chosen cortex_a78_ae, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if ERRATA_A78_AE_1951502
-	mov	x0, x18
-	bl	errata_a78_ae_1951502_wa
-#endif
-
-#if ERRATA_A78_AE_2376748
-	mov	x0, x18
-	bl	errata_a78_ae_2376748_wa
-#endif
-
-#if ERRATA_A78_AE_2395408
-	mov	x0, x18
-	bl	errata_a78_ae_2395408_wa
-#endif
-
+cpu_reset_func_start cortex_a78_ae
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, actlr_el3
-	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
-	msr	actlr_el3, x0
+	sysreg_bit_clear actlr_el3, CORTEX_A78_ACTLR_TAM_BIT
 
 	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
-	mrs	x0, actlr_el2
-	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
-	msr	actlr_el2, x0
+	sysreg_bit_clear actlr_el2, CORTEX_A78_ACTLR_TAM_BIT
 
 	/* Enable group0 counters */
 	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
@@ -233,19 +112,7 @@
 	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
 	msr	CPUAMCNTENSET1_EL0, x0
 #endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex-A78AE generic vectors are overridden to apply errata
-	 * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_cortex_a78_ae
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc cortex_a78_ae_reset_func
+cpu_reset_func_end cortex_a78_ae
 
 	/* -------------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -256,37 +123,12 @@
 	 * Enable CPU power down bit in power control register
 	 * -------------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
-	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	isb
 	ret
 endfunc cortex_a78_ae_core_pwr_dwn
 
-	/*
-	 * Errata printing function for cortex_a78_ae. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_a78_ae_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
-	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
-	report_errata ERRATA_A78_AE_2376748, cortex_a78_ae, 2376748
-	report_errata ERRATA_A78_AE_2395408, cortex_a78_ae, 2395408
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a78_ae, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a78_ae_errata_report
-#endif
+errata_report_shim cortex_a78_ae
 
 	/* -------------------------------------------------------
 	 * This function provides cortex_a78_ae specific
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index fddd24f..d19c693 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -17,174 +17,37 @@
 #error "cortex_a78c must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
-/* --------------------------------------------------
- * Errata Workaround for A78C Erratum 1827430.
- * This applies to revision r0p0 of the Cortex A78C
- * processor and is fixed in r0p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78c_1827430_wa
-	mov	x17, x30
-	bl	check_errata_1827430
-	cbz	x0, 1f
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
+#endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_a78c, ERRATUM(1827430), ERRATA_A78C_1827430
 	/* Disable allocation of splintered pages in the L2 TLB */
-	mrs	x1, CORTEX_A78C_CPUECTLR_EL1
-	orr	x1, x1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
-	msr	CORTEX_A78C_CPUECTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78c_1827430_wa
+	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
+workaround_reset_end cortex_a78c, ERRATUM(1827430)
 
-func check_errata_1827430
-	/* Applies to revision r0p0 only */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1827430
+check_erratum_ls cortex_a78c, ERRATUM(1827430), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for A78C Erratum 1827440.
- * This applies to revision r0p0 of the Cortex A78C
- * processor and is fixed in r0p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78c_1827440_wa
-	mov	x17, x30
-	bl	check_errata_1827440
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78c, ERRATUM(1827440), ERRATA_A78C_1827440
 	/* Force Atomic Store to WB memory be done in L1 data cache */
-	mrs	x1, CORTEX_A78C_CPUACTLR2_EL1
-	orr	x1, x1, #BIT(2)
-	msr	CORTEX_A78C_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78c_1827440_wa
-
-func check_errata_1827440
-	/* Applies to revision r0p0 only */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1827440
+	sysreg_bit_set CORTEX_A78C_CPUACTLR2_EL1, BIT(2)
+workaround_reset_end cortex_a78c, ERRATUM(1827440)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78C Erratum 2376749.
- * This applies to revision r0p1 and r0p2 of the A78C
- * and is currently open. It is a Cat B erratum.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x4, x17
- * --------------------------------------------------
- */
-func errata_a78c_2376749_wa
-	/* Check revision */
-	mov	x17, x30
-	bl	check_errata_2376749
-	cbz	x0, 1f
-	/* Set CPUACTLR2_EL1[0] to 1. */
-	mrs	x1, CORTEX_A78C_CPUACTLR2_EL1
-	orr	x1, x1, #CORTEX_A78C_CPUACTLR2_EL1_BIT_0
-	msr	CORTEX_A78C_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_a78c_2376749_wa
+check_erratum_ls cortex_a78c, ERRATUM(1827440), CPU_REV(0, 0)
 
-func check_errata_2376749
-	/* Applies to r0p1 and r0p2*/
-	mov	x1, #0x01
-	mov	x2, #0x02
-	b	cpu_rev_var_range
-endfunc check_errata_2376749
-
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78C Erratum 2395411.
- * This applies to revision r0p1 and r0p2 of the A78C
- * and is currently open. It is a Cat B erratum.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x4, x17
- * --------------------------------------------------
- */
-func errata_a78c_2395411_wa
-	/* Check revision. */
-	mov 	x17, x30
-	bl 	check_errata_2395411
-	cbz 	x0, 1f
-
-	/* Set CPUACTRL2_EL1[40] to 1. */
-	mrs 	x1, CORTEX_A78C_CPUACTLR2_EL1
-	orr 	x1, x1, #CORTEX_A78C_CPUACTLR2_EL1_BIT_40
-	msr 	CORTEX_A78C_CPUACTLR2_EL1, x1
-1:
-	ret 	x17
-endfunc errata_a78c_2395411_wa
-
-func check_errata_2395411
-	/* Applies to r0p1 and r0p2 */
-	mov 	x1, #0x01
-	mov 	x2, #0x02
-	b 	cpu_rev_var_range
-endfunc check_errata_2395411
-
-#if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-/* --------------------------------------------------
- * Errata Workaround for A78C Erratum 2132064.
- * This applies to revisions r0p1 and r0p2 of A78C
- * and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_a78c_2132064_wa
-	/* Compare x0 against revisions r0p0 - r0p1 */
-	mov	x17, x30
-	bl	check_errata_2132064
-	cbz	x0, 1f
-
+workaround_reset_start cortex_a78c, ERRATUM(2132064), ERRATA_A78C_2132064
 	/* --------------------------------------------------------
 	 * Place the data prefetcher in the most conservative mode
 	 * to reduce prefetches by writing the following bits to
 	 * the value indicated: ecltr[7:6], PF_MODE = 2'b11
 	 * --------------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A78C_CPUECTLR_EL1
-	orr	x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT_6
-	orr	x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT_7
-	msr	CORTEX_A78C_CPUECTLR_EL1, x0
-	isb
-1:
-	ret	x17
-endfunc errata_a78c_2132064_wa
-
-func check_errata_2132064
-	/* Applies to revisions r0p1 and r0p2. */
-	mov	x1, #CPU_REV(0, 1)
-	mov	x2, #CPU_REV(0, 2)
-	b	cpu_rev_var_range
-endfunc check_errata_2132064
+	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, (CORTEX_A78C_CPUECTLR_EL1_BIT_6 | CORTEX_A78C_CPUECTLR_EL1_BIT_7)
+workaround_reset_end cortex_a78c, ERRATUM(2132064)
 
-/* ----------------------------------------------------------
- * Errata Workaround for A78C Erratum 2242638.
- * This applies to revisions r0p1 and r0p2 of the Cortex A78C
- * processor and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------------
- */
-func errata_a78c_2242638_wa
-	/* Compare x0 against revisions r0p1 - r0p2 */
-	mov	x17, x30
-	bl	check_errata_2242638
-	cbz	x0, 1f
+check_erratum_range cortex_a78c, ERRATUM(2132064), CPU_REV(0, 1), CPU_REV(0, 2)
 
+workaround_reset_start cortex_a78c, ERRATUM(2242638), ERRATA_A78C_2242638
 	ldr	x0, =0x5
 	msr	CORTEX_A78C_IMP_CPUPSELR_EL3, x0
 	ldr	x0, =0x10F600E000
@@ -193,139 +56,51 @@
 	msr	CORTEX_A78C_IMP_CPUPMR_EL3, x0
 	ldr	x0, =0x80000000003FF
 	msr	CORTEX_A78C_IMP_CPUPCR_EL3, x0
-
-	isb
-1:
-	ret	x17
-endfunc errata_a78c_2242638_wa
-
-func check_errata_2242638
-	/* Applies to revisions r0p1-r0p2. */
-	mov	x1, #CPU_REV(0, 1)
-	mov	x2, #CPU_REV(0, 2)
-	b	cpu_rev_var_range
-endfunc check_errata_2242638
-
-/* ----------------------------------------------------------------
- * Errata Workaround for A78C Erratum 2772121.
- * This applies to revisions r0p0, r0p1 and r0p2 of the Cortex A78C
- * processor and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------------------
- */
-func errata_a78c_2772121_wa
-	mov	x17, x30
-	bl	check_errata_2772121
-	cbz	x0, 1f
-
-	/* dsb before isb of power down sequence */
-	dsb	sy
-1:
-	ret	x17
-endfunc errata_a78c_2772121_wa
-
-func check_errata_2772121
-	/* Applies to all revisions <= r0p2 */
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-endfunc check_errata_2772121
+workaround_reset_end cortex_a78c, ERRATUM(2242638)
 
-/* --------------------------------------------------
- * Errata Workaround for Cortex A78C Errata 2779484.
- * This applies to revisions r0p1 and r0p2.
- * It is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_a78c_2779484_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2779484
-	cbz	x0, 1f
+check_erratum_range cortex_a78c, ERRATUM(2242638), CPU_REV(0, 1), CPU_REV(0, 2)
 
-	/* Apply the workaround */
-	mrs	x1, CORTEX_A78C_ACTLR3_EL1
-	orr	x1, x1, #BIT(47)
-	msr	CORTEX_A78C_ACTLR3_EL1, x1
+workaround_reset_start cortex_a78c, ERRATUM(2376749), ERRATA_A78C_2376749
+	sysreg_bit_set CORTEX_A78C_CPUACTLR2_EL1, CORTEX_A78C_CPUACTLR2_EL1_BIT_0
+workaround_reset_end cortex_a78c, ERRATUM(2376749)
 
-1:
-	ret	x17
-endfunc errata_a78c_2779484_wa
+check_erratum_range cortex_a78c, ERRATUM(2376749), CPU_REV(0, 1), CPU_REV(0, 2)
 
-func check_errata_2779484
-	/* Applies to r0p1 and r0p2*/
-	mov	x1, #0x01
-	mov	x2, #0x02
-	b	cpu_rev_var_range
-endfunc check_errata_2779484
+workaround_reset_start cortex_a78c, ERRATUM(2395411), ERRATA_A78C_2395411
+	sysreg_bit_set CORTEX_A78C_CPUACTLR2_EL1, CORTEX_A78C_CPUACTLR2_EL1_BIT_40
+workaround_reset_end cortex_a78c, ERRATUM(2395411)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_range cortex_a78c, ERRATUM(2395411), CPU_REV(0, 1), CPU_REV(0, 2)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-A78C
-	 * -------------------------------------------------
-	 */
-func cortex_a78c_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A78C_1827430
-	mov	x0, x18
-	bl	errata_a78c_1827430_wa
-#endif
-
-#if ERRATA_A78C_1827440
-	mov	x0, x18
-	bl	errata_a78c_1827440_wa
-#endif
-
-#if ERRATA_A78C_2132064
-	mov	x0, x18
-	bl	errata_a78c_2132064_wa
-#endif
+workaround_runtime_start cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
+	/* dsb before isb of power down sequence */
+	dsb	sy
+workaround_runtime_end cortex_a78c, ERRATUM(2772121)
 
-#if ERRATA_A78C_2242638
-	mov	x0, x18
-	bl	errata_a78c_2242638_wa
-#endif
+check_erratum_ls cortex_a78c, ERRATUM(2772121), CPU_REV(0, 2)
 
-#if ERRATA_A78C_2376749
-	mov	x0, x18
-	bl	errata_a78c_2376749_wa
-#endif
+workaround_reset_start cortex_a78c, ERRATUM(2779484), ERRATA_A78C_2779484
+	sysreg_bit_set CORTEX_A78C_ACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_a78c, ERRATUM(2779484)
 
-#if ERRATA_A78C_2395411
-	mov 	x0, x18
-	bl	errata_a78c_2395411_wa
-#endif
+check_erratum_range cortex_a78c, ERRATUM(2779484), CPU_REV(0, 1), CPU_REV(0, 2)
 
-#if ERRATA_A78C_2779484
-	mov	x0, x18
-	bl	errata_a78c_2779484_wa
-#endif
+check_erratum_chosen cortex_a78c, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_a78c, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex-A78c generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-	adr	x0, wa_cve_vbar_cortex_a78c
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	override_vector_table wa_cve_vbar_cortex_a78c
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_a78c, CVE(2022, 23960)
 
-	isb
-	ret	x19
-endfunc cortex_a78c_reset_func
+cpu_reset_func_start cortex_a78c
+cpu_reset_func_end cortex_a78c
+
+errata_report_shim cortex_a78c
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -336,48 +111,14 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_A78C_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
-	msr	CORTEX_A78C_CPUPWRCTLR_EL1, x0
-#if ERRATA_A78C_2772121
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_a78c_2772121_wa
-	mov	x30, x15
-#endif /* ERRATA_A78C_2772121 */
+	sysreg_bit_set CORTEX_A78C_CPUPWRCTLR_EL1, CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+
+	apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
+
 	isb
 	ret
 endfunc cortex_a78c_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex A78C. Must follow AAPCS.
- */
-func cortex_a78c_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_A78C_1827430, cortex_a78c, 1827430
-	report_errata ERRATA_A78C_1827440, cortex_a78c, 1827440
-	report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
-	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
-	report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
-	report_errata ERRATA_A78C_2395411, cortex_a78c, 2395411
-	report_errata ERRATA_A78C_2772121, cortex_a78c, 2772121
-	report_errata ERRATA_A78C_2779484, cortex_a78c, 2779484
-	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-        ret
-endfunc cortex_a78c_errata_report
-#endif
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a78c specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_blackhawk.S
index 8dac4e9..b7b7a2d 100644
--- a/lib/cpus/aarch64/cortex_blackhawk.S
+++ b/lib/cpus/aarch64/cortex_blackhawk.S
@@ -21,12 +21,10 @@
 #error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-func cortex_blackhawk_reset_func
+cpu_reset_func_start cortex_blackhawk
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_blackhawk_reset_func
+cpu_reset_func_end cortex_blackhawk
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -37,21 +35,12 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_blackhawk_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Blackhawk. Must follow AAPCS.
- */
-func cortex_blackhawk_errata_report
-	ret
-endfunc cortex_blackhawk_errata_report
-#endif
+errata_report_shim cortex_blackhawk
 
 	/* ---------------------------------------------
 	 * This function provides Cortex Blackhawk specific
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_chaberton.S
index 2c47bd3..596fe4a 100644
--- a/lib/cpus/aarch64/cortex_chaberton.S
+++ b/lib/cpus/aarch64/cortex_chaberton.S
@@ -21,12 +21,10 @@
 #error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-func cortex_chaberton_reset_func
+cpu_reset_func_start cortex_chaberton
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-	isb
-	ret
-endfunc cortex_chaberton_reset_func
+cpu_reset_func_end cortex_chaberton
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -37,21 +35,12 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_CHABERTON_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_CHABERTON_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_CHABERTON_CPUPWRCTLR_EL1, CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_chaberton_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Chaberton. Must follow AAPCS.
- */
-func cortex_chaberton_errata_report
-	ret
-endfunc cortex_chaberton_errata_report
-#endif
+errata_report_shim cortex_chaberton
 
 	/* ---------------------------------------------
 	 * This function provides Cortex Chaberton specific
diff --git a/lib/cpus/aarch64/cortex_gelas.S b/lib/cpus/aarch64/cortex_gelas.S
new file mode 100644
index 0000000..dc704f2
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_gelas.S
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_gelas.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Gelas must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Gelas supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_gelas
+	/* ----------------------------------------------------
+	 * Disable speculative loads
+	 * ----------------------------------------------------
+	 */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_gelas
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_gelas_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+        /* ---------------------------------------------------
+         * Disable SME if enabled and supported
+         * ---------------------------------------------------
+         */
+	mrs     x0, ID_AA64PFR1_EL1
+	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+		#ID_AA64PFR1_EL1_SME_WIDTH
+        cmp     x0, #ID_AA64PFR1_EL1_SME_NOT_SUPPORTED
+	b.eq	1f
+	msr	CORTEX_GELAS_SVCRSM, xzr
+	msr	CORTEX_GELAS_SVCRZA, xzr
+1:
+#endif
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set 	CORTEX_GELAS_CPUPWRCTLR_EL1, \
+		CORTEX_GELAS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_gelas_core_pwr_dwn
+
+errata_report_shim cortex_gelas
+
+	/* ---------------------------------------------
+	 * This function provides Gelas specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_gelas_regs, "aS"
+cortex_gelas_regs: /* The ASCII list of register names to be reported */
+	.asciz	"imp_cpuectlr_el1", ""
+
+func cortex_gelas_cpu_reg_dump
+	adr	x6, cortex_gelas_regs
+	mrs	x8, CORTEX_GELAS_IMP_CPUECTLR_EL1
+	ret
+endfunc cortex_gelas_cpu_reg_dump
+
+declare_cpu_ops cortex_gelas, CORTEX_GELAS_MIDR, \
+	cortex_gelas_reset_func, \
+	cortex_gelas_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index de65365..42634f1 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Google LLC. All rights reserved.
+ * Copyright (c) 2022-2023, Google LLC. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,175 +23,50 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X1_BHB_LOOP_COUNT, cortex_x1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for X1 Erratum 1821534.
- * This applies to revision r0p0 and r1p0 of X1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_x1_1821534_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1821534
-	cbz	x0, 1f
-	mrs	x1, CORTEX_X1_ACTLR2_EL1
-	orr	x1, x1, #BIT(2)
-	msr	CORTEX_X1_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_x1_1821534_wa
-
-func check_errata_1821534
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1821534
-
-/* --------------------------------------------------
- * Errata Workaround for X1 Erratum 1688305.
- * This applies to revision r0p0 and r1p0 of X1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_x1_1688305_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1688305
-	cbz	x0, 1f
-	mrs	x0, CORTEX_X1_ACTLR2_EL1
-	orr	x0, x0, #BIT(1)
-	msr	CORTEX_X1_ACTLR2_EL1, x0
-	isb
-
-1:
-	ret	x17
-endfunc errata_x1_1688305_wa
-
-func check_errata_1688305
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1688305
+workaround_reset_start cortex_x1, ERRATUM(1688305), ERRATA_X1_1688305
+	sysreg_bit_set CORTEX_X1_ACTLR2_EL1, BIT(1)
+workaround_reset_end cortex_x1, ERRATUM(1688305)
 
-/* --------------------------------------------------
- * Errata Workaround for X1 Erratum 1827429.
- * This applies to revision r0p0 and r1p0 of X1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_x1_1827429_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1827429
-	cbz	x0, 1f
-	mrs	x0, CORTEX_X1_CPUECTLR_EL1
-	orr	x0, x0, #BIT(53)
-	msr	CORTEX_X1_CPUECTLR_EL1, x0
-	isb
+check_erratum_ls cortex_x1, ERRATUM(1688305), CPU_REV(1, 0)
 
-1:
-	ret	x17
-endfunc errata_x1_1827429_wa
+workaround_reset_start cortex_x1, ERRATUM(1821534), ERRATA_X1_1821534
+	sysreg_bit_set CORTEX_X1_ACTLR2_EL1, BIT(2)
+workaround_reset_end cortex_x1, ERRATUM(1821534)
 
-func check_errata_1827429
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1827429
+check_erratum_ls cortex_x1, ERRATUM(1821534), CPU_REV(1, 0)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+workaround_reset_start cortex_x1, ERRATUM(1827429), ERRATA_X1_1827429
+	sysreg_bit_set CORTEX_X1_CPUECTLR_EL1, BIT(53)
+workaround_reset_end cortex_x1, ERRATUM(1827429)
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Cortex-X1.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
-	 */
-func cortex_x1_reset_func
-	mov	x19, x30
-	bl	cpu_get_rev_var
-	mov	x18, x0
+check_erratum_ls cortex_x1, ERRATUM(1827429), CPU_REV(1, 0)
 
-#if ERRATA_X1_1821534
-	mov	x0, x18
-	bl	errata_x1_1821534_wa
-#endif
+check_erratum_chosen cortex_x1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if ERRATA_X1_1688305
-	mov	x0, x18
-	bl	errata_x1_1688305_wa
-#endif
-
-#if ERRATA_X1_1827429
-	mov	x0, x18
-	bl	errata_x1_1827429_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_x1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex-X1 generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-	adr	x0, wa_cve_vbar_cortex_x1
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	override_vector_table wa_cve_vbar_cortex_x1
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_x1, CVE(2022, 23960)
 
-	isb
-	ret	x19
-endfunc cortex_x1_reset_func
+cpu_reset_func_start cortex_x1
+cpu_reset_func_end cortex_x1
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
 	 */
 func cortex_x1_core_pwr_dwn
-	/* ---------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
-	 */
-	mrs	x0, CORTEX_X1_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_X1_CORE_PWRDN_EN_MASK
-	msr	CORTEX_X1_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_X1_CPUPWRCTLR_EL1, CORTEX_X1_CORE_PWRDN_EN_MASK
 	isb
 	ret
 endfunc cortex_x1_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex X1. Must follow AAPCS.
- */
-func cortex_x1_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_X1_1821534, cortex_x1, 1821534
-	report_errata ERRATA_X1_1688305, cortex_x1, 1688305
-	report_errata ERRATA_X1_1827429, cortex_x1, 1827429
-	report_errata WORKAROUND_CVE_2022_23960, cortex_x1, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_x1_errata_report
-#endif
+errata_report_shim cortex_x1
 
        /* ---------------------------------------------
 	* This function provides Cortex X1 specific
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 497bd52..816a58f 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -26,20 +26,7 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X2_BHB_LOOP_COUNT, cortex_x2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex X2 Errata #2002765.
-	 * This applies to revisions r0p0, r1p0, and r2p0 and
-	 * is open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_x2_2002765_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2002765
-	cbz	x0, 1f
-
+workaround_reset_start cortex_x2, ERRATUM(2002765), ERRATA_X2_2002765
 	ldr	x0, =0x6
 	msr	S3_6_C15_C8_0, x0 /* CPUPSELR_EL3 */
 	ldr	x0, =0xF3A08002
@@ -48,119 +35,24 @@
 	msr	S3_6_C15_C8_3, x0 /* CPUPMR_EL3 */
 	ldr	x0, =0x40000001003ff
 	msr	S3_6_C15_C8_1, x0 /* CPUPCR_EL3 */
-	isb
-
-1:
-	ret	x17
-endfunc errata_cortex_x2_2002765_wa
-
-func check_errata_2002765
-	/* Applies to r0p0 - r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2002765
+workaround_reset_end cortex_x2, ERRATUM(2002765)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex X2 Errata #2058056.
-	 * This applies to revisions r0p0, r1p0, and r2p0 and
-	 * is open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_x2_2058056_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2058056
-	cbz	x0, 1f
-
-	mrs	x1, CORTEX_X2_CPUECTLR2_EL1
-	mov	x0, #CORTEX_X2_CPUECTLR2_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CORTEX_X2_CPUECTLR2_EL1_PF_MODE_SHIFT, #CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH
-	msr	CORTEX_X2_CPUECTLR2_EL1, x1
+check_erratum_ls cortex_x2, ERRATUM(2002765), CPU_REV(2, 0)
 
-1:
-	ret	x17
-endfunc errata_cortex_x2_2058056_wa
+workaround_reset_start cortex_x2, ERRATUM(2017096), ERRATA_X2_2017096
+	sysreg_bit_set CORTEX_X2_CPUECTLR_EL1, CORTEX_X2_CPUECTLR_EL1_PFSTIDIS_BIT
+workaround_reset_end cortex_x2, ERRATUM(2017096)
 
-func check_errata_2058056
-	/* Applies to r0p0 - r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2058056
+check_erratum_ls cortex_x2, ERRATUM(2017096), CPU_REV(2, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex X2 Errata #2083908.
-	 * This applies to revision r2p0 and is open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x2, x17
-	 * --------------------------------------------------
-	 */
-func errata_cortex_x2_2083908_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2083908
-	cbz	x0, 1f
+workaround_reset_start cortex_x2, ERRATUM(2058056), ERRATA_X2_2058056
+	sysreg_bitfield_insert CORTEX_X2_CPUECTLR2_EL1, CORTEX_X2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
+	CORTEX_X2_CPUECTLR2_EL1_PF_MODE_SHIFT, CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH
+workaround_reset_end cortex_x2, ERRATUM(2058056)
 
-	/* Apply the workaround by setting bit 13 in CPUACTLR5_EL1. */
-	mrs	x1, CORTEX_X2_CPUACTLR5_EL1
-	orr	x1, x1, #BIT(13)
-	msr	CORTEX_X2_CPUACTLR5_EL1, x1
-
-1:
-	ret	x17
-endfunc errata_cortex_x2_2083908_wa
+check_erratum_ls cortex_x2, ERRATUM(2058056), CPU_REV(2, 0)
 
-func check_errata_2083908
-	/* Applies to r2p0 */
-	mov	x1, #0x20
-	mov	x2, #0x20
-	b	cpu_rev_var_range
-endfunc check_errata_2083908
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Errata 2017096.
-	 * This applies only to revisions r0p0, r1p0 and r2p0
-	 * and is fixed in r2p1.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_x2_2017096_wa
-	/* Compare x0 against revision r0p0 to r2p0 */
-	mov     x17, x30
-	bl      check_errata_2017096
-	cbz     x0, 1f
-	mrs     x1, CORTEX_X2_CPUECTLR_EL1
-	orr     x1, x1, CORTEX_X2_CPUECTLR_EL1_PFSTIDIS_BIT
-	msr     CORTEX_X2_CPUECTLR_EL1, x1
-
-1:
-	ret     x17
-endfunc errata_x2_2017096_wa
-
-func check_errata_2017096
-	/* Applies to r0p0, r1p0, r2p0 */
-	mov     x1, #0x20
-	b       cpu_rev_var_ls
-endfunc check_errata_2017096
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Errata 2081180.
-	 * This applies to revision r0p0, r1p0 and r2p0
-	 * and is fixed in r2p1.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_x2_2081180_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2081180
-	cbz	x0, 1f
-
+workaround_reset_start cortex_x2, ERRATUM(2081180), ERRATA_X2_2081180
 	/* Apply instruction patching sequence */
 	ldr	x0, =0x3
 	msr	CORTEX_X2_IMP_CPUPSELR_EL3, x0
@@ -178,34 +70,26 @@
 	msr	CORTEX_X2_IMP_CPUPMR_EL3, x0
 	ldr	x0, =0x10002001003F3
 	msr	CORTEX_X2_IMP_CPUPCR_EL3, x0
-	isb
-1:
-	ret	x17
-endfunc errata_x2_2081180_wa
+workaround_reset_end cortex_x2, ERRATUM(2081180)
 
-func check_errata_2081180
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2081180
+check_erratum_ls cortex_x2, ERRATUM(2081180), CPU_REV(2, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Cortex X2 Errata 2216384.
-	 * This applies to revisions r0p0, r1p0, and r2p0
-	 * and is fixed in r2p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_x2_2216384_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2216384
-	cbz	x0, 1f
+workaround_reset_start cortex_x2, ERRATUM(2083908), ERRATA_X2_2083908
+	/* Apply the workaround by setting bit 13 in CPUACTLR5_EL1. */
+	sysreg_bit_set CORTEX_X2_CPUACTLR5_EL1, BIT(13)
+workaround_reset_end cortex_x2, ERRATUM(2083908)
+
+check_erratum_range cortex_x2, ERRATUM(2083908), CPU_REV(2, 0), CPU_REV(2, 0)
+
+workaround_reset_start cortex_x2, ERRATUM(2147715), ERRATA_X2_2147715
+	/* Apply the workaround by setting bit 22 in CPUACTLR_EL1. */
+	sysreg_bit_set CORTEX_X2_CPUACTLR_EL1, CORTEX_X2_CPUACTLR_EL1_BIT_22
+workaround_reset_end cortex_x2, ERRATUM(2147715)
+
+check_erratum_range cortex_x2, ERRATUM(2147715), CPU_REV(2, 0), CPU_REV(2, 0)
 
-	mrs	x1, CORTEX_X2_CPUACTLR5_EL1
-	orr	x1, x1, CORTEX_X2_CPUACTLR5_EL1_BIT_17
-	msr	CORTEX_X2_CPUACTLR5_EL1, x1
+workaround_reset_start cortex_x2, ERRATUM(2216384), ERRATA_X2_2216384
+	sysreg_bit_set CORTEX_X2_CPUACTLR5_EL1, CORTEX_X2_CPUACTLR5_EL1_BIT_17
 
 	/* Apply instruction patching sequence */
 	ldr	x0, =0x5
@@ -216,138 +100,52 @@
 	msr	CORTEX_X2_IMP_CPUPMR_EL3, x0
 	ldr	x0, =0x80000000003FF
 	msr	CORTEX_X2_IMP_CPUPCR_EL3, x0
-	isb
-
-1:
-	ret	x17
-endfunc errata_x2_2216384_wa
+workaround_reset_end cortex_x2, ERRATUM(2216384)
 
-func check_errata_2216384
-	/* Applies to r0p0 - r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2216384
+check_erratum_ls cortex_x2, ERRATUM(2216384), CPU_REV(2, 0)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-	/* ---------------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Errata 2147715.
-	 * This applies only to revisions r2p0 and is fixed in r2p1.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * ---------------------------------------------------------
-	 */
-func errata_x2_2147715_wa
-	/* Compare x0 against revision r2p0 */
-	mov     x17, x30
-	bl      check_errata_2147715
-	cbz     x0, 1f
-
-	/* Apply the workaround by setting bit 22 in CPUACTLR_EL1. */
-	mrs     x1, CORTEX_X2_CPUACTLR_EL1
-	orr     x1, x1, CORTEX_X2_CPUACTLR_EL1_BIT_22
-	msr     CORTEX_X2_CPUACTLR_EL1, x1
-
-1:
-	ret     x17
-endfunc errata_x2_2147715_wa
-
-func check_errata_2147715
-	/* Applies to r2p0 */
-	mov	x1, #0x20
-	mov	x2, #0x20
-	b	cpu_rev_var_range
-endfunc check_errata_2147715
-
-	/* ---------------------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Erratum 2282622.
-	 * This applies to revision r0p0, r1p0, r2p0 and r2p1.
-	 * It is still open.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x1, x17
-	 * ---------------------------------------------------------------
-	 */
-func errata_x2_2282622_wa
-	/* Compare x0 against revision r2p1 */
-	mov     x17, x30
-	bl      check_errata_2282622
-	cbz     x0, 1f
-
+workaround_reset_start cortex_x2, ERRATUM(2282622), ERRATA_X2_2282622
 	/* Apply the workaround */
-	mrs     x1, CORTEX_X2_CPUACTLR2_EL1
-	orr     x1, x1, #BIT(0)
-	msr     CORTEX_X2_CPUACTLR2_EL1, x1
+	sysreg_bit_set CORTEX_X2_CPUACTLR2_EL1, BIT(0)
+workaround_reset_end cortex_x2, ERRATUM(2282622)
 
-1:
-	ret     x17
-endfunc errata_x2_2282622_wa
+check_erratum_ls cortex_x2, ERRATUM(2282622), CPU_REV(2, 1)
 
-func check_errata_2282622
-	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
-	mov     x1, #0x21
-	b       cpu_rev_var_ls
-endfunc check_errata_2282622
+workaround_reset_start cortex_x2, ERRATUM(2371105), ERRATA_X2_2371105
+	/* Set bit 40 in CPUACTLR2_EL1 */
+	sysreg_bit_set CORTEX_X2_CPUACTLR2_EL1, CORTEX_X2_CPUACTLR2_EL1_BIT_40
+workaround_reset_end cortex_x2, ERRATUM(2371105)
 
-	/* -------------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Erratum 2371105.
-	 * This applies to revisions <= r2p0 and is fixed in r2p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * -------------------------------------------------------
-	 */
-func errata_x2_2371105_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2371105
-	cbz	x0, 1f
+check_erratum_ls cortex_x2, ERRATUM(2371105), CPU_REV(2, 0)
 
-	/* Set bit 40 in CPUACTLR2_EL1 */
-	mrs	x1, CORTEX_X2_CPUACTLR2_EL1
-	orr	x1, x1, #CORTEX_X2_CPUACTLR2_EL1_BIT_40
-	msr	CORTEX_X2_CPUACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_x2_2371105_wa
+workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
+	/* dsb before isb of power down sequence */
+	dsb	sy
+workaround_reset_end cortex_x2, ERRATUM(2768515)
 
-func check_errata_2371105
-	/* Applies to <= r2p0. */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_2371105
+check_erratum_ls cortex_x2, ERRATUM(2768515), CPU_REV(2, 1)
 
-	/* ----------------------------------------------------
-	 * Errata Workaround for Cortex-X2 Errata #2768515
-	 * This applies to revisions <= r2p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ----------------------------------------------------
+workaround_reset_start cortex_x2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Cortex-X2 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
 	 */
-func errata_x2_2768515_wa
-	mov	x17, x30
-	bl	check_errata_2768515
-	cbz	x0, 1f
+	override_vector_table wa_cve_vbar_cortex_x2
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_x2, CVE(2022, 23960)
 
-	/* dsb before isb of power down sequence */
-	dsb	sy
-1:
-	ret	x17
-endfunc errata_x2_2768515_wa
+check_erratum_chosen cortex_x2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-func check_errata_2768515
-	/* Applies to all revisions <= r2p1 */
-	mov	x1, #0x21
-	b	cpu_rev_var_ls
-endfunc check_errata_2768515
+/*
+ * ERRATA_DSU_2313941 :
+ * The errata is defined in dsu_helpers.S but applies to cortex_x2
+ * as well. Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_cortex_x2_2313941, check_errata_dsu_2313941
+.equ erratum_cortex_x2_2313941_wa, errata_dsu_2313941_wa
+add_erratum_entry cortex_x2, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -358,122 +156,24 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_X2_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_X2_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_X2_CPUPWRCTLR_EL1, CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
 #if ERRATA_X2_2768515
 	mov	x15, x30
 	bl	cpu_get_rev_var
-	bl	errata_x2_2768515_wa
+	bl	erratum_cortex_x2_2768515_wa
 	mov	x30, x15
 #endif /* ERRATA_X2_2768515 */
 	isb
 	ret
 endfunc cortex_x2_core_pwr_dwn
 
-	/*
-	 * Errata printing function for Cortex X2. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func cortex_x2_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_X2_2002765, cortex_x2, 2002765
-	report_errata ERRATA_X2_2017096, cortex_x2, 2017096
-	report_errata ERRATA_X2_2058056, cortex_x2, 2058056
-	report_errata ERRATA_X2_2081180, cortex_x2, 2081180
-	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
-	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
-	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
-	report_errata ERRATA_X2_2282622, cortex_x2, 2282622
-	report_errata ERRATA_X2_2371105, cortex_x2, 2371105
-	report_errata ERRATA_X2_2768515, cortex_x2, 2768515
-	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
-	report_errata ERRATA_DSU_2313941, cortex_x2, dsu_2313941
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_x2_errata_report
-#endif
-
-func cortex_x2_reset_func
-	mov	x19, x30
+errata_report_shim cortex_x2
 
+cpu_reset_func_start cortex_x2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-
-	/* Get the CPU revision and stash it in x18. */
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_DSU_2313941
-	bl	errata_dsu_2313941_wa
-#endif
-
-#if ERRATA_X2_2002765
-	mov	x0, x18
-	bl	errata_cortex_x2_2002765_wa
-#endif
-
-#if ERRATA_X2_2058056
-	mov	x0, x18
-	bl	errata_cortex_x2_2058056_wa
-#endif
-
-#if ERRATA_X2_2083908
-	mov	x0, x18
-	bl	errata_cortex_x2_2083908_wa
-#endif
-
-#if ERRATA_X2_2017096
-	mov	x0, x18
-	bl	errata_x2_2017096_wa
-#endif
-
-#if ERRATA_X2_2081180
-	mov	x0, x18
-	bl	errata_x2_2081180_wa
-#endif
-
-#if ERRATA_X2_2216384
-	mov	x0, x18
-	bl	errata_x2_2216384_wa
-#endif
-
-#if ERRATA_X2_2147715
-	mov	x0, x18
-	bl	errata_x2_2147715_wa
-#endif
-
-#if ERRATA_X2_2282622
-	mov	x0, x18
-	bl	errata_x2_2282622_wa
-#endif
-
-#if ERRATA_X2_2371105
-	mov	x0, x18
-	bl	errata_x2_2371105_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex-X2 generic vectors are overridden to apply errata
-         * mitigation on exception entry from lower ELs.
-         */
-	adr	x0, wa_cve_vbar_cortex_x2
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc cortex_x2_reset_func
+cpu_reset_func_end cortex_x2
 
 	/* ---------------------------------------------
 	 * This function provides Cortex X2 specific
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index f104b48..98d148e 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,141 +26,59 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_x3_core_pwr_dwn
-#if ERRATA_X3_2313909
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_cortex_x3_2313909_wa
-	mov	x30, x15
-#endif /* ERRATA_X3_2313909 */
-
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_X3_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc cortex_x3_core_pwr_dwn
+workaround_runtime_start cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
+	sysreg_bit_set	CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36
+workaround_runtime_end cortex_x3, ERRATUM(2313909), NO_ISB
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_x3_reset_func
-	mov	x19, x30
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Cortex-X3 generic vectors are overridden to apply
-	 * errata mitigation on exception entry from lower ELs.
-         */
-	adr	x0, wa_cve_vbar_cortex_x3
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	bl	cpu_get_rev_var
-
-#if ERRATA_X3_2615812
-	bl	errata_cortex_x3_2615812_wa
-#endif /* ERRATA_X3_2615812 */
-
-	isb
-	ret	x19
-endfunc cortex_x3_reset_func
+check_erratum_ls cortex_x3, ERRATUM(2313909), CPU_REV(1, 0)
 
-/* ----------------------------------------------------------------------
- * Errata Workaround for Cortex-X3 Erratum 2313909 on power down request.
- * This applies to revision r0p0 and r1p0 of Cortex-X3. Fixed in r1p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * ----------------------------------------------------------------------
- */
-func errata_cortex_x3_2313909_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2313909
-	cbz	x0, 1f
-
-	/* Set bit 36 in ACTLR2_EL1 */
-	mrs	x1, CORTEX_X3_CPUACTLR2_EL1
-	orr	x1, x1, #CORTEX_X3_CPUACTLR2_EL1_BIT_36
-	msr	CORTEX_X3_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_cortex_x3_2313909_wa
-
-func check_errata_2313909
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_2313909
-
-/* ----------------------------------------------------------------------
- * Errata Workaround for Cortex-X3 Erratum 2615812 on power-on.
- * This applies to revision r0p0, r1p0, r1p1 of Cortex-X3. Open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * ----------------------------------------------------------------------
- */
-func errata_cortex_x3_2615812_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2615812
-	cbz	x0, 1f
-
+workaround_reset_start cortex_x3, ERRATUM(2615812), ERRATA_X3_2615812
 	/* Disable retention control for WFI and WFE. */
 	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
 	bfi	x0, xzr, #CORTEX_X3_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS_SHIFT, #3
 	bfi	x0, xzr, #CORTEX_X3_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS_SHIFT, #3
 	msr	CORTEX_X3_CPUPWRCTLR_EL1, x0
-1:
-	ret	x17
-endfunc errata_cortex_x3_2615812_wa
+workaround_reset_end cortex_x3, ERRATUM(2615812)
 
-func check_errata_2615812
-	/* Applies to r1p1 and below. */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2615812
+check_erratum_ls cortex_x3, ERRATUM(2615812), CPU_REV(1, 1)
 
-#if REPORT_ERRATA
-	/*
-	 * Errata printing function for Cortex-X3. Must follow AAPCS.
-	 */
-func cortex_x3_errata_report
-	stp	x8, x30, [sp, #-16]!
+workaround_reset_start cortex_x3, ERRATUM(2742421), ERRATA_X3_2742421
+	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+	sysreg_bit_set CORTEX_X3_CPUACTLR5_EL1, CORTEX_X3_CPUACTLR5_EL1_BIT_55
+	sysreg_bit_clear CORTEX_X3_CPUACTLR5_EL1, CORTEX_X3_CPUACTLR5_EL1_BIT_56
+workaround_reset_end cortex_x3, ERRATUM(2742421)
 
-	bl	cpu_get_rev_var
-	mov	x8, x0
+check_erratum_ls cortex_x3, ERRATUM(2742421), CPU_REV(1, 1)
 
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_X3_2313909, cortex_x3, 2313909
-	report_errata ERRATA_X3_2615812, cortex_x3, 2615812
-	report_errata WORKAROUND_CVE_2022_23960, cortex_x3, cve_2022_23960
+workaround_reset_start cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	override_vector_table wa_cve_vbar_cortex_x3
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_x3, CVE(2022, 23960)
+
+check_erratum_chosen cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+cpu_reset_func_start cortex_x3
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_x3
 
-	ldp	x8, x30, [sp], #16
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x3_core_pwr_dwn
+apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_X3_CPUPWRCTLR_EL1, CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
 	ret
-endfunc cortex_x3_errata_report
-#endif
+endfunc cortex_x3_core_pwr_dwn
+
+errata_report_shim cortex_x3
 
 	/* ---------------------------------------------
 	 * This function provides Cortex-X3-
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index db87008..7619f9c 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -26,31 +26,22 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func cortex_x4_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+workaround_reset_start cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
 	/*
 	 * The Cortex X4 generic vectors are overridden to apply errata
 	 * mitigation on exception entry from lower ELs.
 	 */
-	adr	x0, wa_cve_vbar_cortex_x4
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	override_vector_table wa_cve_vbar_cortex_x4
+#endif /* IMAGE_BL31 */
+workaround_reset_end cortex_x4, CVE(2022, 23960)
 
-	isb
-	ret
-endfunc cortex_x4_reset_func
+check_erratum_chosen cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+cpu_reset_func_start cortex_x4
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_x4
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -61,33 +52,12 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_X4_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_X4_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set CORTEX_X4_CPUPWRCTLR_EL1, CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
 endfunc cortex_x4_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex X4. Must follow AAPCS.
- */
-func cortex_x4_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_x4, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_x4_errata_report
-#endif
+errata_report_shim cortex_x4
 
 	/* ---------------------------------------------
 	 * This function provides Cortex X4-specific
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index a4285ed..1ae3180 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -33,6 +33,15 @@
 	/* Get the matching cpu_ops pointer */
 	bl	get_cpu_ops_ptr
 
+#if ENABLE_ASSERTIONS
+	/*
+	 * Assert if invalid cpu_ops obtained. If this is not valid, it may
+	 * suggest that the proper CPU file hasn't been included.
+	 */
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+
 	/* Get the cpu_ops reset handler */
 	ldr	x2, [x0, #CPU_RESET_FUNC]
 	mov	x30, x19
diff --git a/lib/cpus/aarch64/cpuamu_helpers.S b/lib/cpus/aarch64/cpuamu_helpers.S
index 5a77fc7..e71e345 100644
--- a/lib/cpus/aarch64/cpuamu_helpers.S
+++ b/lib/cpus/aarch64/cpuamu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index 3c54a6f..884281d 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -207,7 +207,14 @@
 2:	ret
 endfunc denver_disable_dco
 
-func check_errata_cve_2017_5715
+workaround_reset_start denver, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
+#if IMAGE_BL31
+	adr	x1, workaround_bpflush_runtime_exceptions
+	msr	vbar_el3, x1
+#endif
+workaround_reset_end denver, CVE(2017, 5715)
+
+check_erratum_custom_start denver, CVE(2017, 5715)
 	mov	x0, #ERRATA_MISSING
 #if WORKAROUND_CVE_2017_5715
 	/*
@@ -224,43 +231,9 @@
 1:
 #endif
 	ret
-endfunc check_errata_cve_2017_5715
-
-func check_errata_cve_2018_3639
-#if WORKAROUND_CVE_2018_3639
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2018_3639
-
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Denver.
-	 * -------------------------------------------------
-	 */
-func denver_reset_func
-
-	mov	x19, x30
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
-	/*
-	 * Check if the CPU supports the special instruction
-	 * required to flush the indirect branch predictor and
-	 * RSB. Support for this operation can be determined by
-	 * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001.
-	 */
-	mrs	x0, id_afr0_el1
-	mov	x1, #0x10000
-	and	x0, x0, x1
-	cmp	x0, #0
-	adr	x1, workaround_bpflush_runtime_exceptions
-	mrs	x2, vbar_el3
-	csel	x0, x1, x2, ne
-	msr	vbar_el3, x0
-#endif
+check_erratum_custom_end denver, CVE(2017, 5715)
 
-#if WORKAROUND_CVE_2018_3639
+workaround_reset_start denver, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
 	/*
 	 * Denver CPUs with DENVER_MIDR_PN3 or earlier, use different
 	 * bits in the ACTLR_EL3 register to disable speculative
@@ -277,8 +250,11 @@
 	msr	actlr_el3, x0
 	isb
 	dsb	sy
-#endif
+workaround_reset_end denver, CVE(2018, 3639)
+
+check_erratum_chosen denver, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
 
+cpu_reset_func_start denver
 	/* ----------------------------------------------------
 	 * Reset ACTLR.PMSTATE to C1 state
 	 * ----------------------------------------------------
@@ -293,9 +269,7 @@
 	 * ----------------------------------------------------
 	 */
 	bl	denver_enable_dco
-
-	ret	x19
-endfunc denver_reset_func
+cpu_reset_func_end denver
 
 	/* ----------------------------------------------------
 	 * The CPU Ops core power down function for Denver.
@@ -322,27 +296,7 @@
 	ret
 endfunc denver_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-	/*
-	 * Errata printing function for Denver. Must follow AAPCS.
-	 */
-func denver_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2017_5715, denver, cve_2017_5715
-	report_errata WORKAROUND_CVE_2018_3639, denver, cve_2018_3639
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc denver_errata_report
-#endif
+errata_report_shim denver
 
 	/* ---------------------------------------------
 	 * This function provides Denver specific
@@ -367,7 +321,7 @@
 .macro	denver_cpu_ops_wa midr
 	declare_cpu_ops_wa denver, \midr, \
 		denver_reset_func, \
-		check_errata_cve_2017_5715, \
+		check_erratum_denver_5715, \
 		CPU_NO_EXTRA2_FUNC, \
 		CPU_NO_EXTRA3_FUNC, \
 		denver_core_pwr_dwn, \
diff --git a/lib/cpus/aarch64/neoverse_e1.S b/lib/cpus/aarch64/neoverse_e1.S
index 96b63cf..45bd8d3 100644
--- a/lib/cpus/aarch64/neoverse_e1.S
+++ b/lib/cpus/aarch64/neoverse_e1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,20 +21,18 @@
 #error "Neoverse-E1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-	/* -------------------------------------------------
-	 * The CPU Ops reset function for Neoverse-E1.
-	 * Shall clobber: x0-x19
-	 * -------------------------------------------------
-	 */
-func neoverse_e1_reset_func
-	mov	x19, x30
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
-#endif
+/*
+ * ERRATA_DSU_936184:
+ * The errata is defined in dsu_helpers.S and applies to neoverse_e1.
+ * Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
+ */
+.equ check_erratum_neoverse_e1_936184, check_errata_dsu_936184
+.equ erratum_neoverse_e1_936184_wa, errata_dsu_936184_wa
+add_erratum_entry neoverse_e1, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
 
-	ret	x19
-endfunc neoverse_e1_reset_func
+cpu_reset_func_start neoverse_e1
+cpu_reset_func_end neoverse_e1
 
 func neoverse_e1_cpu_pwr_dwn
 	mrs	x0, NEOVERSE_E1_CPUPWRCTLR_EL1
@@ -44,27 +42,7 @@
 	ret
 endfunc neoverse_e1_cpu_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse N1. Must follow AAPCS.
- */
-func neoverse_e1_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_DSU_936184, neoverse_e1, dsu_936184
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_e1_errata_report
-#endif
-
+errata_report_shim neoverse_e1
 
 .section .rodata.neoverse_e1_regs, "aS"
 neoverse_e1_regs:  /* The ascii list of register names to be reported */
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 2cf94c7..36a7ee7 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,20 +27,17 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_N1_BHB_LOOP_COUNT, neoverse_n1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Erratum 1043202.
- * This applies to revision r0p0 and r1p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
+/*
+ * ERRATA_DSU_936184:
+ * The errata is defined in dsu_helpers.S and applies to Neoverse N1.
+ * Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
  */
-func errata_n1_1043202_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1043202
-	cbz	x0, 1f
+.equ check_erratum_neoverse_n1_936184, check_errata_dsu_936184
+.equ erratum_neoverse_n1_936184_wa, errata_dsu_936184_wa
+add_erratum_entry neoverse_n1, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
 
+workaround_reset_start neoverse_n1, ERRATUM(1043202), ERRATA_N1_1043202
 	/* Apply instruction patching sequence */
 	ldr	x0, =0x0
 	msr	CPUPSELR_EL3, x0
@@ -50,314 +47,72 @@
 	msr	CPUPMR_EL3, x0
 	ldr	x0, =0x800200071
 	msr	CPUPCR_EL3, x0
-	isb
-1:
-	ret	x17
-endfunc errata_n1_1043202_wa
+workaround_reset_end neoverse_n1, ERRATUM(1043202)
 
-func check_errata_1043202
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1043202
+check_erratum_ls neoverse_n1, ERRATUM(1043202), CPU_REV(1, 0)
 
-/* --------------------------------------------------
- * Disable speculative loads if Neoverse N1 supports
- * SSBS.
- *
- * Shall clobber: x0.
- * --------------------------------------------------
- */
-func neoverse_n1_disable_speculative_loads
-	/* Check if the PE implements SSBS */
-	mrs	x0, id_aa64pfr1_el1
-	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
-	b.eq	1f
+workaround_reset_start neoverse_n1, ERRATUM(1073348), ERRATA_N1_1073348
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_6
+workaround_reset_end neoverse_n1, ERRATUM(1073348)
 
-	/* Disable speculative loads */
-	msr	SSBS, xzr
+check_erratum_ls neoverse_n1, ERRATUM(1073348), CPU_REV(1, 0)
 
-1:
-	ret
-endfunc neoverse_n1_disable_speculative_loads
-
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1073348
- * This applies to revision r0p0 and r1p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1073348_wa
-	/* Compare x0 against revision r1p0 */
-	mov	x17, x30
-	bl	check_errata_1073348
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_6
-	msr	NEOVERSE_N1_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1073348_wa
-
-func check_errata_1073348
-	/* Applies to r0p0 and r1p0 */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1073348
-
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1130799
- * This applies to revision <=r2p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1130799_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_1130799
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR2_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_59
-	msr	NEOVERSE_N1_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1130799_wa
-
-func check_errata_1130799
-	/* Applies to <=r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1130799
-
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1165347
- * This applies to revision <=r2p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1165347_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_1165347
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR2_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_0
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_15
-	msr	NEOVERSE_N1_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1165347_wa
+workaround_reset_start neoverse_n1, ERRATUM(1130799), ERRATA_N1_1130799
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_59
+workaround_reset_end neoverse_n1, ERRATUM(1130799)
 
-func check_errata_1165347
-	/* Applies to <=r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1165347
-
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1207823
- * This applies to revision <=r2p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1207823_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_1207823
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR2_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_11
-	msr	NEOVERSE_N1_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1207823_wa
+check_erratum_ls neoverse_n1, ERRATUM(1130799), CPU_REV(2, 0)
 
-func check_errata_1207823
-	/* Applies to <=r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1207823
+workaround_reset_start neoverse_n1, ERRATUM(1165347), ERRATA_N1_1165347
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_0
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_15
+workaround_reset_end neoverse_n1, ERRATUM(1165347)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1220197
- * This applies to revision <=r2p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1220197_wa
-	/* Compare x0 against revision r2p0 */
-	mov	x17, x30
-	bl	check_errata_1220197
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUECTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_WS_THR_L2_MASK
-	msr	NEOVERSE_N1_CPUECTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1220197_wa
+check_erratum_ls neoverse_n1, ERRATUM(1165347), CPU_REV(2, 0)
 
-func check_errata_1220197
-	/* Applies to <=r2p0 */
-	mov	x1, #0x20
-	b	cpu_rev_var_ls
-endfunc check_errata_1220197
+workaround_reset_start neoverse_n1, ERRATUM(1207823), ERRATA_N1_1207823
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_11
+workaround_reset_end neoverse_n1, ERRATUM(1207823)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1257314
- * This applies to revision <=r3p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1257314_wa
-	/* Compare x0 against revision r3p0 */
-	mov	x17, x30
-	bl	check_errata_1257314
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR3_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR3_EL1_BIT_10
-	msr	NEOVERSE_N1_CPUACTLR3_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1257314_wa
+check_erratum_ls neoverse_n1, ERRATUM(1207823), CPU_REV(2, 0)
 
-func check_errata_1257314
-	/* Applies to <=r3p0 */
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1257314
+workaround_reset_start neoverse_n1, ERRATUM(1220197), ERRATA_N1_1220197
+	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_WS_THR_L2_MASK
+workaround_reset_end neoverse_n1, ERRATUM(1220197)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1262606
- * This applies to revision <=r3p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1262606_wa
-	/* Compare x0 against revision r3p0 */
-	mov	x17, x30
-	bl	check_errata_1262606
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
-	msr	NEOVERSE_N1_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1262606_wa
+check_erratum_ls neoverse_n1, ERRATUM(1220197), CPU_REV(2, 0)
 
-func check_errata_1262606
-	/* Applies to <=r3p0 */
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1262606
+workaround_reset_start neoverse_n1, ERRATUM(1257314), ERRATA_N1_1257314
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR3_EL1, NEOVERSE_N1_CPUACTLR3_EL1_BIT_10
+workaround_reset_end neoverse_n1, ERRATUM(1257314)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1262888
- * This applies to revision <=r3p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1262888_wa
-	/* Compare x0 against revision r3p0 */
-	mov	x17, x30
-	bl	check_errata_1262888
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUECTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUECTLR_EL1_MM_TLBPF_DIS_BIT
-	msr	NEOVERSE_N1_CPUECTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1262888_wa
+check_erratum_ls neoverse_n1, ERRATUM(1257314), CPU_REV(3, 0)
 
-func check_errata_1262888
-	/* Applies to <=r3p0 */
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1262888
+workaround_reset_start neoverse_n1, ERRATUM(1262606), ERRATA_N1_1262606
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
+workaround_reset_end neoverse_n1, ERRATUM(1262606)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Errata #1275112
- * This applies to revision <=r3p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1275112_wa
-	/* Compare x0 against revision r3p0 */
-	mov	x17, x30
-	bl	check_errata_1275112
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
-	msr	NEOVERSE_N1_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n1_1275112_wa
+check_erratum_ls neoverse_n1, ERRATUM(1262606), CPU_REV(3, 0)
 
-func check_errata_1275112
-	/* Applies to <=r3p0 */
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1275112
+workaround_reset_start neoverse_n1, ERRATUM(1262888), ERRATA_N1_1262888
+	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_CPUECTLR_EL1_MM_TLBPF_DIS_BIT
+workaround_reset_end neoverse_n1, ERRATUM(1262888)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Erratum 1315703.
- * This applies to revision <= r3p0 of Neoverse N1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1315703_wa
-	/* Compare x0 against revision r3p1 */
-	mov	x17, x30
-	bl	check_errata_1315703
-	cbz	x0, 1f
+check_erratum_ls neoverse_n1, ERRATUM(1262888), CPU_REV(3, 0)
 
-	mrs	x0, NEOVERSE_N1_CPUACTLR2_EL1
-	orr	x0, x0, #NEOVERSE_N1_CPUACTLR2_EL1_BIT_16
-	msr	NEOVERSE_N1_CPUACTLR2_EL1, x0
+workaround_reset_start neoverse_n1, ERRATUM(1275112), ERRATA_N1_1275112
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
+workaround_reset_end neoverse_n1, ERRATUM(1275112)
 
-1:
-	ret	x17
-endfunc errata_n1_1315703_wa
+check_erratum_ls neoverse_n1, ERRATUM(1275112), CPU_REV(3, 0)
 
-func check_errata_1315703
-	/* Applies to everything <= r3p0. */
-	mov	x1, #0x30
-	b	cpu_rev_var_ls
-endfunc check_errata_1315703
+workaround_reset_start neoverse_n1, ERRATUM(1315703), ERRATA_N1_1315703
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_16
+workaround_reset_end neoverse_n1, ERRATUM(1315703)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N1 Erratum 1542419.
- * This applies to revisions r3p0 - r4p0 of Neoverse N1
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n1_1542419_wa
-	/* Compare x0 against revision r3p0 and r4p0 */
-	mov	x17, x30
-	bl	check_errata_1542419
-	cbz	x0, 1f
+check_erratum_ls neoverse_n1, ERRATUM(1315703), CPU_REV(3, 0)
 
+workaround_reset_start neoverse_n1, ERRATUM(1542419), ERRATA_N1_1542419
 	/* Apply instruction patching sequence */
 	ldr	x0, =0x0
 	msr	CPUPSELR_EL3, x0
@@ -368,67 +123,17 @@
 	ldr	x0, =0x08000020007D
 	msr	CPUPCR_EL3, x0
 	isb
-1:
-	ret	x17
-endfunc errata_n1_1542419_wa
+workaround_reset_end neoverse_n1, ERRATUM(1542419)
 
-func check_errata_1542419
-	/* Applies to everything r3p0 - r4p0. */
-	mov	x1, #0x30
-	mov	x2, #0x40
-	b	cpu_rev_var_range
-endfunc check_errata_1542419
+check_erratum_range neoverse_n1, ERRATUM(1542419), CPU_REV(3, 0), CPU_REV(4, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse N1 Errata #1868343.
-	 * This applies to revision <= r4p0 of Neoverse N1.
-	 * This workaround is the same as the workaround for
-	 * errata 1262606 and 1275112 but applies to a wider
-	 * revision range.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_n1_1868343_wa
-	/*
-	 * Compare x0 against revision r4p0
-	 */
-	mov	x17, x30
-	bl	check_errata_1868343
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N1_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
-	msr	NEOVERSE_N1_CPUACTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_n1_1868343_wa
+workaround_reset_start neoverse_n1, ERRATUM(1868343), ERRATA_N1_1868343
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
+workaround_reset_end neoverse_n1, ERRATUM(1868343)
 
-func check_errata_1868343
-	/* Applies to everything <= r4p0 */
-	mov	x1, #0x40
-	b	cpu_rev_var_ls
-endfunc check_errata_1868343
+check_erratum_ls neoverse_n1, ERRATUM(1868343), CPU_REV(4, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse N1 Errata #1946160.
-	 * This applies to revisions r3p0, r3p1, r4p0, and
-	 * r4p1 of Neoverse N1. It also exists in r0p0, r1p0,
-	 * and r2p0 but there is no fix in these revisions.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_n1_1946160_wa
-	/*
-	 * Compare x0 against r3p0 - r4p1
-	 */
-	mov	x17, x30
-	bl	check_errata_1946160
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_n1, ERRATUM(1946160), ERRATA_N1_1946160
 	mov	x0, #3
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0x10E3900002
@@ -437,7 +142,6 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_C15_C8_1, x0
-
 	mov	x0, #4
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0x10E3800082
@@ -446,7 +150,6 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_C15_C8_1, x0
-
 	mov	x0, #5
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0x10E3800200
@@ -455,147 +158,62 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x2001003FF
 	msr	S3_6_C15_C8_1, x0
-
 	isb
-1:
-	ret	x17
-endfunc errata_n1_1946160_wa
+workaround_reset_end neoverse_n1, ERRATUM(1946160)
 
-func check_errata_1946160
-	/* Applies to r3p0 - r4p1. */
-	mov	x1, #0x30
-	mov	x2, #0x41
-	b	cpu_rev_var_range
-endfunc check_errata_1946160
+check_erratum_range neoverse_n1, ERRATUM(1946160), CPU_REV(3, 0), CPU_REV(4, 1)
 
-	/* ----------------------------------------------------
-	 * Errata Workaround for Neoverse N1 Errata #2743102
-	 * This applies to revisions <= r4p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ----------------------------------------------------
-	 */
-func errata_n1_2743102_wa
-	mov	x17, x30
-	bl	check_errata_2743102
-	cbz	x0, 1f
-
+workaround_runtime_start neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_n1_2743102_wa
+workaround_runtime_end neoverse_n1, ERRATUM(2743102)
 
-func check_errata_2743102
-	/* Applies to all revisions <= r4p1 */
-	mov	x1, #0x41
-	b	cpu_rev_var_ls
-endfunc check_errata_2743102
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func neoverse_n1_reset_func
-	mov	x19, x30
+check_erratum_ls neoverse_n1, ERRATUM(2743102), CPU_REV(4, 1)
 
-	bl neoverse_n1_disable_speculative_loads
-
-	/* Forces all cacheable atomic instructions to be near */
-	mrs	x0, NEOVERSE_N1_CPUACTLR2_EL1
-	orr	x0, x0, #NEOVERSE_N1_CPUACTLR2_EL1_BIT_2
-	msr	NEOVERSE_N1_CPUACTLR2_EL1, x0
-	isb
-
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_N1_1043202
-	mov	x0, x18
-	bl	errata_n1_1043202_wa
-#endif
-
-#if ERRATA_N1_1073348
-	mov	x0, x18
-	bl	errata_n1_1073348_wa
-#endif
-
-#if ERRATA_N1_1130799
-	mov	x0, x18
-	bl	errata_n1_1130799_wa
-#endif
-
-#if ERRATA_N1_1165347
-	mov	x0, x18
-	bl	errata_n1_1165347_wa
-#endif
-
-#if ERRATA_N1_1207823
-	mov	x0, x18
-	bl	errata_n1_1207823_wa
-#endif
-
-#if ERRATA_N1_1220197
-	mov	x0, x18
-	bl	errata_n1_1220197_wa
-#endif
-
-#if ERRATA_N1_1257314
-	mov	x0, x18
-	bl	errata_n1_1257314_wa
-#endif
-
-#if ERRATA_N1_1262606
-	mov	x0, x18
-	bl	errata_n1_1262606_wa
-#endif
+workaround_reset_start neoverse_n1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse-N1 generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_n1
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_n1, CVE(2022, 23960)
 
-#if ERRATA_N1_1262888
-	mov	x0, x18
-	bl	errata_n1_1262888_wa
-#endif
+check_erratum_chosen neoverse_n1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-#if ERRATA_N1_1275112
-	mov	x0, x18
-	bl	errata_n1_1275112_wa
-#endif
+/* --------------------------------------------------
+ * Disable speculative loads if Neoverse N1 supports
+ * SSBS.
+ *
+ * Shall clobber: x0.
+ * --------------------------------------------------
+ */
+func neoverse_n1_disable_speculative_loads
+	/* Check if the PE implements SSBS */
+	mrs	x0, id_aa64pfr1_el1
+	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
+	b.eq	1f
 
-#if ERRATA_N1_1315703
-	mov	x0, x18
-	bl	errata_n1_1315703_wa
-#endif
+	/* Disable speculative loads */
+	msr	SSBS, xzr
 
-#if ERRATA_N1_1542419
-	mov	x0, x18
-	bl	errata_n1_1542419_wa
-#endif
+1:
+	ret
+endfunc neoverse_n1_disable_speculative_loads
 
-#if ERRATA_N1_1868343
-	mov	x0, x18
-	bl	errata_n1_1868343_wa
-#endif
+cpu_reset_func_start neoverse_n1
+	bl neoverse_n1_disable_speculative_loads
 
-#if ERRATA_N1_1946160
-	mov	x0, x18
-	bl	errata_n1_1946160_wa
-#endif
+	/* Forces all cacheable atomic instructions to be near */
+	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_2
+	isb
 
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, actlr_el3
-	orr	x0, x0, #NEOVERSE_N1_ACTLR_AMEN_BIT
-	msr	actlr_el3, x0
-
+	sysreg_bit_set actlr_el3, NEOVERSE_N1_ACTLR_AMEN_BIT
 	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	mrs	x0, actlr_el2
-	orr	x0, x0, #NEOVERSE_N1_ACTLR_AMEN_BIT
-	msr	actlr_el2, x0
-
+	sysreg_bit_set actlr_el2, NEOVERSE_N1_ACTLR_AMEN_BIT
 	/* Enable group0 counters */
 	mov	x0, #NEOVERSE_N1_AMU_GROUP0_MASK
 	msr	CPUAMCNTENSET_EL0, x0
@@ -603,27 +221,9 @@
 
 #if NEOVERSE_Nx_EXTERNAL_LLC
 	/* Some system may have External LLC, core needs to be made aware */
-	mrs     x0, NEOVERSE_N1_CPUECTLR_EL1
-	orr     x0, x0, NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT
-	msr     NEOVERSE_N1_CPUECTLR_EL1, x0
-#endif
-
-#if ERRATA_DSU_936184
-	bl	errata_dsu_936184_wa
+	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT
 #endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse-N1 generic vectors are overridden to apply errata
-         * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_n1
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc neoverse_n1_reset_func
+cpu_reset_func_end neoverse_n1
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -634,55 +234,15 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, NEOVERSE_N1_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_N1_CORE_PWRDN_EN_MASK
-	msr	NEOVERSE_N1_CPUPWRCTLR_EL1, x0
-#if ERRATA_N1_2743102
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_n1_2743102_wa
-	mov	x30, x15
-#endif /* ERRATA_N1_2743102 */
+	sysreg_bit_set NEOVERSE_N1_CPUPWRCTLR_EL1, NEOVERSE_N1_CORE_PWRDN_EN_MASK
+
+	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
+
 	isb
 	ret
 endfunc neoverse_n1_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse N1. Must follow AAPCS.
- */
-func neoverse_n1_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_N1_1043202, neoverse_n1, 1043202
-	report_errata ERRATA_N1_1073348, neoverse_n1, 1073348
-	report_errata ERRATA_N1_1130799, neoverse_n1, 1130799
-	report_errata ERRATA_N1_1165347, neoverse_n1, 1165347
-	report_errata ERRATA_N1_1207823, neoverse_n1, 1207823
-	report_errata ERRATA_N1_1220197, neoverse_n1, 1220197
-	report_errata ERRATA_N1_1257314, neoverse_n1, 1257314
-	report_errata ERRATA_N1_1262606, neoverse_n1, 1262606
-	report_errata ERRATA_N1_1262888, neoverse_n1, 1262888
-	report_errata ERRATA_N1_1275112, neoverse_n1, 1275112
-	report_errata ERRATA_N1_1315703, neoverse_n1, 1315703
-	report_errata ERRATA_N1_1542419, neoverse_n1, 1542419
-	report_errata ERRATA_N1_1868343, neoverse_n1, 1868343
-	report_errata ERRATA_N1_1946160, neoverse_n1, 1946160
-	report_errata ERRATA_N1_2743102, neoverse_n1, 2743102
-	report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_n1, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_n1_errata_report
-#endif
+errata_report_shim neoverse_n1
 
 /*
  * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
diff --git a/lib/cpus/aarch64/neoverse_n1_pubsub.c b/lib/cpus/aarch64/neoverse_n1_pubsub.c
index b1b7bb8..ecfb501 100644
--- a/lib/cpus/aarch64/neoverse_n1_pubsub.c
+++ b/lib/cpus/aarch64/neoverse_n1_pubsub.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 60d322f..ead3908 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -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
  */
@@ -24,20 +24,17 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_N2_BHB_LOOP_COUNT, neoverse_n2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2002655.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
+/*
+ * ERRATA_DSU_2313941:
+ * The errata is defined in dsu_helpers.S and applies to Neoverse N2.
+ * Henceforth creating symbolic names to the already existing errata
+ * workaround functions to get them registered under the Errata Framework.
  */
-func errata_n2_2002655_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2002655
-	cbz	x0, 1f
+.equ check_erratum_neoverse_n2_2313941, check_errata_dsu_2313941
+.equ erratum_neoverse_n2_2313941_wa, errata_dsu_2313941_wa
+add_erratum_entry neoverse_n2, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
 
+workaround_reset_start neoverse_n2, ERRATUM(2002655), ERRATA_N2_2002655
 	/* Apply instruction patching sequence */
 	ldr x0,=0x6
 	msr S3_6_c15_c8_0,x0
@@ -55,111 +52,49 @@
 	msr S3_6_c15_c8_3,x0
 	ldr x0,=0x40000001003f3
 	msr S3_6_c15_c8_1,x0
-	isb
-1:
-	ret	x17
-endfunc errata_n2_2002655_wa
+workaround_reset_end neoverse_n2, ERRATUM(2002655)
 
-func check_errata_2002655
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2002655
+check_erratum_ls neoverse_n2, ERRATUM(2002655), CPU_REV(0, 0)
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2067956.
- * This applies to revision r0p0 of Neoverse N2 and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------
- */
-func errata_n2_2067956_wa
-	/* Compare x0 against revision r0p0 */
-	mov	x17, x30
-	bl	check_errata_2067956
-	cbz	x0, 1f
-	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
-	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2067956_wa
+workaround_reset_start neoverse_n2, ERRATUM(2025414), ERRATA_N2_2025414
+	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
+workaround_reset_end neoverse_n2, ERRATUM(2025414)
 
-func check_errata_2067956
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2067956
+check_erratum_ls neoverse_n2, ERRATUM(2025414), CPU_REV(0, 0)
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2025414.
- * This applies to revision r0p0 of Neoverse N2 and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------
- */
-func errata_n2_2025414_wa
-	/* Compare x0 against revision r0p0 */
-	mov     x17, x30
-	bl      check_errata_2025414
-	cbz     x0, 1f
-	mrs     x1, NEOVERSE_N2_CPUECTLR_EL1
-	orr     x1, x1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
-	msr     NEOVERSE_N2_CPUECTLR_EL1, x1
+workaround_reset_start neoverse_n2, ERRATUM(2067956), ERRATA_N2_2067956
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR_EL1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
+workaround_reset_end neoverse_n2, ERRATUM(2067956)
 
-1:
-	ret     x17
-endfunc errata_n2_2025414_wa
+check_erratum_ls neoverse_n2, ERRATUM(2067956), CPU_REV(0, 0)
 
-func check_errata_2025414
-	/* Applies to r0p0 */
-	mov     x1, #0x00
-	b       cpu_rev_var_ls
-endfunc check_errata_2025414
+workaround_runtime_start neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	/* Stash ERRSELR_EL1 in x2 */
+	mrs     x2, ERRSELR_EL1
 
-/* ---------------------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2189731.
- * This applies to revision r0p0 of Neoverse N2 and is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ---------------------------------------------------------------
- */
-func errata_n2_2189731_wa
-	/* Compare x0 against revision r0p0 */
-	mov     x17, x30
-	bl      check_errata_2189731
-	cbz     x0, 1f
-	mrs     x1, NEOVERSE_N2_CPUACTLR5_EL1
-	orr     x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_44
-	msr     NEOVERSE_N2_CPUACTLR5_EL1, x1
+	/* Select error record 0 and clear ED bit */
+	msr     ERRSELR_EL1, xzr
+	mrs     x1, ERXCTLR_EL1
+	bfi     x1, xzr, #ERXCTLR_ED_SHIFT, #1
+	msr     ERXCTLR_EL1, x1
 
-1:
-	ret     x17
-endfunc errata_n2_2189731_wa
+	/* Restore ERRSELR_EL1 from x2 */
+	msr     ERRSELR_EL1, x2
+workaround_runtime_end neoverse_n2, ERRATUM(2009478), NO_ISB
 
-func check_errata_2189731
-	/* Applies to r0p0 */
-	mov     x1, #0x00
-	b       cpu_rev_var_ls
-endfunc check_errata_2189731
+check_erratum_ls neoverse_n2, ERRATUM(2009478), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2138956.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * --------------------------------------------------
- */
-func errata_n2_2138956_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2138956
-	cbz	x0, 1f
+workaround_reset_start neoverse_n2, ERRATUM(2138953), ERRATA_N2_2138953
+	/* Apply instruction patching sequence */
+	mrs	x1, NEOVERSE_N2_CPUECTLR2_EL1
+	mov	x0, #NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV
+	bfi	x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH
+	msr	NEOVERSE_N2_CPUECTLR2_EL1, x1
+workaround_reset_end neoverse_n2, ERRATUM(2138953)
 
+check_erratum_ls neoverse_n2, ERRATUM(2138953), CPU_REV(0, 3)
+
+workaround_reset_start neoverse_n2, ERRATUM(2138956), ERRATA_N2_2138956
 	/* Apply instruction patching sequence */
 	ldr	x0,=0x3
 	msr	S3_6_c15_c8_0,x0
@@ -177,120 +112,27 @@
 	msr	S3_6_c15_c8_3,x0
 	ldr	x0,=0x10002001003F3
 	msr	S3_6_c15_c8_1,x0
-	isb
-1:
-	ret	x17
-endfunc errata_n2_2138956_wa
+workaround_reset_end neoverse_n2, ERRATUM(2138956)
 
-func check_errata_2138956
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2138956
+check_erratum_ls neoverse_n2, ERRATUM(2138956), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2242415.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2242415_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2242415
-	cbz	x0, 1f
 
+workaround_reset_start neoverse_n2, ERRATUM(2138958), ERRATA_N2_2138958
 	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
-	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2242415_wa
-
-func check_errata_2242415
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2242415
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_13
+workaround_reset_end neoverse_n2, ERRATUM(2138958)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2138953.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2138953_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2138953
-	cbz	x0, 1f
+check_erratum_ls neoverse_n2, ERRATUM(2138958), CPU_REV(0, 0)
 
-	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUECTLR2_EL1
-	mov	x0, #NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH
-	msr	NEOVERSE_N2_CPUECTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2138953_wa
+workaround_reset_start neoverse_n2, ERRATUM(2189731), ERRATA_N2_2189731
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_44
+workaround_reset_end neoverse_n2, ERRATUM(2189731)
 
-func check_errata_2138953
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2138953
+check_erratum_ls neoverse_n2, ERRATUM(2189731), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2138958.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2138958_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2138958
-	cbz	x0, 1f
-
-	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUACTLR5_EL1
-	orr	x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_13
-	msr	NEOVERSE_N2_CPUACTLR5_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2138958_wa
-
-func check_errata_2138958
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2138958
-
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2242400.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2242400_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2242400
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_n2, ERRATUM(2242400), ERRATA_N2_2242400
 	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUACTLR5_EL1
-	orr	x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_17
-	msr	NEOVERSE_N2_CPUACTLR5_EL1, x1
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_17
 	ldr	x0, =0x2
 	msr	S3_6_c15_c8_0, x0
 	ldr	x0, =0x10F600E000
@@ -299,174 +141,86 @@
 	msr	S3_6_c15_c8_3, x0
 	ldr	x0, =0x80000000003FF
 	msr	S3_6_c15_c8_1, x0
-	isb
-1:
-	ret	x17
-endfunc errata_n2_2242400_wa
+workaround_reset_end neoverse_n2, ERRATUM(2242400)
 
-func check_errata_2242400
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2242400
+check_erratum_ls neoverse_n2, ERRATUM(2242400), CPU_REV(0, 0)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2280757.
- * This applies to revision r0p0 of Neoverse N2. it is still open.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2280757_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2280757
-	cbz	x0, 1f
+workaround_reset_start neoverse_n2, ERRATUM(2242415), ERRATA_N2_2242415
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR_EL1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+workaround_reset_end neoverse_n2, ERRATUM(2242415)
 
-	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
-	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
-	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2280757_wa
+check_erratum_ls neoverse_n2, ERRATUM(2242415), CPU_REV(0, 0)
 
-func check_errata_2280757
-	/* Applies to r0p0 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2280757
+workaround_reset_start neoverse_n2, ERRATUM(2280757), ERRATA_N2_2280757
+	/* Apply instruction patching sequence */
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR_EL1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+workaround_reset_end neoverse_n2, ERRATUM(2280757)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2326639.
- * This applies to revision r0p0 of Neoverse N2,
- * fixed in r0p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2326639_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2326639
-	cbz	x0, 1f
+check_erratum_ls neoverse_n2, ERRATUM(2280757), CPU_REV(0, 0)
 
+workaround_runtime_start neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639
 	/* Set bit 36 in ACTLR2_EL1 */
-	mrs	x1, NEOVERSE_N2_CPUACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_36
-	msr	NEOVERSE_N2_CPUACTLR2_EL1, x1
-1:
-	ret	x17
-endfunc errata_n2_2326639_wa
-
-func check_errata_2326639
-	/* Applies to r0p0, fixed in r0p1 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2326639
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_36
+workaround_runtime_end neoverse_n2, ERRATUM(2326639)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2376738.
- * This applies to revision r0p0 of Neoverse N2,
- * fixed in r0p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current CPU.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2376738_wa
-	mov	x17, x30
-	bl	check_errata_2376738
-	cbz	x0, 1f
+check_erratum_ls neoverse_n2, ERRATUM(2326639), CPU_REV(0, 0)
 
+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
 	 * invalidations to other PE caches.
 	 */
-	mrs	x1, NEOVERSE_N2_CPUACTLR2_EL1
-	orr	x1, x1,	NEOVERSE_N2_CPUACTLR2_EL1_BIT_0
-	msr	NEOVERSE_N2_CPUACTLR2_EL1, x1
-1:
-	ret x17
-endfunc errata_n2_2376738_wa
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_0
+workaround_reset_end neoverse_n2, ERRATUM(2376738)
 
-func check_errata_2376738
-	/* Applies to r0p0, fixed in r0p1 */
-	mov	x1, 0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2376738
+check_erratum_ls neoverse_n2, ERRATUM(2376738), CPU_REV(0, 3)
 
-/* --------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2388450.
- * This applies to revision r0p0 of Neoverse N2,
- * fixed in r0p1.
- * Inputs:
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x1, x17
- * --------------------------------------------------
- */
-func errata_n2_2388450_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2388450
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_n2, ERRATUM(2388450), ERRATA_N2_2388450
 	/*Set bit 40 in ACTLR2_EL1 */
-	mrs	x1, NEOVERSE_N2_CPUACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_40
-	msr	NEOVERSE_N2_CPUACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_n2_2388450_wa
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_40
+workaround_reset_end neoverse_n2, ERRATUM(2388450)
 
-func check_errata_2388450
-	/* Applies to r0p0, fixed in r0p1 */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_2388450
+check_erratum_ls neoverse_n2, ERRATUM(2388450), CPU_REV(0, 0)
 
-/* -------------------------------------------------------
- * Errata Workaround for Neoverse N2 Erratum 2743089.
- * This applies to revisions <= r0p2 and is fixed in r0p3.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * -------------------------------------------------------
- */
-func errata_n2_2743089_wa
-	mov	x17, x30
-	bl	check_errata_2743089
-	cbz	x0, 1f
+workaround_reset_start neoverse_n2, ERRATUM(2743014), ERRATA_N2_2743014
+	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_55
+	sysreg_bit_clear NEOVERSE_N2_CPUACTLR5_EL1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_56
+workaround_reset_end neoverse_n2, ERRATUM(2743014)
 
+check_erratum_ls neoverse_n2, ERRATUM(2743014), CPU_REV(0, 2)
+
+workaround_runtime_start neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_n2_2743089_wa
+workaround_runtime_end neoverse_n2, ERRATUM(2743089)
 
-func check_errata_2743089
-	/* Applies to all revisions <= r0p2 */
-	mov	x1, #0x02
-	b	cpu_rev_var_ls
-endfunc check_errata_2743089
+check_erratum_ls neoverse_n2, ERRATUM(2743089), CPU_REV(0, 2)
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+workaround_reset_start neoverse_n2, ERRATUM(2779511), ERRATA_N2_2779511
+	/* Set bit 47 in ACTLR3_EL1 */
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR3_EL1, NEOVERSE_N2_CPUACTLR3_EL1_BIT_47
+workaround_reset_end neoverse_n2, ERRATUM(2779511)
+
+check_erratum_ls neoverse_n2, ERRATUM(2779511), CPU_REV(0, 2)
+
+workaround_reset_start neoverse_n2, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse-N2 generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_n2
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_n2, CVE(2022,23960)
+
+check_erratum_chosen neoverse_n2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
 	/* -------------------------------------------
 	 * The CPU Ops reset function for Neoverse N2.
 	 * -------------------------------------------
 	 */
-func neoverse_n2_reset_func
-	mov	x19, x30
+cpu_reset_func_start neoverse_n2
 
 	/* Check if the PE implements SSBS */
 	mrs	x0, id_aa64pfr1_el1
@@ -477,174 +231,41 @@
 	msr	SSBS, xzr
 1:
 	/* Force all cacheable atomic instructions to be near */
-	mrs	x0, NEOVERSE_N2_CPUACTLR2_EL1
-	orr	x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
-	msr	NEOVERSE_N2_CPUACTLR2_EL1, x0
-
-	/* Get the CPU revision and stash it in x18. */
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_DSU_2313941
-	bl	errata_dsu_2313941_wa
-#endif
-
-#if ERRATA_N2_2067956
-	mov	x0, x18
-	bl	errata_n2_2067956_wa
-#endif
-
-#if ERRATA_N2_2025414
-	mov	x0, x18
-	bl	errata_n2_2025414_wa
-#endif
-
-#if ERRATA_N2_2189731
-	mov	x0, x18
-	bl	errata_n2_2189731_wa
-#endif
-
-
-#if ERRATA_N2_2138956
-	mov	x0, x18
-	bl	errata_n2_2138956_wa
-#endif
-
-#if ERRATA_N2_2138953
-	mov	x0, x18
-	bl	errata_n2_2138953_wa
-#endif
-
-#if ERRATA_N2_2242415
-	mov	x0, x18
-	bl	errata_n2_2242415_wa
-#endif
-
-#if ERRATA_N2_2138958
-	mov	x0, x18
-	bl	errata_n2_2138958_wa
-#endif
-
-#if ERRATA_N2_2242400
-	mov	x0, x18
-	bl	errata_n2_2242400_wa
-#endif
-
-#if ERRATA_N2_2280757
-	mov	x0, x18
-	bl	errata_n2_2280757_wa
-#endif
-
-#if ERRATA_N2_2376738
-	mov	x0, x18
-	bl	errata_n2_2376738_wa
-#endif
-
-#if ERRATA_N2_2388450
-	mov	x0, x18
-	bl	errata_n2_2388450_wa
-#endif
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
 
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	mrs	x0, cptr_el3
-	orr	x0, x0, #TAM_BIT
-	msr	cptr_el3, x0
-
+	sysreg_bit_set cptr_el3, TAM_BIT
 	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	mrs	x0, cptr_el2
-	orr	x0, x0, #TAM_BIT
-	msr	cptr_el2, x0
-
+	sysreg_bit_set cptr_el2, TAM_BIT
 	/* No need to enable the counters as this would be done at el3 exit */
 #endif
 
 #if NEOVERSE_Nx_EXTERNAL_LLC
 	/* Some systems may have External LLC, core needs to be made aware */
-	mrs	x0, NEOVERSE_N2_CPUECTLR_EL1
-	orr	x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
-	msr	NEOVERSE_N2_CPUECTLR_EL1, x0
+	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
 #endif
-
-#if ERRATA_N2_2002655
-	mov	x0, x18
-	bl	errata_n2_2002655_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse-N2 generic vectors are overridden to apply errata
-         * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_n2
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc neoverse_n2_reset_func
+cpu_reset_func_end neoverse_n2
 
 func neoverse_n2_core_pwr_dwn
-#if ERRATA_N2_2326639
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_n2_2326639_wa
-	mov	x30, x15
-#endif /* ERRATA_N2_2326639 */
+
+	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * No need to do cache maintenance here.
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
-	msr	NEOVERSE_N2_CPUPWRCTLR_EL1, x0
-#if ERRATA_N2_2743089
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_n2_2743089_wa
-	mov	x30, x15
-#endif /* ERRATA_N2_2743089 */
+	sysreg_bit_set NEOVERSE_N2_CPUPWRCTLR_EL1, NEOVERSE_N2_CORE_PWRDN_EN_BIT
+
+	apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089
+
 	isb
 	ret
 endfunc neoverse_n2_core_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse N2 cores. Must follow AAPCS.
- */
-func neoverse_n2_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_N2_2002655, neoverse_n2, 2002655
-	report_errata ERRATA_N2_2067956, neoverse_n2, 2067956
-	report_errata ERRATA_N2_2025414, neoverse_n2, 2025414
-	report_errata ERRATA_N2_2189731, neoverse_n2, 2189731
-	report_errata ERRATA_N2_2138956, neoverse_n2, 2138956
-	report_errata ERRATA_N2_2138953, neoverse_n2, 2138953
-	report_errata ERRATA_N2_2242415, neoverse_n2, 2242415
-	report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
-	report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
-	report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
-	report_errata ERRATA_N2_2326639, neoverse_n2, 2326639
-	report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
-	report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
-	report_errata ERRATA_N2_2743089, neoverse_n2, 2743089
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
-	report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_n2_errata_report
-#endif
+errata_report_shim neoverse_n2
 
 	/* ---------------------------------------------
 	 * This function provides Neoverse N2 specific
diff --git a/lib/cpus/aarch64/neoverse_poseidon.S b/lib/cpus/aarch64/neoverse_poseidon.S
index 030293d..3b3245d 100644
--- a/lib/cpus/aarch64/neoverse_poseidon.S
+++ b/lib/cpus/aarch64/neoverse_poseidon.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,19 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_POSEIDON_BHB_LOOP_COUNT, neoverse_poseidon
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start neoverse_poseidon, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse-poseidon generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_poseidon
+
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_poseidon, CVE(2022,23960)
+
+check_erratum_chosen neoverse_poseidon, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -35,59 +48,19 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, NEOVERSE_POSEIDON_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	NEOVERSE_POSEIDON_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set NEOVERSE_POSEIDON_CPUPWRCTLR_EL1, \
+		NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
 	isb
 	ret
 endfunc neoverse_poseidon_core_pwr_dwn
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func neoverse_poseidon_reset_func
+cpu_reset_func_start neoverse_poseidon
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+cpu_reset_func_end neoverse_poseidon
 
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse Poseidon generic vectors are overridden to apply
-	 * errata mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_poseidon
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret
-endfunc neoverse_poseidon_reset_func
-
-#if REPORT_ERRATA
-	/*
-	 * Errata printing function for Neoverse Poseidon. Must follow AAPCS.
-	 */
-func neoverse_poseidon_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_poseidon, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_poseidon_errata_report
-#endif
+errata_report_shim neoverse_poseidon
 
 	/* ---------------------------------------------
 	 * This function provides Neoverse-Poseidon specific
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 363c2e6..35d2c48 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -26,20 +26,7 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V1_BHB_LOOP_COUNT, neoverse_v1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1618635.
-	 * This applies to revision r0p0 and is fixed in
-	 * r1p0.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0, x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1618635_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1618635
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(1618635), ERRATA_V1_1618635
 	/* Inserts a DMB SY before and after MRS PAR_EL1 */
 	ldr	x0, =0x0
 	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
@@ -90,146 +77,39 @@
 	ldr	x0, = 0x4004027FF
 	msr	NEOVERSE_V1_CPUPCR_EL3, x0
 
-	/* Synchronize to enable patches */
-	isb
-1:
-	ret x17
-endfunc errata_neoverse_v1_1618635_wa
-
-func check_errata_1618635
-	/* Applies to revision r0p0. */
-	mov	x1, #0x00
-	b	cpu_rev_var_ls
-endfunc check_errata_1618635
+workaround_reset_end neoverse_v1, ERRATUM(1618635)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1774420.
-	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1774420_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1774420
-	cbz	x0, 1f
+check_erratum_ls neoverse_v1, ERRATUM(1618635), CPU_REV(0, 0)
 
+workaround_reset_start neoverse_v1, ERRATUM(1774420), ERRATA_V1_1774420
 	/* Set bit 53 in CPUECTLR_EL1 */
-	mrs     x1, NEOVERSE_V1_CPUECTLR_EL1
-	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_53
-	msr     NEOVERSE_V1_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1774420_wa
+	sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, NEOVERSE_V1_CPUECTLR_EL1_BIT_53
+workaround_reset_end neoverse_v1, ERRATUM(1774420)
 
-func check_errata_1774420
-	/* Applies to r0p0 and r1p0. */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1774420
+check_erratum_ls neoverse_v1, ERRATUM(1774420), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1791573.
-	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1791573_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1791573
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(1791573), ERRATA_V1_1791573
 	/* Set bit 2 in ACTLR2_EL1 */
-	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_2
-	msr	NEOVERSE_V1_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1791573_wa
+	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_2
+workaround_reset_end neoverse_v1, ERRATUM(1791573)
 
-func check_errata_1791573
-	/* Applies to r0p0 and r1p0. */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1791573
+check_erratum_ls neoverse_v1, ERRATUM(1791573), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1852267.
-	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1852267_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1852267
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(1852267), ERRATA_V1_1852267
 	/* Set bit 28 in ACTLR2_EL1 */
-	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_28
-	msr	NEOVERSE_V1_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1852267_wa
+	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_28
+workaround_reset_end neoverse_v1, ERRATUM(1852267)
 
-func check_errata_1852267
-	/* Applies to r0p0 and r1p0. */
-	mov	x1, #0x10
-	b	cpu_rev_var_ls
-endfunc check_errata_1852267
+check_erratum_ls neoverse_v1, ERRATUM(1852267), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1925756.
-	 * This applies to revisions <= r1p1.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1925756_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1925756
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(1925756), ERRATA_V1_1925756
 	/* Set bit 8 in CPUECTLR_EL1 */
-	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
-	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_8
-	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1925756_wa
+	sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, NEOVERSE_V1_CPUECTLR_EL1_BIT_8
+workaround_reset_end neoverse_v1, ERRATUM(1925756)
 
-func check_errata_1925756
-	/* Applies to <= r1p1. */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_1925756
+check_erratum_ls neoverse_v1, ERRATUM(1925756), CPU_REV(1, 1)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Erratum #1940577
-	 * This applies to revisions r1p0 - r1p1 and is open.
-	 * It also exists in r0p0 but there is no fix in that
-	 * revision.
-	 * Inputs:
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1940577_wa
-	/* Compare x0 against revisions r1p0 - r1p1 */
-	mov	x17, x30
-	bl	check_errata_1940577
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(1940577), ERRATA_V1_1940577
 	mov	x0, #0
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0x10E3900002
@@ -257,34 +137,11 @@
 	ldr	x0, =0x2001003FF
 	msr	S3_6_C15_C8_1, x0
 
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1940577_wa
+workaround_reset_end neoverse_v1, ERRATUM(1940577)
 
-func check_errata_1940577
-	/* Applies to revisions r1p0 - r1p1. */
-	mov	x1, #0x10
-	mov	x2, #0x11
-	b	cpu_rev_var_range
-endfunc check_errata_1940577
+check_erratum_range neoverse_v1, ERRATUM(1940577), CPU_REV(1, 0), CPU_REV(1, 1)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #1966096
-	 * This applies to revisions r1p0 - r1p1 and is open.
-	 * It also exists in r0p0 but there is no workaround
-	 * for that revision.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_1966096_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_1966096
-	cbz	x0, 1f
-
-	/* Apply the workaround. */
+workaround_reset_start neoverse_v1, ERRATUM(1966096), ERRATA_V1_1966096
 	mov	x0, #0x3
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0xEE010F12
@@ -293,33 +150,20 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x80000000003FF
 	msr	S3_6_C15_C8_1, x0
-	isb
+workaround_reset_end neoverse_v1, ERRATUM(1966096)
 
-1:
-	ret	x17
-endfunc errata_neoverse_v1_1966096_wa
+check_erratum_range neoverse_v1, ERRATUM(1966096), CPU_REV(1, 0), CPU_REV(1, 1)
 
-func check_errata_1966096
-	mov	x1, #0x10
-	mov	x2, #0x11
-	b	cpu_rev_var_range
-endfunc check_errata_1966096
+workaround_reset_start neoverse_v1, ERRATUM(2108267), ERRATA_V1_2108267
+	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
+	mov	x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
+	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
+	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
+workaround_reset_end neoverse_v1, ERRATUM(2108267)
 
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2139242.
-	 * This applies to revisions r0p0, r1p0, and r1p1, it
-	 * is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_2139242_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2139242
-	cbz	x0, 1f
+check_erratum_ls neoverse_v1, ERRATUM(2108267), CPU_REV(1, 1)
 
-	/* Apply the workaround. */
+workaround_reset_start neoverse_v1, ERRATUM(2139242), ERRATA_V1_2139242
 	mov	x0, #0x3
 	msr	S3_6_C15_C8_0, x0
 	ldr	x0, =0xEE720F14
@@ -328,63 +172,11 @@
 	msr	S3_6_C15_C8_3, x0
 	ldr	x0, =0x40000005003FF
 	msr	S3_6_C15_C8_1, x0
-	isb
+workaround_reset_end neoverse_v1, ERRATUM(2139242)
 
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2139242_wa
+check_erratum_ls neoverse_v1, ERRATUM(2139242), CPU_REV(1, 1)
 
-func check_errata_2139242
-	/* Applies to r0p0, r1p0, r1p1 */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2139242
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2108267.
-	 * This applies to revisions r0p0, r1p0, and r1p1, it
-	 * is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x1, x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_2108267_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2108267
-	cbz	x0, 1f
-
-	/* Apply the workaround. */
-	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
-	mov	x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
-	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2108267_wa
-
-func check_errata_2108267
-	/* Applies to r0p0, r1p0, r1p1 */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2108267
-
-	/* --------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2216392.
-	 * This applies to revisions r1p0 and r1p1 and is
-	 * still open.
-	 * This issue is also present in r0p0 but there is no
-	 * workaround in that revision.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * --------------------------------------------------
-	 */
-func errata_neoverse_v1_2216392_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2216392
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(2216392), ERRATA_V1_2216392
 	ldr	x0, =0x5
 	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
 	ldr	x0, =0x10F600E000
@@ -393,167 +185,56 @@
 	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
 	ldr	x0, =0x80000000003FF
 	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+workaround_reset_end neoverse_v1, ERRATUM(2216392)
 
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2216392_wa
+check_erratum_range neoverse_v1, ERRATUM(2216392), CPU_REV(1, 0), CPU_REV(1, 1)
 
-func check_errata_2216392
-	/* Applies to revisions r1p0 and r1p1. */
-	mov	x1, #CPU_REV(1, 0)
-	mov	x2, #CPU_REV(1, 1)
-	b	cpu_rev_var_range
-endfunc check_errata_2216392
-
-	/* -----------------------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2294912.
-	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * -----------------------------------------------------------------
-	 */
-func errata_neoverse_v1_2294912_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2294912
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(2294912), ERRATA_V1_2294912
 	/* Set bit 0 in ACTLR2_EL1 */
-	mrs     x1, NEOVERSE_V1_ACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_0
-	msr     NEOVERSE_V1_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2294912_wa
+	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_0
+workaround_reset_end neoverse_v1, ERRATUM(2294912)
 
-func check_errata_2294912
-	/* Applies to r0p0, r1p0, and r1p1 right now */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2294912
+check_erratum_ls neoverse_v1, ERRATUM(2294912), CPU_REV(1, 1)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2372203.
-	 * This applies to revisions <= r1p1 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ----------------------------------------------------
-	 */
-func errata_neoverse_v1_2372203_wa
-	/* Check workaround compatibility. */
-	mov	x17, x30
-	bl	check_errata_2372203
-	cbz	x0, 1f
-
+workaround_reset_start neoverse_v1, ERRATUM(2372203), ERRATA_V1_2372203
 	/* Set bit 40 in ACTLR2_EL1 */
-	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
-	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_40
-	msr	NEOVERSE_V1_ACTLR2_EL1, x1
-	isb
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2372203_wa
-
-func check_errata_2372203
-	/* Applies to <= r1p1. */
-	mov	x1, #0x11
-	b	cpu_rev_var_ls
-endfunc check_errata_2372203
+	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_40
+workaround_reset_end neoverse_v1, ERRATUM(2372203)
 
-	/* ----------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2743093.
-	 * This applies to revisions <= r1p2 and is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x17
-	 * ----------------------------------------------------
-	 */
-func errata_neoverse_v1_2743093_wa
-	mov	x17, x30
-	bl	check_errata_2743093
-	cbz	x0, 1f
+check_erratum_ls neoverse_v1, ERRATUM(2372203), CPU_REV(1, 1)
 
+workaround_runtime_start neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
 	/* dsb before isb of power down sequence */
 	dsb	sy
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2743093_wa
+workaround_runtime_end neoverse_v1, ERRATUM(2743093)
 
-func check_errata_2743093
-	/* Applies to all revisions <= r1p2 */
-	mov	x1, #0x12
-	b	cpu_rev_var_ls
-endfunc check_errata_2743093
+check_erratum_ls neoverse_v1, ERRATUM(2743093), CPU_REV(1, 2)
 
-	/* ---------------------------------------------------
-	 * Errata Workaround for Neoverse V1 Errata #2743233.
-	 * This applies to revisions r0p0, r1p0, r1p1 and r1p2.
-	 * It is still open.
-	 * x0: variant[4:7] and revisions[0:3] of current cpu.
-	 * Shall clobber: x0-x1, x17
-	 * ---------------------------------------------------
-	 */
-func errata_neoverse_v1_2743233_wa
-	/* Check revision. */
-	mov 	x17, x30
-	bl	check_errata_2743233
-	cbz	x0, 1f
+workaround_reset_start neoverse_v1, ERRATUM(2743233), ERRATA_V1_2743233
+	sysreg_bit_clear NEOVERSE_V1_ACTLR5_EL1, NEOVERSE_V1_ACTLR5_EL1_BIT_56
+	sysreg_bit_set NEOVERSE_V1_ACTLR5_EL1, NEOVERSE_V1_ACTLR5_EL1_BIT_55
+workaround_reset_end neoverse_v1, ERRATUM(2743233)
 
-	/* Apply the workaround */
-	mrs	x1, NEOVERSE_V1_ACTLR5_EL1
-	bic	x1, x1, #BIT(56)
-	orr	x1, x1, #BIT(55)
-	msr	NEOVERSE_V1_ACTLR5_EL1, x1
+check_erratum_ls neoverse_v1, ERRATUM(2743233), CPU_REV(1, 2)
 
-1:
-	ret 	x17
-endfunc errata_neoverse_v1_2743233_wa
+workaround_reset_start neoverse_v1, ERRATUM(2779461), ERRATA_V1_2779461
+	sysreg_bit_set NEOVERSE_V1_ACTLR3_EL1, NEOVERSE_V1_ACTLR3_EL1_BIT_47
+workaround_reset_end neoverse_v1, ERRATUM(2779461)
 
-func check_errata_2743233
-	/* Applies to r0p0, r1p0, r1p1 and r1p2 */
-	mov	x1, #CPU_REV(1,2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2743233
+check_erratum_ls neoverse_v1, ERRATUM(2779461), CPU_REV(1, 2)
 
 
-	/* ----------------------------------------------------
- 	 * Errata Workaround for Neoverse V1 Errata #2779461.
-	 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
-	 * It is still open.
-	 * x0: variant[4:7] and revision[0:3] of current cpu.
-	 * Shall clobber: x0-x1, x17
-	 * ----------------------------------------------------
+workaround_reset_start neoverse_v1, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse-V1 generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
 	 */
-func errata_neoverse_v1_2779461_wa
-	/* Check revision. */
-	mov	x17, x30
-	bl	check_errata_2779461
-	cbz	x0, 1f
-
-	/* Apply the workaround */
-	mrs	x1, NEOVERSE_V1_ACTLR3_EL1
-	orr	x1, x1, #BIT(47)
-	msr	NEOVERSE_V1_ACTLR3_EL1, x1
+	override_vector_table wa_cve_vbar_neoverse_v1
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_v1, CVE(2022,23960)
 
-1:
-	ret	x17
-endfunc errata_neoverse_v1_2779461_wa
-
-func check_errata_2779461
-	/* Applies to r0p0, r1p0, r1p1, r1p2 */
-	mov	x1, #CPU_REV(1, 2)
-	b	cpu_rev_var_ls
-endfunc check_errata_2779461
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
+check_erratum_chosen neoverse_v1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -564,148 +245,19 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------
 	 */
-	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
-#if ERRATA_V1_2743093
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	errata_neoverse_v1_2743093_wa
-	mov	x30, x15
-#endif /* ERRATA_V1_2743093 */
+	sysreg_bit_set NEOVERSE_V1_CPUPWRCTLR_EL1, NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
+
 	isb
 	ret
 endfunc neoverse_v1_core_pwr_dwn
 
-	/*
-	 * Errata printing function for Neoverse V1. Must follow AAPCS.
-	 */
-#if REPORT_ERRATA
-func neoverse_v1_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
+errata_report_shim neoverse_v1
 
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_V1_1618635, neoverse_v1, 1618635
-	report_errata ERRATA_V1_1774420, neoverse_v1, 1774420
-	report_errata ERRATA_V1_1791573, neoverse_v1, 1791573
-	report_errata ERRATA_V1_1852267, neoverse_v1, 1852267
-	report_errata ERRATA_V1_1925756, neoverse_v1, 1925756
-	report_errata ERRATA_V1_1940577, neoverse_v1, 1940577
-	report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
-	report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
-	report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
-	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
-	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
-	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
-	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
-	report_errata ERRATA_V1_2743233, neoverse_v1, 2743233
-	report_errata ERRATA_V1_2779461, neoverse_v1, 2779461
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_v1_errata_report
-#endif
-
-func neoverse_v1_reset_func
-	mov	x19, x30
-
+cpu_reset_func_start neoverse_v1
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-	isb
-
-	/* Get the CPU revision and stash it in x18. */
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_V1_1618635
-	mov x0, x18
-	bl errata_neoverse_v1_1618635_wa
-#endif
-
-#if ERRATA_V1_1774420
-	mov	x0, x18
-	bl	errata_neoverse_v1_1774420_wa
-#endif
-
-#if ERRATA_V1_1791573
-	mov	x0, x18
-	bl	errata_neoverse_v1_1791573_wa
-#endif
-
-#if ERRATA_V1_1852267
-	mov	x0, x18
-	bl	errata_neoverse_v1_1852267_wa
-#endif
-
-#if ERRATA_V1_1925756
-	mov	x0, x18
-	bl	errata_neoverse_v1_1925756_wa
-#endif
-
-#if ERRATA_V1_1940577
-	mov	x0, x18
-	bl	errata_neoverse_v1_1940577_wa
-#endif
-
-#if ERRATA_V1_1966096
-	mov	x0, x18
-	bl	errata_neoverse_v1_1966096_wa
-#endif
-
-#if ERRATA_V1_2139242
-	mov	x0, x18
-	bl	errata_neoverse_v1_2139242_wa
-#endif
-
-#if ERRATA_V1_2108267
-	mov	x0, x18
-	bl	errata_neoverse_v1_2108267_wa
-#endif
-
-#if ERRATA_V1_2216392
-	mov	x0, x18
-	bl	errata_neoverse_v1_2216392_wa
-#endif
-
-#if ERRATA_V1_2294912
-	mov	x0, x18
-	bl	errata_neoverse_v1_2294912_wa
-#endif
-
-#if ERRATA_V1_2372203
-	mov	x0, x18
-	bl	errata_neoverse_v1_2372203_wa
-#endif
-
-#if ERRATA_V1_2743233
-	mov	x0, x18
-	bl	errata_neoverse_v1_2743233_wa
-#endif
-
-#if ERRATA_V1_2779461
-	mov	x0, x18
-	bl	errata_neoverse_v1_2779461_wa
-#endif
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse-V1 generic vectors are overridden to apply errata
-         * mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_v1
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-
-	isb
-	ret	x19
-endfunc neoverse_v1_reset_func
+cpu_reset_func_end neoverse_v1
 
 	/* ---------------------------------------------
 	 * This function provides Neoverse-V1 specific
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index 4ea887f..36ae4de 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,25 @@
 #error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+workaround_runtime_start neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+	/* dsb before isb of power down sequence */
+	dsb	sy
+workaround_runtime_end neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+
+check_erratum_ls neoverse_v2, ERRATUM(2801372), CPU_REV(0, 1)
+
+workaround_reset_start neoverse_v2, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse-V2 generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_v2
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_v2, CVE(2022,23960)
+
+check_erratum_chosen neoverse_v2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V2_BHB_LOOP_COUNT, neoverse_v2
 #endif /* WORKAROUND_CVE_2022_23960 */
@@ -35,59 +54,19 @@
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, NEOVERSE_V2_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	NEOVERSE_V2_CPUPWRCTLR_EL1, x0
+	sysreg_bit_set NEOVERSE_V2_CPUPWRCTLR_EL1, NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+
 	isb
 	ret
 endfunc neoverse_v2_core_pwr_dwn
 
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func neoverse_v2_reset_func
+cpu_reset_func_start neoverse_v2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse V2 vectors are overridden to apply
-	 * errata mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_v2
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-	isb
-	ret
-endfunc neoverse_v2_reset_func
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse V2. Must follow AAPCS.
- */
-func neoverse_v2_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_v2, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_v2_errata_report
-#endif
+cpu_reset_func_end neoverse_v2
 
+errata_report_shim neoverse_v2
 	/* ---------------------------------------------
 	 * This function provides Neoverse V2-
 	 * specific register information for crash
diff --git a/lib/cpus/aarch64/nevis.S b/lib/cpus/aarch64/nevis.S
new file mode 100644
index 0000000..36830a9
--- /dev/null
+++ b/lib/cpus/aarch64/nevis.S
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <nevis.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Nevis must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Nevis supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start nevis
+	/* ----------------------------------------------------
+	 * Disable speculative loads
+	 * ----------------------------------------------------
+	 */
+	msr	SSBS, xzr
+cpu_reset_func_end nevis
+
+func nevis_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set NEVIS_IMP_CPUPWRCTLR_EL1, \
+		NEVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	isb
+	ret
+endfunc nevis_core_pwr_dwn
+
+errata_report_shim nevis
+
+.section .rodata.nevis_regs, "aS"
+nevis_regs: /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func nevis_cpu_reg_dump
+	adr 	x6, nevis_regs
+	mrs	x8, NEVIS_CPUECTLR_EL1
+	ret
+endfunc nevis_cpu_reg_dump
+
+declare_cpu_ops nevis, NEVIS_MIDR, \
+	nevis_reset_func, \
+	nevis_core_pwr_dwn
diff --git a/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S b/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
index 0222818..8d9aa5e 100644
--- a/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
+++ b/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S b/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
index ed0a549..823f849 100644
--- a/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
+++ b/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S b/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
index ceb93f1..bf26658 100644
--- a/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
+++ b/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index e16c8e4..0d8f4d4 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -612,43 +612,47 @@
 CPU_FLAG_LIST += ERRATA_A710_2768515
 
 # Flag to apply erratum 2002655 workaround during reset. This erratum applies
-# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+# to revisions r0p0 of the Neoverse-N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2002655
 
+# Flag to apply erratum 2009478 workaround during powerdown. This erratum
+# applies to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_N2_2009478
+
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2067956
 
 # Flag to apply erratum 2025414 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2025414
 
 # Flag to apply erratum 2189731 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2189731
 
 # Flag to apply erratum 2138956 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2138956
 
 # Flag to apply erratum 2138953 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0, r0p1, r0p2, r0p3 of the Neoverse N2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_N2_2138953
 
 # Flag to apply erratum 2242415 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2242415
 
 # Flag to apply erratum 2138958 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2138958
 
 # Flag to apply erratum 2242400 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2242400
 
 # Flag to apply erratum 2280757 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu and is still open.
+# 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
@@ -656,7 +660,7 @@
 CPU_FLAG_LIST += ERRATA_N2_2326639
 
 # Flag to apply erratum 2376738 workaround during reset. This erratum applies
-# to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
+# to revision r0p0, r0p1, r0p2, r0p3 of the Neoverse N2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_N2_2376738
 
 # Flag to apply erratum 2388450 workaround during reset. This erratum applies
@@ -668,10 +672,18 @@
 # r0p3.
 CPU_FLAG_LIST += ERRATA_N2_2728475
 
+# Flag to apply erratum 2743014 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_2743014
+
 # Flag to apply erratum 2743089 workaround during during powerdown. This erratum
 # applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
 CPU_FLAG_LIST += ERRATA_N2_2743089
 
+# Flag to apply erratum 2779511 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_2779511
+
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2002765
@@ -730,6 +742,10 @@
 # to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is still open.
 CPU_FLAG_LIST += ERRATA_X3_2615812
 
+# Flag to apply erratum 2742421 workaround on reset. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2742421
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A510_1922240
@@ -782,6 +798,10 @@
 # erratum applies to revisions r0p0, rop1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2719103
 
+# Flag to apply erratum 2801372 workaround for all configurations.
+# This erratum applies to revisions r0p0, r0p1. Fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2801372
+
 # Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
 # This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_A715_2701951
diff --git a/lib/debugfs/debugfs.mk b/lib/debugfs/debugfs.mk
index 138fc72..caa9fcf 100644
--- a/lib/debugfs/debugfs.mk
+++ b/lib/debugfs/debugfs.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/debugfs/debugfs_smc.c b/lib/debugfs/debugfs_smc.c
index 13ced3d..64c64f8 100644
--- a/lib/debugfs/debugfs_smc.c
+++ b/lib/debugfs/debugfs_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 6414aaa..b60b8e0 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -142,19 +142,19 @@
 	}
 
 	if (is_feat_sys_reg_trace_supported()) {
-		sys_reg_trace_enable();
+		sys_reg_trace_init_el3();
 	}
 
 	if (is_feat_trf_supported()) {
-		trf_enable();
+		trf_init_el3();
 	}
 
 	/*
 	 * Also applies to PMU < v3. The PMU is only disabled for EL3 and Secure
 	 * state execution. This does not affect lower NS ELs.
 	 */
-	pmuv3_disable_el3();
-#endif
+	pmuv3_init_el3();
+#endif /*  IMAGE_BL32 */
 }
 
 /*******************************************************************************
diff --git a/lib/el3_runtime/aarch32/cpu_data.S b/lib/el3_runtime/aarch32/cpu_data.S
index bdad2c1..e59b7fd 100644
--- a/lib/el3_runtime/aarch32/cpu_data.S
+++ b/lib/el3_runtime/aarch32/cpu_data.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 771fcdc..f47e779 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -10,15 +10,6 @@
 #include <context.h>
 #include <el3_common_macros.S>
 
-#if CTX_INCLUDE_EL2_REGS
-	.global	el2_sysregs_context_save_common
-	.global	el2_sysregs_context_restore_common
-#if CTX_INCLUDE_MTE_REGS
-	.global	el2_sysregs_context_save_mte
-	.global	el2_sysregs_context_restore_mte
-#endif /* CTX_INCLUDE_MTE_REGS */
-#endif /* CTX_INCLUDE_EL2_REGS */
-
 	.global	el1_sysregs_context_save
 	.global	el1_sysregs_context_restore
 #if CTX_INCLUDE_FPREGS
@@ -30,183 +21,6 @@
 	.global save_and_update_ptw_el1_sys_regs
 	.global	el3_exit
 
-#if CTX_INCLUDE_EL2_REGS
-
-/* -----------------------------------------------------
- * The following functions strictly follow the AArch64
- * PCS to use x9-x16 (temporary caller-saved registers)
- * to save/restore EL2 system register context.
- * el2_sysregs_context_save/restore_common functions
- * save and restore registers that are common to all
- * configurations. The rest of the functions save and
- * restore EL2 system registers that are present when a
- * particular feature is enabled. All functions assume
- * that 'x0' is pointing to a 'el2_sys_regs' structure
- * where the register context will be saved/restored.
- *
- * The following registers are not added.
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
- * ICH_AP0R<n>_EL2
- * ICH_AP1R<n>_EL2
- * ICH_LR<n>_EL2
- * -----------------------------------------------------
- */
-func el2_sysregs_context_save_common
-	mrs	x9, actlr_el2
-	mrs	x10, afsr0_el2
-	stp	x9, x10, [x0, #CTX_ACTLR_EL2]
-
-	mrs	x11, afsr1_el2
-	mrs	x12, amair_el2
-	stp	x11, x12, [x0, #CTX_AFSR1_EL2]
-
-	mrs	x13, cnthctl_el2
-	mrs	x14, cntvoff_el2
-	stp	x13, x14, [x0, #CTX_CNTHCTL_EL2]
-
-	mrs	x15, cptr_el2
-	str	x15, [x0, #CTX_CPTR_EL2]
-
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x16, dbgvcr32_el2
-	str	x16, [x0, #CTX_DBGVCR32_EL2]
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	mrs	x9, elr_el2
-	mrs	x10, esr_el2
-	stp	x9, x10, [x0, #CTX_ELR_EL2]
-
-	mrs	x11, far_el2
-	mrs	x12, hacr_el2
-	stp	x11, x12, [x0, #CTX_FAR_EL2]
-
-	mrs	x13, hcr_el2
-	mrs	x14, hpfar_el2
-	stp	x13, x14, [x0, #CTX_HCR_EL2]
-
-	mrs	x15, hstr_el2
-	mrs	x16, ICC_SRE_EL2
-	stp	x15, x16, [x0, #CTX_HSTR_EL2]
-
-	mrs	x9, ICH_HCR_EL2
-	mrs	x10, ICH_VMCR_EL2
-	stp	x9, x10, [x0, #CTX_ICH_HCR_EL2]
-
-	mrs	x11, mair_el2
-	mrs	x12, mdcr_el2
-	stp	x11, x12, [x0, #CTX_MAIR_EL2]
-
-	mrs	x14, sctlr_el2
-	str	x14, [x0, #CTX_SCTLR_EL2]
-
-	mrs	x15, spsr_el2
-	mrs	x16, sp_el2
-	stp	x15, x16, [x0, #CTX_SPSR_EL2]
-
-	mrs	x9, tcr_el2
-	mrs	x10, tpidr_el2
-	stp	x9, x10, [x0, #CTX_TCR_EL2]
-
-	mrs	x11, ttbr0_el2
-	mrs	x12, vbar_el2
-	stp	x11, x12, [x0, #CTX_TTBR0_EL2]
-
-	mrs	x13, vmpidr_el2
-	mrs	x14, vpidr_el2
-	stp	x13, x14, [x0, #CTX_VMPIDR_EL2]
-
-	mrs	x15, vtcr_el2
-	mrs	x16, vttbr_el2
-	stp	x15, x16, [x0, #CTX_VTCR_EL2]
-	ret
-endfunc el2_sysregs_context_save_common
-
-func el2_sysregs_context_restore_common
-	ldp	x9, x10, [x0, #CTX_ACTLR_EL2]
-	msr	actlr_el2, x9
-	msr	afsr0_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_AFSR1_EL2]
-	msr	afsr1_el2, x11
-	msr	amair_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_CNTHCTL_EL2]
-	msr	cnthctl_el2, x13
-	msr	cntvoff_el2, x14
-
-	ldr	x15, [x0, #CTX_CPTR_EL2]
-	msr	cptr_el2, x15
-
-#if CTX_INCLUDE_AARCH32_REGS
-	ldr	x16, [x0, #CTX_DBGVCR32_EL2]
-	msr	dbgvcr32_el2, x16
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	ldp	x9, x10, [x0, #CTX_ELR_EL2]
-	msr	elr_el2, x9
-	msr	esr_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_FAR_EL2]
-	msr	far_el2, x11
-	msr	hacr_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_HCR_EL2]
-	msr	hcr_el2, x13
-	msr	hpfar_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_HSTR_EL2]
-	msr	hstr_el2, x15
-	msr	ICC_SRE_EL2, x16
-
-	ldp	x9, x10, [x0, #CTX_ICH_HCR_EL2]
-	msr	ICH_HCR_EL2, x9
-	msr	ICH_VMCR_EL2, x10
-
-	ldp	x11, x12, [x0, #CTX_MAIR_EL2]
-	msr	mair_el2, x11
-	msr	mdcr_el2, x12
-
-	ldr	x14, [x0, #CTX_SCTLR_EL2]
-	msr	sctlr_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_SPSR_EL2]
-	msr	spsr_el2, x15
-	msr	sp_el2, x16
-
-	ldp	x9, x10, [x0, #CTX_TCR_EL2]
-	msr	tcr_el2, x9
-	msr	tpidr_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_TTBR0_EL2]
-	msr	ttbr0_el2, x11
-	msr	vbar_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_VMPIDR_EL2]
-	msr	vmpidr_el2, x13
-	msr	vpidr_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_VTCR_EL2]
-	msr	vtcr_el2, x15
-	msr	vttbr_el2, x16
-	ret
-endfunc el2_sysregs_context_restore_common
-
-#if CTX_INCLUDE_MTE_REGS
-func el2_sysregs_context_save_mte
-	mrs	x9, TFSR_EL2
-	str	x9, [x0, #CTX_TFSR_EL2]
-	ret
-endfunc el2_sysregs_context_save_mte
-
-func el2_sysregs_context_restore_mte
-	ldr	x9, [x0, #CTX_TFSR_EL2]
-	msr	TFSR_EL2, x9
-	ret
-endfunc el2_sysregs_context_restore_mte
-#endif /* CTX_INCLUDE_MTE_REGS */
-
-#endif /* CTX_INCLUDE_EL2_REGS */
 
 /* ------------------------------------------------------------------
  * The following function strictly follows the AArch64 PCS to use
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 4a6598a..b16c113 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -279,6 +279,20 @@
 		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
 			HCRX_EL2_INIT_VAL);
 	}
+
+	if (is_feat_fgt_supported()) {
+		/*
+		 * Initialize HFG*_EL2 registers with a default value so legacy
+		 * systems unaware of FEAT_FGT do not get trapped due to their lack
+		 * of initialization for this feature.
+		 */
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGITR_EL2,
+			HFGITR_EL2_INIT_VAL);
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGRTR_EL2,
+			HFGRTR_EL2_INIT_VAL);
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGWTR_EL2,
+			HFGWTR_EL2_INIT_VAL);
+	}
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	manage_extensions_nonsecure(ctx);
@@ -496,63 +510,42 @@
 }
 
 /*******************************************************************************
- * Enable architecture extensions on first entry to Non-secure world.
- * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
- * it is zero. This function updates some registers in-place and its contents
- * are being prepared to be moved to cm_manage_extensions_el3 and
- * cm_manage_extensions_nonsecure.
+ * Enable architecture extensions for EL3 execution. This function only updates
+ * registers in-place which are expected to either never change or be
+ * overwritten by el3_exit.
  ******************************************************************************/
-static void manage_extensions_nonsecure_mixed(bool el2_unused, cpu_context_t *ctx)
-{
 #if IMAGE_BL31
+void cm_manage_extensions_el3(void)
+{
 	if (is_feat_spe_supported()) {
-		spe_enable(el2_unused);
+		spe_init_el3();
 	}
 
 	if (is_feat_amu_supported()) {
-		amu_enable(el2_unused, ctx);
+		amu_init_el3();
 	}
 
-	/* Enable SVE and FPU/SIMD */
-	if (is_feat_sve_supported()) {
-		sve_enable(ctx);
-	}
-
 	if (is_feat_sme_supported()) {
-		sme_enable(ctx);
+		sme_init_el3();
 	}
 
 	if (is_feat_mpam_supported()) {
-		mpam_enable(el2_unused);
+		mpam_init_el3();
 	}
 
 	if (is_feat_trbe_supported()) {
-		trbe_enable();
+		trbe_init_el3();
 	}
 
 	if (is_feat_brbe_supported()) {
-		brbe_enable();
+		brbe_init_el3();
 	}
 
-	if (is_feat_sys_reg_trace_supported()) {
-		sys_reg_trace_enable(ctx);
-	}
-
 	if (is_feat_trf_supported()) {
-		trf_enable();
+		trf_init_el3();
 	}
-#endif
-}
 
-/*******************************************************************************
- * Enable architecture extensions for EL3 execution. This function only updates
- * registers in-place which are expected to either never change or be
- * overwritten by el3_exit.
- ******************************************************************************/
-#if IMAGE_BL31
-void cm_manage_extensions_el3(void)
-{
-	pmuv3_disable_el3();
+	pmuv3_init_el3();
 }
 #endif /* IMAGE_BL31 */
 
@@ -562,10 +555,41 @@
 static void manage_extensions_nonsecure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
+	if (is_feat_amu_supported()) {
+		amu_enable(ctx);
+	}
+
+	/* Enable SVE and FPU/SIMD */
+	if (is_feat_sve_supported()) {
+		sve_enable(ctx);
+	}
+
+	if (is_feat_sme_supported()) {
+		sme_enable(ctx);
+	}
+
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_enable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 #endif /* IMAGE_BL31 */
 }
 
+/* TODO: move to lib/extensions/pauth when it has been ported to FEAT_STATE */
+static __unused void enable_pauth_el2(void)
+{
+	u_register_t hcr_el2 = read_hcr_el2();
+	/*
+	 * For Armv8.3 pointer authentication feature, disable traps to EL2 when
+	 *  accessing key registers or using pointer authentication instructions
+	 *  from lower ELs.
+	 */
+	hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
+
+	write_hcr_el2(hcr_el2);
+}
+
 /*******************************************************************************
  * Enable architecture extensions in-place at EL2 on first entry to Non-secure
  * world when EL2 is empty and unused.
@@ -573,7 +597,43 @@
 static void manage_extensions_nonsecure_el2_unused(void)
 {
 #if IMAGE_BL31
+	if (is_feat_spe_supported()) {
+		spe_init_el2_unused();
+	}
+
+	if (is_feat_amu_supported()) {
+		amu_init_el2_unused();
+	}
+
+	if (is_feat_mpam_supported()) {
+		mpam_init_el2_unused();
+	}
+
+	if (is_feat_trbe_supported()) {
+		trbe_init_el2_unused();
+	}
+
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_init_el2_unused();
+	}
+
+	if (is_feat_trf_supported()) {
+		trf_init_el2_unused();
+	}
+
 	pmuv3_init_el2_unused();
+
+	if (is_feat_sve_supported()) {
+		sve_init_el2_unused();
+	}
+
+	if (is_feat_sme_supported()) {
+		sme_init_el2_unused();
+	}
+
+#if ENABLE_PAUTH
+	enable_pauth_el2();
+#endif /* ENABLE_PAUTH */
 #endif /* IMAGE_BL31 */
 }
 
@@ -606,6 +666,7 @@
 		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
 		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
 		 */
+			sme_init_el3();
 			sme_enable(ctx);
 		} else {
 		/*
@@ -615,6 +676,11 @@
 			sme_disable(ctx);
 		}
 	}
+
+	/* NS can access this but Secure shouldn't */
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_disable(ctx);
+	}
 #endif /* IMAGE_BL31 */
 }
 
@@ -643,6 +709,109 @@
 	cm_setup_context(ctx, ep);
 }
 
+/* EL2 present but unused, need to disable safely. SCTLR_EL2 can be ignored */
+static __unused void init_nonsecure_el2_unused(cpu_context_t *ctx)
+{
+	u_register_t hcr_el2 = HCR_RESET_VAL;
+	u_register_t mdcr_el2;
+	u_register_t scr_el3;
+
+	scr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
+
+	/* Set EL2 register width: Set HCR_EL2.RW to match SCR_EL3.RW */
+	if ((scr_el3 & SCR_RW_BIT) != 0U) {
+		hcr_el2 |= HCR_RW_BIT;
+	}
+
+	write_hcr_el2(hcr_el2);
+
+	/*
+	 * Initialise CPTR_EL2 setting all fields rather than relying on the hw.
+	 * All fields have architecturally UNKNOWN reset values.
+	 */
+	write_cptr_el2(CPTR_EL2_RESET_VAL);
+
+	/*
+	 * Initialise CNTHCTL_EL2. All fields are architecturally UNKNOWN on
+	 * reset and are set to zero except for field(s) listed below.
+	 *
+	 * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to Hyp mode of
+	 * Non-secure EL0 and EL1 accesses to the physical timer registers.
+	 *
+	 * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to Hyp mode of
+	 * Non-secure EL0 and EL1 accesses to the physical counter registers.
+	 */
+	write_cnthctl_el2(CNTHCTL_RESET_VAL | EL1PCEN_BIT | EL1PCTEN_BIT);
+
+	/*
+	 * Initialise CNTVOFF_EL2 to zero as it resets to an architecturally
+	 * UNKNOWN value.
+	 */
+	write_cntvoff_el2(0);
+
+	/*
+	 * Set VPIDR_EL2 and VMPIDR_EL2 to match MIDR_EL1 and MPIDR_EL1
+	 * respectively.
+	 */
+	write_vpidr_el2(read_midr_el1());
+	write_vmpidr_el2(read_mpidr_el1());
+
+	/*
+	 * Initialise VTTBR_EL2. All fields are architecturally UNKNOWN on reset.
+	 *
+	 * VTTBR_EL2.VMID: Set to zero. Even though EL1&0 stage 2 address
+	 * translation is disabled, cache maintenance operations depend on the
+	 * VMID.
+	 *
+	 * VTTBR_EL2.BADDR: Set to zero as EL1&0 stage 2 address translation is
+	 * disabled.
+	 */
+	write_vttbr_el2(VTTBR_RESET_VAL &
+		     ~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT) |
+		       (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
+
+	/*
+	 * Initialise MDCR_EL2, setting all fields rather than relying on hw.
+	 * Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and EL1 System
+	 * register accesses to the Debug ROM registers are not trapped to EL2.
+	 *
+	 * MDCR_EL2.TDOSA: Set to zero so that Non-secure EL1 System register
+	 * accesses to the powerdown debug registers are not trapped to EL2.
+	 *
+	 * MDCR_EL2.TDA: Set to zero so that System register accesses to the
+	 * debug registers do not trap to EL2.
+	 *
+	 * MDCR_EL2.TDE: Set to zero so that debug exceptions are not routed to
+	 * EL2.
+	 */
+	mdcr_el2 = MDCR_EL2_RESET_VAL &
+		 ~(MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT | MDCR_EL2_TDA_BIT |
+		   MDCR_EL2_TDE_BIT);
+
+	write_mdcr_el2(mdcr_el2);
+
+	/*
+	 * Initialise HSTR_EL2. All fields are architecturally UNKNOWN on reset.
+	 *
+	 * HSTR_EL2.T<n>: Set all these fields to zero so that Non-secure EL0 or
+	 * EL1 accesses to System registers do not trap to EL2.
+	 */
+	write_hstr_el2(HSTR_EL2_RESET_VAL & ~(HSTR_EL2_T_MASK));
+
+	/*
+	 * Initialise CNTHP_CTL_EL2. All fields are architecturally UNKNOWN on
+	 * reset.
+	 *
+	 * CNTHP_CTL_EL2:ENABLE: Set to zero to disable the EL2 physical timer
+	 * and prevent timer interrupts.
+	 */
+	write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL & ~(CNTHP_CTL_ENABLE_BIT));
+
+	manage_extensions_nonsecure_el2_unused();
+}
+
 /*******************************************************************************
  * Prepare the CPU system registers for first entry into realm, secure, or
  * normal world.
@@ -654,10 +823,8 @@
  ******************************************************************************/
 void cm_prepare_el3_exit(uint32_t security_state)
 {
-	u_register_t sctlr_elx, scr_el3, mdcr_el2;
+	u_register_t sctlr_elx, scr_el3;
 	cpu_context_t *ctx = cm_get_context(security_state);
-	bool el2_unused = false;
-	uint64_t hcr_el2 = 0U;
 
 	assert(ctx != NULL);
 
@@ -676,8 +843,27 @@
 			if (is_feat_hcx_supported()) {
 				write_hcrx_el2(HCRX_EL2_INIT_VAL);
 			}
+
+			/*
+			 * Initialize Fine-grained trap registers introduced
+			 * by FEAT_FGT so all traps are initially disabled when
+			 * switching to EL2 or a lower EL, preventing undesired
+			 * behavior.
+			 */
+			if (is_feat_fgt_supported()) {
+				/*
+				 * Initialize HFG*_EL2 registers with a default
+				 * value so legacy systems unaware of FEAT_FGT
+				 * do not get trapped due to their lack of
+				 * initialization for this feature.
+				 */
+				write_hfgitr_el2(HFGITR_EL2_INIT_VAL);
+				write_hfgrtr_el2(HFGRTR_EL2_INIT_VAL);
+				write_hfgwtr_el2(HFGWTR_EL2_INIT_VAL);
+			}
 		}
 
+
 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
@@ -694,157 +880,8 @@
 #endif
 			write_sctlr_el2(sctlr_elx);
 		} else if (el2_implemented != EL_IMPL_NONE) {
-			el2_unused = true;
-
-			/*
-			 * EL2 present but unused, need to disable safely.
-			 * SCTLR_EL2 can be ignored in this case.
-			 *
-			 * Set EL2 register width appropriately: Set HCR_EL2
-			 * field to match SCR_EL3.RW.
-			 */
-			if ((scr_el3 & SCR_RW_BIT) != 0U)
-				hcr_el2 |= HCR_RW_BIT;
-
-			/*
-			 * For Armv8.3 pointer authentication feature, disable
-			 * traps to EL2 when accessing key registers or using
-			 * pointer authentication instructions from lower ELs.
-			 */
-			hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
-
-			write_hcr_el2(hcr_el2);
-
-			/*
-			 * Initialise CPTR_EL2 setting all fields rather than
-			 * relying on the hw. All fields have architecturally
-			 * UNKNOWN reset values.
-			 *
-			 * CPTR_EL2.TCPAC: Set to zero so that Non-secure EL1
-			 *  accesses to the CPACR_EL1 or CPACR from both
-			 *  Execution states do not trap to EL2.
-			 *
-			 * CPTR_EL2.TTA: Set to zero so that Non-secure System
-			 *  register accesses to the trace registers from both
-			 *  Execution states do not trap to EL2.
-			 *  If PE trace unit System registers are not implemented
-			 *  then this bit is reserved, and must be set to zero.
-			 *
-			 * CPTR_EL2.TFP: Set to zero so that Non-secure accesses
-			 *  to SIMD and floating-point functionality from both
-			 *  Execution states do not trap to EL2.
-			 */
-			write_cptr_el2(CPTR_EL2_RESET_VAL &
-					~(CPTR_EL2_TCPAC_BIT | CPTR_EL2_TTA_BIT
-					| CPTR_EL2_TFP_BIT));
-
-			/*
-			 * Initialise CNTHCTL_EL2. All fields are
-			 * architecturally UNKNOWN on reset and are set to zero
-			 * except for field(s) listed below.
-			 *
-			 * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to
-			 *  Hyp mode of Non-secure EL0 and EL1 accesses to the
-			 *  physical timer registers.
-			 *
-			 * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to
-			 *  Hyp mode of  Non-secure EL0 and EL1 accesses to the
-			 *  physical counter registers.
-			 */
-			write_cnthctl_el2(CNTHCTL_RESET_VAL |
-						EL1PCEN_BIT | EL1PCTEN_BIT);
-
-			/*
-			 * Initialise CNTVOFF_EL2 to zero as it resets to an
-			 * architecturally UNKNOWN value.
-			 */
-			write_cntvoff_el2(0);
-
-			/*
-			 * Set VPIDR_EL2 and VMPIDR_EL2 to match MIDR_EL1 and
-			 * MPIDR_EL1 respectively.
-			 */
-			write_vpidr_el2(read_midr_el1());
-			write_vmpidr_el2(read_mpidr_el1());
-
-			/*
-			 * Initialise VTTBR_EL2. All fields are architecturally
-			 * UNKNOWN on reset.
-			 *
-			 * VTTBR_EL2.VMID: Set to zero. Even though EL1&0 stage
-			 *  2 address translation is disabled, cache maintenance
-			 *  operations depend on the VMID.
-			 *
-			 * VTTBR_EL2.BADDR: Set to zero as EL1&0 stage 2 address
-			 *  translation is disabled.
-			 */
-			write_vttbr_el2(VTTBR_RESET_VAL &
-				~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT)
-				| (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
-
-			/*
-			 * Initialise MDCR_EL2, setting all fields rather than
-			 * relying on hw. Some fields are architecturally
-			 * UNKNOWN on reset.
-			 *
-			 * MDCR_EL2.TTRF: Set to zero so that access to Trace
-			 *  Filter Control register TRFCR_EL1 at EL1 is not
-			 *  trapped to EL2. This bit is RES0 in versions of
-			 *  the architecture earlier than ARMv8.4.
-			 *
-			 * MDCR_EL2.TPMS: Set to zero so that accesses to
-			 *  Statistical Profiling control registers from EL1
-			 *  do not trap to EL2. This bit is RES0 when SPE is
-			 *  not implemented.
-			 *
-			 * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
-			 *  EL1 System register accesses to the Debug ROM
-			 *  registers are not trapped to EL2.
-			 *
-			 * MDCR_EL2.TDOSA: Set to zero so that Non-secure EL1
-			 *  System register accesses to the powerdown debug
-			 *  registers are not trapped to EL2.
-			 *
-			 * MDCR_EL2.TDA: Set to zero so that System register
-			 *  accesses to the debug registers do not trap to EL2.
-			 *
-			 * MDCR_EL2.TDE: Set to zero so that debug exceptions
-			 *  are not routed to EL2.
-			 *
-			 * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
-			 *  owning exception level is NS-EL1 and, tracing is
-			 *  prohibited at NS-EL2. These bits are RES0 when
-			 *  FEAT_TRBE is not implemented.
-			 */
-			mdcr_el2 = ((MDCR_EL2_RESET_VAL) & ~(MDCR_EL2_TTRF |
-				     MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
-				     MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
-				     MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1)));
-
-			write_mdcr_el2(mdcr_el2);
-
-			/*
-			 * Initialise HSTR_EL2. All fields are architecturally
-			 * UNKNOWN on reset.
-			 *
-			 * HSTR_EL2.T<n>: Set all these fields to zero so that
-			 *  Non-secure EL0 or EL1 accesses to System registers
-			 *  do not trap to EL2.
-			 */
-			write_hstr_el2(HSTR_EL2_RESET_VAL & ~(HSTR_EL2_T_MASK));
-			/*
-			 * Initialise CNTHP_CTL_EL2. All fields are
-			 * architecturally UNKNOWN on reset.
-			 *
-			 * CNTHP_CTL_EL2:ENABLE: Set to zero to disable the EL2
-			 *  physical timer and prevent timer interrupts.
-			 */
-			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
-						~(CNTHP_CTL_ENABLE_BIT));
-
-			manage_extensions_nonsecure_el2_unused();
+			init_nonsecure_el2_unused(ctx);
 		}
-		manage_extensions_nonsecure_mixed(el2_unused, ctx);
 	}
 
 	cm_el1_sysregs_context_restore(security_state);
@@ -965,6 +1002,89 @@
 		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
 		break;
 	}
+}
+
+/* -----------------------------------------------------
+ * The following registers are not added:
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * ICH_AP0R<n>_EL2
+ * ICH_AP1R<n>_EL2
+ * ICH_LR<n>_EL2
+ * -----------------------------------------------------
+ */
+static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
+{
+	write_ctx_reg(ctx, CTX_ACTLR_EL2, read_actlr_el2());
+	write_ctx_reg(ctx, CTX_AFSR0_EL2, read_afsr0_el2());
+	write_ctx_reg(ctx, CTX_AFSR1_EL2, read_afsr1_el2());
+	write_ctx_reg(ctx, CTX_AMAIR_EL2, read_amair_el2());
+	write_ctx_reg(ctx, CTX_CNTHCTL_EL2, read_cnthctl_el2());
+	write_ctx_reg(ctx, CTX_CNTVOFF_EL2, read_cntvoff_el2());
+	write_ctx_reg(ctx, CTX_CPTR_EL2, read_cptr_el2());
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_ctx_reg(ctx, CTX_DBGVCR32_EL2, read_dbgvcr32_el2());
+	}
+	write_ctx_reg(ctx, CTX_ELR_EL2, read_elr_el2());
+	write_ctx_reg(ctx, CTX_ESR_EL2, read_esr_el2());
+	write_ctx_reg(ctx, CTX_FAR_EL2, read_far_el2());
+	write_ctx_reg(ctx, CTX_HACR_EL2, read_hacr_el2());
+	write_ctx_reg(ctx, CTX_HCR_EL2, read_hcr_el2());
+	write_ctx_reg(ctx, CTX_HPFAR_EL2, read_hpfar_el2());
+	write_ctx_reg(ctx, CTX_HSTR_EL2, read_hstr_el2());
+	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+	write_ctx_reg(ctx, CTX_ICH_HCR_EL2, read_ich_hcr_el2());
+	write_ctx_reg(ctx, CTX_ICH_VMCR_EL2, read_ich_vmcr_el2());
+	write_ctx_reg(ctx, CTX_MAIR_EL2, read_mair_el2());
+	write_ctx_reg(ctx, CTX_MDCR_EL2, read_mdcr_el2());
+	write_ctx_reg(ctx, CTX_SCTLR_EL2, read_sctlr_el2());
+	write_ctx_reg(ctx, CTX_SPSR_EL2, read_spsr_el2());
+	write_ctx_reg(ctx, CTX_SP_EL2, read_sp_el2());
+	write_ctx_reg(ctx, CTX_TCR_EL2, read_tcr_el2());
+	write_ctx_reg(ctx, CTX_TPIDR_EL2, read_tpidr_el2());
+	write_ctx_reg(ctx, CTX_TTBR0_EL2, read_ttbr0_el2());
+	write_ctx_reg(ctx, CTX_VBAR_EL2, read_vbar_el2());
+	write_ctx_reg(ctx, CTX_VMPIDR_EL2, read_vmpidr_el2());
+	write_ctx_reg(ctx, CTX_VPIDR_EL2, read_vpidr_el2());
+	write_ctx_reg(ctx, CTX_VTCR_EL2, read_vtcr_el2());
+	write_ctx_reg(ctx, CTX_VTTBR_EL2, read_vttbr_el2());
+}
+
+static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
+{
+	write_actlr_el2(read_ctx_reg(ctx, CTX_ACTLR_EL2));
+	write_afsr0_el2(read_ctx_reg(ctx, CTX_AFSR0_EL2));
+	write_afsr1_el2(read_ctx_reg(ctx, CTX_AFSR1_EL2));
+	write_amair_el2(read_ctx_reg(ctx, CTX_AMAIR_EL2));
+	write_cnthctl_el2(read_ctx_reg(ctx, CTX_CNTHCTL_EL2));
+	write_cntvoff_el2(read_ctx_reg(ctx, CTX_CNTVOFF_EL2));
+	write_cptr_el2(read_ctx_reg(ctx, CTX_CPTR_EL2));
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_dbgvcr32_el2(read_ctx_reg(ctx, CTX_DBGVCR32_EL2));
+	}
+	write_elr_el2(read_ctx_reg(ctx, CTX_ELR_EL2));
+	write_esr_el2(read_ctx_reg(ctx, CTX_ESR_EL2));
+	write_far_el2(read_ctx_reg(ctx, CTX_FAR_EL2));
+	write_hacr_el2(read_ctx_reg(ctx, CTX_HACR_EL2));
+	write_hcr_el2(read_ctx_reg(ctx, CTX_HCR_EL2));
+	write_hpfar_el2(read_ctx_reg(ctx, CTX_HPFAR_EL2));
+	write_hstr_el2(read_ctx_reg(ctx, CTX_HSTR_EL2));
+	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+	write_ich_hcr_el2(read_ctx_reg(ctx, CTX_ICH_HCR_EL2));
+	write_ich_vmcr_el2(read_ctx_reg(ctx, CTX_ICH_VMCR_EL2));
+	write_mair_el2(read_ctx_reg(ctx, CTX_MAIR_EL2));
+	write_mdcr_el2(read_ctx_reg(ctx, CTX_MDCR_EL2));
+	write_sctlr_el2(read_ctx_reg(ctx, CTX_SCTLR_EL2));
+	write_spsr_el2(read_ctx_reg(ctx, CTX_SPSR_EL2));
+	write_sp_el2(read_ctx_reg(ctx, CTX_SP_EL2));
+	write_tcr_el2(read_ctx_reg(ctx, CTX_TCR_EL2));
+	write_tpidr_el2(read_ctx_reg(ctx, CTX_TPIDR_EL2));
+	write_ttbr0_el2(read_ctx_reg(ctx, CTX_TTBR0_EL2));
+	write_vbar_el2(read_ctx_reg(ctx, CTX_VBAR_EL2));
+	write_vmpidr_el2(read_ctx_reg(ctx, CTX_VMPIDR_EL2));
+	write_vpidr_el2(read_ctx_reg(ctx, CTX_VPIDR_EL2));
+	write_vtcr_el2(read_ctx_reg(ctx, CTX_VTCR_EL2));
+	write_vttbr_el2(read_ctx_reg(ctx, CTX_VTTBR_EL2));
 }
 
 /*******************************************************************************
@@ -990,7 +1110,7 @@
 
 		el2_sysregs_context_save_common(el2_sysregs_ctx);
 #if CTX_INCLUDE_MTE_REGS
-		el2_sysregs_context_save_mte(el2_sysregs_ctx);
+		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
 #endif
 		if (is_feat_mpam_supported()) {
 			el2_sysregs_context_save_mpam(el2_sysregs_ctx);
@@ -1079,7 +1199,7 @@
 
 		el2_sysregs_context_restore_common(el2_sysregs_ctx);
 #if CTX_INCLUDE_MTE_REGS
-		el2_sysregs_context_restore_mte(el2_sysregs_ctx);
+		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
 #endif
 		if (is_feat_mpam_supported()) {
 			el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
@@ -1149,23 +1269,15 @@
 void cm_prepare_el3_exit_ns(void)
 {
 #if CTX_INCLUDE_EL2_REGS
+#if ENABLE_ASSERTIONS
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
 	assert(ctx != NULL);
 
 	/* Assert that EL2 is used. */
-#if ENABLE_ASSERTIONS
-	el3_state_t *state = get_el3state_ctx(ctx);
-	u_register_t scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
-#endif
+	u_register_t scr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
 	assert(((scr_el3 & SCR_HCE_BIT) != 0UL) &&
 			(el_implemented(2U) != EL_IMPL_NONE));
-
-	/*
-	 * Currently some extensions are configured using
-	 * direct register updates. Therefore, do this here
-	 * instead of when setting up context.
-	 */
-	manage_extensions_nonsecure_mixed(0, ctx);
+#endif /* ENABLE_ASSERTIONS */
 
 	/*
 	 * Set the NS bit to be able to access the ICC_SRE_EL2
diff --git a/lib/el3_runtime/aarch64/cpu_data.S b/lib/el3_runtime/aarch64/cpu_data.S
index 2392d6b..313f882 100644
--- a/lib/el3_runtime/aarch64/cpu_data.S
+++ b/lib/el3_runtime/aarch64/cpu_data.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/el3_runtime/cpu_data_array.c b/lib/el3_runtime/cpu_data_array.c
index 13d464c..2056182 100644
--- a/lib/el3_runtime/cpu_data_array.c
+++ b/lib/el3_runtime/cpu_data_array.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index 03186d6..351a552 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/amu/aarch32/amu_helpers.S b/lib/extensions/amu/aarch32/amu_helpers.S
index 8ac7678..7090b2d 100644
--- a/lib/extensions/amu/aarch32/amu_helpers.S
+++ b/lib/extensions/amu/aarch32/amu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index c650629..8c5ef0b 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -188,95 +188,66 @@
  * Enable counters. This function is meant to be invoked by the context
  * management library before exiting from EL3.
  */
-void amu_enable(bool el2_unused, cpu_context_t *ctx)
+void amu_enable(cpu_context_t *ctx)
 {
-	uint64_t amcfgr_el0_ncg;		/* Number of counter groups */
-	uint64_t amcgcr_el0_cg0nc;		/* Number of group 0 counters */
-
-	uint64_t amcntenset0_el0_px = 0x0;	/* Group 0 enable mask */
-	uint64_t amcntenset1_el0_px = 0x0;	/* Group 1 enable mask */
-
-	if (el2_unused) {
-		/*
-		 * CPTR_EL2.TAM: Set to zero so any accesses to the Activity
-		 * Monitor registers do not trap to EL2.
-		 */
-		write_cptr_el2_tam(0U);
-	}
-
 	/*
-	 * Retrieve and update the CPTR_EL3 value from the context mentioned
-	 * in 'ctx'. Set CPTR_EL3.TAM to zero so that any accesses to
-	 * the Activity Monitor registers do not trap to EL3.
+	 * Set CPTR_EL3.TAM to zero so that any accesses to the Activity Monitor
+	 * registers do not trap to EL3.
 	 */
 	ctx_write_cptr_el3_tam(ctx, 0U);
 
-	/*
-	 * Retrieve the number of architected counters. All of these counters
-	 * are enabled by default.
-	 */
-
-	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
-	amcntenset0_el0_px = (UINT64_C(1) << (amcgcr_el0_cg0nc)) - 1U;
+	/* Initialize FEAT_AMUv1p1 features if present. */
+	if (is_feat_amuv1p1_supported()) {
+		/*
+		 * Set SCR_EL3.AMVOFFEN to one so that accesses to virtual
+		 * offset registers at EL2 do not trap to EL3
+		 */
+		ctx_write_scr_el3_amvoffen(ctx, 1U);
+	}
+}
 
-	assert(amcgcr_el0_cg0nc <= AMU_AMCGCR_CG0NC_MAX);
+void amu_init_el3(void)
+{
+	uint64_t group0_impl_ctr = read_amcgcr_el0_cg0nc();
+	uint64_t group0_en_mask = (1 << (group0_impl_ctr)) - 1U;
+	uint64_t num_ctr_groups = read_amcfgr_el0_ncg();
 
-	/*
-	 * The platform may opt to enable specific auxiliary counters. This can
-	 * be done via the common FCONF getter, or via the platform-implemented
-	 * function.
-	 */
+	/* Enable all architected counters by default */
+	write_amcntenset0_el0_px(group0_en_mask);
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
-	const struct amu_topology *topology;
+	if (num_ctr_groups > 0U) {
+		uint64_t amcntenset1_el0_px = 0x0; /* Group 1 enable mask */
+		const struct amu_topology *topology;
 
+		/*
+		 * The platform may opt to enable specific auxiliary counters.
+		 * This can be done via the common FCONF getter, or via the
+		 * platform-implemented function.
+		 */
 #if ENABLE_AMU_FCONF
-	topology = FCONF_GET_PROPERTY(amu, config, topology);
+		topology = FCONF_GET_PROPERTY(amu, config, topology);
 #else
-	topology = plat_amu_topology();
+		topology = plat_amu_topology();
 #endif /* ENABLE_AMU_FCONF */
 
-	if (topology != NULL) {
-		unsigned int core_pos = plat_my_core_pos();
+		if (topology != NULL) {
+			unsigned int core_pos = plat_my_core_pos();
 
-		amcntenset1_el0_px = topology->cores[core_pos].enable;
-	} else {
-		ERROR("AMU: failed to generate AMU topology\n");
-	}
-#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
-
-	/*
-	 * Enable the requested counters.
-	 */
-
-	write_amcntenset0_el0_px(amcntenset0_el0_px);
+			amcntenset1_el0_px = topology->cores[core_pos].enable;
+		} else {
+			ERROR("AMU: failed to generate AMU topology\n");
+		}
 
-	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
-	if (amcfgr_el0_ncg > 0U) {
 		write_amcntenset1_el0_px(amcntenset1_el0_px);
-
-#if !ENABLE_AMU_AUXILIARY_COUNTERS
+	}
+#else /* ENABLE_AMU_AUXILIARY_COUNTERS */
+	if (num_ctr_groups > 0U) {
 		VERBOSE("AMU: auxiliary counters detected but support is disabled\n");
-#endif
 	}
+#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
 
-	/* Initialize FEAT_AMUv1p1 features if present. */
 	if (is_feat_amuv1p1_supported()) {
-		if (el2_unused) {
-			/*
-			 * Make sure virtual offsets are disabled if EL2 not
-			 * used.
-			 */
-			write_hcr_el2_amvoffen(0U);
-		} else {
-			/*
-			 * Virtual offset registers are only accessible from EL3
-			 * and EL2, when clear, this bit traps accesses from EL2
-			 * so we set it to 1 when EL2 is present.
-			 */
-			ctx_write_scr_el3_amvoffen(ctx, 1U);
-		}
-
 #if AMU_RESTRICT_COUNTERS
 		/*
 		 * FEAT_AMUv1p1 adds a register field to restrict access to
@@ -297,6 +268,21 @@
 #endif
 }
 
+void amu_init_el2_unused(void)
+{
+	/*
+	 * CPTR_EL2.TAM: Set to zero so any accesses to the Activity Monitor
+	 *  registers do not trap to EL2.
+	 */
+	write_cptr_el2_tam(0U);
+
+	/* Initialize FEAT_AMUv1p1 features if present. */
+	if (is_feat_amuv1p1_supported()) {
+		/* Make sure virtual offsets are disabled if EL2 not used. */
+		write_hcr_el2_amvoffen(0U);
+	}
+}
+
 /* Read the group 0 counter identified by the given `idx`. */
 static uint64_t amu_group0_cnt_read(unsigned int idx)
 {
@@ -526,10 +512,10 @@
 
 	uint64_t hcr_el2_amvoffen = 0;	/* AMU virtual offsets enabled */
 
-	uint64_t amcfgr_el0_ncg;	/* Number of counter groups */
 	uint64_t amcgcr_el0_cg0nc;	/* Number of group 0 counters */
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
+	uint64_t amcfgr_el0_ncg;	/* Number of counter groups */
 	uint64_t amcgcr_el0_cg1nc;	/* Number of group 1 counters */
 	uint64_t amcg1idr_el0_voff;	/* Auxiliary counters with virtual offsets */
 #endif
@@ -541,7 +527,6 @@
 	core_pos = plat_my_core_pos();
 	ctx = &amu_ctxs_[core_pos];
 
-	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
 	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
 
 	if (is_feat_amuv1p1_supported()) {
@@ -549,22 +534,12 @@
 	}
 
 #if ENABLE_AMU_AUXILIARY_COUNTERS
+	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
 	amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U;
 	amcg1idr_el0_voff = (hcr_el2_amvoffen != 0U) ? read_amcg1idr_el0_voff() : 0U;
 #endif
 
 	/*
-	 * Sanity check that all counters were disabled when the context was
-	 * previously saved.
-	 */
-
-	assert(read_amcntenset0_el0_px() == 0U);
-
-	if (amcfgr_el0_ncg > 0U) {
-		assert(read_amcntenset1_el0_px() == 0U);
-	}
-
-	/*
 	 * Restore the counter values from the local context.
 	 */
 
diff --git a/lib/extensions/amu/aarch64/amu_helpers.S b/lib/extensions/amu/aarch64/amu_helpers.S
index 0f6d799..95d4ad6 100644
--- a/lib/extensions/amu/aarch64/amu_helpers.S
+++ b/lib/extensions/amu/aarch64/amu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/amu/amu_private.h b/lib/extensions/amu/amu_private.h
index eb7ff0e..a3b6845 100644
--- a/lib/extensions/amu/amu_private.h
+++ b/lib/extensions/amu/amu_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index 329cf98..37bd834 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,9 @@
 #include <arch.h>
 #include <arch_features.h>
 #include <arch_helpers.h>
+#include <lib/extensions/brbe.h>
 
-void brbe_enable(void)
+void brbe_init_el3(void)
 {
 	uint64_t val;
 
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index 62533fc..6462c97 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <arch_helpers.h>
 #include <lib/extensions/mpam.h>
 
-void mpam_enable(bool el2_unused)
+void mpam_init_el3(void)
 {
 	/*
 	 * Enable MPAM, and disable trapping to EL3 when lower ELs access their
@@ -19,15 +19,18 @@
 	 */
 	write_mpam3_el3(MPAM3_EL3_MPAMEN_BIT);
 
-	/*
-	 * If EL2 is implemented but unused, disable trapping to EL2 when lower
-	 * ELs access their own MPAM registers.
-	 */
-	if (el2_unused) {
-		write_mpam2_el2(0ULL);
+}
+
+/*
+ * If EL2 is implemented but unused, disable trapping to EL2 when lower ELs
+ * access their own MPAM registers.
+ */
+void mpam_init_el2_unused(void)
+{
+	write_mpam2_el2(0ULL);
 
-		if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
-			write_mpamhcr_el2(0ULL);
-		}
+	if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
+		write_mpamhcr_el2(0ULL);
 	}
+
 }
diff --git a/lib/extensions/pmuv3/aarch32/pmuv3.c b/lib/extensions/pmuv3/aarch32/pmuv3.c
index fe4205e..effb7e0 100644
--- a/lib/extensions/pmuv3/aarch32/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch32/pmuv3.c
@@ -29,7 +29,7 @@
  * Applies to all PMU versions. Name is PMUv3 for compatibility with aarch64 and
  * to not clash with platforms which reuse the PMU name
  */
-void pmuv3_disable_el3(void)
+void pmuv3_init_el3(void)
 {
 	u_register_t sdcr = read_sdcr();
 
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index f83a5ee..61fc47d 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -48,7 +48,7 @@
 	return mdcr_el3;
 }
 
-void pmuv3_disable_el3(void)
+void pmuv3_init_el3(void)
 {
 	u_register_t mdcr_el3 = read_mdcr_el3();
 
@@ -82,9 +82,12 @@
 	 *   0  |  1   |    enabled   | disabled
 	 *   1  |  1   |    enabled   | disabled only for counters 0 to
 	 *                              MDCR_EL2.HPMN - 1. Enabled for the rest
+	 *
+	 * MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
+	 *  accesses to all Performance Monitors registers do not trap to EL3.
 	 */
 	mdcr_el3 = (mdcr_el3 | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
-		  ~(MDCR_MPMX_BIT | MDCR_SPME_BIT);
+		  ~(MDCR_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
 	mdcr_el3 = mtpmu_disable_el3(mdcr_el3);
 	write_mdcr_el3(mdcr_el3);
 
diff --git a/lib/extensions/ras/ras_common.c b/lib/extensions/ras/ras_common.c
index 622879e..50f3727 100644
--- a/lib/extensions/ras/ras_common.c
+++ b/lib/extensions/ras/ras_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/lib/extensions/ras/std_err_record.c b/lib/extensions/ras/std_err_record.c
index c03fbbe..6c1dc9f 100644
--- a/lib/extensions/ras/std_err_record.c
+++ b/lib/extensions/ras/std_err_record.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 3423dba..d705b64 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -17,7 +17,6 @@
 void sme_enable(cpu_context_t *context)
 {
 	u_register_t reg;
-	u_register_t cptr_el3;
 	el3_state_t *state;
 
 	/* Get the context state. */
@@ -32,9 +31,14 @@
 	reg = read_ctx_reg(state, CTX_SCR_EL3);
 	reg |= SCR_ENTP2_BIT;
 	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
 
-	/* Set CPTR_EL3.ESM bit so we can write SMCR_EL3 without trapping. */
-	cptr_el3 = read_cptr_el3();
+void sme_init_el3(void)
+{
+	u_register_t cptr_el3 = read_cptr_el3();
+	u_register_t smcr_el3;
+
+	/* Set CPTR_EL3.ESM bit so we can access SMCR_EL3 without trapping. */
 	write_cptr_el3(cptr_el3 | ESM_BIT);
 	isb();
 
@@ -43,11 +47,10 @@
 	 * to be the least restrictive, then lower ELs can restrict as needed
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
-	reg = SMCR_ELX_LEN_MAX;
-
+	smcr_el3 = SMCR_ELX_LEN_MAX;
 	if (read_feat_sme_fa64_id_field() != 0U) {
 		VERBOSE("[SME] FA64 enabled\n");
-		reg |= SMCR_ELX_FA64_BIT;
+		smcr_el3 |= SMCR_ELX_FA64_BIT;
 	}
 
 	/*
@@ -58,15 +61,24 @@
 	 */
 	if (is_feat_sme2_supported()) {
 		VERBOSE("SME2 enabled\n");
-		reg |= SMCR_ELX_EZT0_BIT;
+		smcr_el3 |= SMCR_ELX_EZT0_BIT;
 	}
-	write_smcr_el3(reg);
+	write_smcr_el3(smcr_el3);
 
 	/* Reset CPTR_EL3 value. */
 	write_cptr_el3(cptr_el3);
 	isb();
 }
 
+void sme_init_el2_unused(void)
+{
+	/*
+	 * CPTR_EL2.TCPAC: Set to zero so that Non-secure EL1 accesses to the
+	 *  CPACR_EL1 or CPACR from both Execution states do not trap to EL2.
+	 */
+	write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TCPAC_BIT);
+}
+
 void sme_disable(cpu_context_t *context)
 {
 	u_register_t reg;
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index b1fe39f..2c25a9d 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,30 +21,18 @@
 	__asm__ volatile("hint #17");
 }
 
-void spe_enable(bool el2_unused)
+void spe_init_el3(void)
 {
 	uint64_t v;
 
-	if (el2_unused) {
-		/*
-		 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
-		 * profiling controls to EL2.
-		 *
-		 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
-		 * state. Accesses to profiling buffer controls at
-		 * Non-secure EL1 are not trapped to EL2.
-		 */
-		v = read_mdcr_el2();
-		v &= ~MDCR_EL2_TPMS;
-		v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
-		write_mdcr_el2(v);
-	}
-
 	/*
-	 * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
+	 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state
 	 * and disabled in secure state. Accesses to SPE registers at
 	 * S-EL1 generate trap exceptions to EL3.
 	 *
+	 * MDCR_EL3.NSPBE: Profiling Buffer uses Non-secure Virtual Addresses.
+	 * When FEAT_RME is not implemented, this field is RES0.
+	 *
 	 * MDCR_EL3.EnPMSN (ARM v8.7): Do not trap access to PMSNEVFR_EL1
 	 * register at NS-EL1 or NS-EL2 to EL3 if FEAT_SPEv1p2 is implemented.
 	 * Setting this bit to 1 doesn't have any effect on it when
@@ -52,9 +40,28 @@
 	 */
 	v = read_mdcr_el3();
 	v |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
+	v &= ~(MDCR_NSPBE_BIT);
 	write_mdcr_el3(v);
 }
 
+void spe_init_el2_unused(void)
+{
+	uint64_t v;
+
+	/*
+	 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
+	 * profiling controls to EL2.
+	 *
+	 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
+	 * state. Accesses to profiling buffer controls at
+	 * Non-secure EL1 are not trapped to EL2.
+	 */
+	v = read_mdcr_el2();
+	v &= ~MDCR_EL2_TPMS;
+	v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
+	write_mdcr_el2(v);
+}
+
 void spe_disable(void)
 {
 	uint64_t v;
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index f551ca7..eb4ac8d 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -37,6 +37,16 @@
 		(ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(SVE_VECTOR_LEN)));
 }
 
+void sve_init_el2_unused(void)
+{
+	/*
+	 * CPTR_EL2.TFP: Set to zero so that Non-secure accesses to Advanced
+	 *  SIMD and floating-point functionality from both Execution states do
+	 *  not trap to EL2.
+	 */
+	write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TFP_BIT);
+}
+
 void sve_disable(cpu_context_t *context)
 {
 	u_register_t reg;
diff --git a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
index b3f44b7..6da504e 100644
--- a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
+++ b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
@@ -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
  */
@@ -10,7 +10,7 @@
 #include <arch_helpers.h>
 #include <lib/extensions/sys_reg_trace.h>
 
-void sys_reg_trace_enable(void)
+void sys_reg_trace_init_el3(void)
 {
 	uint32_t val;
 
diff --git a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
index e61cb90..1349566 100644
--- a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
+++ b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
@@ -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
  */
@@ -12,15 +12,36 @@
 
 void sys_reg_trace_enable(cpu_context_t *ctx)
 {
-	uint64_t val;
+	/*
+	 * CPTR_EL3.TTA: Set to zero so that System register accesses to the
+	 *  trace registers do not trap to EL3.
+	 */
+	uint64_t val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+
+	val &= ~(TTA_BIT);
+	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
+}
 
-	/* Retrieve CPTR_EL3 value from the given context 'ctx',
-	 * and update CPTR_EL3.TTA bit to 0.
-	 * This function is called while switching context to NS to
-	 * allow system trace register access to NS-EL2 and NS-EL1
-	 * when NS-EL2 is implemented but not used.
+void sys_reg_trace_disable(cpu_context_t *ctx)
+{
+	/*
+	 * CPTR_EL3.TTA: Set to one so that System register accesses to the
+	 *  trace registers trap to EL3, unless it is trapped by CPACR.TRCDIS,
+	 *  CPACR_EL1.TTA, or CPTR_EL2.TTA
 	 */
-	val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
-	val &= ~TTA_BIT;
+	uint64_t val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+
+	val |= TTA_BIT;
 	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
 }
+
+void sys_reg_trace_init_el2_unused(void)
+{
+	/*
+	 * CPTR_EL2.TTA: Set to zero so that Non-secure System register accesses
+	 *  to the trace registers from both Execution states do not trap to
+	 *  EL2. If PE trace unit System registers are not implemented then this
+	 *  bit is reserved, and must be set to zero.
+	 */
+	write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TTA_BIT);
+}
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index fa139ca..d4fbdfb 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,21 +19,37 @@
 	__asm__ volatile("hint #18");
 }
 
-void trbe_enable(void)
+void trbe_init_el3(void)
 {
-	uint64_t val;
+	u_register_t val;
 
 	/*
+	 * MDCR_EL3.NSTBE = 0b0
+	 *  Trace Buffer owning Security state is Non-secure state. If FEAT_RME
+	 *  is not implemented, this field is RES0.
+	 *
 	 * MDCR_EL3.NSTB = 0b11
-	 * Allow access of trace buffer control registers from NS-EL1
-	 * and NS-EL2, tracing is prohibited in Secure and Realm state
-	 * (if implemented).
+	 *  Allow access of trace buffer control registers from NS-EL1 and
+	 *  NS-EL2, tracing is prohibited in Secure and Realm state (if
+	 *  implemented).
 	 */
 	val = read_mdcr_el3();
 	val |= MDCR_NSTB(MDCR_NSTB_EL1);
+	val &= ~(MDCR_NSTBE_BIT);
 	write_mdcr_el3(val);
 }
 
+void trbe_init_el2_unused(void)
+{
+	/*
+	 * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
+	 *  owning exception level is NS-EL1 and, tracing is
+	 *  prohibited at NS-EL2. These bits are RES0 when
+	 *  FEAT_TRBE is not implemented.
+	 */
+	write_mdcr_el2(read_mdcr_el2() & ~MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
+}
+
 static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
 {
 	if (is_feat_trbe_supported()) {
diff --git a/lib/extensions/trf/aarch32/trf.c b/lib/extensions/trf/aarch32/trf.c
index 0c63efa..321c089 100644
--- a/lib/extensions/trf/aarch32/trf.c
+++ b/lib/extensions/trf/aarch32/trf.c
@@ -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
  */
@@ -10,15 +10,15 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-void trf_enable(void)
+void trf_init_el3(void)
 {
 	uint32_t val;
 
 	/*
 	 * Allow access of trace filter control registers from
-	 * non-monitor mode
+	 * non-monitor mode.
 	 */
 	val = read_sdcr();
-	val &= ~SDCR_TTRF_BIT;
+	val &= ~(SDCR_TTRF_BIT);
 	write_sdcr(val);
 }
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index 941692b..83fbf85 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -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
  */
@@ -9,16 +9,32 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-void trf_enable(void)
+void trf_init_el3(void)
 {
-	uint64_t val;
+	u_register_t val;
 
 	/*
+	 * MDCR_EL3.STE = b0
+	 * Trace prohibited in Secure state unless overridden by the
+	 * IMPLEMENTATION DEFINED authentication interface.
+	 *
 	 * MDCR_EL3.TTRF = b0
 	 * Allow access of trace filter control registers from NS-EL2
 	 * and NS-EL1 when NS-EL2 is implemented but not used
 	 */
 	val = read_mdcr_el3();
-	val &= ~MDCR_TTRF_BIT;
+	val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
 	write_mdcr_el3(val);
 }
+
+void trf_init_el2_unused(void)
+{
+	/*
+	 * MDCR_EL2.TTRF: Set to zero so that access to Trace
+	 *  Filter Control register TRFCR_EL1 at EL1 is not
+	 *  trapped to EL2. This bit is RES0 in versions of
+	 *  the architecture earlier than ARMv8.4.
+	 *
+	 */
+	write_mdcr_el2(read_mdcr_el2() & ~MDCR_EL2_TTRF);
+}
diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c
index b1d6eaa..136e056 100644
--- a/lib/fconf/fconf.c
+++ b/lib/fconf/fconf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk
index fb88910..ff781aa 100644
--- a/lib/fconf/fconf.mk
+++ b/lib/fconf/fconf.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/libc/aarch64/setjmp.S b/lib/libc/aarch64/setjmp.S
index 9d9eb49..9cb31ea 100644
--- a/lib/libc/aarch64/setjmp.S
+++ b/lib/libc/aarch64/setjmp.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/abort.c b/lib/libc/abort.c
index 432b1d0..ac27f62 100644
--- a/lib/libc/abort.c
+++ b/lib/libc/abort.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/assert.c b/lib/libc/assert.c
index 8973ed5..301d142 100644
--- a/lib/libc/assert.c
+++ b/lib/libc/assert.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/exit.c b/lib/libc/exit.c
index f4ffe27..6de2e93 100644
--- a/lib/libc/exit.c
+++ b/lib/libc/exit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index 5eb8b52..95da68c 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2021, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/libc/memchr.c b/lib/libc/memchr.c
index 8cbb715..66d7ba1 100644
--- a/lib/libc/memchr.c
+++ b/lib/libc/memchr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/memcmp.c b/lib/libc/memcmp.c
index cd5f0df..db2701b 100644
--- a/lib/libc/memcmp.c
+++ b/lib/libc/memcmp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/memcpy.c b/lib/libc/memcpy.c
index 158df9b..af9ed45 100644
--- a/lib/libc/memcpy.c
+++ b/lib/libc/memcpy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/memcpy_s.c b/lib/libc/memcpy_s.c
index 01e88b0..26953bf 100644
--- a/lib/libc/memcpy_s.c
+++ b/lib/libc/memcpy_s.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/lib/libc/memmove.c b/lib/libc/memmove.c
index 63acf26..5c2b661 100644
--- a/lib/libc/memmove.c
+++ b/lib/libc/memmove.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/memset.c b/lib/libc/memset.c
index 17f798c..c5bac8d 100644
--- a/lib/libc/memset.c
+++ b/lib/libc/memset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
index faccfdf..6931a7e 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -36,7 +36,7 @@
 }
 
 static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
-			      char padc, int padn)
+			      char padc, int padn, bool uppercase)
 {
 	/* Just need enough space to store 64 bit decimal integer */
 	char num_buf[20];
@@ -51,10 +51,13 @@
 
 	do {
 		rem = unum % radix;
-		if (rem < 0xa)
+		if (rem < 0xa) {
 			num_buf[i] = '0' + rem;
-		else
+		} else if (uppercase) {
+			num_buf[i] = 'A' + (rem - 0xa);
+		} else {
 			num_buf[i] = 'a' + (rem - 0xa);
+		}
 		i++;
 		unum /= radix;
 	} while (unum > 0U);
@@ -105,8 +108,10 @@
 	char padc = '\0'; /* Padding character */
 	int padn; /* Number of characters to pad */
 	int count = 0; /* Number of printed characters */
+	bool uppercase; /* Print characters in uppercase */
 
 	while (*fmt != '\0') {
+		uppercase = false;
 		l_count = 0;
 		padn = 0;
 
@@ -129,7 +134,7 @@
 					unum = (unsigned long long int)num;
 
 				count += unsigned_num_print(unum, 10,
-							    padc, padn);
+							    padc, padn, uppercase);
 				break;
 			case 'c':
 				(void)putchar(va_arg(args, int));
@@ -147,12 +152,15 @@
 				}
 
 				count += unsigned_num_print(unum, 16,
-							    padc, padn);
+							    padc, padn, uppercase);
 				break;
+			case 'X':
+				uppercase = true;
+				// fall through
 			case 'x':
 				unum = get_unum_va_args(args, l_count);
 				count += unsigned_num_print(unum, 16,
-							    padc, padn);
+							    padc, padn, uppercase);
 				break;
 			case 'z':
 				if (sizeof(size_t) == 8U)
@@ -167,7 +175,7 @@
 			case 'u':
 				unum = get_unum_va_args(args, l_count);
 				count += unsigned_num_print(unum, 10,
-							    padc, padn);
+							    padc, padn, uppercase);
 				break;
 			case '0':
 				padc = '0';
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 340bdd8..1f919d1 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/puts.c b/lib/libc/puts.c
index 2a0ca11..f57fc98 100644
--- a/lib/libc/puts.c
+++ b/lib/libc/puts.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/strchr.c b/lib/libc/strchr.c
index d94bb9e..1cd03ca 100644
--- a/lib/libc/strchr.c
+++ b/lib/libc/strchr.c
@@ -30,7 +30,7 @@
  */
 
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/lib/libc/strcmp.c b/lib/libc/strcmp.c
index b742f9b..290db4c 100644
--- a/lib/libc/strcmp.c
+++ b/lib/libc/strcmp.c
@@ -33,7 +33,7 @@
  */
 
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/lib/libc/strlen.c b/lib/libc/strlen.c
index 3c27630..e4b79d9 100644
--- a/lib/libc/strlen.c
+++ b/lib/libc/strlen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/libc/strncmp.c b/lib/libc/strncmp.c
index ce9e5ed..f0bbadc 100644
--- a/lib/libc/strncmp.c
+++ b/lib/libc/strncmp.c
@@ -30,7 +30,7 @@
  */
 
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/lib/libc/strnlen.c b/lib/libc/strnlen.c
index b944e95..49e9f7a 100644
--- a/lib/libc/strnlen.c
+++ b/lib/libc/strnlen.c
@@ -27,7 +27,7 @@
  */
 
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
  * All rights reserved.
  */
 
diff --git a/lib/libfdt/libfdt.mk b/lib/libfdt/libfdt.mk
index 1cbbd78..812057d 100644
--- a/lib/libfdt/libfdt.mk
+++ b/lib/libfdt/libfdt.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/locks/bakery/bakery_lock_coherent.c b/lib/locks/bakery/bakery_lock_coherent.c
index 748eedd..bcd89ef 100644
--- a/lib/locks/bakery/bakery_lock_coherent.c
+++ b/lib/locks/bakery/bakery_lock_coherent.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index 3c03ae6..9f27322 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/lib/locks/exclusive/aarch32/spinlock.S b/lib/locks/exclusive/aarch32/spinlock.S
index 9492cc0..853d096 100644
--- a/lib/locks/exclusive/aarch32/spinlock.S
+++ b/lib/locks/exclusive/aarch32/spinlock.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/locks/exclusive/aarch64/spinlock.S b/lib/locks/exclusive/aarch64/spinlock.S
index e941b8a..5144bf7 100644
--- a/lib/locks/exclusive/aarch64/spinlock.S
+++ b/lib/locks/exclusive/aarch64/spinlock.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 6641db9..14f5533 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c
index ce2f0d9..bf0ad83 100644
--- a/lib/pmf/pmf_main.c
+++ b/lib/pmf/pmf_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/pmf/pmf_smc.c b/lib/pmf/pmf_smc.c
index 6d79502..71486df 100644
--- a/lib/pmf/pmf_smc.c
+++ b/lib/pmf/pmf_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psa/rss_platform.c b/lib/psa/rss_platform.c
index 359f894..7d90bfc 100644
--- a/lib/psa/rss_platform.c
+++ b/lib/psa/rss_platform.c
@@ -5,10 +5,9 @@
  *
  */
 
-#include <stdint.h>
-
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
+#include <rss_crypto_defs.h>
 #include <rss_platform_api.h>
 
 psa_status_t
@@ -41,3 +40,30 @@
 			RSS_PLATFORM_API_ID_NV_READ,
 			in_vec, 1, out_vec, 1);
 }
+
+psa_status_t
+rss_platform_key_read(enum rss_key_id_builtin_t key, uint8_t *data,
+		size_t data_size, size_t *data_length)
+{
+	psa_status_t status;
+
+	struct rss_crypto_pack_iovec iov = {
+		.function_id = RSS_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+		.key_id = key,
+	};
+
+	psa_invec in_vec[] = {
+		{.base = &iov, .len = sizeof(struct rss_crypto_pack_iovec)},
+	};
+	psa_outvec out_vec[] = {
+		{.base = data, .len = data_size}
+	};
+
+	status = psa_call(RSS_CRYPTO_HANDLE, PSA_IPC_CALL,
+			in_vec, IOVEC_LEN(in_vec),
+			out_vec, IOVEC_LEN(out_vec));
+
+	*data_length = out_vec[0].len;
+
+	return status;
+}
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index d28d469..4e1013c 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index 61f31e5..3b77ab2 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psci/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
index 8d46691..89e3e12 100644
--- a/lib/psci/aarch64/runtime_errata.S
+++ b/lib/psci/aarch64/runtime_errata.S
@@ -20,7 +20,7 @@
 	mov	x18, x0
 
 #if ERRATA_A510_2684597
-	bl errata_cortex_a510_2684597_wa
+	bl erratum_cortex_a510_2684597_wa
 #endif
 
 	ret	x19
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 8aa0cce..70bf77e 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1037,6 +1037,13 @@
 		psci_cpu_suspend_finish(cpu_idx, &state_info);
 
 	/*
+	 * Generic management: Now we just need to retrieve the
+	 * information that we had stashed away during the cpu_on
+	 * call to set this cpu on its way.
+	 */
+	cm_prepare_el3_exit_ns();
+
+	/*
 	 * Set the requested and target state of this CPU and all the higher
 	 * power domains which are ancestors of this CPU to run.
 	 */
diff --git a/lib/psci/psci_mem_protect.c b/lib/psci/psci_mem_protect.c
index 481051f..385dcd2 100644
--- a/lib/psci/psci_mem_protect.c
+++ b/lib/psci/psci_mem_protect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 76eb50c..31875ff 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -225,11 +225,4 @@
 	/* Populate the mpidr field within the cpu node array */
 	/* This needs to be done only once */
 	psci_cpu_pd_nodes[cpu_idx].mpidr = read_mpidr() & MPIDR_AFFINITY_MASK;
-
-	/*
-	 * Generic management: Now we just need to retrieve the
-	 * information that we had stashed away during the cpu_on
-	 * call to set this cpu on its way.
-	 */
-	cm_prepare_el3_exit_ns();
 }
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 1f93cc9..6bf1ff4 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index ecef95a..ad88d07 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index d93e60d..cb12b83 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -367,11 +367,4 @@
 	psci_set_suspend_pwrlvl(PSCI_INVALID_PWR_LVL);
 
 	PUBLISH_EVENT(psci_suspend_pwrdown_finish);
-
-	/*
-	 * Generic management: Now we just need to retrieve the
-	 * information that we had stashed away during the suspend
-	 * call to set this cpu on its way.
-	 */
-	cm_prepare_el3_exit_ns();
 }
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 2ff480b..c3ddc5a 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/romlib/gen_combined_bl1_romlib.sh b/lib/romlib/gen_combined_bl1_romlib.sh
index 1e3f73a..3941467 100755
--- a/lib/romlib/gen_combined_bl1_romlib.sh
+++ b/lib/romlib/gen_combined_bl1_romlib.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
diff --git a/lib/romlib/init.s b/lib/romlib/init.s
index 7d97e4d..2bea15b 100644
--- a/lib/romlib/init.s
+++ b/lib/romlib/init.s
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
index 33710f5..44751a2 100644
--- a/lib/romlib/jmptbl.i
+++ b/lib/romlib/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
index d54a684..0d076b4 100644
--- a/lib/romlib/romlib.ld.S
+++ b/lib/romlib/romlib.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/semihosting/aarch32/semihosting_call.S b/lib/semihosting/aarch32/semihosting_call.S
index aced3d1..42d4718 100644
--- a/lib/semihosting/aarch32/semihosting_call.S
+++ b/lib/semihosting/aarch32/semihosting_call.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/semihosting/aarch64/semihosting_call.S b/lib/semihosting/aarch64/semihosting_call.S
index 97d2bca..6f60f3e 100644
--- a/lib/semihosting/aarch64/semihosting_call.S
+++ b/lib/semihosting/aarch64/semihosting_call.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2014, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c
index 163a82d..adc6b78 100644
--- a/lib/semihosting/semihosting.c
+++ b/lib/semihosting/semihosting.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/stack_protector/aarch32/asm_stack_protector.S b/lib/stack_protector/aarch32/asm_stack_protector.S
index 19b7525..0ffcf8a 100644
--- a/lib/stack_protector/aarch32/asm_stack_protector.S
+++ b/lib/stack_protector/aarch32/asm_stack_protector.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/stack_protector/aarch64/asm_stack_protector.S b/lib/stack_protector/aarch64/asm_stack_protector.S
index c2245d3..a002617 100644
--- a/lib/stack_protector/aarch64/asm_stack_protector.S
+++ b/lib/stack_protector/aarch64/asm_stack_protector.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/stack_protector/stack_protector.c b/lib/stack_protector/stack_protector.c
index 3ff74fc..d0f2400 100644
--- a/lib/stack_protector/stack_protector.c
+++ b/lib/stack_protector/stack_protector.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/stack_protector/stack_protector.mk b/lib/stack_protector/stack_protector.mk
index b5aba15..4f13bc3 100644
--- a/lib/stack_protector/stack_protector.mk
+++ b/lib/stack_protector/stack_protector.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c
index fec086b..e9f0a12 100644
--- a/lib/utils/mem_region.c
+++ b/lib/utils/mem_region.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/aarch64/enable_mpu.S b/lib/xlat_mpu/aarch64/enable_mpu.S
index 3791f2d..0dda979 100644
--- a/lib/xlat_mpu/aarch64/enable_mpu.S
+++ b/lib/xlat_mpu/aarch64/enable_mpu.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
index 5068eb8..5a2120b 100644
--- a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
+++ b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/ro_xlat_mpu.mk b/lib/xlat_mpu/ro_xlat_mpu.mk
index 23f1d46..d3af3bd 100644
--- a/lib/xlat_mpu/ro_xlat_mpu.mk
+++ b/lib/xlat_mpu/ro_xlat_mpu.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, ARM Limited. All rights reserved.
+# Copyright (c) 2021, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/xlat_mpu/xlat_mpu.mk b/lib/xlat_mpu/xlat_mpu.mk
index 041b91c..31bef04 100644
--- a/lib/xlat_mpu/xlat_mpu.mk
+++ b/lib/xlat_mpu/xlat_mpu.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/xlat_mpu/xlat_mpu_context.c b/lib/xlat_mpu/xlat_mpu_context.c
index 28c463b..783f21d 100644
--- a/lib/xlat_mpu/xlat_mpu_context.c
+++ b/lib/xlat_mpu/xlat_mpu_context.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/xlat_mpu_core.c b/lib/xlat_mpu/xlat_mpu_core.c
index 6b4b0c2..33f381d 100644
--- a/lib/xlat_mpu/xlat_mpu_core.c
+++ b/lib/xlat_mpu/xlat_mpu_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/xlat_mpu_private.h b/lib/xlat_mpu/xlat_mpu_private.h
index e0e479d..14800e9 100644
--- a/lib/xlat_mpu/xlat_mpu_private.h
+++ b/lib/xlat_mpu/xlat_mpu_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_mpu/xlat_mpu_utils.c b/lib/xlat_mpu/xlat_mpu_utils.c
index 5400875..dc5f956 100644
--- a/lib/xlat_mpu/xlat_mpu_utils.c
+++ b/lib/xlat_mpu/xlat_mpu_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index 4b01b9b..6d098be 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index dc167e3..4dbfc11 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index e2c8370..8b44df2 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index 82bc70c..cfecc39 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables_v2/aarch32/enable_mmu.S b/lib/xlat_tables_v2/aarch32/enable_mmu.S
index f2fff36..22c2876 100644
--- a/lib/xlat_tables_v2/aarch32/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch32/enable_mmu.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index a1a44af..920754b 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S
index 9f075e4..247a796 100644
--- a/lib/xlat_tables_v2/aarch64/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index c847a9e..bb6a35c 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -27,16 +27,14 @@
 	if (size == PAGE_SIZE_4KB) {
 		tgranx = read_id_aa64mmfr0_el0_tgran4_field();
 		/* MSB of TGRAN4 field will be '1' for unsupported feature */
-		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED) &&
-			(tgranx < 8U));
+		return (tgranx < 8U);
 	} else if (size == PAGE_SIZE_16KB) {
 		tgranx = read_id_aa64mmfr0_el0_tgran16_field();
 		return (tgranx >= ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED);
 	} else if (size == PAGE_SIZE_64KB) {
 		tgranx = read_id_aa64mmfr0_el0_tgran64_field();
 		/* MSB of TGRAN64 field will be '1' for unsupported feature */
-		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED) &&
-			(tgranx < 8U));
+		return (tgranx < 8U);
 	} else {
 		return false;
 	}
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
index fb8a426..20bb015 100644
--- a/lib/xlat_tables_v2/ro_xlat_tables.mk
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020-2022, ARM Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index bcc3e68..b4ad34b 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index 95dae88..2fbbc78 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/zlib/tf_gunzip.c b/lib/zlib/tf_gunzip.c
index 3ac80bc..8b8d14d 100644
--- a/lib/zlib/tf_gunzip.c
+++ b/lib/zlib/tf_gunzip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/lib/zlib/zlib.mk b/lib/zlib/zlib.mk
index 98d4efa..a8937a7 100644
--- a/lib/zlib/zlib.mk
+++ b/lib/zlib/zlib.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 3bce3a5..a5c93a6 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -334,10 +334,10 @@
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
-$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS))
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
 	$$(ECHO) "  CC      $$<"
@@ -357,10 +357,10 @@
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
-$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS))
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
 	$$(ECHO) "  AS      $$<"
@@ -379,9 +379,9 @@
 
 $(eval DEP := $(1).d)
 
-$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
+$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
 
 $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
 	$$(ECHO) "  PP      $$<"
@@ -504,7 +504,7 @@
 define MAKE_BL
         $(eval BUILD_DIR  := ${BUILD_PLAT}/$(1))
         $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
-        $(eval SOURCES    := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
+        $(eval SOURCES    := $(sort $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
         $(eval ELF        := $(call IMG_ELF,$(1)))
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index f9077eb..964e0f9 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -191,6 +191,9 @@
 # Flag to enable access to Guarded Control Stack (FEAT_GCS)
 ENABLE_FEAT_GCS			:= 0
 
+# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
+ENABLE_FEAT_MTE_PERM		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -505,3 +508,6 @@
 # Check platform if cache management operations should be performed.
 # Disabled by default.
 CONDITIONAL_CMO			:= 0
+
+# By default, disable SPMD Logical partitions
+ENABLE_SPMD_LP			:= 0
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
new file mode 100644
index 0000000..2417709
--- /dev/null
+++ b/make_helpers/march.mk
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This build helper makefile is used to determine a suitable march build
+# option to be used, based on platform provided ARM_ARCH_MAJOR/MINOR
+# data and compiler supported march version.
+
+# Set the compiler's target architecture profile based on
+# ARM_ARCH_MAJOR and ARM_ARCH_MINOR options.
+
+
+# This is used to collect available march values from compiler.
+# Example on a gcc-12.2 arm64 toolchain it will look like:
+# [...]
+#./aarch64-none-elf-gcc --target-help -march=foo
+# cc1: error: unknown value 'foo' for '-march'
+# cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a
+# armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
+# [...]
+#
+GCC_MARCH_OUTPUT := $(shell $(CC) -march=foo -Q --help=target -v 2>&1)
+
+# This function is used to find the best march value supported by the given compiler.
+# We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
+# to find armvX.Y-a or armvX-a values, then filter the best supported arch based on ARM_ARCH_MAJOR.
+#
+# Example on a gcc-12.2 arm64 toolchain this will return armv9-a if platform requested for armv9.2-a
+# Similarly on gcc 11.3 it would return armv8.6-a if platform requested armv8.8-a
+define major_best_avail_march
+$(1) := $(lastword $(filter armv$(ARM_ARCH_MAJOR)% ,$(filter armv%-a, $(GCC_MARCH_OUTPUT))))
+endef
+
+# This function is used to just return latest march value supported by the given compiler.
+#
+# Example: this would return armv8.6-a on a gcc-11.3 when platform requested for armv9.0-a
+#
+# Thus this function should be used in conjunction with major_best_avail_march, when best match
+# is not found it should be ok to try with lastest known supported march value from the
+# compiler.
+define latest_match_march
+$(1) := $(lastword $(filter armv%-a, $(GCC_MARCH_OUTPUT)))
+endef
+
+ifdef MARCH_DIRECTIVE
+    march-directive		:= $(MARCH_DIRECTIVE)
+else
+
+ifeq (${ARM_ARCH_MINOR},0)
+    provided-march = armv${ARM_ARCH_MAJOR}-a
+else
+    provided-march = armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+endif
+
+ifeq ($(findstring clang,$(notdir $(CC))),)
+
+# We expect from Platform to provide a correct Major/Minor value but expecting something
+# from compiler with unsupported march means we shouldn't fail without trying anything,
+# so here we try to find best supported march value and use that for compilation.
+# If we don't support current march version from gcc compiler, try with lower arch based on
+# availability. In TF-A there is no hard rule for need of higher version march for basic
+# functionality, denying a build on only this fact doesn't look correct, so try with best
+# or latest march values from whats available from compiler.
+ifeq (,$(findstring $(provided-march), $(GCC_MARCH_OUTPUT)))
+    $(eval $(call major_best_avail_march, available-march))
+
+ifeq (, $(available-march))
+    $(eval $(call latest_match_march, available-march))
+endif
+
+# If we fail to come up with any available-march value so far, don't update
+# provided-march and thus allow the build to fail using the provided-march
+# which is derived based on arch_major and arch_minor values.
+ifneq (,$(available-march))
+    provided-march := ${available-march}
+endif
+
+endif # provided-march supported
+endif # not clang
+
+march-directive := -march=${provided-march}
+
+endif # MARCH_DIRECTIVE
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index a3351eb..3a2c53f 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -118,8 +118,10 @@
 ifeq (${NEED_BL32},yes)
     $(if ${BL32_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL32_KEY},--tos-fw-key)))
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tos_fw_content.crt,--tos-fw-cert))
+ifneq (${COT},cca)
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tos_fw_key.crt,--tos-fw-key-cert))
 endif
+endif
 
 # Add the BL33 CoT (key cert + img cert)
 ifneq (${BL33},)
diff --git a/package-lock.json b/package-lock.json
index 89ebd51..e23f9a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3894,9 +3894,9 @@
       }
     },
     "node_modules/word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+      "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -4022,7 +4022,7 @@
       }
     },
     "tools/conventional-changelog-tf-a": {
-      "version": "2.7.0",
+      "version": "2.9.0",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
@@ -6978,9 +6978,9 @@
       }
     },
     "word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+      "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
       "dev": true
     },
     "wordwrap": {
diff --git a/plat/allwinner/common/sunxi_scpi_pm.c b/plat/allwinner/common/sunxi_scpi_pm.c
index 41dc563..6a0e967 100644
--- a/plat/allwinner/common/sunxi_scpi_pm.c
+++ b/plat/allwinner/common/sunxi_scpi_pm.c
@@ -125,6 +125,32 @@
 	psci_power_down_wfi();
 }
 
+static int sunxi_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
+{
+	uint32_t ret;
+
+	if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET))
+		return PSCI_E_NOT_SUPPORTED;
+
+	gicv2_cpuif_disable();
+
+	/* Send the system reset request to the SCP. */
+	ret = scpi_sys_power_state(scpi_system_reset);
+	if (ret != SCP_OK) {
+		ERROR("PSCI: SCPI %s failed: %d\n", "reset", ret);
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	psci_power_down_wfi();
+
+	/*
+	 * Should not reach here.
+	 * However sunxi_system_reset2 has to return some value
+	 * according to PSCI v1.1 spec.
+	 */
+	return PSCI_E_SUCCESS;
+}
+
 static int sunxi_validate_power_state(unsigned int power_state,
 				      psci_power_state_t *req_state)
 {
@@ -177,6 +203,7 @@
 	.pwr_domain_suspend_finish	= sunxi_pwr_domain_on_finish,
 	.system_off			= sunxi_system_off,
 	.system_reset			= sunxi_system_reset,
+	.system_reset2			= sunxi_system_reset2,
 	.validate_power_state		= sunxi_validate_power_state,
 	.validate_ns_entrypoint		= sunxi_validate_ns_entrypoint,
 	.get_sys_suspend_power_state	= sunxi_get_sys_suspend_power_state,
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 6fcf080..3ed7a63 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -98,6 +98,10 @@
 
 NEED_BL32 := yes
 
+ifeq (${AARCH32_SP},none)
+    $(error Variable AARCH32_SP has to be set for AArch32)
+endif
+
 MULTI_CONSOLE_API		:=	1
 
 ARM_DISABLE_TRUSTED_WDOG	:=	1
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index c9425c5..bd56f30 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -33,7 +33,17 @@
 FPGA_PRELOADED_CMD_LINE := 0x1000
 $(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
 
-ENABLE_FEAT_AMU		:=	2
+ENABLE_BRBE_FOR_NS		:= 2
+ENABLE_TRBE_FOR_NS		:= 2
+ENABLE_FEAT_AMU			:= 2
+ENABLE_FEAT_AMUv1p1		:= 2
+ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_ECV			:= 2
+ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_HCX			:= 2
+ENABLE_MPAM_FOR_LOWER_ELS	:= 2
+ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
+ENABLE_TRF_FOR_NS		:= 2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -60,7 +70,6 @@
 # AArch64-only cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a510.S			\
 				lib/cpus/aarch64/cortex_a520.S			\
-				lib/cpus/aarch64/cortex_a710.S			\
 				lib/cpus/aarch64/cortex_a715.S			\
 				lib/cpus/aarch64/cortex_a720.S			\
 				lib/cpus/aarch64/cortex_x3.S 			\
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index 75833f6..d6d3bef 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,6 +25,10 @@
 
 NEED_BL32		:=	yes
 
+ifeq (${AARCH32_SP},none)
+    $(error Variable AARCH32_SP has to be set for AArch32)
+endif
+
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
 
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 72fdfef..dc95ba1 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <drivers/measured_boot/event_log/event_log.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
 #include <plat/arm/common/plat_arm.h>
+#include <tools_share/zero_oid.h>
 
 /* Event Log data */
 static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
@@ -31,18 +32,21 @@
 		.slot = U(6),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = TB_FW_CONFIG_ID,
 		.slot = U(7),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = BL2_IMAGE_ID,
 		.slot = U(8),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_BL2_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 
 	{
@@ -54,7 +58,7 @@
 	event_log_init(event_log, event_log + sizeof(event_log));
 	event_log_write_header();
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index e6b9192..349e064 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -9,7 +9,11 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/measured_boot/event_log/event_log.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
+#if defined(ARM_COT_cca)
+#include <tools_share/cca_oid.h>
+#else
 #include <tools_share/tbbr_oid.h>
+#endif /* ARM_COT_cca */
 #include <fvp_critical_data.h>
 
 #include <plat/arm/common/plat_arm.h>
@@ -62,25 +66,31 @@
 		.slot = U(9),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_BL31_STRING,
+		.pk_oid = BL31_IMAGE_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = HW_CONFIG_ID,
 		.slot = U(10),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+		.pk_oid = HW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = SOC_FW_CONFIG_ID,
 		.slot = U(11),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
+#if ENABLE_RME
 	{
 		.id = RMM_IMAGE_ID,
 		.slot = U(12),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_RMM_STRING,
+		.pk_oid = RMM_IMAGE_KEY_OID,
 		.lock_measurement = true },
+#endif /* ENABLE_RME */
 	{
 		.id = RSS_MBOOT_INVALID_ID }
 };
@@ -117,7 +127,7 @@
 
 	event_log_init((uint8_t *)event_log_start, event_log_finish);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 int plat_mboot_measure_critical_data(unsigned int critical_data_id,
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index b5b8f10..0c1d5e7 100644
--- a/plat/arm/board/fvp/fvp_common_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_common_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,11 +16,6 @@
 extern event_log_metadata_t fvp_event_log_metadata[];
 extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
 
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
-{
-	return fvp_rss_mboot_metadata;
-}
-
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
@@ -38,7 +33,8 @@
 	}
 
 	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(image_data->image_base,
+	err = rss_mboot_measure_and_record(fvp_rss_mboot_metadata,
+					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
@@ -49,3 +45,10 @@
 
 	return rc;
 }
+
+int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+			   size_t pk_len)
+{
+	return rss_mboot_set_signer_id(fvp_rss_mboot_metadata, pk_oid, pk_ptr,
+				       pk_len);
+}
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
index 944571d..b8fa4ea 100644
--- a/plat/arm/board/fvp/fvp_cpu_errata.mk
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -30,6 +30,7 @@
 CORTEX_A77_H_INC	:= 1
 CORTEX_A78_H_INC	:= 1
 NEOVERSE_N1_H_INC	:= 1
+NEOVERSE_N2_H_INC	:= 1
 NEOVERSE_V1_H_INC	:= 1
 CORTEX_A78_AE_H_INC	:= 1
 CORTEX_A510_H_INC	:= 1
@@ -41,6 +42,7 @@
 $(eval $(call add_define, CORTEX_A77_H_INC))
 $(eval $(call add_define, CORTEX_A78_H_INC))
 $(eval $(call add_define, NEOVERSE_N1_H_INC))
+$(eval $(call add_define, NEOVERSE_N2_H_INC))
 $(eval $(call add_define, NEOVERSE_V1_H_INC))
 $(eval $(call add_define, CORTEX_A78_AE_H_INC))
 $(eval $(call add_define, CORTEX_A510_H_INC))
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index b8c97f8..534a175 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -393,6 +393,10 @@
 
 	for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
 		req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
+
+#if PSCI_OS_INIT_MODE
+	req_state->last_at_pwrlvl = PLAT_MAX_PWR_LVL;
+#endif
 }
 #endif
 
diff --git a/plat/arm/board/fvp/fvp_spmd_logical_sp.c b/plat/arm/board/fvp/fvp_spmd_logical_sp.c
new file mode 100644
index 0000000..37b4466
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_spmd_logical_sp.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <services/el3_spmd_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <smccc_helpers.h>
+
+#define SPMD_LP_PARTITION_ID SPMD_LP_ID_START
+#define SPMD_LP_UUID {0xe98e43ad, 0xb7db524f, 0x47a3bf57, 0x1588f4e3}
+
+/* SPMD Logical SP currently only supports sending direct message. */
+#define SPMD_PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_SEND
+
+#define SPMD_LP_MAX_SUPPORTED_SP 10
+static void fvp_get_partition_info(void)
+{
+	struct ffa_value ret = { 0 };
+	uint32_t target_uuid[4] = { 0 };
+	static struct ffa_partition_info_v1_1
+		part_info[SPMD_LP_MAX_SUPPORTED_SP] = { 0 };
+
+	uint16_t num_partitions = 0;
+
+	if (!spmd_el3_invoke_partition_info_get(target_uuid, 0, 0, &ret)) {
+		panic();
+	}
+
+	if (is_ffa_error(&ret)) {
+		panic();
+	}
+
+	num_partitions = ffa_partition_info_regs_get_last_idx(ret) + 1;
+	if (num_partitions > SPMD_LP_MAX_SUPPORTED_SP) {
+		panic();
+	}
+
+	INFO("Number of secure partitions = %d\n", num_partitions);
+
+	for (uint16_t i = 0; i < num_partitions; i++) {
+		INFO("***Start Partition***\n");
+		if (!ffa_partition_info_regs_get_part_info(ret, i, &part_info[i]))
+			panic();
+		INFO("\tPartition ID: 0x%x\n", part_info[i].ep_id);
+		INFO("\tvCPU count:0x%x\n", part_info[i].execution_ctx_count);
+		INFO("\tProperties: 0x%x\n", part_info[i].properties);
+		INFO("\tUUID: 0x%x 0x%x 0x%x 0x%x\n", part_info[i].uuid[0],
+				part_info[i].uuid[1], part_info[i].uuid[2],
+				part_info[i].uuid[3]);
+		INFO("***End Partition***\n");
+	}
+
+}
+
+static int32_t fvp_spmd_logical_partition_init(void)
+{
+	INFO("FVP SPMD LSP: Init function called.\n");
+
+	fvp_get_partition_info();
+	return 0;
+}
+
+/*
+ * Platform specific SMC handler used to translate SIP SMCs or other platform
+ * specific SMCs into FF-A direct messages.
+ */
+uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
+			u_register_t x1,
+			u_register_t x2,
+			u_register_t x3,
+			u_register_t x4,
+			void *cookie,
+			void *handle,
+			u_register_t flags)
+{
+	struct ffa_value retval = { 0 };
+	uint64_t send_recv_id = SPMD_LP_PARTITION_ID << 16 | 0x8001;
+
+	/*
+	 * Forward the SMC as direct request.
+	 */
+	if (!spmd_el3_ffa_msg_direct_req(send_recv_id, x2, x3, x4, handle, &retval)) {
+		panic();
+	}
+
+	SMC_RET8(handle, retval.func, retval.arg1, retval.arg2, retval.arg3,
+			retval.arg4, retval.arg5, retval.arg6, retval.arg7);
+}
+
+/* Register SPMD logical partition  */
+DECLARE_SPMD_LOGICAL_PARTITION(
+	fvp_spmd_logical_partition,
+	fvp_spmd_logical_partition_init,/* Init Function */
+	SPMD_LP_PARTITION_ID,		/* FF-A Partition ID */
+	SPMD_LP_UUID,			/* UUID */
+	SPMD_PARTITION_PROPERTIES	/* Partition Properties. */
+);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 99dd6c7..d9fe24f 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -168,8 +168,8 @@
 #  define MAX_XLAT_TABLES		6
 # endif
 #elif !USE_ROMLIB
-# define PLAT_ARM_MMAP_ENTRIES		11
-# define MAX_XLAT_TABLES		5
+# define PLAT_ARM_MMAP_ENTRIES		12
+# define MAX_XLAT_TABLES		6
 #else
 # define PLAT_ARM_MMAP_ENTRIES		12
 # if (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) && \
@@ -205,14 +205,18 @@
 #endif
 
 /*
- * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth.
+ * Set the maximum size of BL2 to be close to half of the Trusted SRAM.
+ * Maximum size of BL2 increases as Trusted SRAM size increases.
  */
 #if CRYPTO_SUPPORT
 #if (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) || COT_DESC_IN_DTB
-# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+# define PLAT_ARM_MAX_BL2_SIZE	((PLAT_ARM_TRUSTED_SRAM_SIZE / 2) - \
+				 (2 * PAGE_SIZE) - \
+				 FVP_BL2_ROMLIB_OPTIMIZATION)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+# define PLAT_ARM_MAX_BL2_SIZE	((PLAT_ARM_TRUSTED_SRAM_SIZE / 2) - \
+				 (3 * PAGE_SIZE) - \
+				 FVP_BL2_ROMLIB_OPTIMIZATION)
 #endif
 #elif ARM_BL31_IN_DRAM
 /* When ARM_BL31_IN_DRAM is set, BL2 can use almost all of Trusted SRAM. */
@@ -433,7 +437,12 @@
 /*
  * Maximum size of Event Log buffer used in Measured Boot Event Log driver
  */
+#if ENABLE_RME && (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd))
+/* Account for additional measurements of secure partitions and SPM. */
+#define	PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x800)
+#else
 #define	PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x400)
+#endif
 
 /*
  * Maximum size of Event Log buffer used for DRTM
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 436cab3..4803f35 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -80,6 +80,7 @@
 ENABLE_FEAT_CSV2_2		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
+ENABLE_FEAT_MTE_PERM		:= 2
 ENABLE_FEAT_VHE			:= 2
 CTX_INCLUDE_NEVE_REGS		:= 2
 ENABLE_FEAT_SEL2		:= 2
@@ -212,7 +213,9 @@
 					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
-					lib/cpus/aarch64/cortex_x2.S
+					lib/cpus/aarch64/cortex_x2.S		\
+					lib/cpus/aarch64/cortex_gelas.S		\
+					lib/cpus/aarch64/nevis.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
@@ -221,7 +224,8 @@
 
 else
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S			\
-				lib/cpus/aarch32/cortex_a57.S
+				lib/cpus/aarch32/cortex_a57.S			\
+				lib/cpus/aarch32/cortex_a53.S
 endif
 
 BL1_SOURCES		+=	drivers/arm/smmu/smmu_v3.c			\
@@ -404,10 +408,6 @@
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_stack_protector.c
 endif
 
-ifeq (${ARCH},aarch32)
-    NEED_BL32 := yes
-endif
-
 # Enable the dynamic translation tables library.
 ifeq ($(filter 1,${RESET_TO_BL2} ${ARM_XLAT_TABLES_LIB_V1}),)
     ifeq (${ARCH},aarch32)
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index f7eace8..79cf356 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -96,6 +96,10 @@
 
 NEED_BL32 := yes
 
+ifeq (${AARCH32_SP},none)
+    $(error Variable AARCH32_SP has to be set for AArch32)
+endif
+
 # Modification of arm_common.mk
 
 # Process ARM_DISABLE_TRUSTED_WDOG flag
diff --git a/plat/arm/board/juno/cert_create_tbbr.mk b/plat/arm/board/juno/cert_create_tbbr.mk
index c092fe0..4d133b2 100644
--- a/plat/arm/board/juno/cert_create_tbbr.mk
+++ b/plat/arm/board/juno/cert_create_tbbr.mk
@@ -7,7 +7,7 @@
 PLAT_DEF_OID := 1
 
 ifeq (${PLAT_DEF_OID},1)
-  ifeq (${ARM_ETHOSN_NPU_DRIVER},1)
+  ifeq (${ETHOSN_NPU_DRIVER},1)
     $(eval $(call add_define, PLAT_DEF_OID))
     $(eval $(call add_define, PDEF_CERTS))
     $(eval $(call add_define, PDEF_EXTS))
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
index 986299e..ec72160 100644
--- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
@@ -51,10 +51,10 @@
 			tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d";
 			nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7";
 			plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f";
-#if ARM_ETHOSN_NPU_TZMP1
-			arm_ethosn_npu_fw_uuid = "cfd499b5-a3bc-4a7e-98cb-48a41cb8dae1";
-			arm_ethosn_npu_fw_key_cert_uuid = "5666d004-ab98-40aa-8988-b72a03a256e2";
-			arm_ethosn_npu_fw_content_cert_uuid = "a5c418da-430f-48b1-88cd-93f67889d9ed";
+#if ETHOSN_NPU_TZMP1
+			ethosn_npu_fw_uuid = "cfd499b5-a3bc-4a7e-98cb-48a41cb8dae1";
+			ethosn_npu_fw_key_cert_uuid = "5666d004-ab98-40aa-8988-b72a03a256e2";
+			ethosn_npu_fw_content_cert_uuid = "a5c418da-430f-48b1-88cd-93f67889d9ed";
 #endif
 		};
 	};
diff --git a/plat/arm/board/juno/fip/plat_def_fip_uuid.h b/plat/arm/board/juno/fip/plat_def_fip_uuid.h
index 0f0d11d..46adf24 100644
--- a/plat/arm/board/juno/fip/plat_def_fip_uuid.h
+++ b/plat/arm/board/juno/fip/plat_def_fip_uuid.h
@@ -7,8 +7,8 @@
 #ifndef PLAT_DEF_FIP_UUID_H
 #define PLAT_DEF_FIP_UUID_H
 
-#ifdef ARM_ETHOSN_NPU_TZMP1
+#ifdef ETHOSN_NPU_TZMP1
 #include <drivers/arm/ethosn_fip.h>
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 #endif /* PLAT_DEF_FIP_UUID_H */
diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/plat/arm/board/juno/fip/plat_def_uuid_config.c
index 8133927..705a8ca 100644
--- a/plat/arm/board/juno/fip/plat_def_uuid_config.c
+++ b/plat/arm/board/juno/fip/plat_def_uuid_config.c
@@ -12,11 +12,11 @@
 #include "plat_def_fip_uuid.h"
 
 toc_entry_t plat_def_toc_entries[] = {
-#ifdef ARM_ETHOSN_NPU_TZMP1
+#ifdef ETHOSN_NPU_TZMP1
 	ETHOSN_FW_KEY_CERTIFICATE_DEF,
 	ETHOSN_FW_CONTENT_CERTIFICATE_DEF,
 	ETHOSN_FW_DEF,
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 	{
 		.name = NULL,
 		.uuid = { { 0 } },
diff --git a/plat/arm/board/juno/include/plat_tbbr_img_def.h b/plat/arm/board/juno/include/plat_tbbr_img_def.h
index 3e17ed3..5fbeb4e 100644
--- a/plat/arm/board/juno/include/plat_tbbr_img_def.h
+++ b/plat/arm/board/juno/include/plat_tbbr_img_def.h
@@ -7,12 +7,12 @@
 #ifndef JUNO_IMG_DEF_H
 #define JUNO_IMG_DEF_H
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 /* Arm(R) Ethos(TM)-N NPU images */
-#define ARM_ETHOSN_NPU_FW_KEY_CERT_ID		U(MAX_IMG_IDS_WITH_SPMDS + 1)
-#define ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID	U(MAX_IMG_IDS_WITH_SPMDS + 2)
-#define ARM_ETHOSN_NPU_FW_IMAGE_ID		U(MAX_IMG_IDS_WITH_SPMDS + 3)
+#define ETHOSN_NPU_FW_KEY_CERT_ID		U(MAX_IMG_IDS_WITH_SPMDS + 1)
+#define ETHOSN_NPU_FW_CONTENT_CERT_ID		U(MAX_IMG_IDS_WITH_SPMDS + 2)
+#define ETHOSN_NPU_FW_IMAGE_ID			U(MAX_IMG_IDS_WITH_SPMDS + 3)
 #define MAX_NUMBER_IDS				U(MAX_IMG_IDS_WITH_SPMDS + 4)
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 #endif	/* JUNO_IMG_DEF_H */
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 47258cb..aa96038 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -327,15 +327,15 @@
 
 /* Protected NSAIDs and memory regions for the Arm(R) Ethos(TM)-N NPU driver */
 #ifdef JUNO_ETHOSN_TZMP1
-#define ARM_ETHOSN_NPU_PROT_FW_NSAID		JUNO_ETHOSN_TZC400_NSAID_FW_PROT
-#define ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID	JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT
-#define ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID	JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT
+#define ETHOSN_NPU_PROT_FW_NSAID		JUNO_ETHOSN_TZC400_NSAID_FW_PROT
+#define ETHOSN_NPU_PROT_RW_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT
+#define ETHOSN_NPU_PROT_RO_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT
 
-#define ARM_ETHOSN_NPU_NS_RW_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS
-#define ARM_ETHOSN_NPU_NS_RO_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS
+#define ETHOSN_NPU_NS_RW_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS
+#define ETHOSN_NPU_NS_RO_DATA_NSAID		JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS
 
-#define ARM_ETHOSN_NPU_FW_IMAGE_BASE		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE
-#define ARM_ETHOSN_NPU_FW_IMAGE_LIMIT \
+#define ETHOSN_NPU_FW_IMAGE_BASE		JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE
+#define ETHOSN_NPU_FW_IMAGE_LIMIT \
 	(JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE)
 #endif
 
diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
index d48d2e6..8930dbb 100644
--- a/plat/arm/board/juno/juno_tbbr_cot_bl2.c
+++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
@@ -32,9 +32,9 @@
 #if defined(SPD_spmd)
 static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
 #endif /* SPD_spmd */
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 static unsigned char npu_fw_image_hash_buf[HASH_DER_LEN];
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#endif /* ETHOSN_NPU_TZMP1 */
 
 
 static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
@@ -87,12 +87,12 @@
 static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
 #endif /* SPD_spmd */
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 static auth_param_type_desc_t npu_fw_cert_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, ETHOSN_NPU_FW_CONTENT_CERT_PK_OID);
 static auth_param_type_desc_t npu_fw_image_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, ETHOSN_NPU_FW_BINARY_OID);
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#endif /* ETHOSN_NPU_TZMP1 */
 
 /*
  * Trusted key certificate
@@ -662,9 +662,9 @@
 DEFINE_SIP_SP_PKG(8);
 #endif /* SPD_spmd */
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 static const auth_img_desc_t npu_fw_key_cert = {
-	.img_id = ARM_ETHOSN_NPU_FW_KEY_CERT_ID,
+	.img_id = ETHOSN_NPU_FW_KEY_CERT_ID,
 	.img_type = IMG_CERT,
 	.parent = &trusted_key_cert,
 	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
@@ -697,7 +697,7 @@
 };
 
 static const auth_img_desc_t npu_fw_content_cert = {
-	.img_id = ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID,
+	.img_id = ETHOSN_NPU_FW_CONTENT_CERT_ID,
 	.img_type = IMG_CERT,
 	.parent = &npu_fw_key_cert,
 	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
@@ -730,7 +730,7 @@
 };
 
 static const auth_img_desc_t npu_fw_image = {
-	.img_id = ARM_ETHOSN_NPU_FW_IMAGE_ID,
+	.img_id = ETHOSN_NPU_FW_IMAGE_ID,
 	.img_type = IMG_RAW,
 	.parent = &npu_fw_content_cert,
 	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
@@ -743,7 +743,7 @@
 		}
 	}
 };
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#endif /* ETHOSN_NPU_TZMP1 */
 
 
 static const auth_img_desc_t * const cot_desc[] = {
@@ -778,11 +778,11 @@
 	[SP_PKG7_ID]				=	&sp_pkg7,
 	[SP_PKG8_ID]				=       &sp_pkg8,
 #endif
-#if ARM_ETHOSN_NPU_TZMP1
-	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID]		=	&npu_fw_key_cert,
-	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID]	=	&npu_fw_content_cert,
-	[ARM_ETHOSN_NPU_FW_IMAGE_ID]		=	&npu_fw_image,
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#if ETHOSN_NPU_TZMP1
+	[ETHOSN_NPU_FW_KEY_CERT_ID]		=	&npu_fw_key_cert,
+	[ETHOSN_NPU_FW_CONTENT_CERT_ID]		=	&npu_fw_content_cert,
+	[ETHOSN_NPU_FW_IMAGE_ID]		=	&npu_fw_image,
+#endif /* ETHOSN_NPU_TZMP1 */
 };
 
 /* Register the CoT in the authentication module */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index a4e6407..a00bf26 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -43,8 +43,8 @@
 JUNO_TZMP1		:=	0
 $(eval $(call assert_boolean,JUNO_TZMP1))
 ifeq (${JUNO_TZMP1}, 1)
-  ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
-    $(error JUNO_TZMP1 cannot be used together with ARM_ETHOSN_NPU_TZMP1)
+  ifeq (${ETHOSN_NPU_TZMP1},1)
+    $(error JUNO_TZMP1 cannot be used together with ETHOSN_NPU_TZMP1)
   else
     $(eval $(call add_define,JUNO_TZMP1))
   endif
@@ -63,6 +63,10 @@
   ifneq (${ARCH}, aarch32)
     override BL32_SOURCES =
   endif
+else
+  ifeq (${ARCH}, aarch32)
+    $(error JUNO_AARCH32_EL3_RUNTIME has to be enabled to build BL32 for AArch32)
+  endif
 endif
 
 ifeq (${ARCH},aarch64)
@@ -207,6 +211,7 @@
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
 
+include drivers/arm/ethosn/ethosn_npu.mk
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 0ae7693..12ffb5a 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -89,6 +89,9 @@
 
 override ARM_BL31_IN_DRAM		:=	1
 
+override PSCI_EXTENDED_STATE_ID		:=	1
+override ARM_RECOM_STATE_ID_ENC		:=	1
+
 # Errata workarounds:
 ERRATA_N1_1868343			:=	1
 
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index b3799a7..74d0c91 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -190,11 +190,47 @@
 #define PLAT_CSS_MHU_BASE			0x45000000
 #define PLAT_MAX_PWR_LVL			2
 
-#define PLAT_ARM_G1S_IRQS			ARM_G1S_IRQS,			\
-						CSS_IRQ_MHU
-#define PLAT_ARM_G0_IRQS			ARM_G0_IRQS
+/* Interrupt handling constants */
+#define N1SDP_IRQ_MMU_TCU1_EVENT_Q_SEC		U(257)
+#define N1SDP_IRQ_MMU_TCU1_CMD_SYNC_SEC		U(258)
+#define N1SDP_IRQ_MMU_TCU1_GLOBAL		U(259)
+#define N1SDP_IRQ_MMU_TCU2_EVENT_Q_SEC		U(264)
+#define N1SDP_IRQ_MMU_TCU2_CMD_SYNC_SEC		U(265)
+#define N1SDP_IRQ_MMU_TCU2_GLOBAL		U(266)
+#define N1SDP_IRQ_CLUSTER0_MHU			U(349)
+#define N1SDP_IRQ_CLUSTER1_MHU			U(351)
+#define N1SDP_IRQ_P0_REFCLK			U(412)
+#define N1SDP_IRQ_P1_REFCLK			U(413)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+	ARM_G1S_IRQ_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_EVENT_Q_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_CMD_SYNC_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU1_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_EVENT_Q_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_CMD_SYNC_SEC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_MMU_TCU2_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_CLUSTER0_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_CLUSTER1_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_P0_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(N1SDP_IRQ_P1_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
 #define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
 
 
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 9ebca23..1506714 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -72,7 +72,8 @@
 ifeq (${RAS_FFH_SUPPORT},1)
 BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
 				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
-				${CSS_ENT_BASE}/ras/sgi_ras_sram.c
+				${CSS_ENT_BASE}/ras/sgi_ras_sram.c	\
+				${CSS_ENT_BASE}/ras/sgi_ras_cpu.c
 endif
 
 # Add the FDT_SOURCES and options for Dynamic Config
diff --git a/plat/arm/board/rdn2/rdn2_ras.c b/plat/arm/board/rdn2/rdn2_ras.c
index c1e5ab6..3aed58e 100644
--- a/plat/arm/board/rdn2/rdn2_ras.c
+++ b/plat/arm/board/rdn2/rdn2_ras.c
@@ -14,6 +14,9 @@
 
 	/* Non Secure base RAM ECC UE interrupt */
 	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_UE_INT, SGI_RAS_INTR_TYPE_SPI},
+
+	/* CPU 1-bit ECC CE error interrupt */
+	{SGI_SDEI_DS_EVENT_1, PLAT_CORE_FAULT_IRQ, SGI_RAS_INTR_TYPE_PPI}
 };
 
 /* RAS error record list definition, used by the common RAS framework. */
@@ -21,11 +24,15 @@
 	/* Base element RAM Non-secure error record. */
 	ERR_RECORD_MEMMAP_V1(SOC_NS_RAM_ERR_REC_BASE, 4, NULL,
 				&sgi_ras_sram_intr_handler, 0),
+	ERR_RECORD_SYSREG_V1(0, 1, NULL, &sgi_ras_cpu_intr_handler, 0),
 };
 
 /* RAS error interrupt list definition, used by the common RAS framework. */
 struct ras_interrupt plat_ras_interrupts[] = {
 	{
+		.intr_number = PLAT_CORE_FAULT_IRQ,
+		.err_record = &plat_err_records[1],
+	}, {
 		.intr_number = NS_RAM_ECC_CE_INT,
 		.err_record = &plat_err_records[0],
 	}, {
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index 117fbb4..a6b2b0d 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,10 @@
 #ifndef TC_PLAT_H
 #define TC_PLAT_H
 
+#ifdef PLATFORM_TEST_ROTPK
+#include <rss_crypto_defs.h>
+#endif
+
 void tc_bl31_common_platform_setup(void);
 
 #ifdef PLATFORM_TEST_TFM_TESTSUITE
@@ -17,4 +21,13 @@
 int nv_counter_test(void);
 #endif
 
+#ifdef PLATFORM_TEST_ROTPK
+struct key_id_info {
+	enum rss_key_id_builtin_t key_id;
+	const char *key_id_name;
+};
+
+int rotpk_test(void);
+#endif
+
 #endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
index f9e001e..179ec4b 100644
--- a/plat/arm/board/tc/nv_counter_test.c
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,29 +22,29 @@
 
 	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
-		printf("Failed to initialize RSS communication channel\n");
+		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
 		return -1;
 	}
 
 	for (id = 0; id < 3; id++) {
 		status = rss_platform_nv_counter_read(id, sizeof(old_val), (uint8_t *)&old_val);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during first id=(%d) rss_platform_nv_counter_read\n",
-				       id);
+			printf("Failed during first id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+				       id, status);
 			return -1;
 		}
 
 		status = rss_platform_nv_counter_increment(id);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during id=(%d) rss_platform_nv_counter_increment\n",
-					id);
+			printf("Failed during id=(%d) rss_platform_nv_counter_increment - psa_status = %d\n",
+					id, status);
 			return -1;
 		}
 
 		status = rss_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during second id=(%d) rss_platform_nv_counter_read\n",
-					id);
+			printf("Failed during second id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+					id, status);
 			return -1;
 		}
 
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 5a1d83a..8ca33ca 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -189,31 +189,11 @@
 endif
 
 ifneq (${PLATFORM_TEST},)
-    $(eval $(call add_define,PLATFORM_TESTS))
-
-    ifeq (${PLATFORM_TEST},rss-nv-counters)
-        include drivers/arm/rss/rss_comms.mk
-
-        # Test code.
-        BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
-
-        # Code under testing.
-        BL31_SOURCES	+=	lib/psa/rss_platform.c \
-				drivers/arm/rss/rss_comms.c \
-				${RSS_COMMS_SOURCES}
-
-        PLAT_INCLUDES	+=	-Iinclude/lib/psa
-
-        $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
-    else ifeq (${PLATFORM_TEST},tfm-testsuite)
-        # Add this include as first, before arm_common.mk. This is necessary
-        # because arm_common.mk builds Mbed TLS, and platform_test.mk can
-        # change the list of Mbed TLS files that are to be compiled
-        # (LIBMBEDTLS_SRCS).
-        include plat/arm/board/tc/platform_test.mk
-    else
-        $(error "Unsupported PLATFORM_TEST value")
-    endif
+    # Add this include as first, before arm_common.mk. This is necessary
+    # because arm_common.mk builds Mbed TLS, and platform_test.mk can
+    # change the list of Mbed TLS files that are to be compiled
+    # (LIBMBEDTLS_SRCS).
+    include plat/arm/board/tc/platform_test.mk
 endif
 
 
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index e974855..2fd5ea0 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -3,7 +3,37 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-ifeq (${PLATFORM_TEST},tfm-testsuite)
+$(eval $(call add_define,PLATFORM_TESTS))
+
+ifeq (${PLATFORM_TEST},rss-nv-counters)
+    include drivers/arm/rss/rss_comms.mk
+
+    # Test code.
+    BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+
+    # Code under testing.
+    BL31_SOURCES	+=	lib/psa/rss_platform.c \
+				drivers/arm/rss/rss_comms.c \
+				${RSS_COMMS_SOURCES}
+
+    PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
+else ifeq (${PLATFORM_TEST},rss-rotpk)
+    include drivers/arm/rss/rss_comms.mk
+
+    # Test code.
+    BL31_SOURCES	+=	plat/arm/board/tc/rotpk_test.c
+
+    # Code under testing.
+    BL31_SOURCES	+=	lib/psa/rss_platform.c \
+				drivers/arm/rss/rss_comms.c \
+				${RSS_COMMS_SOURCES}
+
+    PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    $(eval $(call add_define,PLATFORM_TEST_ROTPK))
+else ifeq (${PLATFORM_TEST},tfm-testsuite)
 
     # The variables need to be set to compile the platform test:
     ifeq (${TF_M_TESTS_PATH},)
@@ -77,4 +107,6 @@
     $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
 
     $(eval $(call add_define,PLATFORM_TEST_TFM_TESTSUITE))
+else
+    $(error "Unsupported PLATFORM_TEST value")
 endif
diff --git a/plat/arm/board/tc/region_defs.h b/plat/arm/board/tc/region_defs.h
index d3dfd13..50ec2f1 100644
--- a/plat/arm/board/tc/region_defs.h
+++ b/plat/arm/board/tc/region_defs.h
@@ -7,6 +7,6 @@
 #ifndef REGION_DEFS_H
 #define REGION_DEFS_H
 
-#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE   0x800
+#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE   0x800
 
 #endif /* REGION_DEFS_H */
diff --git a/plat/arm/board/tc/rotpk_test.c b/plat/arm/board/tc/rotpk_test.c
new file mode 100644
index 0000000..ed56c31
--- /dev/null
+++ b/plat/arm/board/tc/rotpk_test.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <plat/common/platform.h>
+#include <rss_platform_api.h>
+#include <tc_plat.h>
+
+static void print_hex(const char *key_id_name, size_t key_size, const uint8_t *key_buf)
+{
+	printf("%s = ", key_id_name);
+	for (int i = 0; i < key_size; i++) {
+		printf("%02x", key_buf[i]);
+	}
+	printf("\n\n");
+}
+
+int rotpk_test(void)
+{
+	psa_status_t status;
+	uint8_t key_buf[128];
+	size_t key_size;
+
+	struct key_id_info key_ids[3] = {
+	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_S_ROTPK,  .key_id_name = "Secure-ROTPK"},
+	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_NS_ROTPK,  .key_id_name = "NS-ROTPK"},
+	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_CCA_ROTPK,  .key_id_name = "CCA-ROTPK"}
+	};
+
+	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	if (status != PSA_SUCCESS) {
+		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+		return -1;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(key_ids); i++) {
+		status = rss_platform_key_read(key_ids[i].key_id, key_buf,
+			       sizeof(key_buf), &key_size);
+		if (status != PSA_SUCCESS) {
+			printf("Failed to retrieve %s - psa_status = %d\n", key_ids[i].key_id_name, status);
+			return -1;
+		}
+		print_hex(key_ids[i].key_id_name, key_size, key_buf);
+	}
+
+	printf("Passed rotpk_test\n");
+
+	return 0;
+}
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
index 8c40271..ea90ac3 100644
--- a/plat/arm/board/tc/rss_ap_tests.c
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -56,7 +56,7 @@
 	return 0;
 }
 
-void run_platform_tests(void)
+int run_platform_tests(void)
 {
 	size_t i;
 	int ret;
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
index 0d29c51..6821a6a 100644
--- a/plat/arm/board/tc/tc_bl1_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <drivers/arm/rss_comms.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
 #include <lib/psa/measured_boot.h>
+#include <tools_share/zero_oid.h>
 
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
@@ -22,18 +23,21 @@
 		.slot = U(6),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = TB_FW_CONFIG_ID,
 		.slot = U(7),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = BL2_IMAGE_ID,
 		.slot = U(8),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_BL2_STRING,
+		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 
 	{
@@ -46,7 +50,7 @@
 	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
 			     PLAT_RSS_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(tc_rss_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index 7ea2c2e..4b79170 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <drivers/arm/rss_comms.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
 #include <lib/psa/measured_boot.h>
+#include <tools_share/tbbr_oid.h>
 
 #include <plat/common/common_def.h>
 #include <platform_def.h>
@@ -22,18 +23,21 @@
 		.slot = U(9),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_BL31_STRING,
+		.pk_oid = BL31_IMAGE_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = HW_CONFIG_ID,
 		.slot = U(10),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+		.pk_oid = HW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = SOC_FW_CONFIG_ID,
 		.slot = U(11),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
 		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = RSS_MBOOT_INVALID_ID }
@@ -45,7 +49,7 @@
 	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
 			     PLAT_RSS_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init();
+	rss_measured_boot_init(tc_rss_mboot_metadata);
 }
 
 void bl2_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index ca3a032..ff7809d 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -59,6 +59,8 @@
 
 #ifdef PLATFORM_TEST_NV_COUNTERS
 	tests_failed = nv_counter_test();
+#elif PLATFORM_TEST_ROTPK
+	tests_failed = rotpk_test();
 #elif PLATFORM_TEST_TFM_TESTSUITE
 	tests_failed = run_platform_tests();
 #endif
@@ -120,12 +122,9 @@
 {
 	/* Trusted Watchdog timer is the only source of Group0 interrupt now. */
 	if (intid == SBSA_SECURE_WDOG_INTID) {
-		INFO("Watchdog restarted\n");
 		/* Refresh the timer. */
 		plat_arm_secure_wdt_refresh();
 
-		/* Deactivate the corresponding interrupt. */
-		plat_ic_end_of_interrupt(intid);
 		return 0;
 	}
 
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
index fe71899..925a411 100644
--- a/plat/arm/board/tc/tc_common_measured_boot.c
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,17 +12,13 @@
 
 extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
 
-struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
-{
-	return tc_rss_mboot_metadata;
-}
-
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
 
 	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(image_data->image_base,
+	err = rss_mboot_measure_and_record(tc_rss_mboot_metadata,
+					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
@@ -33,3 +28,9 @@
 
 	return err;
 }
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return rss_mboot_set_signer_id(tc_rss_mboot_metadata, pk_oid, pk_ptr,
+				       pk_len);
+}
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index e512192..9a65e7c 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -223,17 +223,17 @@
 	},
 #endif /* EL3_PAYLOAD_BASE */
 
-# if ARM_ETHOSN_NPU_TZMP1
+# if ETHOSN_NPU_TZMP1
 	{
-		.image_id = ARM_ETHOSN_NPU_FW_IMAGE_ID,
+		.image_id = ETHOSN_NPU_FW_IMAGE_ID,
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
 				      VERSION_2, image_info_t, 0),
-		.image_info.image_base = ARM_ETHOSN_NPU_FW_IMAGE_BASE,
-		.image_info.image_max_size = ARM_ETHOSN_NPU_FW_IMAGE_LIMIT -
-			ARM_ETHOSN_NPU_FW_IMAGE_BASE,
+		.image_info.image_base = ETHOSN_NPU_FW_IMAGE_BASE,
+		.image_info.image_max_size = ETHOSN_NPU_FW_IMAGE_LIMIT -
+			ETHOSN_NPU_FW_IMAGE_BASE,
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
-# endif
+#endif /* ETHOSN_NPU_TZMP1 */
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 647a9d9..41d1b66 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -6,6 +6,12 @@
 
 include common/fdt_wrappers.mk
 
+ifeq (${ARCH},aarch32)
+    ifeq (${AARCH32_SP},none)
+        $(error Variable AARCH32_SP has to be set for AArch32)
+    endif
+endif
+
 ifeq (${ARCH}, aarch64)
   # On ARM standard platorms, the TSP can execute from Trusted SRAM, Trusted
   # DRAM (if available) or the TZC secured area of DRAM.
@@ -114,48 +120,6 @@
   endif
 endif
 
-# Arm(R) Ethos(TM)-N NPU SiP service
-ARM_ETHOSN_NPU_DRIVER			:=	0
-$(eval $(call assert_boolean,ARM_ETHOSN_NPU_DRIVER))
-$(eval $(call add_define,ARM_ETHOSN_NPU_DRIVER))
-
-# Arm(R) Ethos(TM)-N NPU TZMP1
-ARM_ETHOSN_NPU_TZMP1			:=	0
-$(eval $(call assert_boolean,ARM_ETHOSN_NPU_TZMP1))
-$(eval $(call add_define,ARM_ETHOSN_NPU_TZMP1))
-ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
-  ifeq (${ARM_ETHOSN_NPU_DRIVER},0)
-    $(error ARM_ETHOSN_NPU_TZMP1 is only available if ARM_ETHOSN_NPU_DRIVER=1)
-  endif
-  ifeq (${PLAT},juno)
-    $(eval $(call add_define,JUNO_ETHOSN_TZMP1))
-  else
-    $(error ARM_ETHOSN_NPU_TZMP1 only supported on Juno platform, not ${PLAT})
-  endif
-
-  ifeq (${TRUSTED_BOARD_BOOT},0)
-    # We rely on TRUSTED_BOARD_BOOT to prevent the firmware code from being
-    # tampered with, which is required to protect the confidentiality of protected
-    # inference data.
-    $(error ARM_ETHOSN_NPU_TZMP1 is only available if TRUSTED_BOARD_BOOT is enabled)
-  endif
-
-  # We need the FW certificate and key certificate
-  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_key.crt,--npu-fw-key-cert))
-  $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_content.crt,--npu-fw-cert))
-  # Needed for our OIDs to be available in tbbr_cot_bl2.c
-  $(eval $(call add_define, PLAT_DEF_OID))
-  PLAT_INCLUDES	+=	-I${PLAT_DIR}certificate/include
-  PLAT_INCLUDES	+=	-Iinclude/drivers/arm/
-
-  # We need the firmware to be built into the FIP
-  $(eval $(call TOOL_ADD_IMG,ARM_ETHOSN_NPU_FW,--npu-fw))
-
-  # Needed so that UUIDs from the FIP are available in BL2
-  $(eval $(call add_define,PLAT_DEF_FIP_UUID))
-  PLAT_INCLUDES		+=	-I${PLAT_DIR}fip
-endif # ARM_ETHOSN_NPU_TZMP1
-
 # Use an implementation of SHA-256 with a smaller memory footprint but reduced
 # speed.
 $(eval $(call add_define,MBEDTLS_SHA256_SMALLER))
@@ -348,18 +312,18 @@
 				plat/arm/common/arm_topology.c			\
 				plat/common/plat_psci_common.c
 
-ifneq ($(filter 1,${ENABLE_PMF} ${ARM_ETHOSN_NPU_DRIVER}),)
+ifneq ($(filter 1,${ENABLE_PMF} ${ETHOSN_NPU_DRIVER}),)
 ARM_SVC_HANDLER_SRCS :=
 
 ifeq (${ENABLE_PMF},1)
 ARM_SVC_HANDLER_SRCS	+=	lib/pmf/pmf_smc.c
 endif
 
-ifeq (${ARM_ETHOSN_NPU_DRIVER},1)
+ifeq (${ETHOSN_NPU_DRIVER},1)
 ARM_SVC_HANDLER_SRCS	+=	plat/arm/common/fconf/fconf_ethosn_getter.c	\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/arm/ethosn/ethosn_smc.c
-ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
+ifeq (${ETHOSN_NPU_TZMP1},1)
 ARM_SVC_HANDLER_SRCS	+=	drivers/arm/ethosn/ethosn_big_fw.c
 endif
 endif
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 1c95afb..8c16877 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -40,7 +40,11 @@
 
 static const interrupt_prop_t arm_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
-	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
+	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0),
+#if 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/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index af8a02f..352d477 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -13,6 +13,9 @@
 #include <lib/pmf/pmf.h>
 #include <plat/arm/common/arm_sip_svc.h>
 #include <plat/arm/common/plat_arm.h>
+#if ENABLE_SPMD_LP
+#include <services/el3_spmd_logical_sp.h>
+#endif
 #include <tools_share/uuid.h>
 
 /* ARM SiP Service UUID */
@@ -34,13 +37,13 @@
 
 #endif /* USE_DEBUGFS */
 
-#if ARM_ETHOSN_NPU_DRIVER
+#if ETHOSN_NPU_DRIVER
 
 	if (ethosn_smc_setup() != 0) {
 		return 1;
 	}
 
-#endif /* ARM_ETHOSN_NPU_DRIVER */
+#endif /* ETHOSN_NPU_DRIVER */
 
 	return 0;
 }
@@ -81,14 +84,14 @@
 
 #endif /* USE_DEBUGFS */
 
-#if ARM_ETHOSN_NPU_DRIVER
+#if ETHOSN_NPU_DRIVER
 
 	if (is_ethosn_fid(smc_fid)) {
 		return ethosn_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 					  handle, flags);
 	}
 
-#endif /* ARM_ETHOSN_NPU_DRIVER */
+#endif /* ETHOSN_NPU_DRIVER */
 
 	switch (smc_fid) {
 	case ARM_SIP_SVC_EXE_STATE_SWITCH: {
@@ -114,10 +117,10 @@
 		/* PMF calls */
 		call_count += PMF_NUM_SMC_CALLS;
 
-#if ARM_ETHOSN_NPU_DRIVER
+#if ETHOSN_NPU_DRIVER
 		/* ETHOSN calls */
 		call_count += ETHOSN_NUM_SMC_CALLS;
-#endif /* ARM_ETHOSN_NPU_DRIVER */
+#endif          /* ETHOSN_NPU_DRIVER */
 
 		/* State switch call */
 		call_count += 1;
@@ -133,8 +136,13 @@
 		SMC_RET2(handle, ARM_SIP_SVC_VERSION_MAJOR, ARM_SIP_SVC_VERSION_MINOR);
 
 	default:
+#if ENABLE_SPMD_LP
+		return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
+				cookie, handle, flags);
+#else
 		WARN("Unimplemented ARM SiP Service Call: 0x%x \n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
+#endif
 	}
 
 }
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 743cc90..27acc3a 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -68,9 +68,9 @@
 	[TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG},
 	[NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG},
 	[RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE},
-#if ARM_ETHOSN_NPU_TZMP1
-	[ARM_ETHOSN_NPU_FW_IMAGE_ID] = {UUID_ETHOSN_FW},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#if ETHOSN_NPU_TZMP1
+	[ETHOSN_NPU_FW_IMAGE_ID] = {UUID_ETHOSN_FW},
+#endif /* ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
@@ -91,10 +91,10 @@
 	[SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
 	[PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT},
 #endif
-#if ARM_ETHOSN_NPU_TZMP1
-	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = {UUID_ETHOSN_FW_KEY_CERTIFICATE},
-	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = {UUID_ETHOSN_FW_CONTENT_CERTIFICATE},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#if ETHOSN_NPU_TZMP1
+	[ETHOSN_NPU_FW_KEY_CERT_ID] = {UUID_ETHOSN_FW_KEY_CERTIFICATE},
+	[ETHOSN_NPU_FW_CONTENT_CERT_ID] = {UUID_ETHOSN_FW_CONTENT_CERTIFICATE},
+#endif /* ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -198,13 +198,13 @@
 		(uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID],
 		open_fip
 	},
-#if ARM_ETHOSN_NPU_TZMP1
-	[ARM_ETHOSN_NPU_FW_IMAGE_ID] = {
+#if ETHOSN_NPU_TZMP1
+	[ETHOSN_NPU_FW_IMAGE_ID] = {
 		&fip_dev_handle,
-		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_IMAGE_ID],
+		(uintptr_t)&arm_uuid_spec[ETHOSN_NPU_FW_IMAGE_ID],
 		open_fip
 	},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#endif /* ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {
@@ -285,18 +285,18 @@
 		open_fip
 	},
 #endif
-#if ARM_ETHOSN_NPU_TZMP1
-	[ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = {
+#if ETHOSN_NPU_TZMP1
+	[ETHOSN_NPU_FW_KEY_CERT_ID] = {
 		&fip_dev_handle,
-		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_KEY_CERT_ID],
+		(uintptr_t)&arm_uuid_spec[ETHOSN_NPU_FW_KEY_CERT_ID],
 		open_fip
 	},
-	[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = {
+	[ETHOSN_NPU_FW_CONTENT_CERT_ID] = {
 		&fip_dev_handle,
-		(uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID],
+		(uintptr_t)&arm_uuid_spec[ETHOSN_NPU_FW_CONTENT_CERT_ID],
 		open_fip
 	},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#endif /* ETHOSN_NPU_TZMP1 */
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -305,11 +305,11 @@
 
 #define FCONF_ARM_IO_UUID_NUM_BASE	U(10)
 
-#if ARM_ETHOSN_NPU_TZMP1
+#if ETHOSN_NPU_TZMP1
 #define FCONF_ARM_IO_UUID_NUM_NPU	U(1)
 #else
 #define FCONF_ARM_IO_UUID_NUM_NPU	U(0)
-#endif
+#endif /* ETHOSN_NPU_TZMP1 */
 
 #if TRUSTED_BOARD_BOOT
 #define FCONF_ARM_IO_UUID_NUM_TBB	U(12)
@@ -323,11 +323,11 @@
 #define FCONF_ARM_IO_UUID_NUM_SPD	U(0)
 #endif /* TRUSTED_BOARD_BOOT && defined(SPD_spmd) */
 
-#if TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1
+#if TRUSTED_BOARD_BOOT && ETHOSN_NPU_TZMP1
 #define FCONF_ARM_IO_UUID_NUM_NPU_TBB	U(2)
 #else
 #define FCONF_ARM_IO_UUID_NUM_NPU_TBB	U(0)
-#endif /* TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1 */
+#endif /* TRUSTED_BOARD_BOOT && ETHOSN_NPU_TZMP1 */
 
 #define FCONF_ARM_IO_UUID_NUMBER	FCONF_ARM_IO_UUID_NUM_BASE + \
 					FCONF_ARM_IO_UUID_NUM_NPU + \
@@ -355,9 +355,9 @@
 	{SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
 	{TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
 	{NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
-#if ARM_ETHOSN_NPU_TZMP1
-	{ARM_ETHOSN_NPU_FW_IMAGE_ID, "arm_ethosn_npu_fw_uuid"},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#if ETHOSN_NPU_TZMP1
+	{ETHOSN_NPU_FW_IMAGE_ID, "ethosn_npu_fw_uuid"},
+#endif /* ETHOSN_NPU_TZMP1 */
 #if TRUSTED_BOARD_BOOT
 	{CCA_CONTENT_CERT_ID, "cca_cert_uuid"},
 	{CORE_SWD_KEY_CERT_ID, "core_swd_cert_uuid"},
@@ -375,10 +375,10 @@
 	{SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"},
 	{PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"},
 #endif
-#if ARM_ETHOSN_NPU_TZMP1
-	{ARM_ETHOSN_NPU_FW_KEY_CERT_ID, "arm_ethosn_npu_fw_key_cert_uuid"},
-	{ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID, "arm_ethosn_npu_fw_content_cert_uuid"},
-#endif /* ARM_ETHOSN_NPU_TZMP1 */
+#if ETHOSN_NPU_TZMP1
+	{ETHOSN_NPU_FW_KEY_CERT_ID, "ethosn_npu_fw_key_cert_uuid"},
+	{ETHOSN_NPU_FW_CONTENT_CERT_ID, "ethosn_npu_fw_content_cert_uuid"},
+#endif /* ETHOSN_NPU_TZMP1 */
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/css/sgi/include/sgi_ras.h
index 24bbfa7..d311807 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/css/sgi/include/sgi_ras.h
@@ -60,4 +60,9 @@
 				int probe_data,
 				const struct err_handler_data *const data);
 
+/* CPU RAS interrupt handler */
+int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data);
+
 #endif /* SGI_RAS_H */
diff --git a/plat/arm/css/sgi/ras/sgi_ras_cpu.c b/plat/arm/css/sgi/ras/sgi_ras_cpu.c
new file mode 100644
index 0000000..5e77dbb
--- /dev/null
+++ b/plat/arm/css/sgi/ras/sgi_ras_cpu.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/extensions/ras.h>
+#include <plat/common/platform.h>
+#include <services/sdei.h>
+#include <services/spm_mm_svc.h>
+
+#include <sgi_ras.h>
+
+#define CPU_CONTEXT_REG_GPR_ARR_SIZE 32
+#define CPU_CONTEXT_REG_EL1_ARR_SIZE 17
+#define CPU_CONTEXT_REG_EL2_ARR_SIZE 16
+#define CPU_CONTEXT_REG_EL3_ARR_SIZE 10
+
+/*
+ * MM Communicate message header GUID to indicate the payload is intended for
+ * CPU MM driver.
+ */
+struct efi_guid cpu_ecc_event_guid = {
+	0x2c1b3bfc, 0x42cd, 0x4a66,
+	{0xac, 0xd1, 0xa4, 0xd1, 0x63, 0xe9, 0x90, 0xf6}
+	};
+
+/*
+ * CPU error information data structure communicated as part of MM
+ * Communication data payload.
+ */
+typedef struct {
+	uint64_t ErrStatus;
+	uint64_t ErrMisc0;
+	uint64_t ErrAddr;
+	uint64_t SecurityState;
+	uint64_t ErrCtxGpr[CPU_CONTEXT_REG_GPR_ARR_SIZE];
+	uint64_t ErrCtxEl1Reg[CPU_CONTEXT_REG_EL1_ARR_SIZE];
+	uint64_t ErrCtxEl2Reg[CPU_CONTEXT_REG_EL2_ARR_SIZE];
+	uint64_t ErrCtxEl3Reg[CPU_CONTEXT_REG_EL3_ARR_SIZE];
+} cpu_err_info;
+
+/*
+ * Reads the CPU context and error information from the relevant registers and
+ * populates the CPU error information data structure.
+ */
+static void populate_cpu_err_data(cpu_err_info *cpu_info,
+					uint64_t security_state)
+{
+	void *ctx;
+
+	ctx = cm_get_context(security_state);
+
+	cpu_info->ErrStatus = read_erxstatus_el1();
+	cpu_info->ErrMisc0 = read_erxmisc0_el1();
+	cpu_info->ErrAddr = read_erxaddr_el1();
+	cpu_info->SecurityState = security_state;
+
+	/* populate CPU EL1 context information. */
+	cpu_info->ErrCtxEl1Reg[0]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_ELR_EL1);
+	cpu_info->ErrCtxEl1Reg[1]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_ESR_EL1);
+	cpu_info->ErrCtxEl1Reg[2]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_FAR_EL1);
+	cpu_info->ErrCtxEl1Reg[3]  = read_isr_el1();
+	cpu_info->ErrCtxEl1Reg[4]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_MAIR_EL1);
+	cpu_info->ErrCtxEl1Reg[5]  = read_midr_el1();
+	cpu_info->ErrCtxEl1Reg[6]  = read_mpidr_el1();
+	cpu_info->ErrCtxEl1Reg[7]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SCTLR_EL1);
+	cpu_info->ErrCtxEl1Reg[8]  = read_ctx_reg(get_gpregs_ctx(ctx),
+						  CTX_GPREG_SP_EL0);
+	cpu_info->ErrCtxEl1Reg[9]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SP_EL1);
+	cpu_info->ErrCtxEl1Reg[10] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SPSR_EL1);
+	cpu_info->ErrCtxEl1Reg[11] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TCR_EL1);
+	cpu_info->ErrCtxEl1Reg[12] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDR_EL0);
+	cpu_info->ErrCtxEl1Reg[13] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDR_EL1);
+	cpu_info->ErrCtxEl1Reg[14] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDRRO_EL0);
+	cpu_info->ErrCtxEl1Reg[15] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TTBR0_EL1);
+	cpu_info->ErrCtxEl1Reg[16] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TTBR1_EL1);
+
+#if CTX_INCLUDE_EL2_REGS
+	cpu_info->ErrCtxEl2Reg[0]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ELR_EL2);
+	cpu_info->ErrCtxEl2Reg[1]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ESR_EL2);
+	cpu_info->ErrCtxEl2Reg[2]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_FAR_EL2);
+	cpu_info->ErrCtxEl2Reg[3]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HACR_EL2);
+	cpu_info->ErrCtxEl2Reg[4]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HCR_EL2);
+	cpu_info->ErrCtxEl2Reg[5]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HPFAR_EL2);
+	cpu_info->ErrCtxEl2Reg[6]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_MAIR_EL2);
+	cpu_info->ErrCtxEl2Reg[7]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SCTLR_EL2);
+	cpu_info->ErrCtxEl2Reg[8]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SP_EL2);
+	cpu_info->ErrCtxEl2Reg[9]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SPSR_EL2);
+	cpu_info->ErrCtxEl2Reg[10]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TCR_EL2);
+	cpu_info->ErrCtxEl2Reg[11]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TPIDR_EL2);
+	cpu_info->ErrCtxEl2Reg[12]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TTBR0_EL2);
+	cpu_info->ErrCtxEl2Reg[13]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_VTCR_EL2);
+	cpu_info->ErrCtxEl2Reg[14]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_VTTBR_EL2);
+	cpu_info->ErrCtxEl2Reg[15]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ESR_EL2);
+#endif
+
+	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
+						   CTX_ELR_EL3);
+	cpu_info->ErrCtxEl3Reg[1]   = read_ctx_reg(get_el3state_ctx(ctx),
+						   CTX_ESR_EL3);
+	cpu_info->ErrCtxEl3Reg[2]   = read_far_el3();
+	cpu_info->ErrCtxEl3Reg[4]   = read_mair_el3();
+	cpu_info->ErrCtxEl3Reg[5]   = read_sctlr_el3();
+	cpu_info->ErrCtxEl3Reg[6]   = 0; /* sp_el3 */
+	cpu_info->ErrCtxEl3Reg[7]   = read_tcr_el3();
+	cpu_info->ErrCtxEl3Reg[8]   = read_tpidr_el3();
+	cpu_info->ErrCtxEl3Reg[9]   = read_ttbr0_el3();
+}
+
+/* CPU RAS interrupt handler */
+int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data)
+{
+	struct sgi_ras_ev_map *ras_map;
+	mm_communicate_header_t *header;
+	cpu_err_info cpu_info = {0};
+	uint64_t clear_status;
+	uint32_t intr;
+	int ret;
+
+	cm_el1_sysregs_context_save(NON_SECURE);
+	intr = data->interrupt;
+
+	INFO("[CPU RAS] CPU intr received = %d on cpu_id = %d\n",
+		intr, plat_my_core_pos());
+
+	INFO("[CPU RAS] ERXMISC0_EL1 = 0x%lx\n", read_erxmisc0_el1());
+	INFO("[CPU RAS] ERXSTATUS_EL1 = 0x%lx\n", read_erxstatus_el1());
+	INFO("[CPU RAS] ERXADDR_EL1 = 0x%lx\n", read_erxaddr_el1());
+
+	/* Populate CPU Error Source Information. */
+	populate_cpu_err_data(&cpu_info, get_interrupt_src_ss(data->flags));
+
+	/* Clear the interrupt. */
+	clear_status = read_erxstatus_el1();
+	write_erxstatus_el1(clear_status);
+	plat_ic_end_of_interrupt(intr);
+
+	header = (void *) PLAT_SPM_BUF_BASE;
+	memset(header, 0, sizeof(*header));
+	memcpy(&header->data, &cpu_info, sizeof(cpu_info));
+	header->message_len = sizeof(cpu_info);
+	memcpy(&header->header_guid, (void *) &cpu_ecc_event_guid,
+		sizeof(struct efi_guid));
+
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+		       plat_my_core_pos());
+
+	/*
+	 * Find if this is a RAS interrupt. There must be an event against
+	 * this interrupt
+	 */
+	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	if (ras_map == NULL) {
+		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+			intr);
+		return -1;
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+	if (ret != 0) {
+		/*
+		 * sdei_dispatch_event() may return failing result in some
+		 * cases, for example kernel may not have registered a handler
+		 * or RAS event may happen early during boot. We restore the NS
+		 * context when sdei_dispatch_event() returns failing result.
+		 */
+		ERROR("SDEI dispatch failed: %d", ret);
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+	}
+
+	return ret;
+}
diff --git a/plat/aspeed/ast2700/include/platform_def.h b/plat/aspeed/ast2700/include/platform_def.h
index 3f2468f..8be26c3 100644
--- a/plat/aspeed/ast2700/include/platform_def.h
+++ b/plat/aspeed/ast2700/include/platform_def.h
@@ -41,13 +41,13 @@
 #define MAX_MMAP_REGIONS		U(32)
 
 /* BL31 region */
-#define BL31_BASE			ULL(0x400000000)
-#define BL31_SIZE			ULL(0x400000)
+#define BL31_BASE			ULL(0x430000000)
+#define BL31_SIZE			SZ_512K
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* BL32 region */
 #define BL32_BASE			BL31_LIMIT
-#define BL32_SIZE			ULL(0x400000)
+#define BL32_SIZE			SZ_16M
 #define BL32_LIMIT			(BL32_BASE + BL32_SIZE)
 
 /* console */
diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk
index aa2fe86..67413c6 100644
--- a/plat/brcm/board/stingray/platform.mk
+++ b/plat/brcm/board/stingray/platform.mk
@@ -210,7 +210,8 @@
 
 BL2_SOURCES		+=	plat/${SOC_DIR}/driver/ihost_pll_config.c \
 				plat/${SOC_DIR}/src/bl2_setup.c \
-				plat/${SOC_DIR}/driver/swreg.c
+				plat/${SOC_DIR}/driver/swreg.c \
+				lib/cpus/aarch64/cpu_helpers.S
 
 ifeq (${USE_DDR},yes)
 PLAT_INCLUDES		+=	-Iplat/${SOC_DIR}/driver/ddr/soc/include
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index f4f5bfc..156c55d 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -110,3 +110,7 @@
 ifeq (${ARCH},aarch64)
   $(error Error: AArch64 not supported on i.mx7)
 endif
+
+ifeq (${AARCH32_SP}, none)
+    $(error Variable AARCH32_SP has to be set for AArch32)
+endif
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
index 8b132d2..31f2f56 100644
--- a/plat/imx/imx8m/ddr/clock.c
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -91,6 +91,10 @@
 	case 4000:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
 		break;
+	case 3733:
+	case 3732:
+		mmio_write_32(DRAM_PLL_CTRL + 0x4, (311 << 12) | (4 << 4) | 1);
+		break;
 	case 3200:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (200 << 12) | (3 << 4) | 1);
 		break;
diff --git a/plat/imx/imx8m/ddr/dram_retention.c b/plat/imx/imx8m/ddr/dram_retention.c
index 983f6e2..d98a37e 100644
--- a/plat/imx/imx8m/ddr/dram_retention.c
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -8,14 +8,12 @@
 #include <lib/mmio.h>
 
 #include <dram.h>
+#include <gpc_reg.h>
 #include <platform_def.h>
 
 #define SRC_DDR1_RCR		(IMX_SRC_BASE + 0x1000)
 #define SRC_DDR2_RCR		(IMX_SRC_BASE + 0x1004)
 
-#define PU_PGC_UP_TRG		0xf8
-#define PU_PGC_DN_TRG		0x104
-#define GPC_PU_PWRHSK		(IMX_GPC_BASE + 0x01FC)
 #define CCM_SRC_CTRL_OFFSET     (IMX_CCM_BASE + 0x800)
 #define CCM_CCGR_OFFSET         (IMX_CCM_BASE + 0x4000)
 #define CCM_TARGET_ROOT_OFFSET	(IMX_CCM_BASE + 0x8000)
@@ -102,21 +100,12 @@
 	}
 	dwc_ddrphy_apb_wr(0xd0000, 0x1);
 
-#if defined(PLAT_imx8mq)
-	/* pwrdnreqn_async adbm/adbs of ddr */
-	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1));
-	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) {
-		;
-	}
-	mmio_setbits_32(GPC_PU_PWRHSK, BIT(1));
-#else
 	/* pwrdnreqn_async adbm/adbs of ddr */
-	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2));
-	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) {
+	mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, DDRMIX_ADB400_SYNC);
+	while (mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & DDRMIX_ADB400_ACK)
 		;
-	}
-	mmio_setbits_32(GPC_PU_PWRHSK, BIT(2));
-#endif
+	mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, DDRMIX_ADB400_SYNC);
+
 	/* remove PowerOk */
 	mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
 
@@ -124,8 +113,8 @@
 	mmio_write_32(CCM_SRC_CTRL(15), 2);
 
 	/* enable the phy iso */
-	mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1);
-	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5));
+	mmio_setbits_32(IMX_GPC_BASE + DDRMIX_PGC, 1);
+	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, DDRMIX_PWR_REQ);
 
 	VERBOSE("dram enter retention\n");
 }
@@ -150,7 +139,7 @@
 	mmio_write_32(CCM_TARGET_ROOT(65) + 0x4, (0x4 << 24) | (0x3 << 16));
 
 	/* disable iso */
-	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
+	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, DDRMIX_PWR_REQ);
 	mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
 
 	/* wait dram pll locked */
diff --git a/plat/imx/imx8m/imx8m_ccm.c b/plat/imx/imx8m/imx8m_ccm.c
new file mode 100644
index 0000000..10a00c9
--- /dev/null
+++ b/plat/imx/imx8m/imx8m_ccm.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023, Pengutronix. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define UCR1    		0x80
+#define UCR1_UARTEN		BIT(0)
+#define DOMAIN0_RUNNING(d)	(((d) & 0x3) != 0)
+
+static struct imx_uart {
+	unsigned int ccm_reg;
+	unsigned int uart_base;
+} imx8m_uart_info[] = {
+	{	/* UART 1 */
+		.ccm_reg = 0x4490,
+		.uart_base = 0x30860000,
+	}, {	/* UART 2 */
+		.ccm_reg = 0x44a0,
+		.uart_base = 0x30890000,
+	}, {	/* UART 3 */
+		.ccm_reg = 0x44b0,
+		.uart_base = 0x30880000,
+	}, {	/* UART 4 */
+		.ccm_reg = 0x44c0,
+		.uart_base = 0x30a60000,
+	}
+};
+
+unsigned int imx8m_uart_get_base(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
+		uint32_t val;
+
+		/*
+		 * At least check that the clock-gate is ungated before we
+		 * access the UART register.
+		 */
+		val = mmio_read_32(IMX_CCM_BASE + imx8m_uart_info[i].ccm_reg);
+		if (DOMAIN0_RUNNING(val)) {
+			val = mmio_read_32(imx8m_uart_info[i].uart_base + UCR1);
+			if (val & UCR1_UARTEN) {
+				return imx8m_uart_info[i].uart_base;
+			}
+		}
+	}
+
+	/*
+	 * We should return an error and inform the user but we can't do it
+	 * this early.
+	 */
+	return 0;
+}
diff --git a/plat/imx/imx8m/imx8m_measured_boot.c b/plat/imx/imx8m/imx8m_measured_boot.c
index e9ea2d8..bfcd6ce 100644
--- a/plat/imx/imx8m/imx8m_measured_boot.c
+++ b/plat/imx/imx8m/imx8m_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  * Copyright (c) 2022, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -79,3 +79,9 @@
 
 	dump_event_log((uint8_t *)event_log, event_log_cur_size);
 }
+
+int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+			   size_t pk_len)
+{
+	return 0;
+}
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
index e0e38a9..f173a16 100644
--- a/plat/imx/imx8m/imx8mm/gpc.c
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -19,46 +19,7 @@
 #include <gpc.h>
 #include <imx_sip_svc.h>
 
-#define MIPI_PWR_REQ		BIT(0)
-#define PCIE_PWR_REQ		BIT(1)
-#define OTG1_PWR_REQ		BIT(2)
-#define OTG2_PWR_REQ		BIT(3)
-#define HSIOMIX_PWR_REQ		BIT(4)
-#define GPU2D_PWR_REQ		BIT(6)
-#define GPUMIX_PWR_REQ		BIT(7)
-#define VPUMIX_PWR_REQ		BIT(8)
-#define GPU3D_PWR_REQ		BIT(9)
-#define DISPMIX_PWR_REQ		BIT(10)
-#define VPU_G1_PWR_REQ		BIT(11)
-#define VPU_G2_PWR_REQ		BIT(12)
-#define VPU_H1_PWR_REQ		BIT(13)
-
-#define HSIOMIX_ADB400_SYNC	(0x3 << 5)
-#define DISPMIX_ADB400_SYNC	BIT(7)
-#define VPUMIX_ADB400_SYNC	BIT(8)
-#define GPU3D_ADB400_SYNC	BIT(9)
-#define GPU2D_ADB400_SYNC	BIT(10)
-#define GPUMIX_ADB400_SYNC	BIT(11)
-#define HSIOMIX_ADB400_ACK	(0x3 << 23)
-#define DISPMIX_ADB400_ACK	BIT(25)
-#define VPUMIX_ADB400_ACK	BIT(26)
-#define GPU3D_ADB400_ACK	BIT(27)
-#define GPU2D_ADB400_ACK	BIT(28)
-#define GPUMIX_ADB400_ACK	BIT(29)
-
-#define MIPI_PGC		0xc00
-#define PCIE_PGC		0xc40
-#define OTG1_PGC		0xc80
-#define OTG2_PGC		0xcc0
-#define HSIOMIX_PGC	        0xd00
-#define GPU2D_PGC		0xd80
-#define GPUMIX_PGC		0xdc0
-#define VPUMIX_PGC		0xe00
-#define GPU3D_PGC		0xe40
-#define DISPMIX_PGC		0xe80
-#define VPU_G1_PGC		0xec0
-#define VPU_G2_PGC		0xf00
-#define VPU_H1_PGC		0xf40
+#define CCGR(x)		(0x4000 + (x) * 16)
 
 enum pu_domain_id {
 	HSIOMIX,
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 67bfd36..c8a3adf 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -27,6 +27,7 @@
 #include <imx_uart.h>
 #include <imx_rdc.h>
 #include <imx8m_caam.h>
+#include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <plat_imx8.h>
 
@@ -130,6 +131,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	int i;
 
@@ -144,7 +146,11 @@
 
 	imx_csu_init(csu_cfg);
 
-	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 24582f8..6f6daf8 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -37,6 +37,7 @@
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c	\
 				plat/imx/imx8m/imx8mm/imx8mm_psci.c		\
@@ -158,6 +159,9 @@
 $(eval $(call add_define,BL32_SIZE))
 
 IMX_BOOT_UART_BASE	?=	0x30890000
+ifeq (${IMX_BOOT_UART_BASE},auto)
+    override IMX_BOOT_UART_BASE	:=	0
+endif
 $(eval $(call add_define,IMX_BOOT_UART_BASE))
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index eff198d..147249e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -25,6 +25,7 @@
 #include <imx_uart.h>
 #include <imx_rdc.h>
 #include <imx8m_caam.h>
+#include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <platform_def.h>
 #include <plat_imx8.h>
@@ -121,6 +122,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	unsigned int val;
 	int i;
@@ -141,7 +143,11 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 1c0ad4f..a6b43f2 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -31,6 +31,7 @@
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c	\
@@ -64,6 +65,9 @@
 $(eval $(call add_define,BL32_SIZE))
 
 IMX_BOOT_UART_BASE	?=	0x30890000
+ifeq (${IMX_BOOT_UART_BASE},auto)
+    override IMX_BOOT_UART_BASE	:=	0
+endif
 $(eval $(call add_define,IMX_BOOT_UART_BASE))
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 4c31fa2..b0a41c7 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -25,6 +25,7 @@
 #include <imx_uart.h>
 #include <imx_rdc.h>
 #include <imx8m_caam.h>
+#include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <platform_def.h>
 #include <plat_imx8.h>
@@ -117,6 +118,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	unsigned int val;
 	unsigned int i;
@@ -137,7 +139,11 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 1102316..a8400a4 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -32,6 +32,7 @@
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c	\
@@ -155,6 +156,9 @@
 $(eval $(call add_define,BL32_SIZE))
 
 IMX_BOOT_UART_BASE	?=	0x30890000
+ifeq (${IMX_BOOT_UART_BASE},auto)
+    override IMX_BOOT_UART_BASE	:=	0
+endif
 $(eval $(call add_define,IMX_BOOT_UART_BASE))
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
diff --git a/plat/imx/imx8m/include/imx8m_ccm.h b/plat/imx/imx8m/include/imx8m_ccm.h
new file mode 100644
index 0000000..acbd135
--- /dev/null
+++ b/plat/imx/imx8m/include/imx8m_ccm.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, Pengutronix. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8M_CCM_H
+#define IMX8M_CCM_H
+
+unsigned int imx8m_uart_get_base(void);
+
+#endif /* IMX8M_CCM_H */
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 85dfeab..a744d09 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -87,6 +87,18 @@
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
 #define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
 
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
new file mode 100644
index 0000000..a2fafd2
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/synopsys/dw_mmc.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_memory_controller.h"
+#include "agilex5_mmc.h"
+#include "agilex5_pinmux.h"
+#include "agilex5_system_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "combophy/combophy.h"
+#include "nand/nand.h"
+#include "qspi/cadence_qspi.h"
+#include "sdmmc/sdmmc.h"
+#include "socfpga_emac.h"
+#include "socfpga_f2sdram_manager.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+#include "wdt/watchdog.h"
+
+
+/* Declare mmc_info */
+static struct mmc_device_info mmc_info;
+
+/* Declare cadence idmac descriptor */
+extern struct cdns_idmac_desc cdns_desc[8] __aligned(32);
+
+const mmap_region_t agilex_plat_mmap[] = {
+	MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE,
+		MT_MEMORY | MT_RW | MT_NS),
+	MAP_REGION_FLAT(PSS_BASE, PSS_SIZE,
+		MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE,
+		MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CCU_BASE, CCU_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE,
+		MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(GIC_BASE, GIC_SIZE,
+		MT_DEVICE | MT_RW | MT_SECURE),
+	{0},
+};
+
+boot_source_type boot_source = BOOT_SOURCE;
+
+void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
+				u_register_t x2, u_register_t x4)
+{
+	static console_t console;
+
+	handoff reverse_handoff_ptr = { 0 };
+
+	generic_delay_timer_init();
+	config_clkmgr_handoff(&reverse_handoff_ptr);
+	mailbox_init();
+	enable_nonsecure_access();
+
+	deassert_peripheral_reset();
+	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
+		ERROR("Combo Phy initialization failed\n");
+	}
+
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+	PLAT_BAUDRATE, &console);
+
+	/* Store magic number */
+	mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+	handoff reverse_handoff_ptr;
+
+	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+
+	mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
+	mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
+
+	/* Request ownership and direct access to QSPI */
+	mailbox_hps_qspi_enable();
+
+	switch (boot_source) {
+	case BOOT_SOURCE_SDMMC:
+		NOTICE("SDMMC boot\n");
+		sdmmc_init(&reverse_handoff_ptr, &params, &mmc_info);
+		socfpga_io_setup(boot_source);
+		break;
+
+	case BOOT_SOURCE_QSPI:
+		NOTICE("QSPI boot\n");
+		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
+			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
+			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
+		socfpga_io_setup(boot_source);
+		break;
+
+	case BOOT_SOURCE_NAND:
+		NOTICE("NAND boot\n");
+		nand_init(&reverse_handoff_ptr);
+		socfpga_io_setup(boot_source);
+		break;
+
+	default:
+		ERROR("Unsupported boot source\n");
+		panic();
+		break;
+	}
+}
+
+uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+	assert(bl_mem_params);
+
+	switch (image_id) {
+	case BL33_IMAGE_ID:
+		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+		bl_mem_params->ep_info.spsr = get_spsr_for_bl33_entry();
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+}
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
new file mode 100644
index 0000000..5ae4bf7
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include "agilex5_power_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+#define SMMU_SDMMC
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ?
+			  &bl33_image_ep_info : &bl32_image_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	static console_t console;
+
+	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
+
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+	PLAT_BAUDRATE, &console);
+
+	init_ncore_ccu();
+	setup_smmu_stream_id();
+
+	/*
+	 * Check params passed from BL31 should not be NULL,
+	 */
+	void *from_bl2 = (void *) arg0;
+
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	void *plat_params_from_bl2 = (void *) arg3;
+
+	assert(plat_params_from_bl2 == NULL);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+	/*
+	 * According to the file ``Documentation/arm64/booting.txt`` of the
+	 * Linux kernel tree, Linux expects the physical address of the device
+	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+	 * must be 0.
+	 */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
+	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+	assert(params_from_bl2 != NULL);
+
+	/*
+	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
+	 * They are stored in Secure RAM, in BL31's address space.
+	 */
+
+	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+		params_from_bl2->h.version >= VERSION_2) {
+
+		bl_params_node_t *bl_params = params_from_bl2->head;
+
+		while (bl_params) {
+			if (bl_params->image_id == BL33_IMAGE_ID) {
+				bl33_image_ep_info = *bl_params->ep_info;
+			}
+				bl_params = bl_params->next_params_info;
+		}
+	} else {
+		struct socfpga_bl31_params *arg_from_bl2 =
+			(struct socfpga_bl31_params *) from_bl2;
+
+		assert(arg_from_bl2->h.type == PARAM_BL31);
+		assert(arg_from_bl2->h.version >= VERSION_1);
+
+		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
+	}
+
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+static const interrupt_prop_t agx5_interrupt_props[] = {
+	PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+static const gicv3_driver_data_t plat_gicv3_gic_data = {
+	.gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+	.gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE,
+	.interrupt_props = agx5_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+};
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	socfpga_delay_timer_init();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	gicv3_driver_init(&plat_gicv3_gic_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+#if !defined(SIMICS_RUN)
+	ncore_enable_ocram_firewall();
+#endif
+
+}
+
+const mmap_region_t plat_agilex_mmap[] = {
+	MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+	MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+	uint32_t boot_core = 0x00;
+	uint32_t cpuid = 0x00;
+
+	cpuid = read_mpidr();
+	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	NOTICE("BL31: Boot Core = %x\n", boot_core);
+	NOTICE("BL31: CPU ID = %x\n", cpuid);
+
+}
+
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+/* SMP: Secondary cores BL31 setup reset vector */
+void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
+{
+	unsigned int pch_cpu = 0x00;
+	unsigned int pchctlr_old = 0x00;
+	unsigned int pchctlr_new = 0x00;
+	uint32_t boot_core = 0x00;
+
+	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	/* Update the p-channel based on cpu id */
+	pch_cpu = 1 << cpu_id;
+
+	if (boot_core == 0x00) {
+		/* Update reset vector to 0x00 */
+		mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	} else {
+		/* Update reset vector to 0x00 */
+		mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	}
+
+	/* Update reset vector to 0x00 */
+	mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+	mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+
+	/* On all cores - temporary */
+	pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+	pchctlr_new = pchctlr_old | (pch_cpu<<1);
+	mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new);
+
+	/* We will only release the target secondary CPUs */
+	/* Bit mask for each CPU BIT0-3 */
+	mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu);
+}
+
+void bl31_plat_set_secondary_cpu_off(void)
+{
+	unsigned int pch_cpu = 0x00;
+	unsigned int pch_cpu_off = 0x00;
+	unsigned int cpu_id = plat_my_core_pos();
+
+	pch_cpu_off = 1 << cpu_id;
+
+	pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+	pch_cpu = pch_cpu & ~(pch_cpu_off << 1);
+
+	mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
+}
+
+void bl31_plat_enable_mmu(uint32_t flags)
+{
+	/* TODO: Enable mmu when needed */
+}
diff --git a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
new file mode 100644
index 0000000..566a80d
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCKMANAGER_H
+#define CLOCKMANAGER_H
+
+#include "socfpga_handoff.h"
+
+/* Clock Manager Registers */
+#define CLKMGR_OFFSET					0x10d10000
+
+#define CLKMGR_CTRL					0x0
+#define CLKMGR_STAT					0x4
+#define CLKMGR_TESTIOCTROL				0x8
+#define CLKMGR_INTRGEN					0xc
+#define CLKMGR_INTRMSK					0x10
+#define CLKMGR_INTRCLR					0x14
+#define CLKMGR_INTRSTS					0x18
+#define CLKMGR_INTRSTK					0x1c
+#define CLKMGR_INTRRAW					0x20
+
+/* Main PLL Group */
+#define CLKMGR_MAINPLL					0x10d10024
+#define CLKMGR_MAINPLL_EN				0x0
+#define CLKMGR_MAINPLL_ENS				0x4
+#define CLKMGR_MAINPLL_BYPASS				0xc
+#define CLKMGR_MAINPLL_BYPASSS				0x10
+#define CLKMGR_MAINPLL_BYPASSR				0x14
+#define CLKMGR_MAINPLL_NOCCLK				0x1c
+#define CLKMGR_MAINPLL_NOCDIV				0x20
+#define CLKMGR_MAINPLL_PLLGLOB				0x24
+#define CLKMGR_MAINPLL_FDBCK				0x28
+#define CLKMGR_MAINPLL_MEM				0x2c
+#define CLKMGR_MAINPLL_MEMSTAT				0x30
+#define CLKMGR_MAINPLL_VCOCALIB				0x34
+#define CLKMGR_MAINPLL_PLLC0				0x38
+#define CLKMGR_MAINPLL_PLLC1				0x3c
+#define CLKMGR_MAINPLL_PLLC2				0x40
+#define CLKMGR_MAINPLL_PLLC3				0x44
+#define CLKMGR_MAINPLL_PLLM				0x48
+#define CLKMGR_MAINPLL_FHOP				0x4c
+#define CLKMGR_MAINPLL_SSC				0x50
+#define CLKMGR_MAINPLL_LOSTLOCK				0x54
+
+/* Peripheral PLL Group */
+#define CLKMGR_PERPLL					0x10d1007c
+#define CLKMGR_PERPLL_EN				0x0
+#define CLKMGR_PERPLL_ENS				0x4
+#define CLKMGR_PERPLL_BYPASS				0xc
+#define CLKMGR_PERPLL_EMACCTL				0x18
+#define CLKMGR_PERPLL_GPIODIV				0x1c
+#define CLKMGR_PERPLL_PLLGLOB				0x20
+#define CLKMGR_PERPLL_FDBCK				0x24
+#define CLKMGR_PERPLL_MEM				0x28
+#define CLKMGR_PERPLL_MEMSTAT				0x2c
+#define CLKMGR_PERPLL_PLLC0				0x30
+#define CLKMGR_PERPLL_PLLC1				0x34
+#define CLKMGR_PERPLL_VCOCALIB				0x38
+#define CLKMGR_PERPLL_PLLC2				0x3c
+#define CLKMGR_PERPLL_PLLC3				0x40
+#define CLKMGR_PERPLL_PLLM				0x44
+#define CLKMGR_PERPLL_LOSTLOCK				0x50
+
+/* Altera Group */
+#define CLKMGR_ALTERA					0x10d100d0
+#define CLKMGR_ALTERA_JTAG				0x0
+#define CLKMGR_ALTERA_EMACACTR				0x4
+#define CLKMGR_ALTERA_EMACBCTR				0x8
+#define CLKMGR_ALTERA_EMACPTPCTR			0xc
+#define CLKMGR_ALTERA_GPIODBCTR				0x10
+#define CLKMGR_ALTERA_S2FUSER0CTR			0x18
+#define CLKMGR_ALTERA_S2FUSER1CTR			0x1c
+#define CLKMGR_ALTERA_PSIREFCTR				0x20
+#define CLKMGR_ALTERA_EXTCNTRST				0x24
+#define CLKMGR_ALTERA_USB31CTR				0x28
+#define CLKMGR_ALTERA_DSUCTR				0x2c
+#define CLKMGR_ALTERA_CORE01CTR				0x30
+#define CLKMGR_ALTERA_CORE23CTR				0x34
+#define CLKMGR_ALTERA_CORE2CTR				0x38
+#define CLKMGR_ALTERA_CORE3CTR				0x3c
+
+/* Membus */
+#define CLKMGR_MEM_REQ					BIT(24)
+#define CLKMGR_MEM_WR					BIT(25)
+#define CLKMGR_MEM_ERR					BIT(26)
+#define CLKMGR_MEM_WDAT_OFFSET				16
+#define CLKMGR_MEM_ADDR					0x4027
+#define CLKMGR_MEM_WDAT					0x80
+
+/* Clock Manager Macros */
+#define CLKMGR_CTRL_BOOTMODE_SET_MSK			0x00000001
+#define CLKMGR_STAT_BUSY_E_BUSY				0x1
+#define CLKMGR_STAT_BUSY(x)				(((x) & 0x00000001) >> 0)
+#define CLKMGR_STAT_MAINPLLLOCKED(x)			(((x) & 0x00000100) >> 8)
+#define CLKMGR_STAT_PERPLLLOCKED(x)			(((x) & 0x00010000) >> 16)
+#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK		0x00000004
+#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK		0x00000008
+#define CLKMGR_INTOSC_HZ				460000000
+
+/* Main PLL Macros */
+#define CLKMGR_MAINPLL_EN_RESET				0x0000005e
+#define CLKMGR_MAINPLL_ENS_RESET			0x0000005e
+
+/* Peripheral PLL Macros */
+#define CLKMGR_PERPLL_EN_RESET				0x040007FF
+#define CLKMGR_PERPLL_ENS_RESET			0x040007FF
+
+#define CLKMGR_PERPLL_EN_SDMMCCLK			BIT(5)
+#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)		(((x) << 0) & 0x0000ffff)
+
+/* Altera Macros */
+#define CLKMGR_ALTERA_EXTCNTRST_RESET			0xff
+
+/* Shared Macros */
+#define CLKMGR_PSRC(x)					(((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN				0
+#define CLKMGR_PSRC_PER					1
+
+#define CLKMGR_PLLGLOB_PSRC_EOSC1			0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC			0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S				0x2
+
+#define CLKMGR_PLLM_MDIV(x)				((x) & 0x000003ff)
+#define CLKMGR_PLLGLOB_PD_SET_MSK			0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK			0x00000002
+
+#define CLKMGR_PLLGLOB_REFCLKDIV(x)			(((x) & 0x00003f00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x)			(((x) & 0x00000f00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x)			(((x) & 0x00003000) >> 12)
+
+#define CLKMGR_VCOCALIB_HSCNT_SET(x)			(((x) << 0) & 0x000003ff)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x)			(((x) << 16) & 0x00ff0000)
+
+#define CLKMGR_CLR_LOSTLOCK_BYPASS			0x20000000
+
+typedef struct {
+	uint32_t  clk_freq_of_eosc1;
+	uint32_t  clk_freq_of_f2h_free;
+	uint32_t  clk_freq_of_cb_intosc_ls;
+} CLOCK_SOURCE_CONFIG;
+
+void config_clkmgr_handoff(handoff *hoff_ptr);
+uint32_t get_wdt_clk(void);
+uint32_t get_uart_clk(void);
+uint32_t get_mmc_clk(void);
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_memory_controller.h b/plat/intel/soc/agilex5/include/agilex5_memory_controller.h
new file mode 100644
index 0000000..1708488
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_memory_controller.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX_MEMORYCONTROLLER_H
+#define AGX_MEMORYCONTROLLER_H
+
+#include "socfpga_plat_def.h"
+
+#define AGX_MPFE_IOHMC_REG_DRAMADDRW				0xf80100a8
+#define AGX_MPFE_IOHMC_CTRLCFG0					0xf8010028
+#define AGX_MPFE_IOHMC_CTRLCFG1					0xf801002c
+#define AGX_MPFE_IOHMC_CTRLCFG2					0xf8010030
+#define AGX_MPFE_IOHMC_CTRLCFG3					0xf8010034
+#define AGX_MPFE_IOHMC_DRAMADDRW				0xf80100a8
+#define AGX_MPFE_IOHMC_DRAMTIMING0				0xf8010050
+#define AGX_MPFE_IOHMC_CALTIMING0				0xf801007c
+#define AGX_MPFE_IOHMC_CALTIMING1				0xf8010080
+#define AGX_MPFE_IOHMC_CALTIMING2				0xf8010084
+#define AGX_MPFE_IOHMC_CALTIMING3				0xf8010088
+#define AGX_MPFE_IOHMC_CALTIMING4				0xf801008c
+#define AGX_MPFE_IOHMC_CALTIMING9				0xf80100a0
+#define AGX_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(x)			(((x) & 0x000000ff) >> 0)
+#define AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value)		(((value) & 0x00000060) >> 5)
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL1				0xf8011100
+#define AGX_MPFE_HMC_ADP_ECCCTRL2				0xf8011104
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT			0xf8011218
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE		0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL			0xf8011214
+
+
+#define AGX_MPFE_IOHMC_REG_CTRLCFG1				0xf801002c
+
+#define AGX_MPFE_IOHMC_REG_NIOSRESERVE0_OFST			0xf8010110
+
+#define IOHMC_DRAMADDRW_COL_ADDR_WIDTH(x)			(((x) & 0x0000001f) >> 0)
+#define IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(x)			(((x) & 0x000003e0) >> 5)
+#define IOHMC_DRAMADDRW_CS_ADDR_WIDTH(x)			(((x) & 0x00070000) >> 16)
+#define IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(x)			(((x) & 0x0000c000) >> 14)
+#define IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(x)			(((x) & 0x00003c00) >> 10)
+
+#define AGX_MPFE_DDR(x)						(0xf8000000 + x)
+#define AGX_MPFE_HMC_ADP_DDRCALSTAT				0xf801100c
+#define AGX_MPFE_DDR_MAIN_SCHED					0xf8000400
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF				0xf8000408
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRTIMING			0xf800040c
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK			0x0000001f
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRMODE				0xf8000410
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV			0xf800043c
+#define AGX_MPFE_DDR_MAIN_SCHED_READLATENCY			0xf8000414
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE			0xf8000438
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST		10
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST		4
+#define AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST		0
+#define AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(x)			(((x) << 0) & 0x0000001f)
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST		0
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK		(BIT(0) | BIT(1))
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST		2
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK		(BIT(2) | BIT(3))
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST		4
+#define AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK		(BIT(4) | BIT(5))
+
+#define AGX_MPFE_HMC_ADP(x)					(0xf8011000 + (x))
+#define AGX_MPFE_HMC_ADP_HPSINTFCSEL				0xf8011210
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL				0xf8011008
+#define HMC_ADP_DDRIOCTRL					0x8
+#define HMC_ADP_DDRIOCTRL_IO_SIZE(x)				(((x) & 0x00000003) >> 0)
+#define HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(x)			(((x) & 0x00003e00) >> 9)
+#define ADP_DRAMADDRWIDTH					0xe0
+
+#define ACT_TO_ACT_DIFF_BANK(value)				(((value) & 0x00fc0000) >> 18)
+#define ACT_TO_ACT(value)					(((value) & 0x0003f000) >> 12)
+#define ACT_TO_RDWR(value)					(((value) & 0x0000003f) >> 0)
+#define ACT_TO_ACT(value)					(((value) & 0x0003f000) >> 12)
+
+/* timing 2 */
+#define RD_TO_RD_DIFF_CHIP(value)				(((value) & 0x00000fc0) >> 6)
+#define RD_TO_WR_DIFF_CHIP(value)				(((value) & 0x3f000000) >> 24)
+#define RD_TO_WR(value)						(((value) & 0x00fc0000) >> 18)
+#define RD_TO_PCH(value)					(((value) & 0x00000fc0) >> 6)
+
+/* timing 3 */
+#define CALTIMING3_WR_TO_RD_DIFF_CHIP(value)			(((value) & 0x0003f000) >> 12)
+#define CALTIMING3_WR_TO_RD(value)				(((value) & 0x00000fc0) >> 6)
+
+/* timing 4 */
+#define PCH_TO_VALID(value)					(((value) & 0x00000fc0) >> 6)
+
+#define DDRTIMING_BWRATIO_OFST					31
+#define DDRTIMING_WRTORD_OFST					26
+#define DDRTIMING_RDTOWR_OFST					21
+#define DDRTIMING_BURSTLEN_OFST					18
+#define DDRTIMING_WRTOMISS_OFST					12
+#define DDRTIMING_RDTOMISS_OFST					6
+#define DDRTIMING_ACTTOACT_OFST					0
+
+#define ADP_DDRIOCTRL_IO_SIZE(x)				(((x) & 0x3) >> 0)
+
+#define DDRMODE_AUTOPRECHARGE_OFST				1
+#define DDRMODE_BWRATIOEXTENDED_OFST				0
+
+
+#define AGX_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(x)		(((x) & 0x7f) >> 0)
+#define AGX_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(x)		(((x) & 0x0f) >> 0)
+
+#define AGX_CCU_CPU0_MPRT_DDR					0xf7004400
+#define AGX_CCU_CPU0_MPRT_MEM0					0xf70045c0
+#define AGX_CCU_CPU0_MPRT_MEM1A					0xf70045e0
+#define AGX_CCU_CPU0_MPRT_MEM1B					0xf7004600
+#define AGX_CCU_CPU0_MPRT_MEM1C					0xf7004620
+#define AGX_CCU_CPU0_MPRT_MEM1D					0xf7004640
+#define AGX_CCU_CPU0_MPRT_MEM1E					0xf7004660
+#define AGX_CCU_IOM_MPRT_MEM0					0xf7018560
+#define AGX_CCU_IOM_MPRT_MEM1A					0xf7018580
+#define	AGX_CCU_IOM_MPRT_MEM1B					0xf70185a0
+#define	AGX_CCU_IOM_MPRT_MEM1C					0xf70185c0
+#define	AGX_CCU_IOM_MPRT_MEM1D					0xf70185e0
+#define	AGX_CCU_IOM_MPRT_MEM1E					0xf7018600
+
+#define AGX_NOC_FW_DDR_SCR					0xf8020200
+#define AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT		0xf802021c
+#define AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT			0xf8020218
+#define AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT		0xf802029c
+#define AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT		0xf8020298
+
+#define AGX_SOC_NOC_FW_DDR_SCR_ENABLE				0xf8020200
+#define AGX_SOC_NOC_FW_DDR_SCR_ENABLESET			0xf8020204
+#define AGX_CCU_NOC_DI_SET_MSK					0x10
+
+#define AGX_SYSMGR_CORE_HMC_CLK					0xffd120b4
+#define AGX_SYSMGR_CORE_HMC_CLK_STATUS				0x00000001
+
+#define AGX_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0(x)		(((x) & 0xffff) >> 0)
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_MSK			0x00000003
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_OFST			0
+#define AGX_MPFE_HMC_ADP_HPSINTFCSEL_ENABLE			0x001f1f1f
+#define AGX_IOHMC_CTRLCFG1_ENABLE_ECC_OFST			7
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK	0x00010000
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK		0x00000100
+#define AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK		0x00000001
+
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK		0x00000001
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK	0x00010000
+#define AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK		0x00000100
+#define AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(value)			(((value) & 0x1) >> 0)
+
+
+#define AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(x)			(((x) & 0x00003) >> 0)
+#define IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(x)			(((x) & 0x03c00) >> 10)
+#define IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(x)		(((x) & 0x0c000) >> 14)
+#define IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(x)			(((x) & 0x0001f) >> 0)
+#define IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(x)			(((x) & 0x70000) >> 16)
+#define IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(x)			(((x) & 0x003e0) >> 5)
+
+#define AGX_SDRAM_0_LB_ADDR					0x0
+#define AGX_DDR_SIZE						0x40000000
+
+/* Macros */
+#define SOCFPGA_MEMCTRL_ECCCTRL1				0x008
+#define SOCFPGA_MEMCTRL_ERRINTEN				0x010
+#define SOCFPGA_MEMCTRL_ERRINTENS				0x014
+#define SOCFPGA_MEMCTRL_ERRINTENR				0x018
+#define SOCFPGA_MEMCTRL_INTMODE					0x01C
+#define SOCFPGA_MEMCTRL_INTSTAT					0x020
+#define SOCFPGA_MEMCTRL_DIAGINTTEST				0x024
+#define SOCFPGA_MEMCTRL_DERRADDRA				0x02C
+
+#define SOCFPGA_MEMCTRL(_reg)					(SOCFPGA_MEMCTRL_REG_BASE \
+								+ (SOCFPGA_MEMCTRL_##_reg))
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_mmc.h b/plat/intel/soc/agilex5/include/agilex5_mmc.h
new file mode 100644
index 0000000..c8a5fba
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_mmc.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+void agx5_mmc_init(void);
diff --git a/plat/intel/soc/agilex5/include/agilex5_pinmux.h b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
new file mode 100644
index 0000000..8a8e8c7
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX5_PINMUX_H
+#define AGX5_PINMUX_H
+
+/* PINMUX REGISTER ADDRESS */
+#define AGX5_PINMUX_PIN0SEL					0x10d13000
+#define AGX5_PINMUX_IO0CTRL					0x10d13130
+#define AGX5_PINMUX_EMAC0_USEFPGA				0x10d13300
+#define AGX5_PINMUX_IO0_DELAY					0x10d13400
+#define AGX5_PERIPHERAL						0x10d14044
+
+#include "socfpga_handoff.h"
+
+/* PINMUX DEFINE */
+#define PINMUX_HANDOFF_ARRAY_SIZE(x)				(sizeof(x) / sizeof((x)[0]))
+#define PINMUX_HANDOFF_CONFIG_ADDR				0xbeec
+#define PINMUX_HANDOFF_CONFIG_VAL				0x7e000
+
+/* Macros */
+#define SOCFPGA_PINMUX_SEL_NAND					(0x03)
+#define SOCFPGA_PINMUX_PIN0SEL					(0x00)
+#define SOCFPGA_PINMUX_PIN1SEL					(0x04)
+#define SOCFPGA_PINMUX_PIN2SEL					(0x08)
+#define SOCFPGA_PINMUX_PIN3SEL					(0x0C)
+#define SOCFPGA_PINMUX_PIN4SEL					(0x10)
+#define SOCFPGA_PINMUX_PIN5SEL					(0x14)
+#define SOCFPGA_PINMUX_PIN6SEL					(0x18)
+#define SOCFPGA_PINMUX_PIN7SEL					(0x1C)
+#define SOCFPGA_PINMUX_PIN8SEL					(0x20)
+#define SOCFPGA_PINMUX_PIN9SEL					(0x24)
+#define SOCFPGA_PINMUX_PIN10SEL					(0x28)
+#define SOCFPGA_PINMUX_PIN11SEL					(0x2C)
+#define SOCFPGA_PINMUX_PIN12SEL					(0x30)
+#define SOCFPGA_PINMUX_PIN13SEL					(0x34)
+#define SOCFPGA_PINMUX_PIN14SEL					(0x38)
+#define SOCFPGA_PINMUX_PIN15SEL					(0x3C)
+#define SOCFPGA_PINMUX_PIN16SEL					(0x40)
+#define SOCFPGA_PINMUX_PIN17SEL					(0x44)
+#define SOCFPGA_PINMUX_PIN18SEL					(0x48)
+#define SOCFPGA_PINMUX_PIN19SEL					(0x4C)
+#define SOCFPGA_PINMUX_PIN20SEL					(0x50)
+#define SOCFPGA_PINMUX_PIN21SEL					(0x54)
+#define SOCFPGA_PINMUX_PIN22SEL					(0x58)
+#define SOCFPGA_PINMUX_PIN23SEL					(0x5C)
+#define SOCFPGA_PINMUX_PIN24SEL					(0x60)
+#define SOCFPGA_PINMUX_PIN25SEL					(0x64)
+#define SOCFPGA_PINMUX_PIN26SEL					(0x68)
+#define SOCFPGA_PINMUX_PIN27SEL					(0x6C)
+#define SOCFPGA_PINMUX_PIN28SEL					(0x70)
+#define SOCFPGA_PINMUX_PIN29SEL					(0x74)
+#define SOCFPGA_PINMUX_PIN30SEL					(0x78)
+#define SOCFPGA_PINMUX_PIN31SEL					(0x7C)
+#define SOCFPGA_PINMUX_PIN32SEL					(0x80)
+#define SOCFPGA_PINMUX_PIN33SEL					(0x84)
+#define SOCFPGA_PINMUX_PIN34SEL					(0x88)
+#define SOCFPGA_PINMUX_PIN35SEL					(0x8C)
+#define SOCFPGA_PINMUX_PIN36SEL					(0x90)
+#define SOCFPGA_PINMUX_PIN37SEL					(0x94)
+#define SOCFPGA_PINMUX_PIN38SEL					(0x98)
+#define SOCFPGA_PINMUX_PIN39SEL					(0x9C)
+#define SOCFPGA_PINMUX_PIN40SEL					(0x100)
+#define SOCFPGA_PINMUX_PIN41SEL					(0x104)
+#define SOCFPGA_PINMUX_PIN42SEL					(0x108)
+#define SOCFPGA_PINMUX_PIN43SEL					(0x10C)
+#define SOCFPGA_PINMUX_PIN44SEL					(0x110)
+#define SOCFPGA_PINMUX_PIN45SEL					(0x114)
+#define SOCFPGA_PINMUX_PIN46SEL					(0x118)
+#define SOCFPGA_PINMUX_PIN47SEL					(0x11C)
+
+#define SOCFPGA_PINMUX_IO0CTRL					(0x00)
+#define SOCFPGA_PINMUX_IO1CTRL					(0x04)
+#define SOCFPGA_PINMUX_IO2CTRL					(0x08)
+#define SOCFPGA_PINMUX_IO3CTRL					(0x0C)
+#define SOCFPGA_PINMUX_IO4CTRL					(0x10)
+#define SOCFPGA_PINMUX_IO5CTRL					(0x14)
+#define SOCFPGA_PINMUX_IO6CTRL					(0x18)
+#define SOCFPGA_PINMUX_IO7CTRL					(0x1C)
+#define SOCFPGA_PINMUX_IO8CTRL					(0x20)
+#define SOCFPGA_PINMUX_IO9CTRL					(0x24)
+#define SOCFPGA_PINMUX_IO10CTRL					(0x28)
+#define SOCFPGA_PINMUX_IO11CTRL					(0x2C)
+#define SOCFPGA_PINMUX_IO12CTRL					(0x30)
+#define SOCFPGA_PINMUX_IO13CTRL					(0x34)
+#define SOCFPGA_PINMUX_IO14CTRL					(0x38)
+#define SOCFPGA_PINMUX_IO15CTRL					(0x3C)
+#define SOCFPGA_PINMUX_IO16CTRL					(0x40)
+#define SOCFPGA_PINMUX_IO17CTRL					(0x44)
+#define SOCFPGA_PINMUX_IO18CTRL					(0x48)
+#define SOCFPGA_PINMUX_IO19CTRL					(0x4C)
+#define SOCFPGA_PINMUX_IO20CTRL					(0x50)
+#define SOCFPGA_PINMUX_IO21CTRL					(0x54)
+#define SOCFPGA_PINMUX_IO22CTRL					(0x58)
+#define SOCFPGA_PINMUX_IO23CTRL					(0x5C)
+#define SOCFPGA_PINMUX_IO24CTRL					(0x60)
+#define SOCFPGA_PINMUX_IO25CTRL					(0x64)
+#define SOCFPGA_PINMUX_IO26CTRL					(0x68)
+#define SOCFPGA_PINMUX_IO27CTRL					(0x6C)
+#define SOCFPGA_PINMUX_IO28CTRL					(0xD0)
+#define SOCFPGA_PINMUX_IO29CTRL					(0xD4)
+#define SOCFPGA_PINMUX_IO30CTRL					(0xD8)
+#define SOCFPGA_PINMUX_IO31CTRL					(0xDC)
+#define SOCFPGA_PINMUX_IO32CTRL					(0xE0)
+#define SOCFPGA_PINMUX_IO33CTRL					(0xE4)
+#define SOCFPGA_PINMUX_IO34CTRL					(0xE8)
+#define SOCFPGA_PINMUX_IO35CTRL					(0xEC)
+#define SOCFPGA_PINMUX_IO36CTRL					(0xF0)
+#define SOCFPGA_PINMUX_IO37CTRL					(0xF4)
+#define SOCFPGA_PINMUX_IO38CTRL					(0xF8)
+#define SOCFPGA_PINMUX_IO39CTRL					(0xFC)
+#define SOCFPGA_PINMUX_IO40CTRL					(0x100)
+#define SOCFPGA_PINMUX_IO41CTRL					(0x104)
+#define SOCFPGA_PINMUX_IO42CTRL					(0x108)
+#define SOCFPGA_PINMUX_IO43CTRL					(0x10C)
+#define SOCFPGA_PINMUX_IO44CTRL					(0x110)
+#define SOCFPGA_PINMUX_IO45CTRL					(0x114)
+#define SOCFPGA_PINMUX_IO46CTRL					(0x118)
+#define SOCFPGA_PINMUX_IO47CTRL					(0x11C)
+
+#define SOCFPGA_PINMUX_EMAC0_USEFPGA				(0x00)
+#define SOCFPGA_PINMUX_EMAC1_USEFPGA				(0x04)
+#define SOCFPGA_PINMUX_EMAC2_USEFPGA				(0x08)
+#define SOCFPGA_PINMUX_I2C0_USEFPGA				(0x0C)
+#define SOCFPGA_PINMUX_I2C1_USEFPGA				(0x10)
+#define SOCFPGA_PINMUX_I2C_EMAC0_USEFPGA			(0x14)
+#define SOCFPGA_PINMUX_I2C_EMAC1_USEFPGA			(0x18)
+#define SOCFPGA_PINMUX_I2C_EMAC2_USEFPGA			(0x1C)
+#define SOCFPGA_PINMUX_NAND_USEFPGA				(0x20)
+#define SOCFPGA_PINMUX_SPIM0_USEFPGA				(0x28)
+#define SOCFPGA_PINMUX_SPIM1_USEFPGA				(0x2C)
+#define SOCFPGA_PINMUX_SPIS0_USEFPGA				(0x30)
+#define SOCFPGA_PINMUX_SPIS1_USEFPGA				(0x34)
+#define SOCFPGA_PINMUX_UART0_USEFPGA				(0x38)
+#define SOCFPGA_PINMUX_UART1_USEFPGA				(0x3C)
+#define SOCFPGA_PINMUX_MDIO0_USEFPGA				(0x40)
+#define SOCFPGA_PINMUX_MDIO1_USEFPGA				(0x44)
+#define SOCFPGA_PINMUX_MDIO2_USEFPGA				(0x48)
+#define SOCFPGA_PINMUX_JTAG_USEFPGA				(0x50)
+#define SOCFPGA_PINMUX_SDMMC_USEFPGA				(0x54)
+
+#define SOCFPGA_PINMUX_IO0DELAY					(0x00)
+#define SOCFPGA_PINMUX_IO1DELAY					(0x04)
+#define SOCFPGA_PINMUX_IO2DELAY					(0x08)
+#define SOCFPGA_PINMUX_IO3DELAY					(0x0C)
+#define SOCFPGA_PINMUX_IO4DELAY					(0x10)
+#define SOCFPGA_PINMUX_IO5DELAY					(0x14)
+#define SOCFPGA_PINMUX_IO6DELAY					(0x18)
+#define SOCFPGA_PINMUX_IO7DELAY					(0x1C)
+#define SOCFPGA_PINMUX_IO8DELAY					(0x20)
+#define SOCFPGA_PINMUX_IO9DELAY					(0x24)
+#define SOCFPGA_PINMUX_IO10DELAY				(0x28)
+#define SOCFPGA_PINMUX_IO11DELAY				(0x2C)
+#define SOCFPGA_PINMUX_IO12DELAY				(0x30)
+#define SOCFPGA_PINMUX_IO13DELAY				(0x34)
+#define SOCFPGA_PINMUX_IO14DELAY				(0x38)
+#define SOCFPGA_PINMUX_IO15DELAY				(0x3C)
+#define SOCFPGA_PINMUX_IO16DELAY				(0x40)
+#define SOCFPGA_PINMUX_IO17DELAY				(0x44)
+#define SOCFPGA_PINMUX_IO18DELAY				(0x48)
+#define SOCFPGA_PINMUX_IO19DELAY				(0x4C)
+#define SOCFPGA_PINMUX_IO20DELAY				(0x50)
+#define SOCFPGA_PINMUX_IO21DELAY				(0x54)
+#define SOCFPGA_PINMUX_IO22DELAY				(0x58)
+#define SOCFPGA_PINMUX_IO23DELAY				(0x5C)
+#define SOCFPGA_PINMUX_IO24DELAY				(0x60)
+#define SOCFPGA_PINMUX_IO25DELAY				(0x64)
+#define SOCFPGA_PINMUX_IO26DELAY				(0x68)
+#define SOCFPGA_PINMUX_IO27DELAY				(0x6C)
+#define SOCFPGA_PINMUX_IO28DELAY				(0x70)
+#define SOCFPGA_PINMUX_IO29DELAY				(0x74)
+#define SOCFPGA_PINMUX_IO30DELAY				(0x78)
+#define SOCFPGA_PINMUX_IO31DELAY				(0x7C)
+#define SOCFPGA_PINMUX_IO32DELAY				(0x80)
+#define SOCFPGA_PINMUX_IO33DELAY				(0x84)
+#define SOCFPGA_PINMUX_IO34DELAY				(0x88)
+#define SOCFPGA_PINMUX_IO35DELAY				(0x8C)
+#define SOCFPGA_PINMUX_IO36DELAY				(0x90)
+#define SOCFPGA_PINMUX_IO37DELAY				(0x94)
+#define SOCFPGA_PINMUX_IO38DELAY				(0x98)
+#define SOCFPGA_PINMUX_IO39DELAY				(0x9C)
+#define SOCFPGA_PINMUX_IO40DELAY				(0xA0)
+#define SOCFPGA_PINMUX_IO41DELAY				(0xA4)
+#define SOCFPGA_PINMUX_IO42DELAY				(0xA8)
+#define SOCFPGA_PINMUX_IO43DELAY				(0xAC)
+#define SOCFPGA_PINMUX_IO44DELAY				(0xB0)
+#define SOCFPGA_PINMUX_IO45DELAY				(0xB4)
+#define SOCFPGA_PINMUX_IO46DELAY				(0xB8)
+#define SOCFPGA_PINMUX_IO47DELAY				(0xBC)
+
+#define SOCFPGA_PINMUX_I3C0_USEFPGA				(0xC0)
+#define SOCFPGA_PINMUX_I3C1_USEFPGA				(0xC4)
+
+#define SOCFPGA_PINMUX(_reg)					(SOCFPGA_PINMUX_REG_BASE \
+								+ (SOCFPGA_PINMUX_##_reg))
+
+void config_pinmux(handoff *handoff);
+void config_peripheral(handoff *handoff);
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
new file mode 100644
index 0000000..1bba74b
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POWERMANAGER_H
+#define POWERMANAGER_H
+
+#include "socfpga_handoff.h"
+
+#define AGX5_PWRMGR_BASE					0x10d14000
+
+/* DSU */
+#define AGX5_PWRMGR_DSU_FWENCTL					0x0
+#define AGX5_PWRMGR_DSU_PGENCTL					0x4
+#define AGX5_PWRMGR_DSU_PGSTAT					0x8
+#define AGX5_PWRMGR_DSU_PWRCTLR					0xc
+#define AGX5_PWRMGR_DSU_PWRSTAT0				0x10
+#define AGX5_PWRMGR_DSU_PWRSTAT1				0x14
+
+/* DSU Macros*/
+#define AGX5_PWRMGR_DSU_FWEN(x)					((x) & 0xf)
+#define AGX5_PWRMGR_DSU_PGEN(x)					((x) & 0xf)
+#define AGX5_PWRMGR_DSU_PGEN_OUT(x)				((x) & 0xf)
+#define AGX5_PWRMGR_DSU_SINGLE_PACCEPT(x)			((x) & 0x1)
+#define AGX5_PWRMGR_DSU_SINGLE_PDENY(x)				(((x) & 0x1) << 1)
+#define AGX5_PWRMGR_DSU_SINGLE_FSM_STATE(x)			(((x) & 0xff) << 8)
+#define AGX5_PWRMGR_DSU_SINGLE_PCH_DONE(x)			(((x) & 0x1) << 31)
+#define AGX5_PWRMGR_DSU_MULTI_PACTIVE_IN(x)			((x) & 0xff)
+#define AGX5_PWRMGR_DSU_MULTI_PACCEPT(x)			(((x) & 0xff) << 8)
+#define AGX5_PWRMGR_DSU_MULTI_PDENY(x)				(((x) & 0xff) << 16)
+#define AGX5_PWRMGR_DSU_MULTI_PCH_DONE(x)			(((x) & 0x1) << 31)
+
+/* CPU */
+#define AGX5_PWRMGR_CPU_PWRCTLR0				0x18
+#define AGX5_PWRMGR_CPU_PWRCTLR1				0x20
+#define AGX5_PWRMGR_CPU_PWRCTLR2				0x28
+#define AGX5_PWRMGR_CPU_PWRCTLR3				0x30
+#define AGX5_PWRMGR_CPU_PWRSTAT0				0x1c
+#define AGX5_PWRMGR_CPU_PWRSTAT1				0x24
+#define AGX5_PWRMGR_CPU_PWRSTAT2				0x2c
+#define AGX5_PWRMGR_CPU_PWRSTAT3				0x34
+
+/* APS */
+#define AGX5_PWRMGR_APS_FWENCTL					0x38
+#define AGX5_PWRMGR_APS_PGENCTL					0x3C
+#define AGX5_PWRMGR_APS_PGSTAT					0x40
+
+/* PSS */
+#define AGX5_PWRMGR_PSS_FWENCTL					0x44
+#define AGX5_PWRMGR_PSS_PGENCTL					0x48
+#define AGX5_PWRMGR_PSS_PGSTAT					0x4c
+
+/* PSS Macros*/
+#define AGX5_PWRMGR_PSS_FWEN(x)					((x) & 0xff)
+#define AGX5_PWRMGR_PSS_PGEN(x)					((x) & 0xff)
+#define AGX5_PWRMGR_PSS_PGEN_OUT(x)				((x) & 0xff)
+
+/* MPU */
+#define AGX5_PWRMGR_MPU_PCHCTLR					0x50
+#define AGX5_PWRMGR_MPU_PCHSTAT					0x54
+#define AGX5_PWRMGR_MPU_BOOTCONFIG				0x58
+#define AGX5_PWRMGR_CPU_POWER_STATE_MASK			0x1E
+
+/* MPU Macros*/
+#define AGX5_PWRMGR_MPU_TRIGGER_PCH_DSU(x)			((x) & 0x1)
+#define AGX5_PWRMGR_MPU_TRIGGER_PCH_CPU(x)			(((x) & 0xf) << 1)
+#define AGX5_PWRMGR_MPU_STATUS_PCH_CPU(x)			(((x) & 0xf) << 1)
+
+/* Shared Macros */
+#define AGX5_PWRMGR(_reg)					(AGX5_PWRMGR_BASE + \
+								(AGX5_PWRMGR_##_reg))
+
+/* POWER MANAGER ERROR CODE */
+#define AGX5_PWRMGR_HANDOFF_PERIPHERAL				-1
+#define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY			0x0
+#define AGX5_PWRMGR_PSS_STAT_BUSY(x)				(((x) & 0x000000FF) >> 0)
+
+int pss_sram_power_off(handoff *hoff_ptr);
+int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
+
+#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
new file mode 100644
index 0000000..9a58cdb
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef AGX5_SOCFPGA_SYSTEMMANAGER_H
+#define AGX5_SOCFPGA_SYSTEMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* System Manager Register Map */
+#define SOCFPGA_SYSMGR_SILICONID_1					0x00
+#define SOCFPGA_SYSMGR_SILICONID_2					0x04
+#define SOCFPGA_SYSMGR_WDDBG						0x08
+#define SOCFPGA_SYSMGR_MPU_STATUS					0x10
+#define SOCFPGA_SYSMGR_SDMMC_L3_MASTER					0x2C
+#define SOCFPGA_SYSMGR_NAND_L3_MASTER					0x34
+#define SOCFPGA_SYSMGR_USB0_L3_MASTER					0x38
+#define SOCFPGA_SYSMGR_USB1_L3_MASTER					0x3C
+#define SOCFPGA_SYSMGR_TSN_GLOBAL					0x40
+#define SOCFPGA_SYSMGR_EMAC_0						0x44 /* TSN_0 */
+#define SOCFPGA_SYSMGR_EMAC_1						0x48 /* TSN_1 */
+#define SOCFPGA_SYSMGR_EMAC_2						0x4C /* TSN_2 */
+#define SOCFPGA_SYSMGR_TSN_0_ACE					0x50
+#define SOCFPGA_SYSMGR_TSN_1_ACE					0x54
+#define SOCFPGA_SYSMGR_TSN_2_ACE					0x58
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_1					0x68
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2					0x6C
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3					0x70
+#define SOCFPGA_SYSMGR_DMAC0_L3_MASTER					0x74
+#define SOCFPGA_SYSMGR_ETR_L3_MASTER					0x78
+#define SOCFPGA_SYSMGR_DMAC1_L3_MASTER					0x7C
+#define SOCFPGA_SYSMGR_SEC_CTRL_SLT					0x80
+#define SOCFPGA_SYSMGR_OSC_TRIM						0x84
+#define SOCFPGA_SYSMGR_DMAC0_CTRL_STATUS_REG				0x88
+#define SOCFPGA_SYSMGR_DMAC1_CTRL_STATUS_REG				0x8C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_VALUE				0x90
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SET					0x94
+#define SOCFPGA_SYSMGR_ECC_INTMASK_CLR					0x98
+#define SOCFPGA_SYSMGR_ECC_INTMASK_SERR					0x9C
+#define SOCFPGA_SYSMGR_ECC_INTMASK_DERR					0xA0
+/* NOC configuration value */
+#define SOCFPGA_SYSMGR_NOC_TIMEOUT					0xC0
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET					0xC4
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR					0xC8
+#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL					0xCC
+#define SOCFPGA_SYSMGR_NOC_IDLEACK					0xD0
+#define SOCFPGA_SYSMGR_NOC_IDLESTATUS					0xD4
+#define SOCFPGA_SYSMGR_FPGA2SOC_CTRL					0xD8
+#define SOCFPGA_SYSMGR_FPGA_CFG						0xDC
+#define SOCFPGA_SYSMGR_GPO						0xE4
+#define SOCFPGA_SYSMGR_GPI						0xE8
+#define SOCFPGA_SYSMGR_MPU						0xF0
+#define SOCFPGA_SYSMGR_SDM_HPS_SPARE					0xF4
+#define SOCFPGA_SYSMGR_HPS_SDM_SPARE					0xF8
+#define SOCFPGA_SYSMGR_DFI_INTF						0xFC
+#define SOCFPGA_SYSMGR_NAND_DD_CTRL					0x100
+#define SOCFPGA_SYSMGR_NAND_PHY_CTRL_REG				0x104
+#define SOCFPGA_SYSMGR_NAND_PHY_TSEL_REG				0x108
+#define SOCFPGA_SYSMGR_NAND_DQ_TIMING_REG				0x10C
+#define SOCFPGA_SYSMGR_PHY_DQS_TIMING_REG				0x110
+#define SOCFPGA_SYSMGR_NAND_PHY_GATE_LPBK_CTRL_REG			0x114
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_MASTER_CTRL_REG			0x118
+#define SOCFPGA_SYSMGR_NAND_PHY_DLL_SLAVE_CTRL_REG			0x11C
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG0			0x120
+#define SOCFPGA_SYSMGR_NAND_DD_DEFAULT_SETTING_REG1			0x124
+#define SOCFPGA_SYSMGR_NAND_DD_STATUS_REG				0x128
+#define SOCFPGA_SYSMGR_NAND_DD_ID_LOW_REG				0x12C
+#define SOCFPGA_SYSMGR_NAND_DD_ID_HIGH_REG				0x130
+#define SOCFPGA_SYSMGR_NAND_WRITE_PROT_EN_REG				0x134
+#define SOCFPGA_SYSMGR_SDMMC_CMD_QUEUE_SETTING_REG			0x138
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_LOW					0x13C
+#define SOCFPGA_SYSMGR_I3C_SLV_PID_HIGH					0x140
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_0					0x144
+#define SOCFPGA_SYSMGR_I3C_SLV_CTRL_1					0x148
+#define SOCFPGA_SYSMGR_F2S_BRIDGE_CTRL					0x14C
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA0			0x150
+#define SOCFPGA_SYSMGR_DMA_TBU_STASH_CTRL_REG_0_DMA1			0x154
+#define SOCFPGA_SYSMGR_SDM_TBU_STASH_CTRL_REG_1_SDM			0x158
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB2			0x15C
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_USB3			0x160
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_SDMMC			0x164
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_NAND			0x168
+#define SOCFPGA_SYSMGR_IO_TBU_STASH_CTRL_REG_2_ETR			0x16C
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN0			0x170
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN1			0x174
+#define SOCFPGA_SYSMGR_TSN_TBU_STASH_CTRL_REG_3_TSN2			0x178
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA0			0x17C
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_CTRL_REG_0_DMA1			0x180
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_CTRL_REG_1_SDM			0x184
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB2			0x188
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_USB3			0x18C
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_SDMMC			0x190
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_NAND			0x194
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_CTRL_REG_2_ETR			0x198
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN0			0x19C
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN1			0x1A0
+#define SOCFPGA_SYSMGR_TSN_TBU_STREAM_CTRL_REG_3_TSN2			0x1A4
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA0			0x1A8
+#define SOCFPGA_SYSMGR_DMA_TBU_STREAM_ID_AX_REG_0_DMA1			0x1AC
+#define SOCFPGA_SYSMGR_SDM_TBU_STREAM_ID_AX_REG_1_SDM			0x1B0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB2			0x1B4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_USB3			0x1B8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_SDMMC			0x1BC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_NAND			0x1C0
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_ETR			0x1C4
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN0			0x1C8
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN1			0x1CC
+#define SOCFPGA_SYSMGR_IO_TBU_STREAM_ID_AX_REG_2_TSN2			0x1D0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG0				0x1F0
+#define SOCFPGA_SYSMGR_USB3_MISC_CTRL_REG1				0x1F4
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0				0x200
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1				0x204
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2				0x208
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_3				0x20C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_4				0x210
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_5				0x214
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_6				0x218
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_7				0x21C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8				0x220
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9				0x224
+#define SOCFPGA_SYSMGR_MPFE_CONFIG					0x228
+#define SOCFPGA_SYSMGR_MPFE_status					0x22C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0				0x230
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1				0x234
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2				0x238
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_3				0x23C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_4				0x240
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_5				0x244
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_6				0x248
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_7				0x24C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_8				0x250
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_9				0x254
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0				0x258
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_1				0x25C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_2				0x260
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_3				0x264
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_4				0x268
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_5				0x26C
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_6				0x270
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7				0x274
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8				0x278
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9				0x27C
+
+#define DMA0_STREAM_CTRL_REG						0x10D1217C
+#define DMA1_STREAM_CTRL_REG						0x10D12180
+#define SDM_STREAM_CTRL_REG						0x10D12184
+#define USB2_STREAM_CTRL_REG						0x10D12188
+#define USB3_STREAM_CTRL_REG						0x10D1218C
+#define SDMMC_STREAM_CTRL_REG						0x10D12190
+#define NAND_STREAM_CTRL_REG						0x10D12194
+#define ETR_STREAM_CTRL_REG						0x10D12198
+#define TSN0_STREAM_CTRL_REG						0x10D1219C
+#define TSN1_STREAM_CTRL_REG						0x10D121A0
+#define TSN2_STREAM_CTRL_REG						0x10D121A4
+
+/* Stream ID configuration value for Agilex5 */
+#define TSN0								0x00010001
+#define TSN1								0x00020002
+#define TSN2								0x00030003
+#define NAND								0x00040004
+#define SDMMC								0x00050005
+#define USB0								0x00060006
+#define USB1								0x00070007
+#define DMA0								0x00080008
+#define DMA1								0x00090009
+#define SDM								0x000A000A
+#define CORE_SIGHT_DEBUG						0x000B000B
+
+/* Field Masking */
+#define SYSMGR_SDMMC_DRVSEL(x)						(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)						(((x) & 0x7) << 4)
+
+#define SYSMGR_F2S_BRIDGE_CTRL_EN					BIT(0)
+#define IDLE_DATA_LWSOC2FPGA						BIT(4)
+#define IDLE_DATA_SOC2FPGA						BIT(0)
+#define IDLE_DATA_MASK							(IDLE_DATA_LWSOC2FPGA \
+									| IDLE_DATA_SOC2FPGA)
+#define SYSMGR_ECC_OCRAM_MASK						BIT(1)
+#define SYSMGR_ECC_DDR0_MASK						BIT(16)
+#define SYSMGR_ECC_DDR1_MASK						BIT(17)
+
+#define WSTREAMIDEN_REG_CTRL						BIT(0)
+#define RSTREAMIDEN_REG_CTRL						BIT(1)
+#define WMMUSECSID_REG_VAL						BIT(4)
+#define RMMUSECSID_REG_VAL						BIT(5)
+
+/* Macros */
+#define SOCFPGA_SYSMGR(_reg)						(SOCFPGA_SYSMGR_REG_BASE \
+									+ (SOCFPGA_SYSMGR_##_reg))
+
+#define ENABLE_STREAMID							WSTREAMIDEN_REG_CTRL \
+									| RSTREAMIDEN_REG_CTRL
+#define ENABLE_STREAMID_SECURE_TX					WSTREAMIDEN_REG_CTRL \
+									| RSTREAMIDEN_REG_CTRL \
+									| WMMUSECSID_REG_VAL \
+									| RMMUSECSID_REG_VAL
+
+#endif /* AGX5_SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
new file mode 100644
index 0000000..8a49d61
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include "agilex5_memory_controller.h"
+#include "agilex5_system_manager.h"
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX5
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#define MMC_DEVICE_TYPE						1  /* MMC = 0, SD = 1 */
+#define XLAT_TABLES_V2						U(1)
+#define PLAT_PRIMARY_CPU_A55					0x000
+#define PLAT_PRIMARY_CPU_A76					0x200
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT				MPIDR_AFF2_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT				MPIDR_AFF1_SHIFT
+#define PLAT_L2_RESET_REQ			0xB007C0DE
+
+/* System Counter */ /* TODO: Update back to 400MHz */
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				(80000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				(80)
+
+/* FPGA config helpers */
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x2000000
+
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST					0x10900000
+#define CAD_QSPI_OFFSET						0x108d2000
+
+/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE				0x1c000000
+#define SOCFPGA_F2SDRAMMGR_REG_BASE				0x18001000
+
+#define SOCFPGA_MMC_REG_BASE					0x10808000
+#define SOCFPGA_MEMCTRL_REG_BASE				0x108CC000
+#define SOCFPGA_RSTMGR_REG_BASE					0x10d11000
+#define SOCFPGA_SYSMGR_REG_BASE					0x10d12000
+#define SOCFPGA_PINMUX_REG_BASE					0x10d13000
+#define SOCFPGA_NAND_REG_BASE					0x10B80000
+
+#define SOCFPGA_L4_PER_SCR_REG_BASE				0x10d21000
+#define SOCFPGA_L4_SYS_SCR_REG_BASE				0x10d21100
+#define SOCFPGA_SOC2FPGA_SCR_REG_BASE				0x10d21200
+#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE				0x10d21300
+
+/* Define maximum page size for NAND flash devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x1000)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE						(0x80000000)
+#define DRAM_SIZE						(0x80000000)
+
+#define OCRAM_BASE						(0x00000000)
+#define OCRAM_SIZE						(0x00080000)
+
+#define MEM64_BASE						(0x0080000000)
+#define MEM64_SIZE						(0x0080000000)
+
+//128MB PSS
+#define PSS_BASE						(0x10000000)
+#define PSS_SIZE						(0x08000000)
+
+//64MB MPFE
+#define MPFE_BASE						(0x18000000)
+#define MPFE_SIZE						(0x04000000)
+
+//16MB CCU
+#define CCU_BASE						(0x1C000000)
+#define CCU_SIZE						(0x01000000)
+
+//1MB GIC
+#define GIC_BASE						(0x1D000000)
+#define GIC_SIZE						(0x00100000)
+
+#define BL2_BASE						(0x00000000)
+#define BL2_LIMIT						(0x0001b000)
+
+#define BL31_BASE						(0x80000000)
+#define BL31_LIMIT						(0x82000000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE						(0x10C02000)
+#define PLAT_UART1_BASE						(0x10C02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE						(0x1D000000)
+#define PLAT_GICC_BASE						(PLAT_GIC_BASE + 0x20000)
+#define PLAT_GICD_BASE						(PLAT_GIC_BASE + 0x00000)
+#define PLAT_GICR_BASE						(PLAT_GIC_BASE + 0x60000)
+
+#define PLAT_INTEL_SOCFPGA_GICR_BASE				PLAT_GICR_BASE
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	sdmmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0x10D12218
+
+#endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
new file mode 100644
index 0000000..779c629
--- /dev/null
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_INCLUDES		:=	\
+			-Iplat/intel/soc/agilex5/include/		\
+			-Iplat/intel/soc/common/drivers/		\
+			-Iplat/intel/soc/common/include/
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600	:=	1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+AGX5_GICv3_SOURCES	:=	\
+			${GICV3_SOURCES}				\
+			plat/common/plat_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	\
+			${AGX5_GICv3_SOURCES}				\
+			drivers/cadence/combo_phy/cdns_combo_phy.c	\
+			drivers/cadence/emmc/cdns_sdmmc.c	\
+			drivers/cadence/nand/cdns_nand.c	\
+			drivers/delay_timer/delay_timer.c		\
+			drivers/delay_timer/generic_delay_timer.c	\
+			drivers/ti/uart/aarch64/16550_console.S		\
+			plat/intel/soc/common/aarch64/platform_common.c	\
+			plat/intel/soc/common/aarch64/plat_helpers.S	\
+			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
+			plat/intel/soc/common/drivers/combophy/combophy.c			\
+			plat/intel/soc/common/drivers/sdmmc/sdmmc.c			\
+			plat/intel/soc/common/drivers/ddr/ddr.c			\
+			plat/intel/soc/common/drivers/nand/nand.c			\
+			plat/intel/soc/common/socfpga_delay_timer.c
+
+BL2_SOURCES		+=	\
+		common/desc_image_load.c				\
+		lib/xlat_tables_v2/aarch64/enable_mmu.S	\
+		lib/xlat_tables_v2/xlat_tables_context.c \
+		lib/xlat_tables_v2/xlat_tables_core.c \
+		lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
+		lib/xlat_tables_v2/xlat_tables_utils.c \
+		drivers/mmc/mmc.c					\
+		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
+		drivers/io/io_storage.c					\
+		drivers/io/io_block.c					\
+		drivers/io/io_fip.c					\
+		drivers/io/io_mtd.c					\
+		drivers/partition/partition.c				\
+		drivers/partition/gpt.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
+		lib/cpus/aarch64/cortex_a55.S				\
+		lib/cpus/aarch64/cortex_a76.S				\
+		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
+		plat/intel/soc/agilex5/soc/agilex5_memory_controller.c	\
+		plat/intel/soc/agilex5/soc/agilex5_mmc.c			\
+		plat/intel/soc/agilex5/soc/agilex5_pinmux.c		\
+		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
+		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/socfpga_vab.c				\
+		plat/intel/soc/common/soc/socfpga_emac.c		\
+		plat/intel/soc/common/soc/socfpga_firewall.c		\
+		plat/intel/soc/common/soc/socfpga_handoff.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
+		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
+		plat/intel/soc/agilex5/bl2_plat_setup.c			\
+		plat/intel/soc/common/drivers/wdt/watchdog.c
+
+include lib/zlib/zlib.mk
+PLAT_INCLUDES	+=	-Ilib/zlib
+BL2_SOURCES	+=	$(ZLIB_SOURCES)
+
+BL31_SOURCES	+=	\
+		drivers/arm/cci/cci.c					\
+		${XLAT_TABLES_LIB_SRCS}						\
+		lib/cpus/aarch64/aem_generic.S				\
+		lib/cpus/aarch64/cortex_a55.S				\
+		lib/cpus/aarch64/cortex_a76.S				\
+		plat/common/plat_psci_common.c				\
+		plat/intel/soc/agilex5/bl31_plat_setup.c		\
+		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/common/socfpga_psci.c			\
+		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_sip_svc_v2.c			\
+		plat/intel/soc/common/socfpga_topology.c		\
+		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
+		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_reset_manager.c
+
+# Configs for A76 and A55
+HW_ASSISTED_COHERENCY := 1
+USE_COHERENT_MEM := 0
+CTX_INCLUDE_AARCH32_REGS := 0
+ERRATA_A55_1530923 := 1
+
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+PROGRAMMABLE_RESET_ADDRESS	:= 0
+RESET_TO_BL2			:= 1
+BL2_INV_DCACHE			:= 0
+MULTI_CONSOLE_API		:= 1
diff --git a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
new file mode 100644
index 0000000..cc68153
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_system_manager.h"
+#include "socfpga_handoff.h"
+
+uint32_t wait_pll_lock(void)
+{
+	uint32_t data;
+	uint32_t count = 0;
+
+	do {
+		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		count++;
+		if (count >= 1000)
+			return -ETIMEDOUT;
+
+	} while ((CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
+			(CLKMGR_STAT_PERPLLLOCKED(data) == 0));
+	return 0;
+}
+
+uint32_t wait_fsm(void)
+{
+	uint32_t data;
+	uint32_t count = 0;
+
+	do {
+		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		count++;
+		if (count >= 1000)
+			return -ETIMEDOUT;
+
+	} while (CLKMGR_STAT_BUSY(data) == CLKMGR_STAT_BUSY_E_BUSY);
+
+	return 0;
+}
+
+uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
+{
+	uint32_t val = 0;
+	uint32_t count = 0;
+	uint32_t req_status = 0;
+
+	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
+		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
+	mmio_write_32(pll_mem_offset, val);
+
+	do {
+		req_status = mmio_read_32(pll_mem_offset);
+		count++;
+	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+
+	if (count >= 10)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
+{
+	uint32_t val = 0;
+	uint32_t rdata = 0;
+	uint32_t count = 0;
+	uint32_t req_status = 0;
+
+	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_ADDR);
+	mmio_write_32(pll_mem_offset, val);
+
+	do {
+		req_status = mmio_read_32(pll_mem_offset);
+		count++;
+	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+
+	if (count >= 10)
+		return -ETIMEDOUT;
+
+	rdata = mmio_read_32(pll_mem_offset + 0x4);
+	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
+
+	return rdata;
+}
+
+void config_clkmgr_handoff(handoff *hoff_ptr)
+{
+	/* Take both PLL out of reset and power up */
+
+	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
+			CLKMGR_PLLGLOB_PD_SET_MSK |
+			CLKMGR_PLLGLOB_RST_SET_MSK);
+	mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
+			CLKMGR_PLLGLOB_PD_SET_MSK |
+			CLKMGR_PLLGLOB_RST_SET_MSK);
+
+	/* PLL lock */
+	wait_pll_lock();
+
+	/* Bypass all mainpllgrp's clocks to input clock ref */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASSS, 0xff);
+	/* Bypass all perpllgrp's clocks to input clock ref */
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0xff);
+
+	/* Pass clock source frequency into scratch register */
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
+		hoff_ptr->hps_osc_clk_hz);
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
+		hoff_ptr->fpga_clk_hz);
+
+	/* Take all PLLs out of bypass */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0);
+	wait_fsm();
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0);
+	wait_fsm();
+
+	/* Enable mainpllgrp's software-managed clock */
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_EN,
+			CLKMGR_MAINPLL_EN_RESET);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+			CLKMGR_PERPLL_EN_RESET);
+}
+
+/* Extract reference clock from platform clock source */
+uint32_t get_ref_clk(uint32_t pllglob)
+{
+	uint32_t arefclkdiv, ref_clk;
+	uint32_t scr_reg;
+
+	switch (CLKMGR_PSRC(pllglob)) {
+	case CLKMGR_PLLGLOB_PSRC_EOSC1:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
+		ref_clk = mmio_read_32(scr_reg);
+		break;
+	case CLKMGR_PLLGLOB_PSRC_INTOSC:
+		ref_clk = CLKMGR_INTOSC_HZ;
+		break;
+	case CLKMGR_PLLGLOB_PSRC_F2S:
+		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
+		ref_clk = mmio_read_32(scr_reg);
+		break;
+	default:
+		ref_clk = 0;
+		assert(0);
+		break;
+	}
+
+	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+	ref_clk /= arefclkdiv;
+
+	return ref_clk;
+}
+
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+{
+	uint32_t ref_clk = 0;
+
+	uint32_t clk_psrc, mdiv;
+	uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+
+
+	clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
+	clk_psrc = 0;
+
+	switch (clk_psrc) {
+	case 0:
+		pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
+		pllc_reg = CLKMGR_MAINPLL + main_pllc;
+		pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+		break;
+	}
+
+	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
+	mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
+	ref_clk *= mdiv;
+
+	pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
+	NOTICE("return = %d Hz\n", (ref_clk / pllc_div));
+
+	ref_clk = 200000000;
+	return (uint32_t) ref_clk;
+
+}
+
+/* Return L3 interconnect clock */
+uint32_t get_l3_clk(void)
+{
+	uint32_t l3_clk;
+
+	l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
+				CLKMGR_PERPLL_PLLC1);
+	return l3_clk;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+uint32_t get_wdt_clk(void)
+{
+	uint32_t l3_clk, l4_sys_clk;
+
+	l3_clk = get_l3_clk();
+	l4_sys_clk = l3_clk / 4;
+
+	return l4_sys_clk;
+}
+
+/* Calculate clock frequency to be used for UART driver */
+uint32_t get_uart_clk(void)
+{
+	uint32_t data32, l3_clk, l4_sp_clk;
+
+	l3_clk = get_l3_clk();
+
+	data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
+	data32 = (data32 >> 16) & 0x3;
+
+	l4_sp_clk = l3_clk >> data32;
+
+	return l4_sp_clk;
+}
+
+/* Calculate clock frequency to be used for SDMMC driver */
+uint32_t get_mmc_clk(void)
+{
+	uint32_t mmc_clk;
+
+	//TODO: To update when handoff data is ready
+	//uint32_t data32;
+
+	//mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
+
+	//data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
+	//data32 = (data32 & 0x7ff) + 1;
+	//mmc_clk = (mmc_clk / data32) / 4;
+
+
+	mmc_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC3,
+				CLKMGR_PERPLL_PLLC3);
+
+	// TODO: To update when handoff data is ready
+	NOTICE("mmc_clk = %d Hz\n", mmc_clk);
+
+	return mmc_clk;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c b/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c
new file mode 100644
index 0000000..0ddff4a
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_memory_controller.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "agilex5_memory_controller.h"
+#include <platform_def.h>
+
+#define ALT_CCU_NOC_DI_SET_MSK		0x10
+
+#define DDR_READ_LATENCY_DELAY		40
+#define MAX_MEM_CAL_RETRY		3
+#define PRE_CALIBRATION_DELAY		1
+#define POST_CALIBRATION_DELAY		1
+#define TIMEOUT_EMIF_CALIBRATION	1000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
+
+#define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
+#define DDR_CONFIG_ELEMENTS	(ARRAY_SIZE(ddr_config))
+
+/* tWR = Min. 15ns constant, see JEDEC standard eg. DDR4 is JESD79-4.pdf */
+#define tWR_IN_NS 15
+
+void configure_hmc_adaptor_regs(void);
+void configure_ddr_sched_ctrl_regs(void);
+
+/* The followring are the supported configurations */
+uint32_t ddr_config[] = {
+	/* DDR_CONFIG(Address order,Bank,Column,Row) */
+	/* List for DDR3 or LPDDR3 (pinout order > chip, row, bank, column) */
+	DDR_CONFIG(0, 3, 10, 12),
+	DDR_CONFIG(0, 3,  9, 13),
+	DDR_CONFIG(0, 3, 10, 13),
+	DDR_CONFIG(0, 3,  9, 14),
+	DDR_CONFIG(0, 3, 10, 14),
+	DDR_CONFIG(0, 3, 10, 15),
+	DDR_CONFIG(0, 3, 11, 14),
+	DDR_CONFIG(0, 3, 11, 15),
+	DDR_CONFIG(0, 3, 10, 16),
+	DDR_CONFIG(0, 3, 11, 16),
+	DDR_CONFIG(0, 3, 12, 15),	/* 0xa */
+	/* List for DDR4 only (pinout order > chip, bank, row, column) */
+	DDR_CONFIG(1, 3, 10, 14),
+	DDR_CONFIG(1, 4, 10, 14),
+	DDR_CONFIG(1, 3, 10, 15),
+	DDR_CONFIG(1, 4, 10, 15),
+	DDR_CONFIG(1, 3, 10, 16),
+	DDR_CONFIG(1, 4, 10, 16),
+	DDR_CONFIG(1, 3, 10, 17),
+	DDR_CONFIG(1, 4, 10, 17),
+};
+
+static int match_ddr_conf(uint32_t ddr_conf)
+{
+	int i;
+
+	for (i = 0; i < DDR_CONFIG_ELEMENTS; i++) {
+		if (ddr_conf == ddr_config[i])
+			return i;
+	}
+	return 0;
+}
+
+static int check_hmc_clk(void)
+{
+	unsigned long timeout = 0;
+	uint32_t hmc_clk;
+
+	do {
+		hmc_clk = mmio_read_32(AGX_SYSMGR_CORE_HMC_CLK);
+		if (hmc_clk & AGX_SYSMGR_CORE_HMC_CLK_STATUS)
+			break;
+		udelay(1);
+	} while (++timeout < 1000);
+	if (timeout >= 1000)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int clear_emif(void)
+{
+	uint32_t data;
+	unsigned long timeout;
+
+	mmio_write_32(AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL, 0);
+
+	timeout = 0;
+	do {
+		data = mmio_read_32(AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT);
+		if ((data & AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE) == 0)
+			break;
+		udelay(CLEAR_EMIF_DELAY);
+	} while (++timeout < CLEAR_EMIF_TIMEOUT);
+	if (timeout >= CLEAR_EMIF_TIMEOUT)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int mem_calibration(void)
+{
+	int status;
+	uint32_t data;
+	unsigned long timeout;
+	unsigned long retry = 0;
+
+	udelay(PRE_CALIBRATION_DELAY);
+
+	do {
+		if (retry != 0)
+			INFO("DDR: Retrying DRAM calibration\n");
+
+		timeout = 0;
+		do {
+			data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT);
+			if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
+				break;
+			udelay(500);
+		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
+
+		if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
+			status = clear_emif();
+			if (status)
+				ERROR("Failed to clear Emif\n");
+		} else {
+			break;
+		}
+	} while (++retry < MAX_MEM_CAL_RETRY);
+
+	if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
+		ERROR("DDR: DRAM calibration failed.\n");
+		status = -EIO;
+	} else {
+		INFO("DDR: DRAM calibration success.\n");
+		status = 0;
+	}
+
+	udelay(POST_CALIBRATION_DELAY);
+
+	return status;
+}
+
+int init_hard_memory_controller(void)
+{
+	int status;
+
+	status = check_hmc_clk();
+	if (status) {
+		ERROR("DDR: Error, HMC clock not running\n");
+		return status;
+	}
+
+	status = mem_calibration();
+	if (status) {
+		ERROR("DDR: Memory Calibration Failed\n");
+		return status;
+	}
+
+	configure_hmc_adaptor_regs();
+
+	return 0;
+}
+
+void configure_ddr_sched_ctrl_regs(void)
+{
+	uint32_t data, dram_addr_order, ddr_conf, bank, row, col,
+		rd_to_miss, wr_to_miss, burst_len, burst_len_ddr_clk,
+		burst_len_sched_clk, act_to_act, rd_to_wr, wr_to_rd, bw_ratio,
+		t_rtp, t_rp, t_rcd, rd_latency, tw_rin_clk_cycles,
+		bw_ratio_extended, auto_precharge = 0, act_to_act_bank, faw,
+		faw_bank, bus_rd_to_rd, bus_rd_to_wr, bus_wr_to_rd;
+
+	INFO("Init HPS NOC's DDR Scheduler.\n");
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG1);
+	dram_addr_order = AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMADDRW);
+
+	col  = IOHMC_DRAMADDRW_COL_ADDR_WIDTH(data);
+	row  = IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(data);
+	bank = IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(data);
+
+	ddr_conf = match_ddr_conf(DDR_CONFIG(dram_addr_order, bank, col, row));
+
+	if (ddr_conf) {
+		mmio_clrsetbits_32(
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF,
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK,
+			AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(ddr_conf));
+	} else {
+		ERROR("DDR: Cannot find predefined ddrConf configuration.\n");
+	}
+
+	mmio_write_32(AGX_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMTIMING0);
+	rd_latency = AGX_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING0);
+	act_to_act = ACT_TO_ACT(data);
+	t_rcd = ACT_TO_RDWR(data);
+	act_to_act_bank = ACT_TO_ACT_DIFF_BANK(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING1);
+	rd_to_wr = RD_TO_WR(data);
+	bus_rd_to_rd = RD_TO_RD_DIFF_CHIP(data);
+	bus_rd_to_wr = RD_TO_WR_DIFF_CHIP(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING2);
+	t_rtp = RD_TO_PCH(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING3);
+	wr_to_rd = CALTIMING3_WR_TO_RD(data);
+	bus_wr_to_rd = CALTIMING3_WR_TO_RD_DIFF_CHIP(data);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING4);
+	t_rp = PCH_TO_VALID(data);
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL));
+	bw_ratio = ((HMC_ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 0 : 1);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG0);
+	burst_len = HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(data);
+	burst_len_ddr_clk = burst_len / 2;
+	burst_len_sched_clk = ((burst_len/2) / 2);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG0);
+	switch (AGX_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(data)) {
+	case 1:
+		/* DDR4 - 1333MHz */
+		/* 20 (19.995) clock cycles = 15ns */
+		/* Calculate with rounding */
+		tw_rin_clk_cycles = (((tWR_IN_NS * 1333) % 1000) >= 500) ?
+			((tWR_IN_NS * 1333) / 1000) + 1 :
+			((tWR_IN_NS * 1333) / 1000);
+		break;
+	default:
+		/* Others - 1066MHz or slower */
+		/* 16 (15.990) clock cycles = 15ns */
+		/* Calculate with rounding */
+		tw_rin_clk_cycles = (((tWR_IN_NS * 1066) % 1000) >= 500) ?
+			((tWR_IN_NS * 1066) / 1000) + 1 :
+			((tWR_IN_NS * 1066) / 1000);
+		break;
+	}
+
+	rd_to_miss = t_rtp + t_rp + t_rcd - burst_len_sched_clk;
+	wr_to_miss = ((rd_latency + burst_len_ddr_clk + 2 + tw_rin_clk_cycles)
+			/ 2) - rd_to_wr + t_rp + t_rcd;
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DDRTIMING,
+		bw_ratio << DDRTIMING_BWRATIO_OFST |
+		wr_to_rd << DDRTIMING_WRTORD_OFST|
+		rd_to_wr << DDRTIMING_RDTOWR_OFST |
+		burst_len_sched_clk << DDRTIMING_BURSTLEN_OFST |
+		wr_to_miss << DDRTIMING_WRTOMISS_OFST |
+		rd_to_miss << DDRTIMING_RDTOMISS_OFST |
+		act_to_act << DDRTIMING_ACTTOACT_OFST);
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL));
+	bw_ratio_extended = ((ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 1 : 0);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DDRMODE,
+		bw_ratio_extended << DDRMODE_BWRATIOEXTENDED_OFST |
+		auto_precharge << DDRMODE_AUTOPRECHARGE_OFST);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_READLATENCY,
+		(rd_latency / 2) + DDR_READ_LATENCY_DELAY);
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CALTIMING9);
+	faw = AGX_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(data);
+
+	faw_bank = 1; // always 1 because we always have 4 bank DDR.
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE,
+		faw_bank << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST |
+		faw << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST |
+		act_to_act_bank << AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST);
+
+	mmio_write_32(AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV,
+		((bus_rd_to_rd
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK) |
+		((bus_rd_to_wr
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK) |
+		((bus_wr_to_rd
+			<< AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST)
+			& AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK));
+
+}
+
+unsigned long get_physical_dram_size(void)
+{
+	uint32_t data;
+	unsigned long ram_addr_width, ram_ext_if_io_width;
+
+	data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRIOCTRL);
+	switch (AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(data)) {
+	case 0:
+		ram_ext_if_io_width = 16;
+		break;
+	case 1:
+		ram_ext_if_io_width = 32;
+		break;
+	case 2:
+		ram_ext_if_io_width = 64;
+		break;
+	default:
+		ram_ext_if_io_width = 0;
+		break;
+	}
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_REG_DRAMADDRW);
+	ram_addr_width = IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(data) +
+		IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(data);
+
+	return (1 << ram_addr_width) * (ram_ext_if_io_width / 8);
+}
+
+
+
+void configure_hmc_adaptor_regs(void)
+{
+	uint32_t data;
+	uint32_t dram_io_width;
+
+	/* Configure DDR data rate */
+	dram_io_width = AGX_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0(
+		mmio_read_32(AGX_MPFE_IOHMC_REG_NIOSRESERVE0_OFST));
+	dram_io_width = (dram_io_width & 0xFF) >> 5;
+
+	data = mmio_read_32(AGX_MPFE_IOHMC_CTRLCFG3);
+
+	dram_io_width |= (data & 0x4);
+
+	mmio_write_32(AGX_MPFE_HMC_ADP_DDRIOCTRL, dram_io_width);
+
+	/* Copy dram addr width from IOHMC to HMC ADP */
+	data = mmio_read_32(AGX_MPFE_IOHMC_DRAMADDRW);
+	mmio_write_32(AGX_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data);
+
+	/* Enable nonsecure access to DDR */
+	data = get_physical_dram_size();
+
+	if (data < AGX_DDR_SIZE)
+		data = AGX_DDR_SIZE;
+
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT, data - 1);
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT, 0x1f);
+
+	mmio_write_32(AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT, data - 1);
+
+	mmio_write_32(AGX_SOC_NOC_FW_DDR_SCR_ENABLESET, BIT(0) | BIT(8));
+
+	/* ECC enablement */
+	data = mmio_read_32(AGX_MPFE_IOHMC_REG_CTRLCFG1);
+	if (data & (1 << AGX_IOHMC_CTRLCFG1_ENABLE_ECC_OFST)) {
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL1,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK);
+
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL2,
+			AGX_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK);
+
+		mmio_clrsetbits_32(AGX_MPFE_HMC_ADP_ECCCTRL1,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK |
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK,
+			AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK);
+		INFO("Scrubbing ECC\n");
+
+		/* ECC Scrubbing */
+		zeromem((void *)DRAM_BASE, DRAM_SIZE);
+	} else {
+		INFO("ECC is disabled.\n");
+	}
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_mmc.c b/plat/intel/soc/agilex5/soc/agilex5_mmc.c
new file mode 100644
index 0000000..48f7341
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_mmc.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_system_manager.h"
+
+void agx5_mmc_init(void)
+{
+// TODO: To update when handoff data is ready
+
+	//mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+	//	CLKMGR_PERPLL_EN_SDMMCCLK);
+	//mmio_write_32(SOCFPGA_SYSMGR(SDMMC),
+	//	SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3));
+	//mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+	//	CLKMGR_PERPLL_EN_SDMMCCLK);
+
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
new file mode 100644
index 0000000..50d9e36
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include "agilex5_pinmux.h"
+#include "agilex5_system_manager.h"
+
+const uint32_t sysmgr_pinmux_array_sel[] = {
+	0x00000000, 0x00000001, /* usb */
+	0x00000004, 0x00000001,
+	0x00000008, 0x00000001,
+	0x0000000c, 0x00000001,
+	0x00000010, 0x00000001,
+	0x00000014, 0x00000001,
+	0x00000018, 0x00000001,
+	0x0000001c, 0x00000001,
+	0x00000020, 0x00000001,
+	0x00000024, 0x00000001,
+	0x00000028, 0x00000001,
+	0x0000002c, 0x00000001,
+	0x00000030, 0x00000000, /* emac0 */
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x0000004c, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x00000000,
+	0x0000005c, 0x00000000,
+	0x00000060, 0x00000008, /* gpio1 */
+	0x00000064, 0x00000008,
+	0x00000068, 0x00000005, /* uart0 tx */
+	0x0000006c, 0x00000005, /* uart 0 rx */
+	0x00000070, 0x00000008, /* gpio */
+	0x00000074, 0x00000008,
+	0x00000078, 0x00000004, /* i2c1 */
+	0x0000007c, 0x00000004,
+	0x00000080, 0x00000007, /* jtag */
+	0x00000084, 0x00000007,
+	0x00000088, 0x00000007,
+	0x0000008c, 0x00000007,
+	0x00000090, 0x00000001, /* sdmmc data0 */
+	0x00000094, 0x00000001,
+	0x00000098, 0x00000001,
+	0x0000009c, 0x00000001,
+	0x00000100, 0x00000001,
+	0x00000104, 0x00000001, /* sdmmc.data3 */
+	0x00000108, 0x00000008, /* loan */
+	0x0000010c, 0x00000008, /* gpio */
+	0x00000110, 0x00000008,
+	0x00000114, 0x00000008, /* gpio1.io21 */
+	0x00000118, 0x00000005, /* mdio0.mdio */
+	0x0000011c, 0x00000005  /* mdio0.mdc */
+};
+
+const uint32_t sysmgr_pinmux_array_ctrl[] = {
+	0x00000000, 0x00502c38, /* Q1_1 */
+	0x00000004, 0x00102c38,
+	0x00000008, 0x00502c38,
+	0x0000000c, 0x00502c38,
+	0x00000010, 0x00502c38,
+	0x00000014, 0x00502c38,
+	0x00000018, 0x00502c38,
+	0x0000001c, 0x00502c38,
+	0x00000020, 0x00502c38,
+	0x00000024, 0x00502c38,
+	0x00000028, 0x00502c38,
+	0x0000002c, 0x00502c38,
+	0x00000030, 0x00102c38, /* Q2_1 */
+	0x00000034, 0x00102c38,
+	0x00000038, 0x00502c38,
+	0x0000003c, 0x00502c38,
+	0x00000040, 0x00102c38,
+	0x00000044, 0x00102c38,
+	0x00000048, 0x00502c38,
+	0x0000004c, 0x00502c38,
+	0x00000050, 0x00102c38,
+	0x00000054, 0x00102c38,
+	0x00000058, 0x00502c38,
+	0x0000005c, 0x00502c38,
+	0x00000060, 0x00502c38, /* Q3_1 */
+	0x00000064, 0x00502c38,
+	0x00000068, 0x00102c38,
+	0x0000006c, 0x00502c38,
+	0x000000d0, 0x00502c38,
+	0x000000d4, 0x00502c38,
+	0x000000d8, 0x00542c38,
+	0x000000dc, 0x00542c38,
+	0x000000e0, 0x00502c38,
+	0x000000e4, 0x00502c38,
+	0x000000e8, 0x00102c38,
+	0x000000ec, 0x00502c38,
+	0x000000f0, 0x00502c38, /* Q4_1 */
+	0x000000f4, 0x00502c38,
+	0x000000f8, 0x00102c38,
+	0x000000fc, 0x00502c38,
+	0x00000100, 0x00502c38,
+	0x00000104, 0x00502c38,
+	0x00000108, 0x00102c38,
+	0x0000010c, 0x00502c38,
+	0x00000110, 0x00502c38,
+	0x00000114, 0x00502c38,
+	0x00000118, 0x00542c38,
+	0x0000011c, 0x00102c38
+};
+
+const uint32_t sysmgr_pinmux_array_fpga[] = {
+	0x00000000, 0x00000000,
+	0x00000004, 0x00000000,
+	0x00000008, 0x00000000,
+	0x0000000c, 0x00000000,
+	0x00000010, 0x00000000,
+	0x00000014, 0x00000000,
+	0x00000018, 0x00000000,
+	0x0000001c, 0x00000000,
+	0x00000020, 0x00000000,
+	0x00000028, 0x00000000,
+	0x0000002c, 0x00000000,
+	0x00000030, 0x00000000,
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x0000002a
+};
+
+const uint32_t sysmgr_pinmux_array_iodelay[] = {
+	0x00000000, 0x00000000,
+	0x00000004, 0x00000000,
+	0x00000008, 0x00000000,
+	0x0000000c, 0x00000000,
+	0x00000010, 0x00000000,
+	0x00000014, 0x00000000,
+	0x00000018, 0x00000000,
+	0x0000001c, 0x00000000,
+	0x00000020, 0x00000000,
+	0x00000024, 0x00000000,
+	0x00000028, 0x00000000,
+	0x0000002c, 0x00000000,
+	0x00000030, 0x00000000,
+	0x00000034, 0x00000000,
+	0x00000038, 0x00000000,
+	0x0000003c, 0x00000000,
+	0x00000040, 0x00000000,
+	0x00000044, 0x00000000,
+	0x00000048, 0x00000000,
+	0x0000004c, 0x00000000,
+	0x00000050, 0x00000000,
+	0x00000054, 0x00000000,
+	0x00000058, 0x00000000,
+	0x0000005c, 0x00000000,
+	0x00000060, 0x00000000,
+	0x00000064, 0x00000000,
+	0x00000068, 0x00000000,
+	0x0000006c, 0x00000000,
+	0x00000070, 0x00000000,
+	0x00000074, 0x00000000,
+	0x00000078, 0x00000000,
+	0x0000007c, 0x00000000,
+	0x00000080, 0x00000000,
+	0x00000084, 0x00000000,
+	0x00000088, 0x00000000,
+	0x0000008c, 0x00000000,
+	0x00000090, 0x00000000,
+	0x00000094, 0x00000000,
+	0x00000098, 0x00000000,
+	0x0000009c, 0x00000000,
+	0x00000100, 0x00000000,
+	0x00000104, 0x00000000,
+	0x00000108, 0x00000000,
+	0x0000010c, 0x00000000,
+	0x00000110, 0x00000000,
+	0x00000114, 0x00000000,
+	0x00000118, 0x00000000,
+	0x0000011c, 0x00000000
+};
+
+void config_fpgaintf_mod(void)
+{
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+}
+
+void config_pinmux(handoff *hoff_ptr)
+{
+	unsigned int i;
+
+	mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
+	for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_PIN0SEL +
+			hoff_ptr->pinmux_sel_array[i],
+			hoff_ptr->pinmux_sel_array[i + 1]);
+	}
+
+	config_fpgaintf_mod();
+}
+
+void config_peripheral(handoff *hoff_ptr)
+{
+
+	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
+	// Pending SDM to pass over handoff data
+	// unsigned int i;
+
+	// for (i = 0; i < 4; i += 2) {
+	//	mmio_write_32(AGX_EDGE_PERIPHERAL +
+	//	hoff_ptr->peripheral_pwr_gate_array[i],
+	//	hoff_ptr->peripheral_pwr_gate_array[i+1]);
+	// }
+
+
+	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
+	mmio_write_32(AGX5_PERIPHERAL,
+	hoff_ptr->peripheral_pwr_gate_array);
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
new file mode 100644
index 0000000..0d81970
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "agilex5_power_manager.h"
+#include "socfpga_reset_manager.h"
+
+int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
+{
+	uint32_t data = 0;
+	uint32_t count = 0;
+	uint32_t pgstat = 0;
+
+	/* Wait FSM ready */
+	do {
+		data = mmio_read_32(AGX5_PWRMGR(PSS_PGSTAT));
+		count++;
+		if (count >= 1000) {
+			return -ETIMEDOUT;
+		}
+
+	} while (AGX5_PWRMGR_PSS_STAT_BUSY(data) == AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY);
+
+	/* Verify PSS SRAM power gated */
+	pgstat = mmio_read_32(AGX5_PWRMGR(PSS_PGSTAT));
+	if (pgstat != (AGX5_PWRMGR_PSS_PGEN_OUT(peripheral_handoff))) {
+		return AGX5_PWRMGR_HANDOFF_PERIPHERAL;
+	}
+
+	return 0;
+}
+
+int pss_sram_power_off(handoff *hoff_ptr)
+{
+	int ret = 0;
+	uint32_t peripheral_handoff = 0;
+
+	/* Get PSS SRAM handoff data */
+	peripheral_handoff = hoff_ptr->peripheral_pwr_gate_array;
+
+	/* Enable firewall for PSS SRAM */
+	mmio_write_32(AGX5_PWRMGR(PSS_FWENCTL),
+			AGX5_PWRMGR_PSS_FWEN(peripheral_handoff));
+
+	/* Wait */
+	udelay(1);
+
+	/* Power gating PSS SRAM */
+	mmio_write_32(AGX5_PWRMGR(PSS_PGENCTL),
+			AGX5_PWRMGR_PSS_PGEN(peripheral_handoff));
+
+	ret = wait_verify_fsm(1000, peripheral_handoff);
+
+	return ret;
+}
+
+void config_pwrmgr_handoff(handoff *hoff_ptr)
+{
+	int ret = 0;
+
+	switch (hoff_ptr->header_magic) {
+	case HANDOFF_MAGIC_PERIPHERAL:
+		ret = pss_sram_power_off(hoff_ptr);
+		break;
+	default:
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Config PwrMgr handoff failed. error %d\n", ret);
+		assert(false);
+	}
+}
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 6bf2d82..cbd0121 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -34,6 +34,11 @@
 func plat_secondary_cold_boot_setup
 	/* Wait until the it gets reset signal from rstmgr gets populated */
 poll_mailbox:
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mov_imm x0, PLAT_SEC_ENTRY
+	cbz	x0, poll_mailbox
+	br      x0
+#else
 	wfi
 	mov_imm	x0, PLAT_SEC_ENTRY
 	ldr	x1, [x0]
@@ -44,8 +49,13 @@
 	cmp	x3, x4
 	b.ne	poll_mailbox
 	br	x1
+#endif
 endfunc plat_secondary_cold_boot_setup
 
+#if	((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
+
 func platform_is_primary_cpu
 	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
 	cmp	x0, #PLAT_PRIMARY_CPU
@@ -53,6 +63,21 @@
 	ret
 endfunc platform_is_primary_cpu
 
+#else
+
+func platform_is_primary_cpu
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp x0, #(PLAT_PRIMARY_CPU_A76)
+	b.eq primary_cpu
+	cmp x0, #(PLAT_PRIMARY_CPU_A55)
+	b.eq primary_cpu
+primary_cpu:
+	cset	x0, eq
+	ret
+endfunc platform_is_primary_cpu
+
+#endif
+
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
 	b   platform_is_primary_cpu
@@ -62,11 +87,27 @@
 	mrs	x0, mpidr_el1
 	and	x1, x0, #MPIDR_CPU_MASK
 	and	x0, x0, #MPIDR_CLUSTER_MASK
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	add	x0, x1, x0, LSR #8
+#else
 	add	x0, x1, x0, LSR #6
+#endif
 	ret
 endfunc plat_my_core_pos
 
 func warm_reset_req
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	bl	plat_is_my_cpu_primary
+	cbnz	x0, warm_reset
+warm_reset:
+	mov_imm x1, PLAT_SEC_ENTRY
+	str	xzr, [x1]
+	mrs	x1, rmr_el3
+	orr	x1, x1, #0x02
+	msr	rmr_el3, x1
+	isb
+	dsb	sy
+#else
 	str	xzr, [x4]
 	bl	plat_is_my_cpu_primary
 	cbz	x0, cpu_in_wfi
@@ -80,11 +121,28 @@
 cpu_in_wfi:
 	wfi
 	b	cpu_in_wfi
+#endif
 endfunc warm_reset_req
 
+/* TODO: Zephyr warm reset test */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
 	ldr	x5, [x4]
+	ldr	x1, =PLAT_L2_RESET_REQ
+	cmp	x1, x5
+	b.eq	zephyr_reset_req
+	mov_imm	x1, PLAT_SEC_ENTRY
+	ldr	x0, [x1]
+	ret
+zephyr_reset_req:
+	ldr	x0, =0x00
+	ret
+endfunc plat_get_my_entrypoint
+#else
+func plat_get_my_entrypoint
+	ldr	x4, =L2_RESET_DONE_REG
+	ldr	x5, [x4]
 	ldr	x1, =L2_RESET_DONE_STATUS
 	cmp	x1, x5
 	b.eq	warm_reset_req
@@ -92,7 +150,7 @@
 	ldr	x0, [x1]
 	ret
 endfunc plat_get_my_entrypoint
-
+#endif
 
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
@@ -138,6 +196,13 @@
 	ret
 endfunc platform_mem_init
 
+	/* --------------------------------------------------------
+	 * macro plat_secondary_cpus_bl31_entry;
+	 *
+	 * el3_entrypoint_common init param configuration.
+	 * Called very early in the secondary cores boot process.
+	 * --------------------------------------------------------
+	 */
 func plat_secondary_cpus_bl31_entry
 	el3_entrypoint_common                                   \
 		_init_sctlr=0                                   \
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index 38f8b94..684a625 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -3,7 +3,6 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-
 #include <assert.h>
 #include <common/debug.h>
 #include <errno.h>
@@ -16,89 +15,72 @@
 
 uint32_t poll_active_bit(uint32_t dir);
 
-static coh_ss_id_t subsystem_id;
+#define SMMU_DMI			1
 
 
+static coh_ss_id_t subsystem_id;
 void get_subsystem_id(void)
 {
 	uint32_t snoop_filter, directory, coh_agent;
-
 	snoop_filter = CSIDR_NUM_SF(mmio_read_32(NCORE_CCU_CSR(NCORE_CSIDR)));
 	directory = CSUIDR_NUM_DIR(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
 	coh_agent = CSUIDR_NUM_CAI(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
-
 	subsystem_id.num_snoop_filter = snoop_filter + 1;
 	subsystem_id.num_directory = directory;
 	subsystem_id.num_coh_agent = coh_agent;
 }
-
 uint32_t directory_init(void)
 {
 	uint32_t dir_sf_mtn, dir_sf_en;
 	uint32_t dir, sf, ret;
-
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
 		for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) {
 			dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
 			dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
-
 			/* Initialize All Entries */
 			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
-
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
 			if (ret != 0) {
 				ERROR("Timeout during active bit polling");
 				return -ETIMEDOUT;
 			}
-
 			/* Disable snoop filter, a bit per snoop filter */
 			mmio_clrbits_32(dir_sf_en, BIT(sf));
-
 		}
 	}
-
 	return 0;
 }
-
 uint32_t coherent_agent_intfc_init(void)
 {
 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
-
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
 		for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) {
 			ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0);
 			ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR));
-
 			/* Coh Agent Snoop Enable */
 			if (CACHING_AGENT_BIT(ca_id))
-				mmio_write_32(ca_snoop_en, BIT(ca));
-
+				mmio_setbits_32(ca_snoop_en, BIT(ca));
 			/* Coh Agent Snoop DVM Enable */
 			ca_type = CACHING_AGENT_TYPE(ca_id);
 			if (ca_type == ACE_W_DVM || ca_type == ACE_L_W_DVM)
-				mmio_write_32(NCORE_CCU_CSR(NCORE_CSADSER0),
+				mmio_setbits_32(NCORE_CCU_CSR(NCORE_CSADSER0),
 				BIT(ca));
 		}
 	}
-
 	return 0;
 }
-
 uint32_t poll_active_bit(uint32_t dir)
 {
 	uint32_t timeout = 80000;
 	uint32_t poll_dir =  DIRECTORY_UNIT(dir, NCORE_DIRUSFMAR);
-
 	while (timeout > 0) {
 		if (mmio_read_32(poll_dir) == 0)
 			return 0;
 		timeout--;
 	}
-
 	return -1;
 }
-
 void bypass_ocram_firewall(void)
 {
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -110,7 +92,6 @@
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
-
 void ncore_enable_ocram_firewall(void)
 {
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -122,15 +103,44 @@
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
-
 uint32_t init_ncore_ccu(void)
 {
 	uint32_t status;
-
 	get_subsystem_id();
 	status = directory_init();
 	status = coherent_agent_intfc_init();
 	bypass_ocram_firewall();
-
 	return status;
 }
+
+void setup_smmu_stream_id(void)
+{
+	/* Configure Stream ID for Agilex5 */
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_ID_AX_REG_0_DMA0), DMA0);
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_ID_AX_REG_0_DMA1), DMA1);
+	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_ID_AX_REG_1_SDM), SDM);
+	/* Reg map showing USB2 but Linux USB0? */
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_USB2), USB0);
+	/* Reg map showing USB3 but Linux USB1? */
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_USB3), USB1);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_SDMMC), SDMMC);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_NAND), NAND);
+	/* To confirm ETR - core sight debug*/
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_ETR), CORE_SIGHT_DEBUG);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN0), TSN0);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN1), TSN1);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN2), TSN2);
+
+	/* Enabled Stream ctrl register for Agilex5 */
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA0), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA1), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_CTRL_REG_1_SDM), ENABLE_STREAMID_SECURE_TX);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB2), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB3), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_SDMMC), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_NAND), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_ETR), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN0), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN1), ENABLE_STREAMID);
+	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN2), ENABLE_STREAMID);
+}
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index 3f662ff..6cdbeb8 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -1,99 +1,420 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-
 #ifndef NCORE_CCU_H
 #define NCORE_CCU_H
 
+#include <stdbool.h>
+#include <stdint.h>
 
-#define NCORE_CCU_OFFSET		0xf7000000
+#ifndef CCU_ACTIVATE_COH_FPGA
+#define CCU_ACTIVATE_COH_FPGA 0
+#endif
+// Address map for ccu init
+#define addr_CAIUIDR1				(0x1C000000)
+#define addr_GRBUNRRUCR				(0x1c0ffff8)
+#define base_addr_NRS_CAIU0			(0x1c000000)
+#define base_addr_NRS_NCAIU0			(0x1c001000)
+#define base_addr_NRS_NCAIU1			(0x1c002000)
+#define base_addr_NRS_NCAIU2			(0x1c003000)
+#define base_addr_NRS_NCAIU3			(0x1c004000)
+#define base_addr_NRS_DCE0			(0x1c005000)
+#define base_addr_NRS_DCE1			(0x1c006000)
+//#define base_addr_NRS_DMI0			(0x1c007000)
+//#define base_addr_NRS_DMI1			(0x1c008000)
+//DMI
+#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	0x1C007300
+#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	0x1C008300
+//DSU
+#define ALT_CCU_DSU_CAIUAMIGR_ADDR		0x1C0003C0
+#define ALT_CCU_DSU_CAIUMIFSR_ADDR		0x1C0003C4
+#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		0x1C000414
+#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		0x1C000418
+#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		0x1C000410
+#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		0x1C000424
+#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		0x1C000428
+#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		0x1C000420
+#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		0x1C000444
+#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		0x1C000448
+#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		0x1C000440
+#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		0x1C000454
+#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		0x1C000458
+#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		0x1C000450
+#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		0x1C000464
+#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		0x1C000468
+#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		0x1C000460
+#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		0x1C000474
+#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		0x1C000478
+#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		0x1C000470
+#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		0x1C000484
+#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		0x1C000488
+#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		0x1C000480
+#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		0x1C000494
+#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		0x1C000498
+#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		0x1C000490
+#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		0x1C0004A4
+#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		0x1C0004A8
+#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		0x1C0004A0
+//GIC
+#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		0x1C0023C0
+#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		0x1C0023C4
+#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		0x1C002414
+#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		0x1C002418
+#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		0x1C002410
+#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		0x1C002464
+#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		0x1C002468
+#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		0x1C002460
+#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		0x1C002484
+#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		0x1C002488
+#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		0x1C002480
+#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		0x1C0024A4
+#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		0x1C0024A8
+#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		0x1C0024A0
+//FPGA2SOC
+#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		0x1C0013C0
+#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		0x1C0013C4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	0x1C001414
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	0x1C001418
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	0x1C001410
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	0x1C001464
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	0x1C001468
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	0x1C001460
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	0x1C001484
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	0x1C001488
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	0x1C001480
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	0x1C0014A4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	0x1C0014A8
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	0x1C0014A0
+//TCU
+#define ALT_CCU_TCU_BASE 0x1C003000
+#define ALT_CCU_TCU_XAIUAMIGR_ADDR		ALT_CCU_TCU_BASE + 0x03C0
+#define ALT_CCU_TCU_XAIUMIFSR_ADDR		ALT_CCU_TCU_BASE + 0x03C4
+#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		ALT_CCU_TCU_BASE + 0x0404
+#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		ALT_CCU_TCU_BASE + 0x0408
+#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		ALT_CCU_TCU_BASE + 0x0400
+#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		ALT_CCU_TCU_BASE + 0x0414
+#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		ALT_CCU_TCU_BASE + 0x0418
+#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		ALT_CCU_TCU_BASE + 0x0410
+#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		ALT_CCU_TCU_BASE + 0x0424
+#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		ALT_CCU_TCU_BASE + 0x0428
+#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		ALT_CCU_TCU_BASE + 0x0420
+#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		0x1C003464
+#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		0x1C003468
+#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		0x1C003460
+#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		0x1C003484
+#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		0x1C003488
+#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		0x1C003480
+#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		0x1C0034A4
+#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		0x1C0034A8
+#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		0x1C0034A0
+//IOM
+#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		0x1C0043C0
+#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		0x1C0013C4
+#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		0x1C001414
+#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		0x1C001418
+#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		0x1C001410
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	0x1C001464
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	0x1C001468
+#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		0x1C001460
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	0x1C001484
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	0x1C001488
+#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		0x1C001480
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	0x1C0014A4
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	0x1C0014A8
+#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	0x1C0014A0
+//DCE
+#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		0x1C0053C0
+#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		0x1C0053C4
+#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		0x1C005464
+#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		0x1C005468
+#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		0x1C005460
+#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		0x1C005484
+#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		0x1C005488
+#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		0x1C005480
+#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		0x1C0054A4
+#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		0x1C0054A8
+#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		0x1C0054A0
+#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		0x1C0063C0
+#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		0x1C0063C4
+#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		0x1C006464
+#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		0x1C006468
+#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		0x1C006460
+#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		0x1C006484
+#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		0x1C006488
+#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		0x1C006480
+#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		0x1C0064A4
+#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		0x1C0064A8
+#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		0x1C0064A0
+#define offset_NRS_GPRAR0			(0x400)
+#define offset_NRS_GPRBLR0			(0x404)
+#define offset_NRS_GPRBHR0			(0x408)
+#define offset_NRS_GPRAR1			(0x410)
+#define offset_NRS_GPRBLR1			(0x414)
+#define offset_NRS_GPRBHR1			(0x418)
+#define offset_NRS_GPRAR2			(0x420)
+#define offset_NRS_GPRBLR2			(0x424)
+#define offset_NRS_GPRBHR2			(0x428)
+#define offset_NRS_GPRAR3			(0x430)
+#define offset_NRS_GPRBLR3			(0x434)
+#define offset_NRS_GPRBHR3			(0x438)
+#define offset_NRS_GPRAR4			(0x440)
+#define offset_NRS_GPRBLR4			(0x444)
+#define offset_NRS_GPRBHR4			(0x448)
+#define offset_NRS_GPRAR5			(0x450)
+#define offset_NRS_GPRBLR5			(0x454)
+#define offset_NRS_GPRBHR5			(0x458)
+#define offset_NRS_GPRAR6			(0x460)
+#define offset_NRS_GPRBLR6			(0x464)
+#define offset_NRS_GPRBHR6			(0x468)
+#define offset_NRS_GPRAR7			(0x470)
+#define offset_NRS_GPRBLR7			(0x474)
+#define offset_NRS_GPRBHR7			(0x478)
+#define offset_NRS_GPRAR8			(0x480)
+#define offset_NRS_GPRBLR8			(0x484)
+#define offset_NRS_GPRBHR8			(0x488)
+#define offset_NRS_GPRAR9			(0x490)
+#define offset_NRS_GPRBLR9			(0x494)
+#define offset_NRS_GPRBHR9			(0x498)
+#define offset_NRS_GPRAR10			(0x4a0)
+#define offset_NRS_GPRBLR10			(0x4a4)
+#define offset_NRS_GPRBHR10			(0x4a8)
+#define offset_NRS_AMIGR			(0x3c0)
+#define offset_NRS_MIFSR			(0x3c4)
+#define offset_NRS_DMIUSMCTCR			(0x300)
+#define base_addr_DII0_PSSPERIPHS		(0x10000)
+#define base_addr_DII0_LWHPS2FPGA		(0x20000)
+#define base_addr_DII0_HPS2FPGA_1G		(0x40000)
+#define base_addr_DII0_HPS2FPGA_15G		(0x400000)
+#define base_addr_DII0_HPS2FPGA_240G		(0x4000000)
+#define base_addr_DII1_MPFEREGS			(0x18000)
+#define base_addr_DII2_GICREGS			(0x1D000)
+#define base_addr_DII3_OCRAM			(0x0)
+#define base_addr_BHR				(0x0)
+#define base_addr_DMI_SDRAM_2G			(0x80000)
+#define base_addr_DMI_SDRAM_30G			(0x800000)
+#define base_addr_DMI_SDRAM_480G		(0x8000000)
+// ((0x0<<9) | (0xf<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_PSSPERIPHS			0xC0F00000
+// ((0x0<<9) | (0x11<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_LWHPS2FPGA			0xC1100000
+// ((0x0<<9) | (0x12<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_1G			0xC1200000
+// ((0x0<<9) | (0x16<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_15G			0xC1600000
+// ((0x0<<9) | (0x1a<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII0_HPS2FPGA_240G			0xC1A00000
+// ((0x1<<9) | (0xe<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII1_MPFEREGS			0xC0E00200
+// ((0x2<<9) | (0x8<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII2_GICREGS				0xC0800400
+// ((0x3<<9) | (0x9<<20) | (0x1<<30) | (0x1<<31))
+#define wr_DII3_OCRAM				0xC0900600
+// ((0x0<<9) | (0x12<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_1G_ORDERED			0x81200000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x12<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_1G				0x81200006
+// ((0x0<<9) | (0x13<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_2G_ORDERED			0x81300000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x13<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_2G				0x81300006
+// ((0x0<<9) | (0x16<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_15G_ORDERED		0x81600000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x16<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_15G			0x81600006
+// ((0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_30G_ORDERED		0x81700000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_30G			0x81700006
+// ((0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_240G_ORDERED		0x81a00000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_240G			0x81a00006
+// ((0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_480G_ORDERED		0x81b00000
+// ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
+#define wr_DMI_SDRAM_480G			0x81b00006
 
+typedef enum CCU_REGION_SECURITY_e {
+    //
+    // Allow secure accesses only.
+    //
+	CCU_REGION_SECURITY_SECURE_ONLY,
+    //
+    // Allow non-secure accesses only.
+    //
+	CCU_REGION_SECURITY_NON_SECURE_ONLY,
+    //
+    // Allow accesses of any security state.
+    //
+	CCU_REGION_SECURITY_DONT_CARE
+} CCU_REGION_SECURITY_t;
+typedef enum CCU_REGION_PRIVILEGE_e {
+    //
+    // Allow privileged accesses only.
+    //
+	CCU_REGION_PRIVILEGE_PRIVILEGED_ONLY,
+    //
+    // Allow unprivileged accesses only.
+    //
+	CCU_REGION_PRIVILEGE_NON_PRIVILEGED_ONLY,
+    //
+    // Allow accesses of any privilege.
+    //
+	CCU_REGION_PRIVILEGE_DONT_CARE
+} CCU_REGION_PRIVILEGE_t;
+//
+// Initializes the CCU by enabling all regions except RAM 1 - 5.
+// This is needed because of an RTL change around 2016.02.24.
+//
+// Runtime measurement:
+//  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
+//  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
+//
+// Runtime history:
+//  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
+//  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
+//
+int ccu_hps_init(void);
 
-/* Coherent Sub-System Address Map */
-#define NCORE_CAIU_OFFSET		0x00000
-#define NCORE_CAIU_SIZE			0x01000
+typedef enum ccu_hps_ram_region_e {
+	ccu_hps_ram_region_ramspace0 = 0,
+	ccu_hps_ram_region_ramspace1 = 1,
+	ccu_hps_ram_region_ramspace2 = 2,
+	ccu_hps_ram_region_ramspace3 = 3,
+	ccu_hps_ram_region_ramspace4 = 4,
+	ccu_hps_ram_region_ramspace5 = 5,
+} ccu_hps_ram_region_t;
 
-#define NCORE_NCBU_OFFSET		0x60000
-#define NCORE_NCBU_SIZE			0x01000
+// Disables a RAM (OCRAM) region with the given ID.
+int ccu_hps_ram_region_disable(int id);
 
-#define NCORE_DIRU_OFFSET		0x80000
-#define NCORE_DIRU_SIZE			0x01000
+// Enables a RAM (OCRAM) region with the given ID.
+int ccu_hps_ram_region_enable(int id);
 
-#define NCORE_CMIU_OFFSET		0xc0000
-#define NCORE_CMIU_SIZE			0x01000
+// Attempts to remap a RAM (OCRAM) region with the given ID to span the given
+// start and end address. It also assigns the security and privilege policy.
+// Regions must be a power-of-two size with a minimum size of 64B.
+int ccu_hps_ram_region_remap(int id, uintptr_t start, uintptr_t end,
+CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-#define NCORE_CSR_OFFSET		0xff000
-#define NCORE_CSADSERO			0x00040
-#define NCORE_CSUIDR			0x00ff8
-#define NCORE_CSIDR			0x00ffc
+// Verifies that all enabled RAM (OCRAM) regions does not overlap.
+int ccu_hps_ram_validate(void);
 
-/* Directory Unit Register Map */
-#define NCORE_DIRUSFER			0x00010
-#define NCORE_DIRUMRHER			0x00070
-#define NCORE_DIRUSFMCR			0x00080
-#define NCORE_DIRUSFMAR			0x00084
+typedef enum ccu_hps_mem_region_e {
+	ccu_hps_mem_region_ddrspace0  = 0,
+	ccu_hps_mem_region_memspace0  = 1,
+	ccu_hps_mem_region_memspace1a = 2,
+	ccu_hps_mem_region_memspace1b = 3,
+	ccu_hps_mem_region_memspace1c = 4,
+	ccu_hps_mem_region_memspace1d = 5,
+	ccu_hps_mem_region_memspace1e = 6,
+} ccu_hps_mem_region_t;
 
-/* Coherent Agent Interface Unit Register Map */
-#define NCORE_CAIUIDR			0x00ffc
+// Disables mem0 (DDR) region with the given ID.
+int ccu_hps_mem0_region_disable(int id);
 
-/* Snoop Enable Register */
-#define NCORE_DIRUCASER0		0x00040
-#define NCORE_DIRUCASER1		0x00044
-#define NCORE_DIRUCASER2		0x00048
-#define NCORE_DIRUCASER3		0x0004c
+// Enables mem0 (DDR) region with the given ID.
+int ccu_hps_mem0_region_enable(int id);
 
-#define NCORE_CSADSER0			0x00040
-#define NCORE_CSADSER1			0x00044
-#define NCORE_CSADSER2			0x00048
-#define NCORE_CSADSER3			0x0004c
+// Attempts to remap mem0 (DDR) region with the given ID to span the given
+// start and end address. It also assigns the security nad privlege policy.
+// Regions must be a power-of-two in size with a minimum size of 64B.
+int ccu_hps_mem0_region_remap(int id, uintptr_t start, uintptr_t end,
+CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-/* Protocols Definition */
-#define ACE_W_DVM			0
-#define ACE_L_W_DVM			1
-#define ACE_WO_DVM			2
-#define ACE_L_WO_DVM			3
+// Verifies that all enabled mem0 (DDR) regions does not overlap.
+int ccu_hps_mem0_validate(void);
 
-/* Bypass OC Ram Firewall */
-#define NCORE_FW_OCRAM_BLK_BASE		0x100200
-#define NCORE_FW_OCRAM_BLK_CGF1		0x04
-#define NCORE_FW_OCRAM_BLK_CGF2		0x08
-#define NCORE_FW_OCRAM_BLK_CGF3		0x0c
-#define NCORE_FW_OCRAM_BLK_CGF4		0x10
+typedef enum ccu_hps_ios_region_e {
+	ccu_hps_ios_region_iospace0a = 0,
+	ccu_hps_ios_region_iospace0b = 1,
+	ccu_hps_ios_region_iospace1a = 2,
+	ccu_hps_ios_region_iospace1b = 3,
+	ccu_hps_ios_region_iospace1c = 4,
+	ccu_hps_ios_region_iospace1d = 5,
+	ccu_hps_ios_region_iospace1e = 6,
+	ccu_hps_ios_region_iospace1f = 7,
+	ccu_hps_ios_region_iospace1g = 8,
+	ccu_hps_ios_region_iospace2a = 9,
+	ccu_hps_ios_region_iospace2b = 10,
+	ccu_hps_ios_region_iospace2c = 11,
+} ccu_hps_ios_region_t;
+
+// Disables the IOS (IO Slave) region with the given ID.
+int ccu_hps_ios_region_disable(int id);
+
+// Enables the IOS (IO Slave) region with the given ID.
+int ccu_hps_ios_region_enable(int id);
 
-#define OCRAM_PRIVILEGED_MASK		BIT(29)
-#define OCRAM_SECURE_MASK		BIT(30)
 
+#define NCORE_CCU_OFFSET			0xf7000000
+
+/* Coherent Sub-System Address Map */
+#define NCORE_CAIU_OFFSET			0x00000
+#define NCORE_CAIU_SIZE				0x01000
+#define NCORE_NCBU_OFFSET			0x60000
+#define NCORE_NCBU_SIZE				0x01000
+#define NCORE_DIRU_OFFSET			0x80000
+#define NCORE_DIRU_SIZE				0x01000
+#define NCORE_CMIU_OFFSET			0xc0000
+#define NCORE_CMIU_SIZE				0x01000
+#define NCORE_CSR_OFFSET			0xff000
+#define NCORE_CSADSERO				0x00040
+#define NCORE_CSUIDR				0x00ff8
+#define NCORE_CSIDR				0x00ffc
+/* Directory Unit Register Map */
+#define NCORE_DIRUSFER				0x00010
+#define NCORE_DIRUMRHER				0x00070
+#define NCORE_DIRUSFMCR				0x00080
+#define NCORE_DIRUSFMAR				0x00084
+/* Coherent Agent Interface Unit Register Map */
+#define NCORE_CAIUIDR				0x00ffc
+/* Snoop Enable Register */
+#define NCORE_DIRUCASER0			0x00040
+#define NCORE_DIRUCASER1			0x00044
+#define NCORE_DIRUCASER2			0x00048
+#define NCORE_DIRUCASER3			0x0004c
+#define NCORE_CSADSER0				0x00040
+#define NCORE_CSADSER1				0x00044
+#define NCORE_CSADSER2				0x00048
+#define NCORE_CSADSER3				0x0004c
+/* Protocols Definition */
+#define ACE_W_DVM				0
+#define ACE_L_W_DVM				1
+#define ACE_WO_DVM				2
+#define ACE_L_WO_DVM				3
+/* Bypass OC Ram Firewall */
+#define NCORE_FW_OCRAM_BLK_BASE			0x100200
+#define NCORE_FW_OCRAM_BLK_CGF1			0x04
+#define NCORE_FW_OCRAM_BLK_CGF2			0x08
+#define NCORE_FW_OCRAM_BLK_CGF3			0x0c
+#define NCORE_FW_OCRAM_BLK_CGF4			0x10
+#define OCRAM_PRIVILEGED_MASK			BIT(29)
+#define OCRAM_SECURE_MASK			BIT(30)
 /* Macros */
-#define NCORE_CCU_REG(base)		(NCORE_CCU_OFFSET + (base))
-#define NCORE_CCU_CSR(reg)		(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
+#define NCORE_CCU_REG(base)			(NCORE_CCU_OFFSET + (base))
+#define NCORE_CCU_CSR(reg)			(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
 						+ (reg))
-#define NCORE_CCU_DIR(reg)		(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
+#define NCORE_CCU_DIR(reg)			(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
 						+ (reg))
-#define NCORE_CCU_CAI(reg)		(NCORE_CCU_REG(NCORE_CAIU_OFFSET)\
+#define NCORE_CCU_CAI(reg)			(NCORE_CCU_REG(NCORE_CAIU_OFFSET)\
 						+ (reg))
-
-#define DIRECTORY_UNIT(x, reg)		(NCORE_CCU_DIR(reg)\
+#define DIRECTORY_UNIT(x, reg)			(NCORE_CCU_DIR(reg)\
 						+ NCORE_DIRU_SIZE * (x))
-#define COH_AGENT_UNIT(x, reg)		(NCORE_CCU_CAI(reg)\
+#define COH_AGENT_UNIT(x, reg)			(NCORE_CCU_CAI(reg)\
 						+ NCORE_CAIU_SIZE * (x))
-
-#define COH_CPU0_BYPASS_REG(reg)	(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
+#define COH_CPU0_BYPASS_REG(reg)		(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
 						+ (reg))
-
-#define CSUIDR_NUM_CMI(x)		(((x) & 0x3f000000) >> 24)
-#define CSUIDR_NUM_DIR(x)		(((x) & 0x003f0000) >> 16)
-#define CSUIDR_NUM_NCB(x)		(((x) & 0x00003f00) >> 8)
-#define CSUIDR_NUM_CAI(x)		(((x) & 0x0000007f) >> 0)
-
-#define CSIDR_NUM_SF(x)			(((x) & 0x007c0000) >> 18)
-
-#define SNOOP_FILTER_ID(x)		(((x) << 16))
-
-#define CACHING_AGENT_BIT(x)		(((x) & 0x08000) >> 15)
-#define CACHING_AGENT_TYPE(x)		(((x) & 0xf0000) >> 16)
-
+#define CSUIDR_NUM_CMI(x)			(((x) & 0x3f000000) >> 24)
+#define CSUIDR_NUM_DIR(x)			(((x) & 0x003f0000) >> 16)
+#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003f00) >> 8)
+#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007f) >> 0)
+#define CSIDR_NUM_SF(x)				(((x) & 0x007c0000) >> 18)
+#define SNOOP_FILTER_ID(x)			(((x) << 16))
+#define CACHING_AGENT_BIT(x)			(((x) & 0x08000) >> 15)
+#define CACHING_AGENT_TYPE(x)			(((x) & 0xf0000) >> 16)
 
 typedef struct coh_ss_id {
 	uint8_t num_coh_mem;
@@ -105,5 +426,6 @@
 
 uint32_t init_ncore_ccu(void);
 void ncore_enable_ocram_firewall(void);
+void setup_smmu_stream_id(void);
 
 #endif
diff --git a/plat/intel/soc/common/drivers/combophy/combophy.c b/plat/intel/soc/common/drivers/combophy/combophy.c
new file mode 100644
index 0000000..6c53bc1
--- /dev/null
+++ b/plat/intel/soc/common/drivers/combophy/combophy.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "combophy.h"
+#include "sdmmc/sdmmc.h"
+
+/* Temp assigned handoff data, need to remove when SDM up and run. */
+void config_nand(handoff *hoff_ptr)
+{
+	/* This is hardcoded input value for Combo PHY and SD host controller. */
+	hoff_ptr->peripheral_pwr_gate_array = 0x40;
+
+}
+
+/* DFI configuration */
+int dfi_select(handoff *hoff_ptr)
+{
+	uint32_t data = 0;
+
+	/* Temp assigned handoff data, need to remove when SDM up and run. */
+	handoff reverse_handoff_ptr;
+
+	/* Temp assigned handoff data, need to remove when SDM up and run. */
+	config_nand(&reverse_handoff_ptr);
+
+	if (((reverse_handoff_ptr.peripheral_pwr_gate_array) & PERIPHERAL_SDMMC_MASK) == 0U) {
+		ERROR("SDMMC/NAND is not set properly\n");
+		return -ENXIO;
+	}
+
+	mmio_setbits_32(SOCFPGA_SYSMGR(DFI_INTF),
+		(((reverse_handoff_ptr.peripheral_pwr_gate_array) &
+		PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET));
+	data = mmio_read_32(SOCFPGA_SYSMGR(DFI_INTF));
+	if ((data & DFI_INTF_MASK) != (((reverse_handoff_ptr.peripheral_pwr_gate_array) &
+		PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET)) {
+		ERROR("DFI is not set properly\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+int combo_phy_init(handoff *hoff_ptr)
+{
+	/* SDMMC/NAND DFI selection based on system manager DFI register */
+	int ret = dfi_select(hoff_ptr);
+
+	if (ret != 0U) {
+		ERROR("DFI configuration failed\n");
+		return ret;
+	}
+
+	return 0;
+}
diff --git a/plat/intel/soc/common/drivers/combophy/combophy.h b/plat/intel/soc/common/drivers/combophy/combophy.h
new file mode 100644
index 0000000..ca571f7
--- /dev/null
+++ b/plat/intel/soc/common/drivers/combophy/combophy.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef COMBOPHY_H
+#define COMBOPHY_H
+
+#include <lib/mmio.h>
+
+#include "socfpga_handoff.h"
+
+#define PERIPHERAL_SDMMC_MASK		0x60
+#define PERIPHERAL_SDMMC_OFFSET		6
+#define DFI_INTF_MASK			0x1
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief Nand controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int combo_phy_init(handoff *hoff_ptr);
+int dfi_select(handoff *hoff_ptr);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.c b/plat/intel/soc/common/drivers/ddr/ddr.c
new file mode 100644
index 0000000..188302f
--- /dev/null
+++ b/plat/intel/soc/common/drivers/ddr/ddr.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include "ddr.h"
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+int ddr_calibration_check(void)
+{
+	// DDR calibration check
+	int status = 0;
+	uint32_t u32data_read = 0;
+
+	NOTICE("DDR: Access address 0x%x:...\n", IO96B_0_REG_BASE);
+	u32data_read = mmio_read_32(IO96B_0_REG_BASE);
+	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_0_REG_BASE, u32data_read);
+
+	if (u32data_read == -EPERM) {
+		status = -EPERM;
+		assert(u32data_read);
+	}
+
+	u32data_read = 0x0;
+	NOTICE("DDR: Access address 0x%x: ...\n", IO96B_1_REG_BASE);
+	u32data_read = mmio_read_32(IO96B_1_REG_BASE);
+	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_1_REG_BASE, u32data_read);
+
+	if (u32data_read == -EPERM) {
+		status = -EPERM;
+		assert(u32data_read);
+	}
+
+	return status;
+}
+
+int iossm_mb_init(void)
+{
+	// int status;
+
+	// Update according to IOSSM mailbox spec
+
+	// if (status) {
+		// return status;
+	// }
+
+	return 0;
+}
+
+int wait_respond(uint16_t timeout)
+{
+	uint32_t status = 0;
+	uint32_t count = 0;
+	uint32_t data = 0;
+
+	/* Wait status command response ready */
+	do {
+		data = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
+		count++;
+		if (count >= timeout) {
+			return -ETIMEDOUT;
+		}
+
+	} while (STATUS_COMMAND_RESPONSE(data) != STATUS_COMMAND_RESPONSE_READY);
+
+	status = (data & STATUS_GENERAL_ERROR_MASK) >> STATUS_GENERAL_ERROR_OFFSET;
+	if (status != 0) {
+		return status;
+	}
+
+	status = (data & STATUS_CMD_RESPONSE_ERROR_MASK) >> STATUS_CMD_RESPONSE_ERROR_OFFSET;
+	if (status != 0) {
+		return status;
+	}
+
+	return status;
+}
+
+int iossm_mb_read_response(void)
+{
+	uint32_t status = 0;
+	unsigned int i;
+	uint32_t resp_data[IOSSM_RESP_MAX_WORD_SIZE];
+	uint32_t resp_param_reg;
+
+	// Check STATUS_CMD_RESPONSE_DATA_PTR_VALID in
+	// STATUS_COMMAND_RESPONSE to ensure data pointer response
+
+	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
+	resp_data[0] = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
+	resp_data[0] = (resp_data[0] & CMD_RESPONSE_DATA_SHORT_MASK) >>
+			CMD_RESPONSE_DATA_SHORT_OFFSET;
+	resp_param_reg = CMD_RESPONSE_STATUS;
+	for (i = 1; i < IOSSM_RESP_MAX_WORD_SIZE; i++) {
+		resp_param_reg = resp_param_reg - CMD_RESPONSE_OFFSET;
+		resp_data[i] = mmio_read_32(IO96B_CSR_REG(resp_param_reg));
+	}
+
+	/* Wait for STATUS_COMMAND_RESPONSE_READY*/
+	status = wait_respond(1000);
+
+	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
+	mmio_setbits_32(STATUS_COMMAND_RESPONSE(IO96B_CSR_REG(
+			CMD_RESPONSE_STATUS)),
+			STATUS_COMMAND_RESPONSE_READY_CLEAR);
+
+	return status;
+}
+
+int iossm_mb_send(uint32_t cmd_target_ip_type, uint32_t cmd_target_ip_instance_id,
+			uint32_t cmd_type, uint32_t cmd_opcode, uint32_t *args,
+			unsigned int len)
+{
+	unsigned int i;
+	uint32_t status = 0;
+	uint32_t cmd_req;
+	uint32_t cmd_param_reg;
+
+	cmd_target_ip_type = (cmd_target_ip_type & CMD_TARGET_IP_TYPE_MASK) <<
+				CMD_TARGET_IP_TYPE_OFFSET;
+	cmd_target_ip_instance_id = (cmd_target_ip_instance_id &
+				CMD_TARGET_IP_INSTANCE_ID_MASK) <<
+				CMD_TARGET_IP_INSTANCE_ID_OFFSET;
+	cmd_type = (cmd_type & CMD_TYPE_MASK) << CMD_TYPE_OFFSET;
+	cmd_opcode = (cmd_opcode & CMD_OPCODE_MASK) << CMD_OPCODE_OFFSET;
+	cmd_req = cmd_target_ip_type | cmd_target_ip_instance_id | cmd_type |
+			cmd_opcode;
+
+	/* send mailbox request */
+	IOSSM_MB_WRITE(IO96B_CSR_REG(CMD_REQ), cmd_req);
+	if (len != 0) {
+		cmd_param_reg = CMD_REQ;
+		for (i = 0; i < len; i++) {
+			cmd_param_reg = cmd_param_reg - CMD_PARAM_OFFSET;
+			IOSSM_MB_WRITE(IO96B_CSR_REG(cmd_param_reg), args[i]);
+		}
+	}
+
+	status = iossm_mb_read_response();
+	if (status != 0) {
+		return status;
+	}
+
+	return status;
+}
+
+int ddr_iossm_mailbox_cmd(uint32_t cmd_opcode)
+{
+	// IOSSM
+	uint32_t status = 0;
+	unsigned int i = 0;
+	uint32_t payload[IOSSM_CMD_MAX_WORD_SIZE] = {0U};
+
+	switch (cmd_opcode) {
+	case CMD_INIT:
+		status = iossm_mb_init();
+		break;
+
+	case OPCODE_GET_MEM_INTF_INFO:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_SYS_INFO,
+		OPCODE_GET_MEM_INTF_INFO, payload, i);
+		break;
+
+	case OPCODE_GET_MEM_TECHNOLOGY:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
+		OPCODE_GET_MEM_TECHNOLOGY, payload, i);
+		break;
+
+	case OPCODE_GET_MEM_WIDTH_INFO:
+		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
+		OPCODE_GET_MEM_WIDTH_INFO, payload, i);
+		break;
+
+	case OPCODE_ECC_ENABLE_STATUS:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_ENABLE_STATUS,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_INTERRUPT_MASK:
+		// payload[i] = CMD_PARAM_0 [16:0]: ECC_INTERRUPT_MASK
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_INTERRUPT_MASK,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_SCRUB_MODE_0_START:
+		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_INTERVAL
+		//i++;
+		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
+		//i++;
+		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
+		//i++;
+		// payload[i]= CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
+		//i++;
+		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
+		//i++;
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_0_START,
+		payload, i);
+		break;
+
+	case OPCODE_ECC_SCRUB_MODE_1_START:
+		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_IDLE_CNT
+		//i++;
+		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
+		//i++;
+		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
+		//i++;
+		// payload[i] = CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
+		//i++;
+		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
+		//i++;
+		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
+		//i++;
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_1_START,
+		payload, i);
+		break;
+
+	case OPCODE_BIST_RESULTS_STATUS:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_RESULTS_STATUS,
+		payload, i);
+		break;
+
+	case OPCODE_BIST_MEM_INIT_START:
+		status = iossm_mb_send(0, 0,
+		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_MEM_INIT_START,
+		payload, i);
+		break;
+
+	case OPCODE_TRIG_MEM_CAL:
+		status = iossm_mb_send(0, 0, MBOX_CMD_TRIG_MEM_CAL_OP,
+		OPCODE_TRIG_MEM_CAL, payload, i);
+		break;
+
+	default:
+		break;
+	}
+
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	return status;
+}
+
+int ddr_config_handoff(handoff *hoff_ptr)
+{
+	/* Populate DDR handoff data */
+	/* TODO: To add in DDR handoff configuration once available */
+	return 0;
+}
+
+// DDR firewall and non secure access
+void ddr_enable_ns_access(void)
+{
+	/* Please set the ddr non secure registers accordingly */
+
+	mmio_setbits_32(CCU_REG(DMI0_DMIUSMCTCR),
+			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
+	mmio_setbits_32(CCU_REG(DMI1_DMIUSMCTCR),
+			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
+
+	/* TODO: To add in CCU NCORE OCRAM bypass mask for non secure registers */
+	NOTICE("DDR non secure configured\n");
+}
+
+void ddr_enable_firewall(void)
+{
+	/* Please set the ddr firewall registers accordingly */
+	/* TODO: To add in CCU NCORE OCRAM bypass mask for firewall registers */
+	NOTICE("DDR firewall enabled\n");
+}
+
+bool is_ddr_init_in_progress(void)
+{
+	uint32_t reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+	if (reg & SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0_MASK) {
+		return true;
+	}
+	return false;
+}
+
+int ddr_init(void)
+{
+	// DDR driver initialization
+	int status = -EPERM;
+	uint32_t cmd_opcode = 0;
+
+	// Check and set Boot Scratch Register
+	if (is_ddr_init_in_progress()) {
+		return status;
+	}
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x01);
+
+	// Populate DDR handoff data
+	handoff reverse_handoff_ptr;
+
+	if (!socfpga_get_handoff(&reverse_handoff_ptr)) {
+		assert(status);
+	}
+	status = ddr_config_handoff(&reverse_handoff_ptr);
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	// CCU and firewall setup
+	ddr_enable_ns_access();
+	ddr_enable_firewall();
+
+	// DDR calibration check
+	status = ddr_calibration_check();
+	if (status == -EPERM) {
+		assert(status);
+	}
+
+	// DDR mailbox command
+	status = ddr_iossm_mailbox_cmd(cmd_opcode);
+	if (status != 0) {
+		assert(status);
+	}
+
+	// Check and set Boot Scratch Register
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x00);
+
+	NOTICE("DDR init successfully\n");
+	return status;
+}
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.h b/plat/intel/soc/common/drivers/ddr/ddr.h
new file mode 100644
index 0000000..416b64e
--- /dev/null
+++ b/plat/intel/soc/common/drivers/ddr/ddr.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDR_H
+#define DDR_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+/* MACRO DEFINATION */
+#define IO96B_0_REG_BASE				0x18400000
+#define IO96B_1_REG_BASE				0x18800000
+#define IO96B_CSR_BASE					0x05000000
+#define IO96B_CSR_REG(reg)				(IO96B_CSR_BASE + reg)
+
+#define IOSSM_CMD_MAX_WORD_SIZE				7U
+#define IOSSM_RESP_MAX_WORD_SIZE			4U
+
+#define CCU_REG_BASE					0x1C000000
+#define DMI0_DMIUSMCTCR					0x7300
+#define DMI1_DMIUSMCTCR					0x8300
+#define CCU_DMI_ALLOCEN					BIT(1)
+#define CCU_DMI_LOOKUPEN				BIT(2)
+#define CCU_REG(reg)					(CCU_REG_BASE + reg)
+
+// CMD_RESPONSE_STATUS Register
+#define CMD_RESPONSE_STATUS				0x45C
+#define CMD_RESPONSE_OFFSET				0x4
+#define CMD_RESPONSE_DATA_SHORT_MASK			GENMASK(31, 16)
+#define CMD_RESPONSE_DATA_SHORT_OFFSET			16
+#define STATUS_CMD_RESPONSE_ERROR_MASK			GENMASK(7, 5)
+#define STATUS_CMD_RESPONSE_ERROR_OFFSET		5
+#define STATUS_GENERAL_ERROR_MASK			GENMASK(4, 1)
+#define STATUS_GENERAL_ERROR_OFFSET			1
+#define STATUS_COMMAND_RESPONSE_READY			0x1
+#define STATUS_COMMAND_RESPONSE_READY_CLEAR		0x0
+#define STATUS_COMMAND_RESPONSE_READY_MASK		0x1
+#define STATUS_COMMAND_RESPONSE_READY_OFFSET		0
+#define STATUS_COMMAND_RESPONSE(x)			(((x) & \
+							STATUS_COMMAND_RESPONSE_READY_MASK) >> \
+							STATUS_COMMAND_RESPONSE_READY_OFFSET)
+
+// CMD_REQ Register
+#define CMD_STATUS					0x400
+#define CMD_PARAM					0x438
+#define CMD_REQ						0x43C
+#define CMD_PARAM_OFFSET				0x4
+#define CMD_TARGET_IP_TYPE_MASK				GENMASK(31, 29)
+#define CMD_TARGET_IP_TYPE_OFFSET			29
+#define CMD_TARGET_IP_INSTANCE_ID_MASK			GENMASK(28, 24)
+#define CMD_TARGET_IP_INSTANCE_ID_OFFSET		24
+#define CMD_TYPE_MASK					GENMASK(23, 16)
+#define CMD_TYPE_OFFSET					16
+#define CMD_OPCODE_MASK					GENMASK(15, 0)
+#define CMD_OPCODE_OFFSET				0
+
+#define CMD_INIT					0
+
+#define OPCODE_GET_MEM_INTF_INFO			0x0001
+#define OPCODE_GET_MEM_TECHNOLOGY			0x0002
+#define OPCODE_GET_MEM_WIDTH_INFO			0x0004
+#define OPCODE_TRIG_MEM_CAL				0x000A
+#define OPCODE_ECC_ENABLE_STATUS			0x0102
+#define OPCODE_ECC_INTERRUPT_MASK			0x0105
+#define OPCODE_ECC_SCRUB_MODE_0_START			0x0202
+#define OPCODE_ECC_SCRUB_MODE_1_START			0x0203
+#define OPCODE_BIST_RESULTS_STATUS			0x0302
+#define OPCODE_BIST_MEM_INIT_START			0x0303
+// Please update according to IOSSM mailbox spec
+#define MBOX_ID_IOSSM					0x00
+#define MBOX_CMD_GET_SYS_INFO				0x01
+// Please update according to IOSSM mailbox spec
+#define MBOX_CMD_GET_MEM_INFO				0x02
+#define MBOX_CMD_TRIG_CONTROLLER_OP			0x04
+#define MBOX_CMD_TRIG_MEM_CAL_OP			0x05
+#define MBOX_CMD_POKE_REG				0xFD
+#define MBOX_CMD_PEEK_REG				0xFE
+#define MBOX_CMD_GET_DEBUG_LOG				0xFF
+// Please update according to IOSSM mailbox spec
+#define MBOX_CMD_DIRECT					0x00
+
+#define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0_MASK		0x01
+
+#define IOSSM_MB_WRITE(addr, data)			mmio_write_32(addr, data)
+
+/* FUNCTION DEFINATION */
+int ddr_calibration_check(void);
+
+int iossm_mb_init(void);
+
+int iossm_mb_read_response(void);
+
+int iossm_mb_send(uint32_t cmd_target_ip_type, uint32_t cmd_target_ip_instance_id,
+			uint32_t cmd_type, uint32_t cmd_opcode, uint32_t *args,
+			unsigned int len);
+
+int ddr_iossm_mailbox_cmd(uint32_t cmd);
+
+int ddr_init(void);
+
+int ddr_config_handoff(handoff *hoff_ptr);
+
+void ddr_enable_ns_access(void);
+
+void ddr_enable_firewall(void);
+
+bool is_ddr_init_in_progress(void);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/nand/nand.c b/plat/intel/soc/common/drivers/nand/nand.c
new file mode 100644
index 0000000..c6acbe3
--- /dev/null
+++ b/plat/intel/soc/common/drivers/nand/nand.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include "nand.h"
+
+#include "agilex5_pinmux.h"
+#include "combophy/combophy.h"
+
+/* Pinmux configuration */
+static void nand_pinmux_config(void)
+{
+	mmio_write_32(SOCFPGA_PINMUX(PIN0SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN1SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN2SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN3SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN4SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN5SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN6SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN7SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN8SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN9SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN10SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN11SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN12SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN13SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN14SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN16SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN17SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN18SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN19SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN20SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN21SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN22SEL), SOCFPGA_PINMUX_SEL_NAND);
+	mmio_write_32(SOCFPGA_PINMUX(PIN23SEL), SOCFPGA_PINMUX_SEL_NAND);
+}
+
+int nand_init(handoff *hoff_ptr)
+{
+	/* NAND pin mux configuration */
+	nand_pinmux_config();
+
+	return cdns_nand_host_init();
+}
diff --git a/plat/intel/soc/common/drivers/nand/nand.h b/plat/intel/soc/common/drivers/nand/nand.h
new file mode 100644
index 0000000..b060a72
--- /dev/null
+++ b/plat/intel/soc/common/drivers/nand/nand.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDR_H
+#define DDR_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief Nand controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int nand_init(handoff *hoff_ptr);
+
+#endif
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index cecf560..da8a8bd 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -13,6 +13,7 @@
 #include <drivers/console.h>
 
 #include "cadence_qspi.h"
+#include "socfpga_plat_def.h"
 
 #define LESS(a, b)   (((a) < (b)) ? (a) : (b))
 #define MORE(a, b)   (((a) > (b)) ? (a) : (b))
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.h b/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
index cfef585..104ab5f 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.h
@@ -10,8 +10,6 @@
 
 #define CAD_QSPI_MICRON_N25Q_SUPPORT		1
 
-#define CAD_QSPI_OFFSET				0xff8d2000
-
 #define CAD_INVALID				-1
 #define CAD_QSPI_ERROR				-2
 
@@ -38,8 +36,6 @@
 #define CAD_QSPI_CFG_SELCLKPHASE_CLR_MSK	0xfffffffb
 #define CAD_QSPI_CFG_SELCLKPOL_CLR_MSK		0xfffffffd
 
-#define CAD_QSPIDATA_OFST			0xff900000
-
 #define CAD_QSPI_DELAY				0xc
 #define CAD_QSPI_DELAY_CSSOT(x)			(((x) & 0xff) << 0)
 #define CAD_QSPI_DELAY_CSEOT(x)			(((x) & 0xff) << 8)
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
new file mode 100644
index 0000000..8666f54
--- /dev/null
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -0,0 +1,769 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/cadence/cdns_combo_phy.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "agilex5_pinmux.h"
+#include "sdmmc.h"
+
+static const struct mmc_ops *ops;
+static unsigned int mmc_ocr_value;
+static struct mmc_csd_emmc mmc_csd;
+static struct sd_switch_status sd_switch_func_status;
+static unsigned char mmc_ext_csd[512] __aligned(16);
+static unsigned int mmc_flags;
+static struct mmc_device_info *mmc_dev_info;
+static unsigned int rca;
+static unsigned int scr[2]__aligned(16) = { 0 };
+
+extern const struct mmc_ops cdns_sdmmc_ops;
+extern struct cdns_sdmmc_params cdns_params;
+extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
+extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
+
+static bool is_cmd23_enabled(void)
+{
+	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
+}
+
+static bool is_sd_cmd6_enabled(void)
+{
+	return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
+}
+
+/* TODO: Will romove once ATF driver is developed */
+void sdmmc_pin_config(void)
+{
+	/* temp use base + addr. Official must change to common method */
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
+	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
+}
+
+static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+			unsigned int r_type, unsigned int *r_data)
+{
+	struct mmc_cmd cmd;
+	int ret;
+
+	zeromem(&cmd, sizeof(struct mmc_cmd));
+
+	cmd.cmd_idx = idx;
+	cmd.cmd_arg = arg;
+	cmd.resp_type = r_type;
+
+	ret = ops->send_cmd(&cmd);
+
+	if ((ret == 0) && (r_data != NULL)) {
+		int i;
+
+		for (i = 0; i < 4; i++) {
+			*r_data = cmd.resp_data[i];
+			r_data++;
+		}
+	}
+
+	if (ret != 0) {
+		VERBOSE("Send command %u error: %d\n", idx, ret);
+	}
+
+	return ret;
+}
+
+static int sdmmc_device_state(void)
+{
+	int retries = DEFAULT_SDMMC_MAX_RETRIES;
+	unsigned int resp_data[4];
+
+	do {
+		int ret;
+
+		if (retries == 0) {
+			ERROR("CMD13 failed after %d retries\n",
+			      DEFAULT_SDMMC_MAX_RETRIES);
+			return -EIO;
+		}
+
+		ret = sdmmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R1, &resp_data[0]);
+		if (ret != 0) {
+			retries--;
+			continue;
+		}
+
+		if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
+			return -EIO;
+		}
+
+		retries--;
+	} while ((resp_data[0] & STATUS_READY_FOR_DATA) == 0U);
+
+	return MMC_GET_STATE(resp_data[0]);
+}
+
+static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
+{
+	int ret;
+
+	ret = sdmmc_send_cmd(MMC_CMD(6),
+			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
+			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
+			   MMC_RESPONSE_R1B, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int sdmmc_mmc_sd_switch(unsigned int bus_width)
+{
+	int ret;
+	int retries = DEFAULT_SDMMC_MAX_RETRIES;
+	unsigned int bus_width_arg = 0;
+
+	/* CMD55: Application Specific Command */
+	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R5, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD51: SEND_SCR */
+	do {
+		ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
+		if ((ret != 0) && (retries == 0)) {
+			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
+			      DEFAULT_SDMMC_MAX_RETRIES, ret);
+			return ret;
+		}
+
+		retries--;
+	} while (ret != 0);
+
+	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
+	    (bus_width == MMC_BUS_WIDTH_4)) {
+		bus_width_arg = 2;
+	}
+
+	/* CMD55: Application Specific Command */
+	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R5, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD6: SET_BUS_WIDTH */
+	ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int width = bus_width;
+
+	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
+		if (width == MMC_BUS_WIDTH_8) {
+			WARN("Wrong bus config for SD-card, force to 4\n");
+			width = MMC_BUS_WIDTH_4;
+		}
+		ret = sdmmc_mmc_sd_switch(width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else if (mmc_csd.spec_vers == 4U) {
+		ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
+				      (unsigned int)width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		VERBOSE("Wrong MMC type or spec version\n");
+	}
+
+	return ops->set_ios(clk, width);
+}
+
+static int sdmmc_fill_device_info(void)
+{
+	unsigned long long c_size;
+	unsigned int speed_idx;
+	unsigned int nb_blocks;
+	unsigned int freq_unit;
+	int ret = 0;
+	struct mmc_csd_sd_v2 *csd_sd_v2;
+
+	switch (mmc_dev_info->mmc_dev_type) {
+	case MMC_IS_EMMC:
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
+				   sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* MMC CMD8: SEND_EXT_CSD */
+		ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
+				sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		do {
+			ret = sdmmc_device_state();
+			if (ret < 0) {
+				return ret;
+			}
+		} while (ret != MMC_STATE_TRAN);
+
+		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
+
+		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
+			mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD:
+		/*
+		 * Use the same mmc_csd struct, as required fields here
+		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
+		 */
+		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
+
+		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
+			 (unsigned long long)mmc_csd.c_size_low;
+		assert(c_size != 0xFFFU);
+
+		mmc_dev_info->device_size = (c_size + 1U) *
+					    BIT_64(mmc_csd.c_size_mult + 2U) *
+					    mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD_HC:
+		assert(mmc_csd.csd_structure == 1U);
+
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		/* Need to use mmc_csd_sd_v2 struct */
+		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
+		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
+			 (unsigned long long)csd_sd_v2->c_size_low;
+
+		mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
+
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret < 0) {
+		return ret;
+	}
+
+	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
+			 CSD_TRAN_SPEED_MULT_SHIFT;
+
+	assert(speed_idx > 0U);
+
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
+	} else {
+		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
+	}
+
+	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
+	while (freq_unit != 0U) {
+		mmc_dev_info->max_bus_freq *= 10U;
+		--freq_unit;
+	}
+
+	mmc_dev_info->max_bus_freq *= 10000U;
+
+	return 0;
+}
+
+static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
+		     unsigned char func)
+{
+	unsigned int group_shift = (group - 1U) * 4U;
+	unsigned int group_mask = GENMASK(group_shift + 3U,  group_shift);
+	unsigned int arg;
+	int ret;
+
+	ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
+			   sizeof(sd_switch_func_status));
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* MMC CMD6: SWITCH_FUNC */
+	arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
+	arg &= ~group_mask;
+	arg |= func << group_shift;
+	ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ops->read(0, (uintptr_t)&sd_switch_func_status,
+			 sizeof(sd_switch_func_status));
+}
+
+static int sdmmc_sd_send_op_cond(void)
+{
+	int n;
+	unsigned int resp_data[4];
+
+	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
+		int ret;
+
+		/* CMD55: Application Specific Command */
+		ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* ACMD41: SD_SEND_OP_COND */
+		ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
+			mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
+			&resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((resp_data[0] & OCR_POWERUP) != 0U) {
+			mmc_ocr_value = resp_data[0];
+
+			if ((mmc_ocr_value & OCR_HCS) != 0U) {
+				mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
+			} else {
+				mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+			}
+
+			return 0;
+		}
+
+		mdelay(10);
+	}
+
+	ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
+
+	return -EIO;
+}
+
+static int sdmmc_reset_to_idle(void)
+{
+	int ret;
+
+	/* CMD0: reset to IDLE */
+	ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mdelay(2);
+
+	return 0;
+}
+
+static int sdmmc_send_op_cond(void)
+{
+	int ret, n;
+	unsigned int resp_data[4];
+
+	ret = sdmmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	}
+
+	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
+		ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
+				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
+				   MMC_RESPONSE_R3, &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((resp_data[0] & OCR_POWERUP) != 0U) {
+			mmc_ocr_value = resp_data[0];
+			return 0;
+		}
+
+		mdelay(10);
+	}
+
+	ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
+
+	return -EIO;
+}
+
+static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int resp_data[4];
+
+	ops->init();
+
+	ret = sdmmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		ret = sdmmc_send_op_cond();
+	} else {
+		/* CMD8: Send Interface Condition Command */
+		ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
+				   MMC_RESPONSE_R5, &resp_data[0]);
+
+		if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
+			ret = sdmmc_sd_send_op_cond();
+		}
+	}
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD2: Card Identification */
+	ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD3: Set Relative Address */
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		rca = MMC_FIX_RCA;
+		ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		ret = sdmmc_send_cmd(MMC_CMD(3), 0,
+				   MMC_RESPONSE_R6, &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
+	}
+
+	/* CMD9: CSD Register */
+	ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R2, &resp_data[0]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));
+
+	/* CMD7: Select Card */
+	ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret != MMC_STATE_TRAN);
+
+	ret = sdmmc_set_ios(clk, bus_width);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = sdmmc_fill_device_info();
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (is_sd_cmd6_enabled() &&
+	    (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
+		/* Try to switch to High Speed Mode */
+		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
+			/* High speed not supported, keep default speed */
+			return 0;
+		}
+
+		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
+			/* Cannot switch to high speed, keep default speed */
+			return 0;
+		}
+
+		mmc_dev_info->max_bus_freq = 50000000U;
+		ret = ops->set_ios(clk, bus_width);
+	}
+
+	return ret;
+}
+
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->read != NULL) &&
+	       (size != 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(18);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(18);
+		} else {
+			cmd_idx = MMC_CMD(17);
+		}
+	}
+
+	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
+	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->read(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->write != NULL) &&
+	       (size != 0U) &&
+	       ((buf & MMC_BLOCK_MASK) == 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R1, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(25);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(25);
+		} else {
+			cmd_idx = MMC_CMD(24);
+		}
+	}
+
+	if ((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->write(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = sdmmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_RCV));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info)
+{
+	assert((ops_ptr != NULL) &&
+	       (ops_ptr->init != NULL) &&
+	       (ops_ptr->send_cmd != NULL) &&
+	       (ops_ptr->set_ios != NULL) &&
+	       (ops_ptr->prepare != NULL) &&
+	       (ops_ptr->read != NULL) &&
+	       (ops_ptr->write != NULL) &&
+	       (device_info != NULL) &&
+	       (clk != 0) &&
+	       ((width == MMC_BUS_WIDTH_1) ||
+		(width == MMC_BUS_WIDTH_4) ||
+		(width == MMC_BUS_WIDTH_8) ||
+		(width == MMC_BUS_WIDTH_DDR_4) ||
+		(width == MMC_BUS_WIDTH_DDR_8)));
+
+	ops = ops_ptr;
+	mmc_flags = flags;
+	mmc_dev_info = device_info;
+
+	return sdmmc_enumerate(clk, width);
+}
+
+int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
+{
+	int result = 0;
+
+	/* SDMMC pin mux configuration */
+	sdmmc_pin_config();
+	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (result < 0) {
+		return result;
+	}
+
+	assert((params != NULL) &&
+	       ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+	       ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
+	       ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
+		   ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
+		   ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
+	       (params->desc_size > 0) &&
+	       (params->clk_rate > 0) &&
+	       ((params->bus_width == MMC_BUS_WIDTH_1) ||
+		(params->bus_width == MMC_BUS_WIDTH_4) ||
+		(params->bus_width == MMC_BUS_WIDTH_8)));
+
+	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
+	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
+	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
+
+	result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
+		params->flags, info);
+
+	return result;
+}
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
new file mode 100644
index 0000000..16c6b04
--- /dev/null
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include <lib/mmio.h>
+#include "socfpga_handoff.h"
+
+#define PERIPHERAL_SDMMC_MASK			0x60
+#define PERIPHERAL_SDMMC_OFFSET			6
+
+#define DEFAULT_SDMMC_MAX_RETRIES		5
+#define SEND_SDMMC_OP_COND_MAX_RETRIES		100
+#define SDMMC_MULT_BY_512K_SHIFT		19
+
+static const unsigned char tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
+};
+
+static const unsigned char sd_tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
+};
+
+
+/* FUNCTION DEFINATION */
+/*
+ * @brief SDMMC controller initialization function
+ *
+ * @hoff_ptr: Pointer to the hand-off data
+ * Return: 0 on success, a negative errno on failure
+ */
+int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params,
+	     struct mmc_device_info *info);
+int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info);
+void sdmmc_pin_config(void);
+#endif
diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.h b/plat/intel/soc/common/drivers/wdt/watchdog.h
index 2c72463..4ee4cff 100644
--- a/plat/intel/soc/common/drivers/wdt/watchdog.h
+++ b/plat/intel/soc/common/drivers/wdt/watchdog.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,11 @@
 #ifndef CAD_WATCHDOG_H
 #define CAD_WATCHDOG_H
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define WDT_BASE			(0x10D00200)
+#else
 #define WDT_BASE			(0xFFD00200)
+#endif
 #define WDT_REG_SIZE_OFFSET		(0x4)
 #define WDT_MIN_CYCLES			(65536)
 #define WDT_PERIOD			(20)
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 78deebc..49fc567 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,12 +25,6 @@
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
 
-/*
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
- * is done and HPS should trigger warm reset via RMR_EL3.
- */
-#define L2_RESET_DONE_REG			0xFFD12218
-
 /* Magic word to indicate L2 reset is completed */
 #define L2_RESET_DONE_STATUS			0x1228E5E7
 
diff --git a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
index b30a11e..1bebfc9 100644
--- a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
+++ b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTCLR0	0x54
 #define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTSET0	0x50
 
+#define FLAGOUTCLR0_F2SDRAM0_ENABLE		(BIT(8))
 #define FLAGOUTSETCLR_F2SDRAM0_ENABLE		(BIT(1))
 #define FLAGOUTSETCLR_F2SDRAM1_ENABLE		(BIT(4))
 #define FLAGOUTSETCLR_F2SDRAM2_ENABLE		(BIT(7))
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index ba0f7f3..b2913c7 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,15 @@
 #ifndef	HANDOFF_H
 #define	HANDOFF_H
 
-#define HANDOFF_MAGIC_HEADER		0x424f4f54	/* BOOT */
-#define HANDOFF_MAGIC_PINMUX_SEL	0x504d5558	/* PMUX */
-#define HANDOFF_MAGIC_IOCTLR		0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA		0x46504741	/* FPGA */
-#define HANDOFF_MAGIC_IODELAY		0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK		0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC		0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_HEADER			0x424f4f54	/* BOOT */
+#define HANDOFF_MAGIC_PINMUX_SEL		0x504d5558	/* PMUX */
+#define HANDOFF_MAGIC_IOCTLR			0x494f4354	/* IOCT */
+#define HANDOFF_MAGIC_FPGA				0x46504741	/* FPGA */
+#define HANDOFF_MAGIC_IODELAY			0x444c4159	/* DLAY */
+#define HANDOFF_MAGIC_CLOCK				0x434c4b53	/* CLKS */
+#define HANDOFF_MAGIC_MISC				0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_PERIPHERAL		0x50455249	/* PERIPHERAL */
+#define HANDOFF_MAGIC_DDR				0x5344524d	/* DDR */
 
 #include <socfpga_plat_def.h>
 
@@ -39,8 +41,9 @@
 	uint32_t	pinmux_fpga_magic;
 	uint32_t	pinmux_fpga_length;
 	uint32_t	_pad_0x338_0x340[2];
-	uint32_t	pinmux_fpga_array[42];	/* offset, value */
-	uint32_t	_pad_0x3e8_0x3f0[2];
+	uint32_t	pinmux_fpga_array[44];	/* offset, value */
+	/* TODO: Temp remove due to add in extra handoff data */
+	// uint32_t	_pad_0x3e8_0x3f0[2];
 
 	/* pinmux configuration - io delay */
 	uint32_t	pinmux_delay_magic;
@@ -49,7 +52,6 @@
 	uint32_t	pinmux_iodelay_array[96];	/* offset, value */
 
 	/* clock configuration */
-
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
@@ -120,16 +122,68 @@
 	uint32_t	hps_osc_clk_h;
 	uint32_t	fpga_clk_hz;
 	uint32_t	_pad_0x604_0x610[3];
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	uint32_t	clock_magic;
+	uint32_t	clock_length;
+	uint32_t	_pad_0x588_0x590[2];
+	uint32_t	main_pll_nocclk;
+	uint32_t	main_pll_nocdiv;
+	uint32_t	main_pll_pllglob;
+	uint32_t	main_pll_fdbck;
+	uint32_t	main_pll_pllc0;
+	uint32_t	main_pll_pllc1;
+	uint32_t	main_pll_pllc2;
+	uint32_t	main_pll_pllc3;
+	uint32_t	main_pll_pllm;
+	uint32_t	per_pll_emacctl;
+	uint32_t	per_pll_gpiodiv;
+	uint32_t	per_pll_pllglob;
+	uint32_t	per_pll_fdbck;
+	uint32_t	per_pll_pllc0;
+	uint32_t	per_pll_pllc1;
+	uint32_t	per_pll_pllc2;
+	uint32_t	per_pll_pllc3;
+	uint32_t	per_pll_pllm;
+	uint32_t	alt_emacactr;
+	uint32_t	alt_emacbctr;
+	uint32_t	alt_emacptpctr;
+	uint32_t	alt_gpiodbctr;
+	uint32_t	alt_sdmmcctr;
+	uint32_t	alt_s2fuser0ctr;
+	uint32_t	alt_s2fuser1ctr;
+	uint32_t	alt_psirefctr;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	qspi_clk_khz;
+	uint32_t	hps_osc_clk_hz;
+	uint32_t	fpga_clk_hz;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	ddr_reset_type;
+	/* TODO: Temp added for clk manager. */
+	uint32_t	hps_status_coldreset;
+	/* TODO: Temp remove due to add in extra handoff data */
+	//uint32_t	_pad_0x604_0x610[3];
 #endif
 	/* misc configuration */
 	uint32_t	misc_magic;
 	uint32_t	misc_length;
 	uint32_t	_pad_0x618_0x620[2];
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* peripheral configuration - select */
+	uint32_t	peripheral_pwr_gate_magic;
+	uint32_t	peripheral_pwr_gate_length;
+	uint32_t	_pad_0x08_0x0C[2];
+	uint32_t	peripheral_pwr_gate_array;	/* offset, value */
+
+	/* ddr configuration - select */
+	uint32_t	ddr_magic;
+	uint32_t	ddr_length;
+	uint32_t	_pad_0x1C_0x20[2];
+	uint32_t	ddr_array[4];	/* offset, value */
+#endif
 } handoff;
 
 int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
 int socfpga_get_handoff(handoff *hoff_ptr);
 
 #endif
-
-
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 564b4ee..77d3af9 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,11 @@
 
 #include <lib/utils_def.h>
 
-
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define MBOX_OFFSET					0x10a30000
+#else
 #define MBOX_OFFSET					0xffa30000
+#endif
 
 #define MBOX_ATF_CLIENT_ID				0x1U
 #define MBOX_MAX_JOB_ID					0xFU
@@ -193,9 +196,9 @@
 #define RSU_VERSION_ACMF_MASK				0xff00
 
 /* Config Status Macros */
-#define CONFIG_STATUS_WORD_SIZE		16U
-#define CONFIG_STATUS_FW_VER_OFFSET	1
-#define CONFIG_STATUS_FW_VER_MASK	0x00FFFFFF
+#define CONFIG_STATUS_WORD_SIZE			16U
+#define CONFIG_STATUS_FW_VER_OFFSET		1
+#define CONFIG_STATUS_FW_VER_MASK		0x00FFFFFF
 
 /* Data structure */
 
@@ -233,6 +236,7 @@
 			unsigned int *resp_len);
 
 void mailbox_reset_cold(void);
+void mailbox_reset_warm(uint32_t reset_type);
 void mailbox_clear_response(void);
 
 int intel_mailbox_get_config_status(uint32_t cmd, bool init_done);
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
index e3c0f73..3fc3f81 100644
--- a/plat/intel/soc/common/include/socfpga_noc.h
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,6 +74,10 @@
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2			0x0070
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3			0x0074
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP				0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG4			0x007c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_PWRMGR			0x0080
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_RXECC			0x0084
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_TXECC			0x0088
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES			0x0090
 #define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS			0x0094
 
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index cce16ab..9d06a3d 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,10 @@
 
 #include "socfpga_plat_def.h"
 
+/* Status Response */
+#define RSTMGR_RET_OK				0
+#define RSTMGR_RET_ERROR			-1
+
 #define SOCFPGA_BRIDGE_ENABLE			BIT(0)
 #define SOCFPGA_BRIDGE_HAS_MASK			BIT(1)
 
@@ -22,28 +26,51 @@
 /* Register Mapping */
 
 #define SOCFPGA_RSTMGR_STAT			0x000
+#define SOCFPGA_RSTMGR_MISCSTAT			0x008
 #define SOCFPGA_RSTMGR_HDSKEN			0x010
 #define SOCFPGA_RSTMGR_HDSKREQ			0x014
 #define SOCFPGA_RSTMGR_HDSKACK			0x018
+#define SOCFPGA_RSTMGR_HDSKSTALL		0x01C
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 #define SOCFPGA_RSTMGR_MPUMODRST		0x020
+#endif
 #define SOCFPGA_RSTMGR_PER0MODRST		0x024
 #define SOCFPGA_RSTMGR_PER1MODRST		0x028
-#define SOCFPGA_RSTMGR_BRGMODRST		0x02c
+#define SOCFPGA_RSTMGR_BRGMODRST		0x02C
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 #define SOCFPGA_RSTMGR_COLDMODRST		0x034
+#endif
+#define SOCFPGA_RSTMGR_DBGMODRST		0x03C
+#define SOCFPGA_RSTMGR_BRGWARMMASK		0x04C
+#define SOCFPGA_RSTMGR_TSTSTA			0x05C
 #define SOCFPGA_RSTMGR_HDSKTIMEOUT		0x064
+#define SOCFPGA_RSTMGR_DBGHDSKTIMEOUT		0x06C
+#define SOCFPGA_RSTMGR_DBGRSTCMPLT		0x070
+#define SOCFPGA_RSTMGR_HPSRSTCMPLT		0x080
+#define SOCFPGA_RSTMGR_CPUINREST		0x090
+#define SOCFPGA_RSTMGR_CPURSTRELEASE		0x094
+#define SOCFPGA_RSTMGR_CPUBASELOW_0		0x098
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_0		0x09C
+#define SOCFPGA_RSTMGR_CPUBASELOW_1		0x0A0
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_1		0x0A4
+#define SOCFPGA_RSTMGR_CPUBASELOW_2		0x0A8
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_2		0x0AC
+#define SOCFPGA_RSTMGR_CPUBASELOW_3		0x0B0
+#define SOCFPGA_RSTMGR_CPUBASEHIGH_3		0x0B4
 
 /* Field Mapping */
-
-#define RSTMGR_PER0MODRST_EMAC0			0x00000001
-#define RSTMGR_PER0MODRST_EMAC1			0x00000002
-#define RSTMGR_PER0MODRST_EMAC2			0x00000004
+/* PER0MODRST */
+#define RSTMGR_PER0MODRST_EMAC0			0x00000001	//TSN0
+#define RSTMGR_PER0MODRST_EMAC1			0x00000002	//TSN1
+#define RSTMGR_PER0MODRST_EMAC2			0x00000004	//TSN2
 #define RSTMGR_PER0MODRST_USB0			0x00000008
 #define RSTMGR_PER0MODRST_USB1			0x00000010
 #define RSTMGR_PER0MODRST_NAND			0x00000020
+#define RSTMGR_PER0MODRST_SOFTPHY		0x00000040
 #define RSTMGR_PER0MODRST_SDMMC			0x00000080
-#define RSTMGR_PER0MODRST_EMAC0OCP		0x00000100
-#define RSTMGR_PER0MODRST_EMAC1OCP		0x00000200
-#define RSTMGR_PER0MODRST_EMAC2OCP		0x00000400
+#define RSTMGR_PER0MODRST_EMAC0OCP		0x00000100	//TSN0ECC
+#define RSTMGR_PER0MODRST_EMAC1OCP		0x00000200	//TSN1ECC
+#define RSTMGR_PER0MODRST_EMAC2OCP		0x00000400	//TSN2ECC
 #define RSTMGR_PER0MODRST_USB0OCP		0x00000800
 #define RSTMGR_PER0MODRST_USB1OCP		0x00001000
 #define RSTMGR_PER0MODRST_NANDOCP		0x00002000
@@ -64,6 +91,7 @@
 #define RSTMGR_PER0MODRST_DMAIF6		0x40000000
 #define RSTMGR_PER0MODRST_DMAIF7		0x80000000
 
+/* PER1MODRST */
 #define RSTMGR_PER1MODRST_WATCHDOG0		0x00000001
 #define RSTMGR_PER1MODRST_WATCHDOG1		0x00000002
 #define RSTMGR_PER1MODRST_WATCHDOG2		0x00000004
@@ -77,31 +105,121 @@
 #define RSTMGR_PER1MODRST_I2C2			0x00000400
 #define RSTMGR_PER1MODRST_I2C3			0x00000800
 #define RSTMGR_PER1MODRST_I2C4			0x00001000
+#define RSTMGR_PER1MODRST_I3C0			0x00002000
+#define RSTMGR_PER1MODRST_I3C1			0x00004000
 #define RSTMGR_PER1MODRST_UART0			0x00010000
 #define RSTMGR_PER1MODRST_UART1			0x00020000
 #define RSTMGR_PER1MODRST_GPIO0			0x01000000
 #define RSTMGR_PER1MODRST_GPIO1			0x02000000
+#define RSTMGR_PER1MODRST_WATCHDOG4		0x04000000
 
+/* HDSKEN */
+#define RSTMGR_HDSKEN_EMIF_FLUSH		0x00000001
 #define RSTMGR_HDSKEN_FPGAHSEN			0x00000004
 #define RSTMGR_HDSKEN_ETRSTALLEN		0x00000008
-#define RSTMGR_HDSKEN_L2FLUSHEN			0x00000100
+#define RSTMGR_HDSKEN_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKEN_S2F_FLUSH			0x00000400
+#define RSTMGR_HDSKEN_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKEN_F2S_FLUSH			0x00001000
 #define RSTMGR_HDSKEN_L3NOC_DBG			0x00010000
 #define RSTMGR_HDSKEN_DEBUG_L3NOC		0x00020000
-#define RSTMGR_HDSKEN_SDRSELFREFEN		0x00000001
 
-#define RSTMGR_HDSKEQ_FPGAHSREQ			0x4
+/* HDSKREQ */
+#define RSTMGR_HDSKREQ_EMIFFLUSHREQ		0x00000001
+#define RSTMGR_HDSKREQ_ETRSTALLREQ		0x00000008
+#define RSTMGR_HDSKREQ_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKREQ_S2F_FLUSH		0x00000400
+#define RSTMGR_HDSKREQ_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKREQ_F2S_FLUSH		0x00001000
+#define RSTMGR_HDSKREQ_L3NOC_DBG		0x00010000
+#define RSTMGR_HDSKREQ_DEBUG_L3NOC		0x00020000
+#define RSTMGR_HDSKREQ_FPGAHSREQ		0x00000004
+#define RSTMGR_HDSKREQ_LWSOC2FPGAREQ		0x00000200
+#define RSTMGR_HDSKREQ_SOC2FPGAREQ		0x00000400
+#define RSTMGR_HDSKREQ_F2SDRAM0REQ		0x00000800
+#define RSTMGR_HDSKREQ_FPGA2SOCREQ		0x00001000
 
-#define RSTMGR_BRGMODRST_SOC2FPGA		0x1
-#define RSTMGR_BRGMODRST_LWHPS2FPGA		0x2
-#define RSTMGR_BRGMODRST_FPGA2SOC		0x4
-#define RSTMGR_BRGMODRST_F2SSDRAM0		0x8
+/* HDSKACK */
+#define RSTMGR_HDSKACK_EMIFFLUSHREQ		0x00000001
+#define RSTMGR_HDSKACK_FPGAHSREQ		0x00000004
+#define RSTMGR_HDSKACK_ETRSTALLREQ		0x00000008
+#define RSTMGR_HDSKACK_LWS2F_FLUSH		0x00000200
+#define RSTMGR_HDSKACK_S2F_FLUSH		0x00000400
+#define RSTMGR_HDSKACK_F2SDRAM_FLUSH		0x00000800
+#define RSTMGR_HDSKACK_F2S_FLUSH		0x00001000
+#define RSTMGR_HDSKACK_L3NOC_DBG		0x00010000
+#define RSTMGR_HDSKACK_DEBUG_L3NOC		0x00020000
+#define RSTMGR_HDSKACK_FPGAHSACK		0x00000004
+#define RSTMGR_HDSKACK_LWSOC2FPGAACK		0x00000200
+#define RSTMGR_HDSKACK_SOC2FPGAACK		0x00000400
+#define RSTMGR_HDSKACK_F2SDRAM0ACK		0x00000800
+#define RSTMGR_HDSKACK_FPGA2SOCACK		0x00001000
+#define RSTMGR_HDSKACK_FPGAHSACK_DASRT		0x00000000
+#define RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT	0x00000000
+#define RSTMGR_HDSKACK_FPGA2SOCACK_DASRT	0x00000000
+
+/* HDSKSTALL */
+#define RSTMGR_HDSKACK_ETRSTALLWARMRST		0x00000001
+
+/* BRGMODRST */
+#define RSTMGR_BRGMODRST_SOC2FPGA		0x00000001
+#define RSTMGR_BRGMODRST_LWHPS2FPGA		0x00000002
+#define RSTMGR_BRGMODRST_FPGA2SOC		0x00000004
+#define RSTMGR_BRGMODRST_F2SSDRAM0		0x00000008
+#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 #define RSTMGR_BRGMODRST_F2SSDRAM1		0x10
 #define RSTMGR_BRGMODRST_F2SSDRAM2		0x20
-#define RSTMGR_BRGMODRST_MPFE			0x40
 #define RSTMGR_BRGMODRST_DDRSCH			0x40
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define RSTMGR_BRGMODRST_F2SSDRAM1		0x10
+#define RSTMGR_BRGMODRST_F2SSDRAM2		0x20
+#endif
+
+#define RSTMGR_BRGMODRST_MPFE			0x40
+
+/* DBGMODRST */
+#define RSTMGR_DBGMODRST_DBG_RST		0x00000001
 
-#define RSTMGR_HDSKREQ_FPGAHSREQ		(BIT(2))
-#define RSTMGR_HDSKACK_FPGAHSACK_MASK		(BIT(2))
+/* BRGMODRSTMASK */
+#define RSTMGR_BRGMODRSTMASK_SOC2FPGA		0x00000001
+#define RSTMGR_BRGMODRSTMASK_LWHPS2FPGA		0x00000002
+#define RSTMGR_BRGMODRSTMASK_FPGA2SOC		0x00000004
+#define RSTMGR_BRGMODRSTMASK_F2SDRAM0		0x00000008
+#define RSTMGR_BRGMODRSTMASK_MPFE		0x00000040
+
+/* TSTSTA */
+#define RSTMGR_TSTSTA_RSTST			0x0000001F
+
+/* HDSKTIMEOUT */
+#define RSTMGR_HDSKTIMEOUT_VAL			0xFFFFFFFF
+
+/* DBGHDSKTIMEOUT */
+#define RSTMGR_DBGHDSKTIMEOUT_VAL		0xFFFFFFFF
+
+/* DBGRSTCMPLT */
+#define RSTMGR_DBGRSTCMPLT_VAL			0xFFFFFFFF
+
+/* HPSRSTCMPLT */
+#define RSTMGR_DBGRSTCMPLT_VAL			0xFFFFFFFF
+
+/* CPUINRESET */
+#define RSTMGR_CPUINRESET_CPU0			0x00000001
+#define RSTMGR_CPUINRESET_CPU1			0x00000002
+#define RSTMGR_CPUINRESET_CPU2			0x00000004
+#define RSTMGR_CPUINRESET_CPU3			0x00000008
+
+/* CPUSTRELEASE */
+#define RSTMGR_CPUSTRELEASE_CPUx		0x10D11094
+
+/* CPUxRESETBASE */
+#define RSTMGR_CPUxRESETBASELOW_CPU0		0x10D11098
+#define RSTMGR_CPUxRESETBASEHIGH_CPU0		0x10D1109C
+#define RSTMGR_CPUxRESETBASELOW_CPU1		0x10D110A0
+#define RSTMGR_CPUxRESETBASEHIGH_CPU1		0x10D110A4
+#define RSTMGR_CPUxRESETBASELOW_CPU2		0x10D110A8
+#define RSTMGR_CPUxRESETBASEHIGH_CPU2		0x10D110AC
+#define RSTMGR_CPUxRESETBASELOW_CPU3		0x10D110B0
+#define RSTMGR_CPUxRESETBASEHIGH_CPU3		0x10D110B4
 
 /* Definitions */
 
@@ -109,17 +227,28 @@
 #define RSTMGR_HDSKEN_SET			0x010D
 
 /* Macros */
+#define SOCFPGA_RSTMGR(_reg)			(SOCFPGA_RSTMGR_REG_BASE + (SOCFPGA_RSTMGR_##_reg))
+#define RSTMGR_FIELD(_reg, _field)		(RSTMGR_##_reg##MODRST_##_field)
 
-#define SOCFPGA_RSTMGR(_reg)		(SOCFPGA_RSTMGR_REG_BASE \
-					+ (SOCFPGA_RSTMGR_##_reg))
-#define RSTMGR_FIELD(_reg, _field)	(RSTMGR_##_reg##MODRST_##_field)
+/* Reset type to SDM from PSCI */
+// Temp add macro here for reset type
+#define SOCFPGA_RESET_TYPE_COLD			0
+#define SOCFPGA_RESET_TYPE_WARM			1
 
 /* Function Declarations */
 
 void deassert_peripheral_reset(void);
 void config_hps_hs_before_warm_reset(void);
 
+int socfpga_bridges_reset(uint32_t mask);
 int socfpga_bridges_enable(uint32_t mask);
 int socfpga_bridges_disable(uint32_t mask);
 
+int socfpga_cpurstrelease(unsigned int cpu_id);
+int socfpga_cpu_reset_base(unsigned int cpu_id);
+
+/* SMP: Func proto */
+void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id);
+void bl31_plat_set_secondary_cpu_off(void);
+
 #endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 8d9ba70..f860f57 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/intel/soc/common/include/socfpga_vab.h b/plat/intel/soc/common/include/socfpga_vab.h
new file mode 100644
index 0000000..f6081df
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_vab.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_VAB_H
+#define SOCFPGA_VAB_H
+
+
+#include <stdlib.h>
+#include "socfpga_fcs.h"
+
+struct fcs_hps_vab_certificate_data {
+	uint32_t vab_cert_magic_num;			/* offset 0x10 */
+	uint32_t flags;
+	uint8_t rsvd0_1[8];
+	uint8_t fcs_sha384[FCS_SHA384_WORD_SIZE];	/* offset 0x20 */
+};
+
+struct fcs_hps_vab_certificate_header {
+	uint32_t cert_magic_num;			/* offset 0 */
+	uint32_t cert_data_sz;
+	uint32_t cert_ver;
+	uint32_t cert_type;
+	struct fcs_hps_vab_certificate_data d;		/* offset 0x10 */
+	/* keychain starts at offset 0x50 */
+};
+
+/* Macros */
+#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
+#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
+#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
+#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
+#define SDM_CERT_MAGIC_NUM		0x25D04E7F
+#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
+
+/* SHA related return Macro */
+#define ENOVABIMG		1 /* VAB certificate not available */
+#define EIMGERR		2 /* Image format/size not valid */
+#define ETIMEOUT		3 /* Execution timeout */
+#define EPROCESS		4 /* Process error */
+#define EKEYREJECTED		5/* Key was rejected by service */
+
+/* Function Definitions */
+static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
+int socfpga_vendor_authentication(void **p_image, size_t *p_size);
+static uint32_t get_unaligned_le32(const void *p);
+void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
+unsigned char *output, unsigned int chunk_sz);
+
+#endif
diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c
index 02ff89e..49c92c3 100644
--- a/plat/intel/soc/common/soc/socfpga_emac.c
+++ b/plat/intel/soc/common/soc/socfpga_emac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/intel/soc/common/soc/socfpga_firewall.c b/plat/intel/soc/common/soc/socfpga_firewall.c
index fc3889c..6247df3 100644
--- a/plat/intel/soc/common/soc/socfpga_firewall.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,11 @@
 void enable_ns_peripheral_access(void)
 {
 	mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_REGISTER), DISABLE_L4_FIREWALL);
+#if	((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+	(PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
 	mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_DATA), DISABLE_L4_FIREWALL);
+#endif
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_ECC), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_READ_ECC), DISABLE_L4_FIREWALL);
@@ -87,9 +91,19 @@
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG1), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG2), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG3), DISABLE_L4_FIREWALL);
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG4), DISABLE_L4_FIREWALL);
+#endif
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(DAP), DISABLE_L4_FIREWALL);
 
+#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(PWRMGR), DISABLE_L4_FIREWALL);
+
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_RXECC), DISABLE_L4_FIREWALL);
+	mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_TXECC), DISABLE_L4_FIREWALL);
+#endif
+
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_PROBES), DISABLE_L4_FIREWALL);
 
 	mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
diff --git a/plat/intel/soc/common/soc/socfpga_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
index a3146b4..526c6e1 100644
--- a/plat/intel/soc/common/soc/socfpga_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,16 +29,34 @@
 	for (i = 0; i < sizeof(handoff) / 4; i++)
 		buffer[i] = SWAP_UINT32(buffer[i]);
 
-	if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER)
+	if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL)
+	}
+	if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR)
+	}
+	if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA)
+	}
+	if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA) {
 		return -1;
-	if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY)
+	}
+	if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY) {
 		return -1;
+	}
+	if (reverse_hoff_ptr->clock_magic != HANDOFF_MAGIC_CLOCK) {
+		return -1;
+	}
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	if (reverse_hoff_ptr->peripheral_pwr_gate_magic != HANDOFF_MAGIC_PERIPHERAL) {
+		return -1;
+	}
+
+	if (reverse_hoff_ptr->ddr_magic != HANDOFF_MAGIC_DDR) {
+		return -1;
+	}
+#endif
 
 	return 0;
 }
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 525ac2b..d93fc8a 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -523,10 +523,20 @@
 void mailbox_reset_cold(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U,
-				CMD_CASUAL, NULL, NULL);
+
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0U, 0U,
+				 CMD_CASUAL, NULL, NULL);
 }
 
+void mailbox_reset_warm(uint32_t reset_type)
+{
+	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
+
+	reset_type = 0x01; // Warm reset header data must be 1
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, &reset_type, 1U,
+				 CMD_CASUAL, NULL, NULL);
+}
+
 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
 {
 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
@@ -679,9 +689,10 @@
 				&resp_len);
 }
 
-int mailbox_seu_err_status(uint32_t *resp_buf, uint32_t resp_buf_len)
+int mailbox_seu_err_status(uint32_t *resp_buf, unsigned int resp_buf_len)
 {
+
 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SEU_ERR_READ, NULL, 0U,
 				CMD_CASUAL, resp_buf,
-				&resp_buf_len);;
+				&resp_buf_len);
 }
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index a546638..7db86c7 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -23,6 +24,7 @@
 			RSTMGR_FIELD(PER1, WATCHDOG1) |
 			RSTMGR_FIELD(PER1, WATCHDOG2) |
 			RSTMGR_FIELD(PER1, WATCHDOG3) |
+			RSTMGR_FIELD(PER1, WATCHDOG4) |
 			RSTMGR_FIELD(PER1, L4SYSTIMER0) |
 			RSTMGR_FIELD(PER1, L4SYSTIMER1) |
 			RSTMGR_FIELD(PER1, SPTIMER0) |
@@ -32,12 +34,15 @@
 			RSTMGR_FIELD(PER1, I2C2) |
 			RSTMGR_FIELD(PER1, I2C3) |
 			RSTMGR_FIELD(PER1, I2C4) |
+			RSTMGR_FIELD(PER1, I3C0) |
+			RSTMGR_FIELD(PER1, I3C1) |
 			RSTMGR_FIELD(PER1, UART0) |
 			RSTMGR_FIELD(PER1, UART1) |
 			RSTMGR_FIELD(PER1, GPIO0) |
 			RSTMGR_FIELD(PER1, GPIO1));
 
 	mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+			RSTMGR_FIELD(PER0, SOFTPHY) |
 			RSTMGR_FIELD(PER0, EMAC0OCP) |
 			RSTMGR_FIELD(PER0, EMAC1OCP) |
 			RSTMGR_FIELD(PER0, EMAC2OCP) |
@@ -80,10 +85,10 @@
 {
 	uint32_t or_mask = 0;
 
-	or_mask |= RSTMGR_HDSKEN_SDRSELFREFEN;
+	or_mask |= RSTMGR_HDSKEN_EMIF_FLUSH;
 	or_mask |= RSTMGR_HDSKEN_FPGAHSEN;
 	or_mask |= RSTMGR_HDSKEN_ETRSTALLEN;
-	or_mask |= RSTMGR_HDSKEN_L2FLUSHEN;
+	or_mask |= RSTMGR_HDSKEN_LWS2F_FLUSH;
 	or_mask |= RSTMGR_HDSKEN_L3NOC_DBG;
 	or_mask |= RSTMGR_HDSKEN_DEBUG_L3NOC;
 
@@ -104,6 +109,27 @@
 	return -ETIMEDOUT;
 }
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static int poll_idle_status_by_counter(uint32_t addr, uint32_t mask,
+					uint32_t match, uint32_t delay_ms)
+{
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+
+		/* ToDo: Shall use udelay for product release */
+		for (int i = 0; i < 2000; i++) {
+			/* dummy delay */
+		}
+	}
+	return -ETIMEDOUT;
+}
+#endif
+
 static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
 					 uint32_t match, uint32_t delay_clk_cycles)
 {
@@ -185,6 +211,39 @@
 		*f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
 		*f2s_cmdidle |= FLAGINSTATUS_F2SDRAM2_CMDIDLE;
 	}
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	if (mask & FPGA2SOC_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, FPGA2SOC);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+	}
+	if (mask & F2SDRAM0_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM0);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+	}
+	if (mask & F2SDRAM1_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM1_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM1_RESPEMPTY;
+	}
+	if (mask & F2SDRAM2_MASK) {
+		*brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
+		*f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
+		*f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
+		*f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
+		*f2s_idleack |= FLAGINSTATUS_F2SDRAM2_IDLEACK;
+		*f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
+	}
 #else
 	if ((mask & FPGA2SOC_MASK) != 0U) {
 		*brg_mask |= RSTMGR_FIELD(BRG, FPGA2SOC);
@@ -198,6 +257,153 @@
 #endif
 }
 
+int socfpga_bridges_reset(uint32_t mask)
+{
+	int ret = 0;
+	int timeout = 300;
+	uint32_t brg_mask = 0;
+	uint32_t noc_mask = 0;
+	uint32_t f2s_idlereq = 0;
+	uint32_t f2s_force_drain = 0;
+	uint32_t f2s_en = 0;
+	uint32_t f2s_idleack = 0;
+	uint32_t f2s_respempty = 0;
+	uint32_t f2s_cmdidle = 0;
+
+	/* Reset s2f bridge */
+	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+	if (brg_mask) {
+		if (mask & SOC2FPGA_MASK) {
+			/* Request handshake with SOC2FPGA bridge to clear traffic */
+			mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_S2F_FLUSH);
+
+			/* Wait for bridge to idle status */
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+					RSTMGR_HDSKACK_S2F_FLUSH,
+					RSTMGR_HDSKACK_S2F_FLUSH, 300);
+		}
+
+		if (mask & LWHPS2FPGA_MASK) {
+			/* Request handshake with LWSOC2FPGA bridge to clear traffic */
+			mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_LWS2F_FLUSH);
+
+			/* Wait for bridge to idle status */
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+					RSTMGR_HDSKACK_LWS2F_FLUSH,
+					RSTMGR_HDSKACK_LWS2F_FLUSH, 300);
+		}
+
+		if (ret < 0) {
+			ERROR("S2F Bridge reset: Timeout waiting for idle ack\n");
+			assert(false);
+		}
+
+		/* Assert reset to bridge */
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				brg_mask);
+
+		/* Clear idle requests to bridge */
+		if (mask & SOC2FPGA_MASK) {
+			mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_S2F_FLUSH);
+		}
+
+		if (mask & LWHPS2FPGA_MASK) {
+			mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+					RSTMGR_HDSKREQ_LWS2F_FLUSH);
+		}
+
+		/* When FPGA reconfig is complete */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+	}
+
+	/* Reset f2s bridge */
+	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+					&f2s_force_drain, &f2s_en,
+					&f2s_idleack, &f2s_respempty,
+					&f2s_cmdidle);
+
+	if (brg_mask) {
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
+				RSTMGR_HDSKEN_FPGAHSEN);
+
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSREQ,
+				RSTMGR_HDSKACK_FPGAHSREQ, 300);
+
+		if (ret < 0) {
+			ERROR("F2S Bridge disable: Timeout waiting for idle req\n");
+			assert(false);
+		}
+
+		/* Disable f2s bridge */
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+				f2s_en);
+		udelay(5);
+
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+				f2s_force_drain);
+		udelay(5);
+
+		do {
+			/* Read response queue status to ensure it is empty */
+			uint32_t idle_status;
+
+			idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+				SIDEBANDMGR_FLAGINSTATUS0));
+			if (idle_status & f2s_respempty) {
+				idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+					SIDEBANDMGR_FLAGINSTATUS0));
+				if (idle_status & f2s_respempty) {
+					break;
+				}
+			}
+			udelay(1000);
+		} while (timeout-- > 0);
+
+		/* Assert reset to f2s bridge */
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				brg_mask);
+
+		/* Clear idle request to FPGA */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+				RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Clear idle request to MPFE */
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+				f2s_idlereq);
+
+		/* When FPGA reconfig is complete */
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+
+		/* Enable f2s bridge */
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_idlereq);
+
+		ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
+			SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0, 300);
+		if (ret < 0) {
+			ERROR("F2S bridge enable: Timeout waiting for idle ack");
+			assert(false);
+		}
+
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_force_drain);
+		udelay(5);
+
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+			f2s_en);
+		udelay(5);
+	}
+
+	return ret;
+}
+
 int socfpga_bridges_enable(uint32_t mask)
 {
 	int ret = 0;
@@ -209,9 +415,87 @@
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
 	uint32_t f2s_cmdidle = 0;
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	uint32_t delay = 0;
+#endif
 
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Enable SOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA) {
+		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 1 */
+		NOTICE("Set S2F hdskreq ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+
+		/* Read Reset Manager hdskack[soc2fpga] = 1 */
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("S2F bridge enable: Timeout hdskack\n");
+		}
+
+		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 0 */
+		NOTICE("Clear S2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+
+		/* Write Reset Manager brgmodrst[soc2fpga] = 1 */
+		NOTICE("Assert S2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[soc2fpga] = 0 */
+		NOTICE("Deassert S2F ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_SOC2FPGA);
+	}
+
+	/* Enable LWSOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
+		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 1 */
+		NOTICE("Set LWS2F hdskreq ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+
+		/* Read Reset Manager hdskack[lwsoc2fpga] = 1 */
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("LWS2F bridge enable: Timeout hdskack\n");
+		}
+
+		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0 */
+		NOTICE("Clear LWS2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+
+		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 1 */
+		NOTICE("Assert LWS2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 0 */
+		NOTICE("Deassert LWS2F ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_LWHPS2FPGA);
+	}
+#else
 	if (brg_mask != 0U) {
 		/* Clear idle request */
 		mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_CLR),
@@ -224,15 +508,186 @@
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
 				       noc_mask, 0, 300);
 		if (ret < 0) {
-			ERROR("S2F bridge enable: "
-					"Timeout waiting for idle ack\n");
+			ERROR("S2F bridge enable: Timeout idle ack\n");
 		}
 	}
+#endif
 
 	/* Enable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
 				&f2s_force_drain, &f2s_en,
 				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Enable FPGA2SOC bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
+		/* Write Reset Manager hdsken[fpgahsen] = 1 */
+		NOTICE("Set FPGA hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Set FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Read Reset Manager hdskack[fpgahsack] = 1 */
+		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("FPGA bridge fpga handshake fpgahsreq: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
+		NOTICE("Set F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+
+		/* Read Reset Manager hdskack[f2s_flush_ack] = 1 */
+		NOTICE("Get F2S hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2sdram_flush_req: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Clear FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
+		NOTICE("Clear F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+
+		/* Read Reset Manager hdskack[f2s_flush_ack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+		}
+
+		/* Read Reset Manager hdskack[fpgahsack] = 0 */
+		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2soc] = 1 */
+		NOTICE("Assert F2S ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2soc] = 0 */
+		NOTICE("Deassert F2S ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+
+		/* Write System Manager f2s bridge control register[f2soc_enable] = 1 */
+		NOTICE("Deassert F2S f2soc_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
+			SYSMGR_F2S_BRIDGE_CTRL_EN);
+	}
+
+	/* Enable FPGA2SDRAM bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
+		/* Write Reset Manager hdsken[fpgahsen] = 1 */
+		NOTICE("Set F2SDRAM hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Set F2SDRAM hdskreq(fpgahsreq) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Read Reset Manager hdskack[fpgahsack] = 1 */
+		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake fpgahsreq: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
+		NOTICE("Set F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_F2SDRAM0REQ);
+
+		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 1 */
+		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_req: Timeout\n");
+		}
+
+		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
+		NOTICE("Clear F2SDRAM hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
+		NOTICE("Clear F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_F2SDRAM0REQ);
+
+		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_ack: Timeout\n");
+		}
+
+		/* Read Reset Manager hdskack[fpgahsack] = 0 */
+		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2sdram] = 1 */
+		NOTICE("Assert F2SDRAM ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
+
+		/* ToDo: Shall use udelay for product release */
+		for (delay = 0; delay < 1000; delay++) {
+			/* dummy delay */
+		}
+
+		/* Write Reset Manager brgmodrst[fpga2sdram] = 0 */
+		NOTICE("Deassert F2SDRAM ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
+
+		/*
+		 * Clear fpga2sdram_manager_main_SidebandManager_FlagOutClr0
+		 * f2s_ready_latency_enable
+		 */
+		NOTICE("Clear F2SDRAM f2s_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+			FLAGOUTCLR0_F2SDRAM0_ENABLE);
+	}
+#else
 	if (brg_mask != 0U) {
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
 
@@ -243,8 +698,7 @@
 				       f2s_idleack, 0, 300);
 
 		if (ret < 0) {
-			ERROR("F2S bridge enable: "
-			      "Timeout waiting for idle ack");
+			ERROR("F2S bridge enable: Timeout idle ack");
 		}
 
 		/* Clear the force drain */
@@ -256,7 +710,7 @@
 				f2s_en);
 		udelay(5);
 	}
-
+#endif
 	return ret;
 }
 
@@ -329,15 +783,13 @@
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
 				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
-			ERROR("S2F Bridge disable: "
-			      "Timeout waiting for idle ack\n");
+			ERROR("S2F Bridge disable: Timeout idle ack\n");
 		}
 
 		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
 				       noc_mask, noc_mask, 300);
 		if (ret < 0) {
-			ERROR("S2F Bridge disable: "
-			      "Timeout waiting for idle status\n");
+			ERROR("S2F Bridge disable: Timeout idle status\n");
 		}
 
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
@@ -365,8 +817,8 @@
 				RSTMGR_HDSKREQ_FPGAHSREQ);
 
 		ret = poll_idle_status_by_clkcycles(SOCFPGA_RSTMGR(HDSKACK),
-						    RSTMGR_HDSKACK_FPGAHSACK_MASK,
-						    RSTMGR_HDSKACK_FPGAHSACK_MASK, 1000);
+						    RSTMGR_HDSKACK_FPGAHSREQ,
+						    RSTMGR_HDSKACK_FPGAHSREQ, 1000);
 
 		/* DISABLE F2S Bridge */
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
@@ -394,3 +846,68 @@
 
 	return ret;
 }
+
+/* CPUxRESETBASELOW */
+int socfpga_cpu_reset_base(unsigned int cpu_id)
+{
+	int ret = 0;
+	uint32_t entrypoint = 0;
+
+	ret = socfpga_cpurstrelease(cpu_id);
+
+	if (ret < 0) {
+		return RSTMGR_RET_ERROR;
+	}
+
+	if (ret == RSTMGR_RET_OK) {
+
+		switch (cpu_id) {
+		case 0:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_0);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_0) << 24;
+		break;
+
+		case 1:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_1);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_1) << 24;
+		break;
+
+		case 2:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_2);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_2) << 24;
+		break;
+
+		case 3:
+			entrypoint = mmio_read_32(SOCFPGA_RSTMGR_CPUBASELOW_3);
+			entrypoint |= mmio_read_32(SOCFPGA_RSTMGR_CPUBASEHIGH_3) << 24;
+		break;
+
+		default:
+		break;
+		}
+
+		mmio_write_64(PLAT_SEC_ENTRY, entrypoint);
+	}
+
+	return RSTMGR_RET_OK;
+}
+
+/* CPURSTRELEASE */
+int socfpga_cpurstrelease(unsigned int cpu_id)
+{
+	unsigned int timeout = 0;
+
+	do {
+		/* Read response queue status to ensure it is empty */
+		uint32_t cpurstrelease_status;
+
+		cpurstrelease_status = mmio_read_32(SOCFPGA_RSTMGR(CPURSTRELEASE));
+
+		if ((cpurstrelease_status & RSTMGR_CPUSTRELEASE_CPUx) == cpu_id) {
+			return RSTMGR_RET_OK;
+		}
+		udelay(1000);
+	} while (timeout-- > 0);
+
+	return RSTMGR_RET_ERROR;
+}
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 3b96dfc..5ffd512 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -1,12 +1,14 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
 #include <common/debug.h>
-#ifndef SOCFPGA_GIC_V3
+
+#ifndef GICV3_SUPPORT_GIC600
 #include <drivers/arm/gicv2.h>
 #else
 #include <drivers/arm/gicv3.h>
@@ -14,13 +16,16 @@
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
-
 #include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+void socfpga_wakeup_secondary_cpu(unsigned int cpu_id);
+extern void plat_secondary_cold_boot_setup(void);
+#endif
 
 /*******************************************************************************
  * plat handler called when a CPU is about to enter standby.
@@ -43,13 +48,18 @@
 int socfpga_pwr_domain_on(u_register_t mpidr)
 {
 	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* TODO: Add in CPU FUSE from SDM */
+#else
 	uint32_t psci_boot = 0x00;
 
 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
+#endif
 
 	if (cpu_id == -1)
 		return PSCI_E_INTERN_FAIL;
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	if (cpu_id == 0x00) {
 		psci_boot = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8));
 		psci_boot |= 0x20000; /* bit 17 */
@@ -57,9 +67,16 @@
 	}
 
 	mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
+#endif
 
 	/* release core reset */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	bl31_plat_set_secondary_cpu_entrypoint(cpu_id);
+#else
 	mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
+	mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
+#endif
+
 	return PSCI_E_SUCCESS;
 }
 
@@ -74,7 +91,12 @@
 			__func__, i, target_state->pwr_domain_state[i]);
 
 	/* Prevent interrupts from spuriously waking up this cpu */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_cpuif_disable(plat_my_core_pos());
+#else
 	gicv2_cpuif_disable();
+#endif
+
 }
 
 /*******************************************************************************
@@ -83,15 +105,18 @@
  ******************************************************************************/
 void socfpga_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	unsigned int cpu_id = plat_my_core_pos();
+#endif
 
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* assert core reset */
 	mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
-
+#endif
 }
 
 /*******************************************************************************
@@ -105,12 +130,18 @@
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+	/* Enable the gic cpu interface */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+#else
 	/* Program the gic per-cpu distributor or re-distributor interface */
 	gicv2_pcpu_distif_init();
 	gicv2_set_pe_target_mask(plat_my_core_pos());
 
 	/* Enable the gic cpu interface */
 	gicv2_cpuif_enable();
+#endif
 }
 
 /*******************************************************************************
@@ -122,14 +153,18 @@
  ******************************************************************************/
 void socfpga_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	unsigned int cpu_id = plat_my_core_pos();
+#endif
 
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* release core reset */
 	mmio_clrbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id);
+#endif
 }
 
 /*******************************************************************************
@@ -163,11 +198,20 @@
 static int socfpga_system_reset2(int is_vendor, int reset_type,
 					u_register_t cookie)
 {
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	mailbox_reset_warm(reset_type);
+#else
 	if (cold_reset_for_ecc_dbe()) {
 		mailbox_reset_cold();
 	}
+#endif
+
 	/* disable cpuif */
+#ifdef GICV3_SUPPORT_GIC600
+	gicv3_cpuif_disable(plat_my_core_pos());
+#else
 	gicv2_cpuif_disable();
+#endif
 
 	/* Store magic number */
 	mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
@@ -178,8 +222,10 @@
 	/* Enable handshakes */
 	mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_SET);
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	/* Reset L2 module */
 	mmio_setbits_32(SOCFPGA_RSTMGR(COLDMODRST), 0x100);
+#endif
 
 	while (1)
 		wfi();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 1a18ee1..c6530cf 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -335,6 +335,7 @@
 	return 0;
 #endif
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	switch (reg_addr) {
 	case(0xF8011100):	/* ECCCTRL1 */
 	case(0xF8011104):	/* ECCCTRL2 */
@@ -386,7 +387,41 @@
 	case(0xFFD12220):	/* BOOT_SCRATCH_COLD8 */
 	case(0xFFD12224):	/* BOOT_SCRATCH_COLD9 */
 		return 0;
+#else
+	switch (reg_addr) {
+
+	case(0xF8011104):	/* ECCCTRL2 */
+	case(0xFFD12028):	/* SDMMCGRP_CTRL */
+	case(0xFFD120C4):	/* NOC_IDLEREQ_SET */
+	case(0xFFD120C8):	/* NOC_IDLEREQ_CLR */
+	case(0xFFD120D0):	/* NOC_IDLEACK */
+
 
+	case(SOCFPGA_MEMCTRL(ECCCTRL1)):	/* ECCCTRL1 */
+	case(SOCFPGA_MEMCTRL(ERRINTEN)):	/* ERRINTEN */
+	case(SOCFPGA_MEMCTRL(ERRINTENS)):	/* ERRINTENS */
+	case(SOCFPGA_MEMCTRL(ERRINTENR)):	/* ERRINTENR */
+	case(SOCFPGA_MEMCTRL(INTMODE)):	/* INTMODE */
+	case(SOCFPGA_MEMCTRL(INTSTAT)):	/* INTSTAT */
+	case(SOCFPGA_MEMCTRL(DIAGINTTEST)):	/* DIAGINTTEST */
+	case(SOCFPGA_MEMCTRL(DERRADDRA)):	/* DERRADDRA */
+
+	case(SOCFPGA_SYSMGR(EMAC_0)):	/* EMAC0 */
+	case(SOCFPGA_SYSMGR(EMAC_1)):	/* EMAC1 */
+	case(SOCFPGA_SYSMGR(EMAC_2)):	/* EMAC2 */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_VALUE)):	/* ECC_INT_MASK_VALUE */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_SET)):	/* ECC_INT_MASK_SET */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_CLR)):	/* ECC_INT_MASK_CLEAR */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_SERR)):	/* ECC_INTSTATUS_SERR */
+	case(SOCFPGA_SYSMGR(ECC_INTMASK_DERR)):	/* ECC_INTSTATUS_DERR */
+	case(SOCFPGA_SYSMGR(NOC_TIMEOUT)):	/* NOC_TIMEOUT */
+	case(SOCFPGA_SYSMGR(NOC_IDLESTATUS)):	/* NOC_IDLESTATUS */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0)):	/* BOOT_SCRATCH_COLD0 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)):	/* BOOT_SCRATCH_COLD1 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8)):	/* BOOT_SCRATCH_COLD8 */
+	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_9)):	/* BOOT_SCRATCH_COLD9 */
+		return 0;
+#endif
 	default:
 		break;
 	}
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index 79e15d7..e80f074 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -9,29 +9,37 @@
 #include <assert.h>
 #include <common/debug.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/cadence/cdns_nand.h>
+#include <drivers/cadence/cdns_sdmmc.h>
 #include <drivers/io/io_block.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_fip.h>
 #include <drivers/io/io_memmap.h>
+#include <drivers/io/io_mtd.h>
 #include <drivers/io/io_storage.h>
 #include <drivers/mmc.h>
 #include <drivers/partition/partition.h>
 #include <lib/mmio.h>
 #include <tools_share/firmware_image_package.h>
 
+#include "drivers/sdmmc/sdmmc.h"
 #include "socfpga_private.h"
 
+
 #define PLAT_FIP_BASE		(0)
 #define PLAT_FIP_MAX_SIZE	(0x1000000)
 #define PLAT_MMC_DATA_BASE	(0xffe3c000)
 #define PLAT_MMC_DATA_SIZE	(0x2000)
 #define PLAT_QSPI_DATA_BASE	(0x3C00000)
 #define PLAT_QSPI_DATA_SIZE	(0x1000000)
-
+#define PLAT_NAND_DATA_BASE	(0x0200000)
+#define PLAT_NAND_DATA_SIZE	(0x1000000)
 
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;
 
+static io_mtd_dev_spec_t nand_dev_spec;
+
 static uintptr_t fip_dev_handle;
 static uintptr_t boot_dev_handle;
 
@@ -136,17 +144,27 @@
 	case BOOT_SOURCE_SDMMC:
 		register_io_dev = &register_io_dev_block;
 		boot_dev_spec.buffer.offset	= PLAT_MMC_DATA_BASE;
-		boot_dev_spec.buffer.length	= MMC_BLOCK_SIZE;
-		boot_dev_spec.ops.read		= mmc_read_blocks;
-		boot_dev_spec.ops.write		= mmc_write_blocks;
+		boot_dev_spec.buffer.length	= SOCFPGA_MMC_BLOCK_SIZE;
+		boot_dev_spec.ops.read		= SDMMC_READ_BLOCKS;
+		boot_dev_spec.ops.write		= SDMMC_WRITE_BLOCKS;
 		boot_dev_spec.block_size	= MMC_BLOCK_SIZE;
 		break;
 
 	case BOOT_SOURCE_QSPI:
 		register_io_dev = &register_io_dev_memmap;
-		fip_spec.offset = fip_spec.offset + PLAT_QSPI_DATA_BASE;
+		fip_spec.offset = PLAT_QSPI_DATA_BASE;
 		break;
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	case BOOT_SOURCE_NAND:
+		register_io_dev = &register_io_dev_mtd;
+		nand_dev_spec.ops.init = cdns_nand_init_mtd;
+		nand_dev_spec.ops.read = cdns_nand_read;
+		nand_dev_spec.ops.write = NULL;
+		fip_spec.offset = PLAT_NAND_DATA_BASE;
+		break;
+#endif
+
 	default:
 		ERROR("Unsupported boot source\n");
 		panic();
@@ -159,8 +177,13 @@
 	result = register_io_dev_fip(&fip_dev_con);
 	assert(result == 0);
 
-	result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
-			&boot_dev_handle);
+	if (boot_source == BOOT_SOURCE_NAND) {
+		result = io_dev_open(boot_dev_con, (uintptr_t)&nand_dev_spec,
+								&boot_dev_handle);
+	} else {
+		result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
+								&boot_dev_handle);
+	}
 	assert(result == 0);
 
 	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
diff --git a/plat/intel/soc/common/socfpga_topology.c b/plat/intel/soc/common/socfpga_topology.c
index ca1a91e..28c9557 100644
--- a/plat/intel/soc/common/socfpga_topology.c
+++ b/plat/intel/soc/common/socfpga_topology.c
@@ -33,8 +33,8 @@
 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
 		return -1;
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = (mpidr >> PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> PLAT_CPU_ID_MPIDR_AFF_SHIFT) & MPIDR_AFFLVL_MASK;
 
 	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
 		return -1;
diff --git a/plat/intel/soc/common/socfpga_vab.c b/plat/intel/soc/common/socfpga_vab.c
new file mode 100644
index 0000000..e16610c
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_vab.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "socfpga_mailbox.h"
+#include "socfpga_vab.h"
+
+static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
+{
+	uint8_t *img_buf_end = img_buf + img_buf_sz;
+	uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
+	uint8_t *p = img_buf_end - cert_sz - sizeof(uint32_t);
+
+	/* Ensure p is pointing within the img_buf */
+	if (p < img_buf || p > (img_buf_end - VAB_CERT_HEADER_SIZE))
+		return 0;
+
+	if (get_unaligned_le32(p) == SDM_CERT_MAGIC_NUM)
+		return (size_t)(p - img_buf);
+
+	return 0;
+}
+
+
+
+int socfpga_vendor_authentication(void **p_image, size_t *p_size)
+{
+	int retry_count = 20;
+	uint8_t hash384[FCS_SHA384_WORD_SIZE];
+	uint64_t img_addr, mbox_data_addr;
+	uint32_t img_sz, mbox_data_sz;
+	uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
+	uint32_t resp = 0, resp_len = 1;
+	int ret = 0;
+
+	img_addr = (uintptr_t)*p_image;
+	img_sz = get_img_size((uint8_t *)img_addr, *p_size);
+
+	if (!img_sz) {
+		NOTICE("VAB certificate not found in image!\n");
+		return -ENOVABIMG;
+	}
+
+	if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
+		NOTICE("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
+		return -EIMGERR;
+	}
+
+	/* Generate HASH384 from the image */
+	/* TODO: This part need to cross check !!!!!! */
+	sha384_csum_wd((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
+	cert_hash_ptr = (uint8_t *)(img_addr + img_sz +
+	VAB_CERT_MAGIC_OFFSET + VAB_CERT_FIT_SHA384_OFFSET);
+
+	/*
+	 * Compare the SHA384 found in certificate against the SHA384
+	 * calculated from image
+	 */
+	if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
+		NOTICE("SHA384 does not match!\n");
+		return -EKEYREJECTED;
+	}
+
+
+	mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
+	/* Size in word (32bits) */
+	mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
+
+	NOTICE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
+
+	/* TODO: This part need to cross check !!!!!! */
+	// mbox_relocate_data_addr = (uint8_t *)malloc(mbox_data_sz * sizeof(uint32_t));
+	// if (!mbox_relocate_data_addr) {
+		// NOTICE("Cannot allocate memory for VAB certificate relocation!\n");
+		// return -ENOMEM;
+	// }
+
+	memcpy(mbox_relocate_data_addr, (uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
+	*(uint32_t *)mbox_relocate_data_addr = 0;
+
+	do {
+		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
+		ret  = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_VAB_SRC_CERT,
+(uint32_t *)mbox_relocate_data_addr, mbox_data_sz, 0, &resp, &resp_len);
+
+		/* If SDM is not available, just delay 50ms and retry again */
+		/* 0x1FF = The device is busy */
+		if (ret == MBOX_RESP_ERR(0x1FF)) {
+			mdelay(50);
+		} else {
+			break;
+		}
+	} while (--retry_count);
+
+	/* Free the relocate certificate memory space */
+	zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
+
+
+	/* Exclude the size of the VAB certificate from image size */
+	*p_size = img_sz;
+
+	if (ret) {
+		/*
+		 * Unsupported mailbox command or device not in the
+		 * owned/secure state
+		 */
+		 /* 0x85 = Not allowed under current security setting */
+		if (ret == MBOX_RESP_ERR(0x85)) {
+			/* SDM bypass authentication */
+			NOTICE("Image Authentication bypassed at address\n");
+			return 0;
+		}
+		NOTICE("VAB certificate authentication failed in SDM\n");
+		/* 0x1FF = The device is busy */
+		if (ret == MBOX_RESP_ERR(0x1FF)) {
+			NOTICE("Operation timed out\n");
+			return -ETIMEOUT;
+		} else if (ret == MBOX_WRONG_ID) {
+			NOTICE("No such process\n");
+			return -EPROCESS;
+		}
+	} else {
+		/* If Certificate Process Status has error */
+		if (resp) {
+			NOTICE("VAB certificate execution format error\n");
+			return -EIMGERR;
+		}
+	}
+
+	NOTICE("Image Authentication bypassed at address\n");
+	return ret;
+
+}
+
+static uint32_t get_unaligned_le32(const void *p)
+{
+	/* TODO: Temp for testing */
+	//return le32_to_cpup((__le32 *)p);
+	return 0;
+}
+
+void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
+		unsigned char *output, unsigned int chunk_sz)
+{
+	/* TODO: Update sha384 start, update and finish */
+}
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 197bbca..a06bbc4 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -88,6 +88,18 @@
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
 #define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
 
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 8a5d4a4..7c9f15a 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -86,6 +86,18 @@
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
 #define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
 
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS	mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG			0xFFD12218
+
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
 
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
index 2f5d47b..1b77942 100644
--- a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
@@ -155,19 +155,4 @@
 			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
 			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN, \
 			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN)
-
-#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW(domain)			 \
-	APUSYS_APC_AO_ATTR(domain,						 \
-			   NO_PROTECTION, FORBIDDEN,     FORBIDDEN, SEC_RW_ONLY, \
-			   FORBIDDEN,     NO_PROTECTION, FORBIDDEN, FORBIDDEN,   \
-			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN,   \
-			   FORBIDDEN,     FORBIDDEN,     FORBIDDEN, FORBIDDEN)
-
-#define SLAVE_FORBID_EXCEPT_D0_D3_SEC_RW_D5_NO_PROTECT(domain)		       \
-	APUSYS_APC_AO_ATTR(domain,					       \
-			   SEC_RW_ONLY, FORBIDDEN,     FORBIDDEN, SEC_RW_ONLY, \
-			   FORBIDDEN,   NO_PROTECTION, FORBIDDEN, FORBIDDEN,   \
-			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN,   \
-			   FORBIDDEN,   FORBIDDEN,     FORBIDDEN, FORBIDDEN)
-
 #endif /* APUSYS_DAPC_V1_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h
index e74b022..47a2a94 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h
@@ -29,14 +29,14 @@
 #define SLAVE_AO_BCRM			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_AO_DAPC_WRAP		SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_AO_DAPC_CON		SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
-#define SLAVE_RCX_ACX_BULK		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
-#define SLAVE_ACX0_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_RCX_ACX_BULK		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
+#define SLAVE_ACX0_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_RPCTOP_LITE_ACX0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
-#define SLAVE_ACX1_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_ACX1_BCRM			SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_RPCTOP_LITE_ACX1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
-#define SLAVE_RCX_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_RCX_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_RCX_TO_ACX0_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
-#define SLAVE_SAE_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT_D3_SEC_RW
+#define SLAVE_SAE_TO_ACX0_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_SAE_TO_ACX0_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_RCX_TO_ACX1_0		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
 #define SLAVE_RCX_TO_ACX1_1		SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT
@@ -79,7 +79,7 @@
 #define SLAVE_SENSOR_WRAP_ACX1_DLA1	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_SENSOR_WRAP_ACX1_VPU0	SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_REVISER			SLAVE_FORBID_EXCEPT_D0_SEC_RW
-#define SLAVE_NOC			SLAVE_FORBID_EXCEPT_D0_D3_SEC_RW_D5_NO_PROTECT
+#define SLAVE_NOC			SLAVE_FORBID_EXCEPT_D0_SEC_RW
 #define SLAVE_BCRM			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_DAPC_WRAP			SLAVE_FORBID_EXCEPT_D5_NO_PROTECT
 #define SLAVE_DAPC_CON			SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index 9c1ebb5..ef7134c 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -57,9 +57,18 @@
 	unsigned int apc[EMI_MPU_DGROUP_NUM];
 };
 
+enum MPU_REQ_ORIGIN_ZONE_ID {
+	MPU_REQ_ORIGIN_TEE_ZONE_SVP = 0,
+	MPU_REQ_ORIGIN_TEE_ZONE_TUI = 1,
+	MPU_REQ_ORIGIN_TEE_ZONE_WFD = 2,
+	MPU_REQ_ORIGIN_TEE_ZONE_MAX = 3,
+	MPU_REQ_ORIGIN_ZONE_INVALID = 0x7FFFFFFF,
+};
+
 int emi_mpu_init(void);
+int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
+						  uint64_t zone_info);
 int emi_mpu_set_protection(struct emi_region_info_t *region_info);
 void set_emi_mpu_regions(void);
 int set_apu_emi_mpu_region(void);
-
 #endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index bf77791..7eeadec 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -7,6 +7,8 @@
 #include <string.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
+#include <smccc_helpers.h>
+
 #include <emi_mpu.h>
 #include <lib/mtk_init/mtk_init.h>
 #include <mtk_sip_svc.h>
@@ -116,7 +118,10 @@
 				     u_register_t x3, u_register_t x4,
 				     void *handle, struct smccc_res *smccc_ret)
 {
-	/* TODO: implement emi mpu handler */
+	int ret;
+
+	ret = emi_mpu_optee_handler(x1, x2, x3);
+	SMC_RET2(handle, ret, 0U);
 
 	return 0;
 }
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index 59ab315..ae1b7ef 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -6,6 +6,9 @@
 
 #include <common/debug.h>
 #include <emi_mpu.h>
+#include <mtk_sip_svc.h>
+
+#define MPU_PHYSICAL_ADDR_SHIFT_BITS	(16)
 
 void set_emi_mpu_regions(void)
 {
@@ -29,3 +32,43 @@
 
 	return emi_mpu_set_protection(&region_info);
 }
+
+static inline uint64_t get_decoded_phys_addr(uint64_t addr)
+{
+	return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS);
+}
+
+static inline uint32_t get_decoded_zone_id(uint32_t info)
+{
+	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
+}
+
+int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
+						  uint64_t zone_info)
+{
+	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
+	struct emi_region_info_t region_info;
+	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
+
+	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
+	     encoded_addr, zone_size, zone_info);
+
+	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
+		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
+		return MTK_SIP_E_INVALID_PARAM;
+	}
+
+	/* SVP DRAM */
+	region_info.start = phys_addr;
+	region_info.end = phys_addr + zone_size;
+	region_info.region = 4;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+
+	emi_mpu_set_protection(&region_info);
+
+	return 0;
+}
\ No newline at end of file
diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
index cca5d0a..85f9e37 100644
--- a/plat/mediatek/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -42,13 +42,19 @@
 
 struct gic_chip_data {
 	/* All cores share the same configuration */
+	unsigned int saved_ctlr;
 	unsigned int saved_group;
 	unsigned int saved_enable;
 	unsigned int saved_conf0;
 	unsigned int saved_conf1;
 	unsigned int saved_grpmod;
+	unsigned int saved_ispendr;
+	unsigned int saved_isactiver;
+	unsigned int saved_nsacr;
 	/* Per-core sgi */
 	unsigned int saved_sgi[PLATFORM_CORE_COUNT];
+	/* Per-core priority */
+	unsigned int saved_prio[PLATFORM_CORE_COUNT][GICR_NUM_REGS(IPRIORITYR)];
 };
 
 static struct gic_chip_data gic_data;
@@ -94,53 +100,84 @@
 
 void mt_gic_rdistif_save(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	proc_num = plat_my_core_pos();
 	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 
+	/*
+	 * Wait for any write to GICR_CTLR to complete before trying to save any
+	 * state.
+	 */
+	gicr_wait_for_pending_write(gicr_base);
+
+	gic_data.saved_ctlr = mmio_read_32(gicr_base + GICR_CTLR);
 	gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0);
 	gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0);
 	gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0);
 	gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1);
 	gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0);
+	gic_data.saved_ispendr = mmio_read_32(gicr_base + GICR_ISPENDR0);
+	gic_data.saved_isactiver = mmio_read_32(gicr_base + GICR_ISACTIVER0);
+	gic_data.saved_nsacr = mmio_read_32(gicr_base + GICR_NSACR);
+
+	for (i = 0U; i < 8U; ++i)
+		gic_data.saved_prio[proc_num][i] = gicr_ipriorityr_read(gicr_base, i);
 
 	rdist_has_saved[proc_num] = 1;
 }
 
 void mt_gic_rdistif_restore(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	proc_num = plat_my_core_pos();
 	if (rdist_has_saved[proc_num] == 1) {
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
 		mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
-		mmio_write_32(gicr_base + GICR_ISENABLER0,
-			gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod);
+		mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr);
 		mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
 		mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
-		mmio_write_32(gicr_base + GICR_IGRPMODR0,
-			gic_data.saved_grpmod);
+
+		for (i = 0U; i < 8U; ++i)
+			gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]);
+
+		mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr);
+		mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver);
+		mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr);
+
+		gicr_wait_for_pending_write(gicr_base);
 	}
 }
 
 void mt_gic_rdistif_restore_all(void)
 {
-	unsigned int proc_num;
+	unsigned int i, proc_num;
 	uintptr_t gicr_base;
 
 	for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) {
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
 		mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
-		mmio_write_32(gicr_base + GICR_ISENABLER0,
-			gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod);
+		mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr);
 		mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
 		mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
-		mmio_write_32(gicr_base + GICR_IGRPMODR0,
-			gic_data.saved_grpmod);
+
+		for (i = 0U; i < 8U; ++i)
+			gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]);
+
+		mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr);
+		mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver);
+		mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr);
+
+		gicr_wait_for_pending_write(gicr_base);
 	}
 }
 
diff --git a/plat/nuvoton/common/nuvoton_helpers.S b/plat/nuvoton/common/nuvoton_helpers.S
new file mode 100644
index 0000000..09035a1
--- /dev/null
+++ b/plat/nuvoton/common/nuvoton_helpers.S
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NUVOTON_HELPERS_S
+#define NUVOTON_HELPERS_S
+
+#include <asm_macros.S>
+#include <cortex_a35.h>
+#include <platform_def.h>
+
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_calc_core_pos
+	.globl	plat_reset_handler
+	.globl	plat_get_my_entrypoint
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.globl	platform_mem_init
+	.globl  npcm845x_mailbox_init
+
+	/* --------------------------------------------------------------------
+	 * Helper macro that reads the part number of the current CPU and jumps
+	 * to the given label if it matches the CPU MIDR provided.
+	 *
+	 * Clobbers x0.
+	 * --------------------------------------------------------------------
+	 */
+	.macro  jump_if_cpu_midr _cpu_midr, _label
+
+	mrs	x0, midr_el1
+	ubfx	x0, x0, MIDR_PN_SHIFT, #12
+	cmp     w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	\_label
+
+	.endm
+
+	/* ----------------------------------------------
+	 * The mailbox_base is used to distinguish warm/cold
+	 * reset. The mailbox_base is in the data section, not
+	 * in .bss, this allows function to start using this
+	 * variable before the runtime memory is initialized.
+	 * ----------------------------------------------
+	 */
+	.section .data.mailbox_base
+	.align 3
+	mailbox_base: .quad 0x0
+
+	/* ---------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * To add: Determine the SoC type and call the appropriate
+	 * reset handler.
+	 *-----------------------------------------------	 */
+
+func plat_reset_handler
+	 ret
+endfunc plat_reset_handler
+
+	/* ----------------------------------------------
+	 * unsigned int plat_is_my_cpu_primary(void);
+	 * This function checks if this is the primary CPU
+	 * ----------------------------------------------
+	 */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	and	x0, x0, #(MPIDR_CPU_MASK)
+	cmp	x0, #PLAT_PRIMARY_CPU
+	cset	x0, eq
+	ret
+endfunc plat_is_my_cpu_primary
+
+	/* ----------------------------------------------
+	 * unsigned int plat_my_core_pos(void)
+	 * This Function uses the plat_calc_core_pos()
+	 * to get the index of the calling CPU.
+	 * ----------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	and	x1, x0, #MPIDR_CPU_MASK
+	and 	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_my_core_pos
+
+	/*
+	 * unsigned int plat_calc_core_pos(uint64_t mpidr)
+	 * helper function to calculate the core position.
+	 * With this function.
+	 */
+func plat_calc_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and 	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_calc_core_pos
+
+	/* ---------------------------------------------
+	 * function to get the entrypoint.
+	 * ---------------------------------------------
+	 */
+	/* ---------------------------------------------------------------------
+	 * uintptr_t plat_get_my_entrypoint (void);
+	 *
+	 * Main job of this routine is to distinguish between a cold and a warm
+	 * boot.
+	 *
+	 * This functions returns:
+	 *  - 0 for a cold boot.
+	 *  - Any other value for a warm boot.
+	 * ---------------------------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	mov	x1, x30
+	bl	plat_is_my_cpu_primary
+	/*
+	 * Secondaries always cold boot.
+	*/
+	cbz	w0, 1f
+	/*
+	 * Primaries warm boot if they are requested
+	 * to power off.
+	 */
+	mov_imm	x0, PLAT_NPCM_TM_HOLD_BASE
+	ldr	x0, [x0]
+	cmp	x0, PLAT_NPCM_TM_HOLD_STATE_BSP_OFF
+	adr	x0, plat_wait_for_warm_boot
+	csel	x0, x0, xzr, eq
+	ret	x1
+1:	mov	x0, #0
+	ret	x1
+endfunc plat_get_my_entrypoint
+
+func npcm845x_mailbox_init
+	adrp	x1, mailbox_base
+	str	x0, [x1, :lo12:mailbox_base]
+	ret
+endfunc npcm845x_mailbox_init
+
+func plat_wait_for_warm_boot
+	/*
+	 * Calculate address of our hold entry.
+	 * As the function will never return, there is no need to save LR.
+	 */
+	bl	plat_my_core_pos
+	lsl	x0, x0, #3
+	mov x8, x0
+	mov_imm	x2, PLAT_NPCM_TM_HOLD_BASE
+	add	x0, x0, x2
+	mov_imm	x2, PLAT_NPCM_TRUSTED_NOTIFICATION_BASE
+	add	x8, x8, x2
+	/*
+	 * This code runs way before requesting the warmboot of this core,
+	 * so it is possible to clear the mailbox before getting a request
+	 * to boot.
+	 */
+	mov	x1, PLAT_NPCM_TM_HOLD_STATE_WAIT
+	str	x1,[x0]
+
+	/* Notify that core is in pending state - do not use x0!, uses x7 and x8! */
+	mov	x7, PLAT_NPCM_TM_NOTIFICATION_START
+	str	x7,[x8]
+	/*
+	 * This code runs way before requesting the warmboot of this core,
+	 * so it is possible to clear the mailbox before getting a request
+	 * to boot.
+	 */
+	mov	x1, PLAT_NPCM_TM_HOLD_STATE_WAIT
+	str	x1,[x0]
+	/* Wait until we have a go */
+poll_mailbox:
+	wfe
+	ldr	x1, [x0]
+	cmp	x1, PLAT_NPCM_TM_HOLD_STATE_GO
+	bne	poll_mailbox
+
+	mov	x7, PLAT_NPCM_TM_NOTIFICATION_BR
+	str	x7,[x8]
+	/* Jump to the provided entrypoint */
+	mov_imm	x0, PLAT_NPCM_TM_ENTRYPOINT
+	ldr	x1, [x0]
+	br	x1
+endfunc plat_wait_for_warm_boot
+
+func plat_secondary_cold_boot_setup
+	b	plat_wait_for_warm_boot
+endfunc plat_secondary_cold_boot_setup
+
+func plat_crash_console_init
+	mov	x0, #1
+	ret
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+	ret
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+	mov	x0, #0
+	ret
+endfunc plat_crash_console_flush
+
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+#endif /* NUVOTON_HELPERS_S */
diff --git a/plat/nuvoton/common/nuvoton_pm.c b/plat/nuvoton/common/nuvoton_pm.c
new file mode 100644
index 0000000..833ebfb
--- /dev/null
+++ b/plat/nuvoton/common/nuvoton_pm.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+
+/* Allow npcm845x to override these functions */
+#pragma weak plat_arm_program_trusted_mailbox
+#pragma weak plat_setup_psci_ops /* changed to weak */
+
+
+/*******************************************************************************
+ * ARM standard platform handler called to check the validity of the non secure
+ * entrypoint. Returns 0 if the entrypoint is valid, or -1 otherwise.
+ ******************************************************************************/
+int arm_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint >= ARM_NS_DRAM1_BASE) &&
+		(entrypoint < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) {
+		return 0;
+	}
+#ifdef __aarch64__
+	if ((entrypoint >= ARM_DRAM2_BASE) &&
+		(entrypoint < (ARM_DRAM2_BASE + ARM_DRAM2_SIZE))) {
+		return 0;
+	}
+#endif
+
+	return -1;
+}
+
+int arm_validate_psci_entrypoint(uintptr_t entrypoint)
+{
+	return (arm_validate_ns_entrypoint(entrypoint) == 0) ? PSCI_E_SUCCESS :
+		PSCI_E_INVALID_ADDRESS;
+}
+
+/******************************************************************************
+ * Helper function to save the platform state before a system suspend. Save the
+ * state of the system components which are not in the Always ON power domain.
+ *****************************************************************************/
+void arm_system_pwr_domain_save(void)
+{
+	/* Assert system power domain is available on the platform */
+	assert(PLAT_MAX_PWR_LVL > ARM_PWR_LVL1);
+
+	plat_arm_gic_save();
+
+	/*
+	 * Unregister console now so that it is not registered for a second
+	 * time during resume.
+	 */
+	arm_console_runtime_end();
+
+	/*
+	 * All the other peripheral which are configured by TF-A are
+	 * re-initialized on resume from system suspend. Hence we
+	 * don't save their state here.
+	 */
+}
diff --git a/plat/nuvoton/common/nuvoton_topology.c b/plat/nuvoton/common/nuvoton_topology.c
new file mode 100644
index 0000000..892d9e2
--- /dev/null
+++ b/plat/nuvoton/common/nuvoton_topology.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/psci/psci.h>
+#include <lib/semihosting.h>
+#include <plat/common/platform.h>
+
+/*
+ * Since NPCM845 have only powered/non-powered state,
+ * the tree is structure of level 0
+ * (Single cluster == 0) and 4 representing a "leaf" for every CPU
+ */
+const unsigned char npcm845x_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_MAX_CPU_PER_CLUSTER
+};
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	/* A single cluster with 4 CPUs */
+	return npcm845x_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
+		return -1;
+	}
+
+	cluster_id = (unsigned int)MPIDR_AFFLVL1_VAL(mpidr);
+	cpu_id = (unsigned int)MPIDR_AFFLVL0_VAL(mpidr);
+
+	if (cluster_id > PLATFORM_CLUSTER_COUNT ||
+		cpu_id > PLATFORM_MAX_CPU_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (int)(cpu_id + (cluster_id * 4));
+}
diff --git a/plat/nuvoton/common/plat_nuvoton_gic.c b/plat/nuvoton/common/plat_nuvoton_gic.c
new file mode 100644
index 0000000..300670d
--- /dev/null
+++ b/plat/nuvoton/common/plat_nuvoton_gic.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv2.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static const interrupt_prop_t g0_interrupt_props[] = {
+	INTR_PROP_DESC(FIQ_SMP_CALL_SGI, GIC_HIGHEST_SEC_PRIORITY,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+};
+
+gicv2_driver_data_t arm_gic_data = {
+	.gicd_base = BASE_GICD_BASE,
+	.gicc_base = BASE_GICC_BASE,
+	.interrupt_props = g0_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
+};
+
+void plat_gic_driver_init(void)
+{
+	gicv2_driver_init(&arm_gic_data);
+}
+
+void plat_gic_init(void)
+{
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+void plat_gic_cpuif_enable(void)
+{
+	gicv2_cpuif_enable();
+}
+
+void plat_gic_cpuif_disable(void)
+{
+	gicv2_cpuif_disable();
+}
+
+void plat_gic_pcpu_init(void)
+{
+	gicv2_pcpu_distif_init();
+}
diff --git a/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
new file mode 100644
index 0000000..08448db
--- /dev/null
+++ b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2017-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/debugfs.h>
+#include <lib/extensions/ras.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <npcm845x_clock.h>
+#include <npcm845x_gcr.h>
+#include <npcm845x_lpuart.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_npcm845x.h>
+#include <platform_def.h>
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+#if !RESET_TO_BL31
+/*
+ * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
+ * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
+ */
+/* CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); */
+#endif /* !RESET_TO_BL31 */
+
+#define MAP_BL31_TOTAL		MAP_REGION_FLAT( \
+					BL31_START, \
+					BL31_END - BL31_START, \
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#if SEPARATE_NOBITS_REGION
+#define MAP_BL31_NOBITS		MAP_REGION_FLAT( \
+					BL31_NOBITS_BASE, \
+					BL31_NOBITS_LIMIT - \
+					BL31_NOBITS_BASE, \
+					MT_MEMORY | MT_RW | EL3_PAS)
+#endif /* SEPARATE_NOBITS_REGION */
+
+/******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image
+ * for the security state specified. BL33 corresponds to the non-secure
+ * image type while BL32 corresponds to the secure image type.
+ * A NULL pointer is returned if the image does not exist.
+ *****************************************************************************/
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	assert(sec_state_is_valid(type));
+	next_image_info = (type == NON_SECURE)
+			? &bl33_image_ep_info : &bl32_image_ep_info;
+/*
+ * None of the images on the ARM development platforms can have 0x0
+ * as the entrypoint
+ */
+	if (next_image_info->pc) {
+		return next_image_info;
+	} else {
+		return NULL;
+	}
+}
+
+int board_uart_init(void)
+{
+	unsigned long UART_BASE_ADDR;
+	static console_t console;
+
+#ifdef CONFIG_TARGET_ARBEL_PALLADIUM
+	UART_Init(UART0_DEV, UART_MUX_MODE1,
+				UART_BAUDRATE_115200);
+	UART_BASE_ADDR = npcm845x_get_base_uart(UART0_DEV);
+#else
+	UART_BASE_ADDR = npcm845x_get_base_uart(UART0_DEV);
+#endif /* CONFIG_TARGET_ARBEL_PALLADIUM */
+
+/*
+ * Register UART w/o initialization -
+ * A clock rate of zero means to skip the initialisation.
+ */
+	console_16550_register((uintptr_t)UART_BASE_ADDR, 0, 0, &console);
+
+	return 0;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return (unsigned int)COUNTER_FREQUENCY;
+}
+
+/******************************************************************************
+ * Perform any BL31 early platform setup common to ARM standard platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory,
+ * so  we are guaranteed to pick up good data.
+ *****************************************************************************/
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+		u_register_t arg2, u_register_t arg3)
+{
+#if RESET_TO_BL31
+	void *from_bl2 = (void *)arg0;
+	void *plat_params_from_bl2 = (void *)arg3;
+
+	if (from_bl2 != NULL) {
+		assert(from_bl2 == NULL);
+	}
+
+	if (plat_params_from_bl2 != NULL) {
+		assert(plat_params_from_bl2 == NULL);
+	}
+#endif /* RESET_TO_BL31 */
+
+/* Initialize Delay timer */
+	 generic_delay_timer_init();
+
+/* Do Specific Board/Chip initializations */
+	board_uart_init();
+
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	assert(plat_params_from_bl2 == NULL);
+
+#ifdef BL32_BASE
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info,
+					PARAM_EP,
+					VERSION_1,
+					0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+
+#if defined(SPD_spmd)
+/*
+ * SPM (hafnium in secure world) expects SPM Core manifest base address
+ * in x0, which in !RESET_TO_BL31 case loaded after base of non shared
+ * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non
+ * shared SRAM is allocated to BL31, so to avoid overwriting of manifest
+ * keep it in the last page.
+ */
+	bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE +
+					PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE;
+#endif /* SPD_spmd */
+#endif /* BL32_BASE */
+
+/* Populate entry point information for BL33 */
+		SET_PARAM_HEAD(&bl33_image_ep_info,
+					PARAM_EP,
+					VERSION_1,
+					0);
+
+/*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+		bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+		/* Generic ARM code will switch to EL2, revert to EL1 */
+		bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+		bl33_image_ep_info.spsr &= ~0x8;
+		bl33_image_ep_info.spsr |= 0x4;
+
+		SET_SECURITY_STATE(bl33_image_ep_info.h.attr, (uint32_t)NON_SECURE);
+
+#if defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33)
+/*
+ * Hafnium in normal world expects its manifest address in x0,
+ * which is loaded at base of DRAM.
+ */
+		bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE;
+#endif /* SPD_spmd && !ARM_LINUX_KERNEL_AS_BL33 */
+
+#if ARM_LINUX_KERNEL_AS_BL33
+/*
+ * According to the file ``Documentation/arm64/booting.txt`` of the
+ * Linux kernel tree, Linux expects the physical address of the device
+ * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+ * must be 0.
+ */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif /* ARM_LINUX_KERNEL_AS_BL33 */
+
+#else /* RESET_TO_BL31 */
+/*
+ * In debug builds, we pass a special value in 'plat_params_from_bl2'
+ * to verify platform parameters from BL2 to BL31.
+ * In release builds, it's not used.
+ */
+	assert(((unsigned long long)plat_params_from_bl2) ==
+			ARM_BL31_PLAT_PARAM_VAL);
+
+/*
+ * Check params passed from BL2 should not be NULL,
+ */
+	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+/*
+ * Copy BL33 and BL32 (if present), entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+	while (bl_params != NULL) {
+		if (bl_params->image_id == BL32_IMAGE_ID) {
+			bl32_image_ep_info = *bl_params->ep_info;
+		}
+
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			bl33_image_ep_info = *bl_params->ep_info;
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	if (bl33_image_ep_info.pc == 0U) {
+		panic();
+	}
+#endif /* RESET_TO_BL31 */
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+/* Initialize the GIC driver, cpu and distributor interfaces */
+	plat_gic_driver_init();
+	plat_gic_init();
+
+#if RESET_TO_BL31
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
+	arm_nor_psci_do_dyn_mem_protect();
+#endif /* PLAT_ARM_MEM_PROT_ADDR */
+#else
+/*
+ * In this soluction, we also do the security initialzation
+ * even when BL31 is not in the reset vector
+ */
+	npcm845x_security_setup();
+#endif /* RESET_TO_BL31 */
+
+/* Enable and initialize the System level generic timer */
+	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
+			CNTCR_FCREQ(0U) | CNTCR_EN);
+
+/* Initialize power controller before setting up topology */
+	plat_arm_pwrc_setup();
+
+#if RAS_EXTENSION
+	ras_init();
+#endif
+
+#if USE_DEBUGFS
+	debugfs_init();
+#endif /* USE_DEBUGFS */
+}
+
+void arm_console_runtime_init(void)
+{
+/* Added in order to ignore the original weak function */
+}
+
+void plat_arm_program_trusted_mailbox(uintptr_t address)
+{
+/*
+ * now we don't use ARM mailbox,
+ * so that function added to ignore the weak one
+ */
+}
+
+void __init bl31_plat_arch_setup(void)
+{
+	npcm845x_bl31_plat_arch_setup();
+}
+
+void __init plat_arm_pwrc_setup(void)
+{
+/* NPCM850 is always powered so no need for power control */
+}
+
+void __init npcm845x_bl31_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+#if SEPARATE_NOBITS_REGION
+		MAP_BL31_NOBITS,
+#endif /* SEPARATE_NOBITS_REGION */
+		ARM_MAP_BL_RO,
+#if USE_ROMLIB
+		ARM_MAP_ROMLIB_CODE,
+		ARM_MAP_ROMLIB_DATA,
+#endif /* USE_ROMLIB */
+#if USE_COHERENT_MEM
+		ARM_MAP_BL_COHERENT_RAM,
+#endif /* USE_COHERENT_MEM */
+		ARM_MAP_SHARED_RAM,
+#ifdef SECONDARY_BRINGUP
+		ARM_MAP_NS_DRAM1,
+	#ifdef BL32_BASE
+		ARM_MAP_BL32_CORE_MEM
+	#endif /* BL32_BASE */
+#endif /* SECONDARY_BRINGUP */
+		{0}
+	};
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
+	enable_mmu_el3(0U);
+}
diff --git a/plat/nuvoton/npcm845x/npcm845x_common.c b/plat/nuvoton/npcm845x/npcm845x_common.c
new file mode 100644
index 0000000..fc393fd
--- /dev/null
+++ b/plat/nuvoton/npcm845x/npcm845x_common.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2022-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+const mmap_region_t plat_arm_mmap[] = {
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	{0}
+};
diff --git a/plat/nuvoton/npcm845x/npcm845x_psci.c b/plat/nuvoton/npcm845x/npcm845x_psci.c
new file mode 100644
index 0000000..a954265
--- /dev/null
+++ b/plat/nuvoton/npcm845x/npcm845x_psci.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2017-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/semihosting.h>
+#include <npcm845x_clock.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_npcm845x.h>
+
+#define ADP_STOPPED_APPLICATION_EXIT 0x20026
+
+/* Make composite power state parameter till power level 0 */
+#if PSCI_EXTENDED_STATE_ID
+/* Not Extended */
+#define npcm845x_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+		(((lvl0_state) << PSTATE_ID_SHIFT) | \
+		 ((type) << PSTATE_TYPE_SHIFT))
+#else
+#define npcm845x_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+		(((lvl0_state) << PSTATE_ID_SHIFT) | \
+		 ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \
+		 ((type) << PSTATE_TYPE_SHIFT))
+#endif /* PSCI_EXTENDED_STATE_ID */
+
+#define npcm845x_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \
+		(((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \
+		 npcm845x_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type))
+
+/*
+ * The table storing the valid idle power states. Ensure that the
+ * array entries are populated in ascending order of state-id to
+ * enable us to use binary search during power state validation.
+ * The table must be terminated by a NULL entry.
+ */
+static const unsigned int npcm845x_pm_idle_states[] = {
+/*
+ * Cluster = 0 (RUN) CPU=1 (RET, higest in idle) -
+ * Retention. The Power state is Stand-by
+ */
+
+/* State-id - 0x01 */
+	npcm845x_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET,
+				MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY),
+
+/*
+ * For testing purposes.
+ * Only CPU suspend to standby is supported by NPCM845x
+ */
+	/* State-id - 0x02 */
+	npcm845x_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF,
+				MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN),
+	0,
+};
+
+/*******************************************************************************
+ * Platform handler called to check the validity of the non secure
+ * entrypoint.
+ ******************************************************************************/
+int npcm845x_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	NOTICE("%s() nuvoton_psci\n", __func__);
+#ifdef PLAT_ARM_TRUSTED_DRAM_BASE
+	if ((entrypoint >= PLAT_ARM_TRUSTED_DRAM_BASE) &&
+		(entrypoint < (PLAT_ARM_TRUSTED_DRAM_BASE +
+		PLAT_ARM_TRUSTED_DRAM_SIZE))) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+#endif /* PLAT_ARM_TRUSTED_DRAM_BASE */
+	/* For TFTS purposes, '0' is also illegal */
+	#ifdef SPD_tspd
+		if (entrypoint == 0) {
+			return PSCI_E_INVALID_ADDRESS;
+		}
+	#endif /* SPD_tspd */
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler called when a CPU is about to enter standby.
+ ******************************************************************************/
+void npcm845x_cpu_standby(plat_local_state_t cpu_state)
+{
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	uint64_t scr;
+
+	scr = read_scr_el3();
+	write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
+
+	/*
+	 * Enter standby state
+	 * dsb is good practice before using wfi to enter low power states
+	 */
+	isb();
+	dsb();
+	wfi();
+
+	/* Once awake */
+	write_scr_el3(scr);
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ ******************************************************************************/
+int npcm845x_pwr_domain_on(u_register_t mpidr)
+{
+	int rc = PSCI_E_SUCCESS;
+	int cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	if ((unsigned int)cpu_id >= PLATFORM_CORE_COUNT) {
+		ERROR("%s()  CPU 0x%X\n", __func__, cpu_id);
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (cpu_id == -1) {
+		/* domain on was not called by a CPU */
+		ERROR("%s() was not per CPU 0x%X\n", __func__, cpu_id);
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	unsigned int pos = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+	uintptr_t hold_base = PLAT_NPCM_TM_HOLD_BASE;
+
+	assert(pos < PLATFORM_CORE_COUNT);
+
+	hold_base += pos * PLAT_NPCM_TM_HOLD_ENTRY_SIZE;
+
+	mmio_write_64(hold_base, PLAT_NPCM_TM_HOLD_STATE_GO);
+	/* No cache maintenance here, hold_base is mapped as device memory. */
+
+	/* Make sure that the write has completed */
+	dsb();
+	isb();
+
+	sev();
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+void npcm845x_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	for (size_t i = 0; (uint64_t)i <= PLAT_MAX_PWR_LVL; i++) {
+		INFO("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	gicv2_cpuif_disable();
+
+	NOTICE("%s() Out of suspend\n", __func__);
+}
+
+
+/*******************************************************************************
+ * Platform handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ ******************************************************************************/
+void npcm845x_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	for (size_t i = 0; (uint64_t)i <= PLAT_MAX_PWR_LVL; i++) {
+		INFO("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+			PLAT_LOCAL_STATE_OFF);
+
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+
+/*******************************************************************************
+ * Platform handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+void npcm845x_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	for (size_t i = 0; (uint64_t)i <= PLAT_MAX_PWR_LVL; i++) {
+		INFO("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+			PLAT_LOCAL_STATE_OFF);
+
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+
+void __dead2 npcm845x_system_reset(void)
+{
+	uintptr_t RESET_BASE_ADDR;
+	uint32_t val;
+
+	NOTICE("%s() nuvoton_psci\n", __func__);
+	console_flush();
+
+	dsbsy();
+	isb();
+
+	/*
+	 * In future - support all reset types. For now, SW1 reset
+	 * Enable software reset 1 to reboot the BMC
+	 */
+	RESET_BASE_ADDR = (uintptr_t)0xF0801000;
+
+	/* Read SW1 control register */
+	val = mmio_read_32(RESET_BASE_ADDR + 0x44);
+	/* Keep SPI BMC & MC persist*/
+	val &= 0xFBFFFFDF;
+	/* Setting SW1 control register */
+	mmio_write_32(RESET_BASE_ADDR + 0x44, val);
+	/* Set SW1 reset */
+	mmio_write_32(RESET_BASE_ADDR + 0x14, 0x8);
+	dsb();
+
+	while (1) {
+		;
+	}
+}
+
+int npcm845x_validate_power_state(unsigned int power_state,
+			 psci_power_state_t *req_state)
+{
+	unsigned int state_id;
+	int i;
+
+	NOTICE("%s() nuvoton_psci\n", __func__);
+	assert(req_state);
+
+	/*
+	 *  Currently we are using a linear search for finding the matching
+	 *  entry in the idle power state array. This can be made a binary
+	 *  search if the number of entries justify the additional complexity.
+	 */
+	for (i = 0; !!npcm845x_pm_idle_states[i]; i++) {
+		if (power_state == npcm845x_pm_idle_states[i]) {
+			break;
+		}
+	}
+
+	/* Return error if entry not found in the idle state array */
+	if (!npcm845x_pm_idle_states[i]) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	i = 0;
+	state_id = psci_get_pstate_id(power_state);
+
+	/* Parse the State ID and populate the state info parameter */
+	while (state_id) {
+		req_state->pwr_domain_state[i++] = (uint8_t)state_id &
+						PLAT_LOCAL_PSTATE_MASK;
+		state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*
+ * The NPCM845 doesn't truly support power management at SYSTEM power domain.
+ * The SYSTEM_SUSPEND will be down-graded to the cluster level within
+ * the platform layer. The `fake` SYSTEM_SUSPEND allows us to validate
+ * some of the driver save and restore sequences on FVP.
+ */
+#if !ARM_BL31_IN_DRAM
+void npcm845x_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	for (i = ARM_PWR_LVL0; (uint64_t)i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = (uint8_t)PLAT_LOCAL_STATE_OFF;
+	}
+}
+#endif /* !ARM_BL31_IN_DRAM */
+
+/*
+ * The rest of the PSCI implementation are for testing purposes only.
+ * Not supported in Arbel
+ */
+void __dead2 npcm845x_system_off(void)
+{
+	console_flush();
+
+	dsbsy();
+	isb();
+
+	/* NPCM845 doesn't allow real system off, Do reaset instead */
+	/* Do reset here TBD which, in the meanwhile SW1 reset */
+	for (;;) {
+		wfi();
+	}
+}
+
+void __dead2 plat_secondary_cold_boot_setup(void);
+
+void __dead2 npcm845x_pwr_down_wfi(
+		const psci_power_state_t *target_state)
+{
+	uintptr_t hold_base = PLAT_NPCM_TM_HOLD_BASE;
+	unsigned int pos = plat_my_core_pos();
+
+	if (pos == 0) {
+		/*
+		 * The secondaries will always be in a wait
+		 * for warm boot on reset, but the BSP needs
+		 * to be able to distinguish between waiting
+		 * for warm boot (e.g. after psci_off, waiting
+		 * for psci_on) and a cold boot.
+		 */
+		mmio_write_64(hold_base, PLAT_NPCM_TM_HOLD_STATE_BSP_OFF);
+		/* No cache maintenance here, we run with caches off already. */
+		dsb();
+		isb();
+	}
+
+	wfe();
+
+	while (1) {
+		;
+	}
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+void npcm845x_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	NOTICE("%s() nuvoton_psci\n", __func__);
+
+	for (size_t i = 0; (uint64_t)i <= PLAT_MAX_PWR_LVL; i++) {
+		INFO("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	plat_secondary_cold_boot_setup();
+}
+
+static const plat_psci_ops_t npcm845x_plat_psci_ops = {
+	.cpu_standby = npcm845x_cpu_standby,
+	.pwr_domain_on = npcm845x_pwr_domain_on,
+	.pwr_domain_suspend = npcm845x_pwr_domain_suspend,
+	.pwr_domain_on_finish = npcm845x_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = npcm845x_pwr_domain_suspend_finish,
+	.system_reset = npcm845x_system_reset,
+	.validate_power_state = npcm845x_validate_power_state,
+	.validate_ns_entrypoint = npcm845x_validate_ns_entrypoint,
+
+	/* For testing purposes only This PSCI states are not supported */
+	.pwr_domain_off = npcm845x_pwr_domain_off,
+	.pwr_domain_pwr_down_wfi = npcm845x_pwr_down_wfi,
+};
+
+/* For reference only
+ * typedef struct plat_psci_ops {
+ *	void (*cpu_standby)(plat_local_state_t cpu_state);
+ *	int (*pwr_domain_on)(u_register_t mpidr);
+ *	void (*pwr_domain_off)(const psci_power_state_t *target_state);
+ *	void (*pwr_domain_suspend_pwrdown_early)(
+ *				const psci_power_state_t *target_state);
+ *	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
+ *	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
+ *	void (*pwr_domain_on_finish_late)(
+ *				const psci_power_state_t *target_state);
+ *	void (*pwr_domain_suspend_finish)(
+ *				const psci_power_state_t *target_state);
+ *	void __dead2 (*pwr_domain_pwr_down_wfi)(
+ *				const psci_power_state_t *target_state);
+ *	void __dead2 (*system_off)(void);
+ *	void __dead2 (*system_reset)(void);
+ *	int (*validate_power_state)(unsigned int power_state,
+ *				psci_power_state_t *req_state);
+ *	int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint);
+ *	void (*get_sys_suspend_power_state)(
+ *				psci_power_state_t *req_state);
+ *	int (*get_pwr_lvl_state_idx)(plat_local_state_t pwr_domain_state,
+ *				int pwrlvl);
+ *	int (*translate_power_state_by_mpidr)(u_register_t mpidr,
+ *				unsigned int power_state,
+ *				psci_power_state_t *output_state);
+ *	int (*get_node_hw_state)(u_register_t mpidr, unsigned int power_level);
+ *	int (*mem_protect_chk)(uintptr_t base, u_register_t length);
+ *	int (*read_mem_protect)(int *val);
+ *	int (*write_mem_protect)(int val);
+ *	int (*system_reset2)(int is_vendor,
+ *				int reset_type, u_register_t cookie);
+ * } plat_psci_ops_t;
+ */
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	uintptr_t *entrypoint = (void *)PLAT_NPCM_TM_ENTRYPOINT;
+
+	*entrypoint = sec_entrypoint;
+
+	*psci_ops = &npcm845x_plat_psci_ops;
+
+	return 0;
+}
diff --git a/plat/nuvoton/npcm845x/npcm845x_serial_port.c b/plat/nuvoton/npcm845x/npcm845x_serial_port.c
new file mode 100644
index 0000000..946e9d0
--- /dev/null
+++ b/plat/nuvoton/npcm845x/npcm845x_serial_port.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * Copyright (C) 2017-2023 Nuvoton Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <npcm845x_clock.h>
+#include <npcm845x_gcr.h>
+#include <npcm845x_lpuart.h>
+#include <plat_npcm845x.h>
+
+
+uintptr_t npcm845x_get_base_uart(UART_DEV_T devNum)
+{
+	return 0xF0000000 + devNum * 0x1000;
+}
+
+uintptr_t npcm845x_get_base_clk(void)
+{
+	return 0xF0801000;
+}
+
+uintptr_t npcm845x_get_base_gcr(void)
+{
+	return 0xF0800000;
+}
+
+void npcm845x_wait_for_empty(int uart_n)
+{
+	volatile struct npcmX50_uart *uart = (struct npcmX50_uart *)npcm845x_get_base_uart(uart_n);
+
+	while ((*(uint8_t *)(uintptr_t)(&uart->lsr) & 0x40) == 0x00) {
+/*
+ * wait for THRE (Transmitter Holding Register Empty)
+ * and TSR (Transmitter Shift Register) to be empty.
+ * Some delay. notice needed some delay so UartUpdateTool
+ * will pass w/o error log
+ */
+	}
+
+	volatile int delay;
+
+	for (delay = 0; delay < 10000; delay++) {
+		;
+	}
+}
+
+int UART_Init(UART_DEV_T devNum,  UART_BAUDRATE_T baudRate)
+{
+	uint32_t val = 0;
+	uintptr_t clk_base = npcm845x_get_base_clk();
+	uintptr_t gcr_base =  npcm845x_get_base_gcr();
+	uintptr_t uart_base = npcm845x_get_base_uart(devNum);
+	volatile struct npcmX50_uart *uart = (struct npcmX50_uart *)uart_base;
+
+/* Use  CLKREF to be independent of CPU frequency */
+	volatile struct clk_ctl *clk_ctl_obj = (struct clk_ctl *)clk_base;
+	volatile struct npcm845x_gcr *gcr_ctl_obj =
+		(struct npcm845x_gcr *)gcr_base;
+
+	clk_ctl_obj->clksel = clk_ctl_obj->clksel & ~(0x3 << 8);
+	clk_ctl_obj->clksel = clk_ctl_obj->clksel | (0x2 << 8);
+
+	/* Set devider according to baudrate */
+	clk_ctl_obj->clkdiv1 =
+		(unsigned int)(clk_ctl_obj->clkdiv1 & ~(0x1F << 16));
+
+	/* clear bits 11-15 - set value 0 */
+	if (devNum == UART3_DEV) {
+		clk_ctl_obj->clkdiv2 =
+			(unsigned int)(clk_ctl_obj->clkdiv2 & ~(0x1F << 11));
+	}
+
+	npcm845x_wait_for_empty(devNum);
+
+	val = (uint32_t)LCR_WLS_8bit;
+	mmio_write_8((uintptr_t)&uart->lcr, (uint8_t)val);
+
+	/* disable all interrupts */
+	mmio_write_8((uintptr_t)&uart->ier, 0);
+
+	/*
+	 * Set the RX FIFO trigger level, reset RX, TX FIFO
+	 */
+	val = (uint32_t)(FCR_FME | FCR_RFR | FCR_TFR | FCR_RFITL_4B);
+
+	/* reset TX and RX FIFO */
+	mmio_write_8((uintptr_t)(&uart->fcr), (uint8_t)val);
+
+	/* Set port for 8 bit, 1 stop, no parity */
+	val = (uint32_t)LCR_WLS_8bit;
+
+	/* Set DLAB bit; Accesses the Divisor Latch Registers (DLL, DLM). */
+	val |= 0x80;
+	mmio_write_8((uintptr_t)(&uart->lcr), (uint8_t)val);
+
+	/* Baud Rate = UART Clock 24MHz / (16 * (11+2)) = 115384 */
+	mmio_write_8((uintptr_t)(&uart->dll), 11);
+	mmio_write_8((uintptr_t)(&uart->dlm), 0x00);
+
+	val = mmio_read_8((uintptr_t)&uart->lcr);
+
+	/* Clear DLAB bit; Accesses RBR, THR or IER registers. */
+	val &= 0x7F;
+	mmio_write_8((uintptr_t)(&uart->lcr), (uint8_t)val);
+
+	if (devNum == UART0_DEV) {
+		gcr_ctl_obj->mfsel4 &= ~(1 << 1);
+		gcr_ctl_obj->mfsel1 |= 1 << 9;
+	} else if (devNum == UART3_DEV) {
+		/* Pin Mux */
+		gcr_ctl_obj->mfsel4 &= ~(1 << 1);
+		gcr_ctl_obj->mfsel1 |= 1 << 11;
+		gcr_ctl_obj->spswc &= (7 << 0);
+		gcr_ctl_obj->spswc |= (2 << 0);
+	} else {
+		/* halt */
+		while (1) {
+			;
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
new file mode 100644
index 0000000..5120cc6
--- /dev/null
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -0,0 +1,370 @@
+#
+# Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+#
+# Copyright (c) 2017-2023 Nuvoton Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This is a debug flag for bring-up. It allows reducing CPU numbers
+# SECONDARY_BRINGUP	:=	1
+RESET_TO_BL31	:=	1
+SPMD_SPM_AT_SEL2	:= 0
+#temporary until the RAM size is reduced
+USE_COHERENT_MEM	:=	1
+
+
+$(eval $(call add_define,RESET_TO_BL31))
+
+ifeq (${ARCH}, aarch64)
+# On ARM standard platorms, the TSP can execute from Trusted SRAM,
+# Trusted DRAM (if available) or the TZC secured area of DRAM.
+# TZC secured DRAM is the default.
+
+# Process ARM_BL31_IN_DRAM flag
+ARM_BL31_IN_DRAM	:=	0
+$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
+$(eval $(call add_define,ARM_BL31_IN_DRAM))
+endif
+
+# For the original power-state parameter format, the State-ID can be encoded
+# according to the recommended encoding or zero. This flag determines which
+# State-ID encoding to be parsed.
+ARM_RECOM_STATE_ID_ENC	:=	0
+
+# If the PSCI_EXTENDED_STATE_ID is set, then ARM_RECOM_STATE_ID_ENC
+# need to be set. Else throw a build error.
+ifeq (${PSCI_EXTENDED_STATE_ID}, 1)
+ifeq (${ARM_RECOM_STATE_ID_ENC}, 0)
+$(error Build option ARM_RECOM_STATE_ID_ENC needs to be set if \
+	PSCI_EXTENDED_STATE_ID is set for ARM platforms)
+endif
+endif
+
+# Process ARM_RECOM_STATE_ID_ENC flag
+$(eval $(call assert_boolean,ARM_RECOM_STATE_ID_ENC))
+$(eval $(call add_define,ARM_RECOM_STATE_ID_ENC))
+
+# Process ARM_DISABLE_TRUSTED_WDOG flag
+# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
+ARM_DISABLE_TRUSTED_WDOG	:=	0
+ifeq (${SPIN_ON_BL1_EXIT}, 1)
+ARM_DISABLE_TRUSTED_WDOG	:=	1
+endif
+$(eval $(call assert_boolean,ARM_DISABLE_TRUSTED_WDOG))
+$(eval $(call add_define,ARM_DISABLE_TRUSTED_WDOG))
+
+# Process ARM_CONFIG_CNTACR
+ARM_CONFIG_CNTACR	:=	1
+$(eval $(call assert_boolean,ARM_CONFIG_CNTACR))
+$(eval $(call add_define,ARM_CONFIG_CNTACR))
+
+# Process ARM_BL31_IN_DRAM flag
+ARM_BL31_IN_DRAM	:=	0
+$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
+$(eval $(call add_define,ARM_BL31_IN_DRAM))
+
+# Process ARM_PLAT_MT flag
+ARM_PLAT_MT	:=	0
+$(eval $(call assert_boolean,ARM_PLAT_MT))
+$(eval $(call add_define,ARM_PLAT_MT))
+
+# Use translation tables library v2 by default
+ARM_XLAT_TABLES_LIB_V1	:=	0
+$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
+$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
+
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
+
+ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
+ifeq (${ARCH},aarch64)
+ifneq (${RESET_TO_BL31},1)
+$(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_BL31=1.")
+endif
+else
+ifneq (${RESET_TO_SP_MIN},1)
+$(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.")
+endif
+endif
+
+ifndef PRELOADED_BL33_BASE
+$(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+endif
+
+ifndef ARM_PRELOADED_DTB_BASE
+$(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+endif
+
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+endif
+
+# Use an implementation of SHA-256 with a smaller memory footprint
+# but reduced speed.
+$(eval $(call add_define,MBEDTLS_SHA256_SMALLER))
+
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
+endif
+
+# Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms
+ENABLE_PSCI_STAT	:=	1
+ENABLE_PMF		:=	1
+
+# On ARM platforms, separate the code and read-only data sections to allow
+# mapping the former as executable and the latter as execute-never.
+SEPARATE_CODE_AND_RODATA	:=	1
+
+# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS
+# and NOBITS sections of BL31 image are adjacent to each other and loaded
+# into Trusted SRAM.
+SEPARATE_NOBITS_REGION	:=	0
+
+# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load
+# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate
+# the build to require that ARM_BL31_IN_DRAM is enabled as well.
+ifeq ($(SEPARATE_NOBITS_REGION),1)
+ifneq ($(ARM_BL31_IN_DRAM),1)
+$(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled)
+endif
+
+ifneq ($(RECLAIM_INIT_CODE),0)
+$(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported)
+endif
+endif
+
+# Disable ARM Cryptocell by default
+ARM_CRYPTOCELL_INTEG	:=	0
+$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
+$(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
+
+# Enable PIE support for RESET_TO_BL31 case
+ifeq (${RESET_TO_BL31},1)
+ENABLE_PIE	:=	1
+endif
+
+# CryptoCell integration relies on coherent buffers for passing data from
+# the AP CPU to the CryptoCell
+
+ifeq (${ARM_CRYPTOCELL_INTEG},1)
+ifeq (${USE_COHERENT_MEM},0)
+$(error "ARM_CRYPTOCELL_INTEG needs USE_COHERENT_MEM to be set.")
+endif
+endif
+
+PLAT_INCLUDES	:=	-Iinclude/plat/nuvoton/npcm845x \
+		-Iinclude/plat/nuvoton/common \
+		-Iinclude/drivers/nuvoton/npcm845x \
+
+ifeq (${ARCH}, aarch64)
+PLAT_INCLUDES	+=	-Iinclude/plat/arm/common/aarch64
+endif
+
+# Include GICv3 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+NPCM850_GIC_SOURCES	:=	${GICV2_SOURCES}
+
+BL31_SOURCES	+=lib/cpus/aarch64/cortex_a35.S \
+		plat/common/plat_psci_common.c \
+		drivers/ti/uart/aarch64/16550_console.S \
+		plat/nuvoton/npcm845x/npcm845x_psci.c \
+		plat/nuvoton/npcm845x/npcm845x_serial_port.c \
+		plat/nuvoton/common/nuvoton_topology.c \
+		plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/delay_timer/delay_timer.c \
+		drivers/delay_timer/generic_delay_timer.c \
+		plat/common/plat_gicv2.c \
+		plat/arm/common/arm_gicv2.c \
+		plat/nuvoton/common/plat_nuvoton_gic.c \
+		${NPCM850_GIC_SOURCES} \
+		plat/nuvoton/npcm845x/npcm845x_common.c \
+		plat/nuvoton/common/nuvoton_helpers.S \
+		lib/semihosting/semihosting.c \
+		lib/semihosting/${ARCH}/semihosting_call.S \
+		plat/arm/common/arm_common.c \
+		plat/arm/common/arm_console.c
+
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/xlat_tables_common.c \
+		lib/xlat_tables/${ARCH}/xlat_tables.c
+else
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+endif
+
+ARM_IO_SOURCES	+=	plat/arm/common/arm_io_storage.c \
+		plat/arm/common/fconf/arm_fconf_io.c
+
+ifeq (${SPD},spmd)
+ifeq (${SPMD_SPM_AT_SEL2},1)
+ARM_IO_SOURCES	+=	plat/arm/common/fconf/arm_fconf_sp.c
+endif
+endif
+
+BL1_SOURCES	+=	drivers/io/io_fip.c \
+		drivers/io/io_memmap.c \
+		drivers/io/io_storage.c \
+		plat/arm/common/arm_bl1_setup.c \
+		plat/arm/common/arm_err.c \
+		${ARM_IO_SOURCES}
+
+ifdef EL3_PAYLOAD_BASE
+# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs
+# from their holding pen
+BL1_SOURCES	+=	plat/arm/common/arm_pm.c
+endif
+
+BL2_SOURCES	+=	drivers/delay_timer/delay_timer.c \
+		drivers/delay_timer/generic_delay_timer.c \
+		drivers/io/io_fip.c \
+		drivers/io/io_memmap.c \
+		drivers/io/io_storage.c \
+		plat/arm/common/arm_bl2_setup.c \
+		plat/arm/common/arm_err.c \
+		${ARM_IO_SOURCES}
+
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
+# Add `libfdt` and Arm common helpers required for Dynamic Config
+include lib/libfdt/libfdt.mk
+
+DYN_CFG_SOURCES	+=	plat/arm/common/arm_dyn_cfg.c \
+		plat/arm/common/arm_dyn_cfg_helpers.c \
+		common/fdt_wrappers.c
+
+BL1_SOURCES	+=	${DYN_CFG_SOURCES}
+BL2_SOURCES	+=	${DYN_CFG_SOURCES}
+
+ifeq (${BL2_AT_EL3},1)
+BL2_SOURCES	+=	plat/arm/common/arm_bl2_el3_setup.c
+endif
+
+# Because BL1/BL2 execute in AArch64 mode but BL32 in AArch32 we need to use
+# the AArch32 descriptors.
+BL2_SOURCES	+=	plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c
+BL2_SOURCES	+=	plat/arm/common/arm_image_load.c \
+		common/desc_image_load.c
+
+ifeq (${SPD},opteed)
+BL2_SOURCES	+=	lib/optee/optee_utils.c
+endif
+
+BL2U_SOURCES	+=	drivers/delay_timer/delay_timer.c \
+		drivers/delay_timer/generic_delay_timer.c \
+		plat/arm/common/arm_bl2u_setup.c
+
+BL31_SOURCES	+=	plat/arm/common/arm_bl31_setup.c \
+		plat/nuvoton/common/nuvoton_pm.c \
+		plat/nuvoton/common/nuvoton_topology.c \
+		plat/common/plat_psci_common.c
+
+ifeq (${ENABLE_PMF}, 1)
+ifeq (${ARCH}, aarch64)
+BL31_SOURCES	+=	plat/arm/common/aarch64/execution_state_switch.c \
+		plat/arm/common/arm_sip_svc.c \
+		lib/pmf/pmf_smc.c
+else
+BL32_SOURCES	+=	plat/arm/common/arm_sip_svc.c \
+		lib/pmf/pmf_smc.c
+endif
+endif
+
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES	+=	plat/arm/common/aarch64/arm_ehf.c
+endif
+
+ifeq (${SDEI_SUPPORT},1)
+BL31_SOURCES	+=	plat/arm/common/aarch64/arm_sdei.c
+ifeq (${SDEI_IN_FCONF},1)
+BL31_SOURCES	+=	plat/arm/common/fconf/fconf_sdei_getter.c
+endif
+endif
+
+# RAS sources
+ifeq (${RAS_EXTENSION},1)
+BL31_SOURCES	+=	lib/extensions/ras/std_err_record.c \
+		lib/extensions/ras/ras_common.c
+endif
+
+# Pointer Authentication sources
+ifeq (${ENABLE_PAUTH}, 1)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
+endif
+
+ifeq (${SPD},spmd)
+BL31_SOURCES	+=	plat/common/plat_spmd_manifest.c \
+		common/fdt_wrappers.c \
+		${LIBFDT_SRCS}
+endif
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+# Include common TBB sources
+AUTH_SOURCES	:=	drivers/auth/auth_mod.c \
+		drivers/auth/crypto_mod.c \
+		drivers/auth/img_parser_mod.c \
+		lib/fconf/fconf_tbbr_getter.c
+
+# Include the selected chain of trust sources.
+ifeq (${COT},tbbr)
+AUTH_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
+BL1_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_bl1.c
+BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_bl2.c
+else ifeq (${COT},dualroot)
+AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
+else
+$(error Unknown chain of trust ${COT})
+endif
+
+BL1_SOURCES	+=	${AUTH_SOURCES} \
+		bl1/tbbr/tbbr_img_desc.c \
+		plat/arm/common/arm_bl1_fwu.c \
+		plat/common/tbbr/plat_tbbr.c
+
+BL2_SOURCES	+=	${AUTH_SOURCES} \
+		plat/common/tbbr/plat_tbbr.c
+
+$(eval $(call TOOL_ADD_IMG,ns_bl2u,--fwu,FWU_))
+
+# We expect to locate the *.mk files under the directories specified below
+ifeq (${ARM_CRYPTOCELL_INTEG},0)
+CRYPTO_LIB_MK	:=	drivers/auth/mbedtls/mbedtls_crypto.mk
+else
+CRYPTO_LIB_MK	:=	drivers/auth/cryptocell/cryptocell_crypto.mk
+endif
+
+IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk
+
+$(info Including ${CRYPTO_LIB_MK})
+include ${CRYPTO_LIB_MK}
+
+$(info Including ${IMG_PARSER_LIB_MK})
+include ${IMG_PARSER_LIB_MK}
+endif
+
+ifeq (${MEASURED_BOOT},1)
+MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk
+$(info Including ${MEASURED_BOOT_MK})
+include ${MEASURED_BOOT_MK}
+endif
+
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES	+=	plat/arm/common/aarch64/arm_ehf.c
+endif
+
+BL1_SOURCES	:=
+BL2_SOURCES	:=
+BL2U_SOURCES	:=
+
+DEBUG_CONSOLE	?=	0
+$(eval $(call add_define,DEBUG_CONSOLE))
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
index 684c872..a7d5e7b 100644
--- a/plat/nvidia/tegra/include/lib/profiler.h
+++ b/plat/nvidia/tegra/include/lib/profiler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/lib/debug/profiler.c b/plat/nvidia/tegra/lib/debug/profiler.c
index dd76a4e..b5baf42 100644
--- a/plat/nvidia/tegra/lib/debug/profiler.c
+++ b/plat/nvidia/tegra/lib/debug/profiler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
new file mode 100644
index 0000000..b8b57d2
--- /dev/null
+++ b/plat/qemu/common/common.mk
@@ -0,0 +1,112 @@
+#
+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/libfdt/libfdt.mk
+include common/fdt_wrappers.mk
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/		\
+				-I${PLAT_QEMU_COMMON_PATH}/include	\
+				-I${PLAT_QEMU_PATH}/include		\
+				-Iinclude/common/tbbr
+
+ifeq (${ARCH},aarch32)
+QEMU_CPU_LIBS		:=	lib/cpus/${ARCH}/cortex_a15.S
+else
+QEMU_CPU_LIBS		:=	lib/cpus/aarch64/aem_generic.S		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				lib/cpus/aarch64/cortex_a72.S		\
+				lib/cpus/aarch64/cortex_a76.S		\
+				lib/cpus/aarch64/neoverse_n_common.S	\
+				lib/cpus/aarch64/neoverse_n1.S		\
+				lib/cpus/aarch64/neoverse_v1.S		\
+				lib/cpus/aarch64/qemu_max.S
+
+PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
+endif
+
+PLAT_BL_COMMON_SOURCES	:=	${PLAT_QEMU_COMMON_PATH}/qemu_common.c		\
+				${PLAT_QEMU_COMMON_PATH}/qemu_console.c		\
+				drivers/arm/pl011/${ARCH}/pl011_console.S
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+	PLAT_BL_COMMON_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c
+endif
+
+BL1_SOURCES		+=	drivers/io/io_semihosting.c		\
+				drivers/io/io_storage.c			\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				lib/semihosting/semihosting.c		\
+				lib/semihosting/${ARCH}/semihosting_call.S	\
+				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c	\
+				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
+				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c	\
+				${QEMU_CPU_LIBS}
+
+BL2_SOURCES		+=	drivers/io/io_semihosting.c		\
+				drivers/io/io_storage.c			\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				lib/semihosting/semihosting.c		\
+				lib/semihosting/${ARCH}/semihosting_call.S		\
+				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c		\
+				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S		\
+				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c		\
+				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c	\
+				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
+				common/desc_image_load.c		\
+				common/fdt_fixup.c
+
+BL31_SOURCES		+=	${QEMU_CPU_LIBS}				\
+				lib/semihosting/semihosting.c			\
+				lib/semihosting/${ARCH}/semihosting_call.S	\
+				plat/common/plat_psci_common.c			\
+				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
+				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c	\
+				common/fdt_fixup.c				\
+				${QEMU_GIC_SOURCES}
+
+# CPU flag enablement
+ifeq (${ARCH},aarch64)
+
+# Later QEMU versions support SME and SVE.
+# SPM_MM is not compatible with ENABLE_SVE_FOR_NS (build breaks)
+ifeq (${SPM_MM},1)
+	ENABLE_SVE_FOR_NS	:= 0
+	ENABLE_SME_FOR_NS	:= 0
+else
+	ENABLE_SVE_FOR_NS	:= 2
+	ENABLE_SME_FOR_NS	:= 2
+endif
+
+# QEMU will use the RNDR instruction for the stack protector canary.
+ENABLE_FEAT_RNG			:= 2
+
+# QEMU 7.2+ has support for FGT and Linux needs it enabled to boot on max
+ENABLE_FEAT_FGT			:= 2
+
+# Treating this as a memory-constrained port for now
+USE_COHERENT_MEM	:=	0
+
+# This can be overridden depending on CPU(s) used in the QEMU image
+HW_ASSISTED_COHERENCY	:=	1
+
+CTX_INCLUDE_AARCH32_REGS := 0
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
+$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
+endif
+
+# Pointer Authentication sources
+ifeq (${ENABLE_PAUTH}, 1)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
+CTX_INCLUDE_PAUTH_REGS	:=	1
+endif
+
+endif
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 56c96a1..16e89c1 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -4,6 +4,14 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+PLAT_QEMU_PATH		:=      plat/qemu/qemu
+PLAT_QEMU_COMMON_PATH	:=      plat/qemu/common
+
+SEPARATE_CODE_AND_RODATA := 1
+ENABLE_STACK_PROTECTOR	 := 0
+
+include plat/qemu/common/common.mk
+
 # Use the GICv2 driver on QEMU by default
 QEMU_USE_GIC_DRIVER	:= QEMU_GICV2
 
@@ -18,17 +26,6 @@
 $(eval $(call add_define,ARMV7_SUPPORTS_VFP))
 # Qemu expects a BL32 boot stage.
 NEED_BL32		:=	yes
-else
-CTX_INCLUDE_AARCH32_REGS := 0
-ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
-$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
-endif
-
-# Treating this as a memory-constrained port for now
-USE_COHERENT_MEM	:=	0
-
-# This can be overridden depending on CPU(s) used in the QEMU image
-HW_ASSISTED_COHERENCY	:=	1
 endif # ARMv7
 
 ifeq (${SPD},opteed)
@@ -42,41 +39,10 @@
 add-lib-optee 		:= 	yes
 endif
 
-include lib/libfdt/libfdt.mk
-
 ifeq ($(NEED_BL32),yes)
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
 
-PLAT_QEMU_PATH               :=      plat/qemu/qemu
-PLAT_QEMU_COMMON_PATH        :=      plat/qemu/common
-PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/		\
-				-I${PLAT_QEMU_COMMON_PATH}/include			\
-				-I${PLAT_QEMU_PATH}/include			\
-				-Iinclude/common/tbbr
-
-ifeq (${ARM_ARCH_MAJOR},8)
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
-
-QEMU_CPU_LIBS		:=	lib/cpus/aarch64/aem_generic.S		\
-				lib/cpus/aarch64/cortex_a53.S		\
-				lib/cpus/aarch64/cortex_a57.S		\
-				lib/cpus/aarch64/cortex_a72.S		\
-				lib/cpus/aarch64/cortex_a76.S		\
-				lib/cpus/aarch64/neoverse_n_common.S	\
-				lib/cpus/aarch64/neoverse_n1.S		\
-				lib/cpus/aarch64/qemu_max.S
-else
-QEMU_CPU_LIBS		:=	lib/cpus/${ARCH}/cortex_a15.S
-endif
-
-PLAT_BL_COMMON_SOURCES	:=	${PLAT_QEMU_COMMON_PATH}/qemu_common.c			\
-				${PLAT_QEMU_COMMON_PATH}/qemu_console.c		  \
-				drivers/arm/pl011/${ARCH}/pl011_console.S
-
-include lib/xlat_tables_v2/xlat_tables.mk
-PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
-
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
@@ -149,42 +115,7 @@
     include drivers/auth/mbedtls/mbedtls_crypto.mk
 endif
 
-BL1_SOURCES		+=	drivers/io/io_semihosting.c		\
-				drivers/io/io_storage.c			\
-				drivers/io/io_fip.c			\
-				drivers/io/io_memmap.c			\
-				lib/semihosting/semihosting.c		\
-				lib/semihosting/${ARCH}/semihosting_call.S \
-				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c		\
-				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c	\
-				${QEMU_CPU_LIBS}
-
-ifeq (${ARM_ARCH_MAJOR},8)
-BL1_SOURCES		+=	lib/cpus/${ARCH}/aem_generic.S		\
-				lib/cpus/${ARCH}/cortex_a53.S		\
-				lib/cpus/${ARCH}/cortex_a57.S		\
-				lib/cpus/${ARCH}/cortex_a72.S		\
-				lib/cpus/${ARCH}/qemu_max.S		\
-
-else
-BL1_SOURCES		+=	lib/cpus/${ARCH}/cortex_a15.S
-endif
-
-BL2_SOURCES		+=	drivers/io/io_semihosting.c		\
-				drivers/io/io_storage.c			\
-				drivers/io/io_fip.c			\
-				drivers/io/io_memmap.c			\
-				lib/semihosting/semihosting.c		\
-				lib/semihosting/${ARCH}/semihosting_call.S		\
-				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c		\
-				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S		\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c		\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
-				common/fdt_fixup.c					\
-				common/fdt_wrappers.c					\
-				common/desc_image_load.c				\
+BL2_SOURCES		+=	${FDT_WRAPPERS_SOURCES}					\
 				common/uuid.c
 
 ifeq ($(add-lib-optee),yes)
@@ -217,29 +148,16 @@
 $(error "Incorrect GIC driver chosen for QEMU platform")
 endif
 
-ifeq (${ARM_ARCH_MAJOR},8)
-BL31_SOURCES		+=	${QEMU_CPU_LIBS}			\
-				lib/semihosting/semihosting.c		\
-				lib/semihosting/${ARCH}/semihosting_call.S \
-				plat/common/plat_psci_common.c		\
-				drivers/arm/pl061/pl061_gpio.c		\
+ifeq (${ARCH},aarch64)
+BL31_SOURCES		+=	drivers/arm/pl061/pl061_gpio.c		\
 				drivers/gpio/gpio.c			\
-				${PLAT_QEMU_COMMON_PATH}/qemu_pm.c			\
-				${PLAT_QEMU_COMMON_PATH}/topology.c			\
-				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c		\
-				${QEMU_GIC_SOURCES}
+				${PLAT_QEMU_COMMON_PATH}/qemu_pm.c	\
+				${PLAT_QEMU_COMMON_PATH}/topology.c
 
 ifeq (${SDEI_SUPPORT}, 1)
 BL31_SOURCES		+=	plat/qemu/common/qemu_sdei.c
 endif
 
-# Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c	\
-				lib/extensions/pauth/pauth_helpers.S
-endif
-
 ifeq (${SPD},spmd)
 BL31_SOURCES		+=	plat/common/plat_spmd_manifest.c	\
 				common/uuid.c				\
@@ -279,12 +197,6 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${QEMU_TOS_FW_CONFIG},--tos-fw-config,${QEMU_TOS_FW_CONFIG}))
 endif
 
-SEPARATE_CODE_AND_RODATA := 1
-ENABLE_STACK_PROTECTOR	 := 0
-ifneq ($(ENABLE_STACK_PROTECTOR), 0)
-	PLAT_BL_COMMON_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c
-endif
-
 BL32_RAM_LOCATION	:=	tdram
 ifeq (${BL32_RAM_LOCATION}, tsram)
   BL32_RAM_LOCATION_ID = SEC_SRAM_ID
@@ -305,15 +217,6 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# QEMU will use the RNDR instruction for the stack protector canary.
-ENABLE_FEAT_RNG			:= 2
-
-# Later QEMU versions support SME and SVE.
-ifneq (${ARCH},aarch32)
-	ENABLE_SVE_FOR_NS	:= 2
-	ENABLE_SME_FOR_NS	:= 2
-endif
-
 qemu_fw.bios: bl1 fip
 	$(ECHO) "  DD      $@"
 	$(Q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
diff --git a/plat/qemu/qemu/qemu_bl1_measured_boot.c b/plat/qemu/qemu/qemu_bl1_measured_boot.c
index 3d20f97..7984781 100644
--- a/plat/qemu/qemu/qemu_bl1_measured_boot.c
+++ b/plat/qemu/qemu/qemu_bl1_measured_boot.c
@@ -26,3 +26,9 @@
 {
 	return 0;
 }
+
+int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+			   size_t pk_len)
+{
+	return 0;
+}
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 122bb23..077f7a4 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Arm Limited. All rights reserved.
- * Copyright (c) 2022, Linaro.
+ * Copyright (c) 2022-2023, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,3 +118,9 @@
 
 	return 0;
 }
+
+int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
+			   size_t pk_len)
+{
+	return 0;
+}
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 60d6b7e..4a8df46 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -4,11 +4,17 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-include common/fdt_wrappers.mk
+PLAT_QEMU_PATH		:=	plat/qemu/qemu_sbsa
+PLAT_QEMU_COMMON_PATH	:=	plat/qemu/common
+
+MULTI_CONSOLE_API	:= 1
+CRASH_REPORTING		:= 1
 
-CRASH_REPORTING	:=	1
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT	:= 0
 
-include lib/libfdt/libfdt.mk
+SEPARATE_CODE_AND_RODATA := 1
+ENABLE_STACK_PROTECTOR	 := 0
 
 ifeq (${SPM_MM},1)
 NEED_BL32		:=	yes
@@ -16,74 +22,16 @@
 GICV2_G0_FOR_EL3	:=	1
 endif
 
+include plat/qemu/common/common.mk
+
 # Enable new version of image loading on QEMU platforms
 LOAD_IMAGE_V2		:=	1
 
-CTX_INCLUDE_AARCH32_REGS := 0
-ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
-$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
-endif
-
 ifeq ($(NEED_BL32),yes)
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
 
-PLAT_QEMU_PATH		:=	plat/qemu/qemu_sbsa
-PLAT_QEMU_COMMON_PATH	:=	plat/qemu/common
-PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
-				-I${PLAT_QEMU_COMMON_PATH}/include		\
-				-I${PLAT_QEMU_PATH}/include			\
-				-Iinclude/common/tbbr
-
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
-
-PLAT_BL_COMMON_SOURCES	:=	${PLAT_QEMU_COMMON_PATH}/qemu_common.c		\
-				${PLAT_QEMU_COMMON_PATH}/qemu_console.c		\
-				drivers/arm/pl011/${ARCH}/pl011_console.S
-
-# Treating this as a memory-constrained port for now
-USE_COHERENT_MEM	:=	0
-
-# This can be overridden depending on CPU(s) used in the QEMU image
-HW_ASSISTED_COHERENCY	:=	1
-
-QEMU_CPU_LIBS		:=	lib/cpus/aarch64/cortex_a57.S			\
-				lib/cpus/aarch64/cortex_a72.S			\
-				lib/cpus/aarch64/neoverse_n_common.S		\
-				lib/cpus/aarch64/neoverse_n1.S			\
-				lib/cpus/aarch64/qemu_max.S
-
-include lib/xlat_tables_v2/xlat_tables.mk
-PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
-
-BL1_SOURCES		+=	drivers/io/io_semihosting.c			\
-				drivers/io/io_storage.c				\
-				drivers/io/io_fip.c				\
-				drivers/io/io_memmap.c				\
-				lib/semihosting/semihosting.c			\
-				lib/semihosting/${ARCH}/semihosting_call.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c	\
-				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c
-
-BL1_SOURCES		+=	${QEMU_CPU_LIBS}
-
-BL2_SOURCES		+=	drivers/io/io_semihosting.c			\
-				drivers/io/io_storage.c				\
-				drivers/io/io_fip.c				\
-				drivers/io/io_memmap.c				\
-				lib/semihosting/semihosting.c			\
-				lib/semihosting/${ARCH}/semihosting_call.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c	\
-				${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c	\
-				common/fdt_fixup.c				\
-				$(LIBFDT_SRCS)
-ifeq (${LOAD_IMAGE_V2},1)
-BL2_SOURCES		+=	${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
-				common/desc_image_load.c
-endif
+BL2_SOURCES		+=	$(LIBFDT_SRCS)
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
@@ -91,18 +39,10 @@
 QEMU_GIC_SOURCES	:=	${GICV3_SOURCES}				\
 				plat/common/plat_gicv3.c
 
-BL31_SOURCES		+=	${QEMU_CPU_LIBS}				\
-				lib/semihosting/semihosting.c			\
-				lib/semihosting/${ARCH}/semihosting_call.S	\
-				plat/common/plat_psci_common.c			\
-				${PLAT_QEMU_PATH}/sbsa_gic.c 			\
+BL31_SOURCES		+=	${PLAT_QEMU_PATH}/sbsa_gic.c 			\
 				${PLAT_QEMU_PATH}/sbsa_pm.c			\
 				${PLAT_QEMU_PATH}/sbsa_sip_svc.c		\
-				${PLAT_QEMU_PATH}/sbsa_topology.c		\
-				${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S	\
-				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c	\
-				common/fdt_fixup.c				\
-				${QEMU_GIC_SOURCES}
+				${PLAT_QEMU_PATH}/sbsa_topology.c
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
@@ -110,17 +50,6 @@
 	BL31_SOURCES		+=	${PLAT_QEMU_COMMON_PATH}/qemu_spm.c
 endif
 
-SEPARATE_CODE_AND_RODATA	:= 1
-ENABLE_STACK_PROTECTOR		:= 0
-ifneq ($(ENABLE_STACK_PROTECTOR), 0)
-	PLAT_BL_COMMON_SOURCES	+=	${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c
-endif
-
-MULTI_CONSOLE_API	:= 1
-
-# Disable the PSCI platform compatibility layer
-ENABLE_PLAT_COMPAT	:= 0
-
 # Use known base for UEFI if not given from command line
 # By default BL33 is at FLASH1 base
 PRELOADED_BL33_BASE	?= 0x10000000
@@ -136,10 +65,3 @@
 
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
-
-# Later QEMU versions support SME and SVE.
-ENABLE_SVE_FOR_NS	:= 2
-ENABLE_SME_FOR_NS	:= 2
-
-# QEMU 7.2+ has support for FGT and Linux needs it enabled to boot on max
-ENABLE_FEAT_FGT 	:= 2
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 487a56e..1113efc 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -260,6 +260,10 @@
 		    state_id & QTI_LOCAL_PSTATE_MASK;
 		state_id >>= QTI_LOCAL_PSTATE_WIDTH;
 	}
+
+#if PSCI_OS_INIT_MODE
+	req_state->last_at_pwrlvl = PLAT_MAX_PWR_LVL;
+#endif
 }
 
 /*
diff --git a/plat/qti/mdm9607/platform.mk b/plat/qti/mdm9607/platform.mk
new file mode 100644
index 0000000..4c6938c
--- /dev/null
+++ b/plat/qti/mdm9607/platform.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_ARCH_MAJOR		:= 7
+ARM_CORTEX_A7		:= yes
+
+BL31_BASE		?= 0x87e00000
+PRELOADED_BL33_BASE	?= 0x82900000
+QTI_UART_NUM		?= 5
+
+include plat/qti/msm8916/platform.mk
diff --git a/plat/qti/mdm9607/sp_min/sp_min-mdm9607.mk b/plat/qti/mdm9607/sp_min/sp_min-mdm9607.mk
new file mode 100644
index 0000000..28a6f01
--- /dev/null
+++ b/plat/qti/mdm9607/sp_min/sp_min-mdm9607.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qti/msm8916/sp_min/sp_min-msm8916.mk
diff --git a/plat/qti/msm8909/platform.mk b/plat/qti/msm8909/platform.mk
new file mode 100644
index 0000000..8a88aa5
--- /dev/null
+++ b/plat/qti/msm8909/platform.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_ARCH_MAJOR	:= 7
+ARM_CORTEX_A7	:= yes
+
+BL31_BASE	?= 0x87e80000
+QTI_UART_NUM	?= 1
+
+include plat/qti/msm8916/platform.mk
diff --git a/plat/qti/msm8909/sp_min/sp_min-msm8909.mk b/plat/qti/msm8909/sp_min/sp_min-msm8909.mk
new file mode 100644
index 0000000..28a6f01
--- /dev/null
+++ b/plat/qti/msm8909/sp_min/sp_min-msm8909.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qti/msm8916/sp_min/sp_min-msm8916.mk
diff --git a/plat/qti/msm8916/aarch32/msm8916_helpers.S b/plat/qti/msm8916/aarch32/msm8916_helpers.S
index ea39663..dc35043 100644
--- a/plat/qti/msm8916/aarch32/msm8916_helpers.S
+++ b/plat/qti/msm8916/aarch32/msm8916_helpers.S
@@ -6,10 +6,15 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <platform_def.h>
 
 #include <msm8916_mmap.h>
 
+#if PLATFORM_CORE_COUNT > 1
 #define APCS_TCM_START_ADDR	0x10
+#else
+#define APCS_TCM_START_ADDR	0x34
+#endif
 #define APCS_TCM_REDIRECT_EN_0	BIT_32(0)
 
 	.globl	plat_crash_console_init
@@ -79,9 +84,18 @@
 	 * -------------------------------------------------
 	 */
 func plat_my_core_pos
-	/* There is just a single cluster so this is very simple */
-	ldcopr	r0, MPIDR
-	and	r0, r0, #MPIDR_CPU_MASK
+	.if PLATFORM_CORE_COUNT > 1
+		ldcopr	r1, MPIDR
+		and	r0, r1, #MPIDR_CPU_MASK
+		.if PLATFORM_CLUSTER_COUNT > 1
+			and	r1, r1, #MPIDR_CLUSTER_MASK
+			orr	r0, r0, r1, LSR #(MPIDR_AFFINITY_BITS - \
+						  PLATFORM_CPU_PER_CLUSTER_SHIFT)
+		.endif
+	.else
+		/* There is just a single core so always 0 */
+		mov r0, #0
+	.endif
 	bx	lr
 endfunc plat_my_core_pos
 
@@ -102,7 +116,7 @@
 	 * Cold boot: Disable TCM redirect to L2 cache as early as
 	 * possible to avoid crashes when making use of the cache.
 	 */
-	ldr	r1, =APCS_CFG
+	ldr	r1, =APCS_CFG(0)
 	ldr	r2, [r1, #APCS_TCM_START_ADDR]
 	and	r2, r2, #~APCS_TCM_REDIRECT_EN_0
 	str	r2, [r1, #APCS_TCM_START_ADDR]
diff --git a/plat/qti/msm8916/aarch64/msm8916_helpers.S b/plat/qti/msm8916/aarch64/msm8916_helpers.S
index bccc5e5..de9438a 100644
--- a/plat/qti/msm8916/aarch64/msm8916_helpers.S
+++ b/plat/qti/msm8916/aarch64/msm8916_helpers.S
@@ -6,10 +6,15 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <platform_def.h>
 
 #include <msm8916_mmap.h>
 
+#if PLATFORM_CORE_COUNT > 1
 #define APCS_TCM_START_ADDR	0x10
+#else
+#define APCS_TCM_START_ADDR	0x34
+#endif
 #define APCS_TCM_REDIRECT_EN_0	BIT_32(0)
 
 	.globl	plat_crash_console_init
@@ -78,9 +83,18 @@
 	 * -------------------------------------------------
 	 */
 func plat_my_core_pos
-	/* There is just a single cluster so this is very simple */
-	mrs	x0, mpidr_el1
-	and	x0, x0, #MPIDR_CPU_MASK
+	.if PLATFORM_CORE_COUNT > 1
+		mrs	x1, mpidr_el1
+		and	x0, x1, #MPIDR_CPU_MASK
+		.if PLATFORM_CLUSTER_COUNT > 1
+			and	x1, x1, #MPIDR_CLUSTER_MASK
+			orr	x0, x0, x1, LSR #(MPIDR_AFFINITY_BITS - \
+						  PLATFORM_CPU_PER_CLUSTER_SHIFT)
+		.endif
+	.else
+		/* There is just a single core so always 0 */
+		mov	x0, #0
+	.endif
 	ret
 endfunc plat_my_core_pos
 
@@ -100,7 +114,7 @@
 	 * Cold boot: Disable TCM redirect to L2 cache as early as
 	 * possible to avoid crashes when making use of the cache.
 	 */
-	mov_imm	x1, APCS_CFG
+	mov_imm	x1, APCS_CFG(0)
 	ldr	w2, [x1, #APCS_TCM_START_ADDR]
 	and	w2, w2, #~APCS_TCM_REDIRECT_EN_0
 	str	w2, [x1, #APCS_TCM_START_ADDR]
diff --git a/plat/qti/msm8916/include/msm8916_mmap.h b/plat/qti/msm8916/include/msm8916_mmap.h
index 35e3b86..20c5a57 100644
--- a/plat/qti/msm8916/include/msm8916_mmap.h
+++ b/plat/qti/msm8916/include/msm8916_mmap.h
@@ -22,6 +22,7 @@
 
 #define APPS_SMMU_BASE		(PCNOC_BASE + 0x1e00000)
 #define APPS_SMMU_QCOM		(APPS_SMMU_BASE + 0xf0000)
+#define GPU_SMMU_BASE		(PCNOC_BASE + 0x1f00000)
 
 #define BLSP1_BASE		(PCNOC_BASE + 0x7880000)
 #define BLSP1_UART_BASE(n)	(BLSP1_BASE + 0x2f000 + (((n) - 1) * 0x1000))
@@ -32,11 +33,19 @@
 #define APCS_QGIC2_GICC		(APCS_QGIC2_BASE + 0x2000)
 #define APCS_BANKED_ACS		(APCS_BASE + 0x08000)
 #define APCS_BANKED_SAW2	(APCS_BASE + 0x09000)
-#define APCS_CFG		(APCS_BASE + 0x10000)
-#define APCS_GLB		(APCS_BASE + 0x11000)
-#define APCS_L2_SAW2		(APCS_BASE + 0x12000)
-#define APCS_QTMR		(APCS_BASE + 0x20000)
-#define APCS_ALIAS_ACS(cpu)	(APCS_BASE + 0x88000 + ((cpu) * 0x10000))
-#define APCS_ALIAS_SAW2(cpu)	(APCS_BASE + 0x89000 + ((cpu) * 0x10000))
+
+#define _APCS_CLUSTER(cluster)	(APCS_BASE + ((cluster) * 0x100000))
+#define _APCS_CPU(cluster, cpu)	(_APCS_CLUSTER(cluster) + ((cpu) * 0x10000))
+#define APCS_CFG(cluster)	(_APCS_CLUSTER(cluster) + 0x10000)
+#define APCS_GLB(cluster)	(_APCS_CLUSTER(cluster) + 0x11000)
+#define APCS_L2_SAW2(cluster)	(_APCS_CLUSTER(cluster) + 0x12000)
+#define APCS_QTMR(cluster)	(_APCS_CLUSTER(cluster) + 0x20000)
+#define APCS_ALIAS_ACS(cluster, cpu)	(_APCS_CPU(cluster, cpu) + 0x88000)
+#define APCS_ALIAS_SAW2(cluster, cpu)	(_APCS_CPU(cluster, cpu) + 0x89000)
+
+/* Only on platforms with multiple clusters (e.g. MSM8939) */
+#define APCS_CCI_BASE		(APCS_BASE + 0x1c0000)
+#define APCS_CCI_SAW2		(APCS_BASE + 0x1d2000)
+#define APCS_CCI_ACS		(APCS_BASE + 0x1d4000)
 
 #endif /* MSM8916_MMAP_H */
diff --git a/plat/qti/msm8916/include/platform_def.h b/plat/qti/msm8916/include/platform_def.h
index f6ba1cc..a5baacd 100644
--- a/plat/qti/msm8916/include/platform_def.h
+++ b/plat/qti/msm8916/include/platform_def.h
@@ -25,11 +25,20 @@
 #define CACHE_WRITEBACK_GRANULE		U(64)
 #define PLATFORM_STACK_SIZE		SZ_4K
 
-/* CPU topology: single cluster with 4 cores */
+/* CPU topology: one or two clusters with 4 cores each */
+#ifdef PLAT_msm8939
+#define PLATFORM_CLUSTER_COUNT		U(2)
+#else
 #define PLATFORM_CLUSTER_COUNT		U(1)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#endif
+#if defined(PLAT_mdm9607)
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(0)	/* 1 */
+#else
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT	U(2)	/* 4 */
+#endif
+#define PLATFORM_CPUS_PER_CLUSTER	(1 << PLATFORM_CPU_PER_CLUSTER_SHIFT)
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
-					 PLATFORM_MAX_CPUS_PER_CLUSTER)
+					 PLATFORM_CPUS_PER_CLUSTER)
 
 /* Power management */
 #define PLATFORM_SYSTEM_COUNT		U(1)
diff --git a/plat/qti/msm8916/msm8916_bl31_setup.c b/plat/qti/msm8916/msm8916_bl31_setup.c
index 449be7f..c588020 100644
--- a/plat/qti/msm8916/msm8916_bl31_setup.c
+++ b/plat/qti/msm8916/msm8916_bl31_setup.c
@@ -33,6 +33,7 @@
 				u_register_t arg2, u_register_t arg3)
 {
 	msm8916_early_platform_setup();
+	msm8916_configure_early();
 }
 
 void bl31_plat_arch_setup(void)
diff --git a/plat/qti/msm8916/msm8916_config.c b/plat/qti/msm8916/msm8916_config.c
index 350ed5c..0ac604b 100644
--- a/plat/qti/msm8916/msm8916_config.c
+++ b/plat/qti/msm8916/msm8916_config.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 
 #include <arch.h>
+#include <drivers/arm/cci.h>
 #include <lib/mmio.h>
 
 #include "msm8916_config.h"
@@ -14,13 +15,23 @@
 #include <msm8916_mmap.h>
 #include <platform_def.h>
 
-static void msm8916_configure_timer(void)
+static const int cci_map[] = { 3, 4 };
+
+void msm8916_configure_early(void)
+{
+	if (PLATFORM_CLUSTER_COUNT > 1) {
+		cci_init(APCS_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+	}
+}
+
+static void msm8916_configure_timer(uintptr_t base)
 {
 	/* Set timer frequency */
-	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, PLAT_SYSCNT_FREQ);
+	mmio_write_32(base + CNTCTLBASE_CNTFRQ, PLAT_SYSCNT_FREQ);
 
 	/* Make all timer frames available to non-secure world */
-	mmio_write_32(APCS_QTMR + CNTNSAR, GENMASK_32(7, 0));
+	mmio_write_32(base + CNTNSAR, GENMASK_32(7, 0));
 }
 
 /*
@@ -30,16 +41,21 @@
  */
 #define APCS_GLB_SECURE_STS_NS		BIT_32(0)
 #define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
-#define APCS_BOOT_START_ADDR_SEC	(APCS_CFG + 0x04)
+#if PLATFORM_CORE_COUNT > 1
+#define APCS_BOOT_START_ADDR_SEC	0x04
+#define APCS_AA64NAA32_REG		0x0c
+#else
+#define APCS_BOOT_START_ADDR_SEC	0x18
+#endif
 #define REMAP_EN			BIT_32(0)
-#define APCS_AA64NAA32_REG		(APCS_CFG + 0x0c)
 
-static void msm8916_configure_cpu_pm(void)
+static void msm8916_configure_apcs_cluster(unsigned int cluster)
 {
+	uintptr_t cfg = APCS_CFG(cluster);
 	unsigned int cpu;
 
 	/* Disallow non-secure access to boot remapper / TCM registers */
-	mmio_write_32(APCS_CFG, 0);
+	mmio_write_32(cfg, 0);
 
 	/*
 	 * Disallow non-secure access to power management registers.
@@ -47,29 +63,53 @@
 	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
 	 * bits are not set, CPU frequency control fails in the non-secure world.
 	 */
-	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
+	mmio_write_32(APCS_GLB(cluster),
+		      APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
 
-	/* Disallow non-secure access to L2 SAW2 */
-	mmio_write_32(APCS_L2_SAW2, 0);
+	if (PLATFORM_CORE_COUNT > 1) {
+		/* Disallow non-secure access to L2 SAW2 */
+		mmio_write_32(APCS_L2_SAW2(cluster), 0);
 
-	/* Disallow non-secure access to CPU ACS and SAW2 */
-	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
-		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
-		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
+		/* Disallow non-secure access to CPU ACS and SAW2 */
+		for (cpu = 0; cpu < PLATFORM_CPUS_PER_CLUSTER; cpu++) {
+			mmio_write_32(APCS_ALIAS_ACS(cluster, cpu), 0);
+			mmio_write_32(APCS_ALIAS_SAW2(cluster, cpu), 0);
+		}
+	} else {
+		/* There is just one core so no aliases exist */
+		mmio_write_32(APCS_BANKED_ACS, 0);
+		mmio_write_32(APCS_BANKED_SAW2, 0);
 	}
 
 #ifdef __aarch64__
 	/* Make sure all further warm boots end up in BL31 and aarch64 state */
 	CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
-	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
-	mmio_write_32(APCS_AA64NAA32_REG, 1);
+	mmio_write_32(cfg + APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
+	mmio_write_32(cfg + APCS_AA64NAA32_REG, 1);
 #else
 	/* Make sure all further warm boots end up in BL32 */
 	CASSERT((BL32_BASE & 0xffff) == 0, assert_bl32_base_64k_aligned);
-	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL32_BASE | REMAP_EN);
+	mmio_write_32(cfg + APCS_BOOT_START_ADDR_SEC, BL32_BASE | REMAP_EN);
 #endif
+
+	msm8916_configure_timer(APCS_QTMR(cluster));
 }
 
+static void msm8916_configure_apcs(void)
+{
+	unsigned int cluster;
+
+	for (cluster = 0; cluster < PLATFORM_CLUSTER_COUNT; cluster++) {
+		msm8916_configure_apcs_cluster(cluster);
+	}
+
+	if (PLATFORM_CLUSTER_COUNT > 1) {
+		/* Disallow non-secure access to CCI ACS and SAW2 */
+		mmio_write_32(APCS_CCI_ACS, 0);
+		mmio_write_32(APCS_CCI_SAW2, 0);
+	}
+}
+
 /*
  * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
  * which allows routing context bank interrupts to one of 3 interrupt numbers
@@ -77,30 +117,79 @@
  * by default to avoid special setup on the non-secure side.
  */
 #define CLK_OFF					BIT_32(31)
+#define GCC_APSS_TCU_CBCR			(GCC_BASE + 0x12018)
+#define GCC_GFX_TCU_CBCR			(GCC_BASE + 0x12020)
 #define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
+#define GCC_RPM_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x3600c)
 #define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
+#define APSS_TCU_CLK_ENA			BIT_32(1)
+#define GFX_TCU_CLK_ENA				BIT_32(2)
+#define GFX_TBU_CLK_ENA				BIT_32(3)
 #define SMMU_CFG_CLK_ENA			BIT_32(12)
 #define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
 #define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
 
+#define SMMU_SACR				0x010
+#define SMMU_SACR_CACHE_LOCK			BIT_32(26)
+#define SMMU_IDR7				0x03c
+#define SMMU_IDR7_MINOR(val)			(((val) >> 0) & 0xf)
+#define SMMU_IDR7_MAJOR(val)			(((val) >> 4) & 0xf)
+
+static void msm8916_smmu_cache_unlock(uintptr_t smmu_base, uintptr_t clk_cbcr)
+{
+	uint32_t version;
+
+	/* Wait for clock */
+	while (mmio_read_32(clk_cbcr) & CLK_OFF) {
+	}
+
+	version = mmio_read_32(smmu_base + SMMU_IDR7);
+	VERBOSE("SMMU(0x%lx) r%dp%d\n", smmu_base,
+		SMMU_IDR7_MAJOR(version), SMMU_IDR7_MINOR(version));
+
+	/* For SMMU r2p0+ clear CACHE_LOCK to allow writes to CBn_ACTLR */
+	if (SMMU_IDR7_MAJOR(version) >= 2) {
+		mmio_clrbits_32(smmu_base + SMMU_SACR, SMMU_SACR_CACHE_LOCK);
+	}
+}
+
 static void msm8916_configure_smmu(void)
 {
-	/* Enable SMMU configuration clock to enable register access */
-	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
-	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
-		;
+	uint32_t ena_bits = APSS_TCU_CLK_ENA | SMMU_CFG_CLK_ENA;
+
+	/* Single core (MDM) platforms do not have a GPU */
+	if (PLATFORM_CORE_COUNT > 1) {
+		ena_bits |= GFX_TCU_CLK_ENA | GFX_TBU_CLK_ENA;
+	}
+
+	/* Enable SMMU clocks to enable register access */
+	mmio_write_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, ena_bits);
+
+	/* Wait for configuration clock */
+	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF) {
+	}
 
 	/* Route all context bank interrupts to non-secure interrupt */
 	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
 
-	/* Disable configuration clock again */
-	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
+	/* Clear sACR.CACHE_LOCK bit if needed for MMU-500 r2p0+ */
+	msm8916_smmu_cache_unlock(APPS_SMMU_BASE, GCC_APSS_TCU_CBCR);
+	if (PLATFORM_CORE_COUNT > 1) {
+		msm8916_smmu_cache_unlock(GPU_SMMU_BASE, GCC_GFX_TCU_CBCR);
+	}
+
+	/*
+	 * Keep APCS vote for SMMU clocks for rest of booting process, but make
+	 * sure other vote registers (such as RPM) do not keep permanent votes.
+	 */
+	VERBOSE("Clearing GCC_RPM_SMMU_CLOCK_BRANCH_ENA_VOTE (was: 0x%x)\n",
+		mmio_read_32(GCC_RPM_SMMU_CLOCK_BRANCH_ENA_VOTE));
+	mmio_write_32(GCC_RPM_SMMU_CLOCK_BRANCH_ENA_VOTE, 0);
 }
 
 void msm8916_configure(void)
 {
 	msm8916_gicv2_configure();
-	msm8916_configure_timer();
-	msm8916_configure_cpu_pm();
+	msm8916_configure_apcs();
 	msm8916_configure_smmu();
 }
diff --git a/plat/qti/msm8916/msm8916_config.h b/plat/qti/msm8916/msm8916_config.h
index 992625b..977d02c 100644
--- a/plat/qti/msm8916/msm8916_config.h
+++ b/plat/qti/msm8916/msm8916_config.h
@@ -8,5 +8,6 @@
 #define MSM8916_CONFIG_H
 
 void msm8916_configure(void);
+void msm8916_configure_early(void);
 
 #endif /* MSM8916_CONFIG_H */
diff --git a/plat/qti/msm8916/msm8916_cpu_boot.c b/plat/qti/msm8916/msm8916_cpu_boot.c
index b3f51f6..d6faa59 100644
--- a/plat/qti/msm8916/msm8916_cpu_boot.c
+++ b/plat/qti/msm8916/msm8916_cpu_boot.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2022, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 
-#include <msm8916_mmap.h>
 #include "msm8916_pm.h"
 
 #define CPU_PWR_CTL			0x4
@@ -26,12 +26,39 @@
 #define APC_PWR_GATE_CTL_GHDS_EN	BIT_32(0)
 #define APC_PWR_GATE_CTL_GHDS_CNT(cnt)	((cnt) << 24)
 
+#define PWR_CTL_OVERRIDE		0xc
+#define L2_PWR_CTL			0x14
+#define L2_PWR_STATUS			0x18
+#define CORE_CBCR			0x58
+
+#define PWR_CTL_OVERRIDE_PRESETDBG	BIT_32(22)
+
+#define L2_PWR_CTL_L2_ARRAY_HS		BIT_32(0)
+#define L2_PWR_CTL_SCU_ARRAY_HS		BIT_32(1)
+#define L2_PWR_CTL_L2_RST_DIS		BIT_32(2)
+#define L2_PWR_CTL_L2_HS_CLAMP		BIT_32(8)
+#define L2_PWR_CTL_L2_HS_EN		BIT_32(9)
+#define L2_PWR_CTL_L2_HS_RST		BIT_32(10)
+#define L2_PWR_CTL_L2_SLEEP_STATE	BIT_32(11)
+#define L2_PWR_CTL_SYS_RESET		BIT_32(12)
+#define L2_PWR_CTL_L2_RET_SLP		BIT_32(13)
+#define L2_PWR_CTL_SCU_ARRAY_HS_CLAMP	BIT_32(14)
+#define L2_PWR_CTL_L2_ARRAY_HS_CLAMP	BIT_32(15)
+#define L2_PWR_CTL_L2_HS_CNT(cnt)	((cnt) << 16)
+#define L2_PWR_CTL_PMIC_APC_ON		BIT_32(28)
+
+#define L2_PWR_STATUS_L2_HS_STS		BIT_32(9)
+
+#define CORE_CBCR_CLK_ENABLE		BIT_32(0)
+#define CORE_CBCR_HW_CTL		BIT_32(1)
+
 /* Boot a secondary CPU core for the first time. */
-void msm8916_cpu_boot(unsigned int core)
+void msm8916_cpu_boot(uintptr_t acs)
 {
-	uintptr_t acs = APCS_ALIAS_ACS(core);
 	uint32_t pwr_ctl;
 
+	VERBOSE("PSCI: Powering on CPU @ 0x%08lx\n", acs);
+
 	pwr_ctl = CPU_PWR_CTL_CLAMP | CPU_PWR_CTL_CORE_MEM_CLAMP |
 		  CPU_PWR_CTL_CORE_RST | CPU_PWR_CTL_COREPOR_RST;
 	mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
@@ -64,3 +91,60 @@
 	mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
 	dsb();
 }
+
+/* Power on cluster L2 cache for the first time. */
+void msm8916_l2_boot(uintptr_t base)
+{
+	uint32_t pwr_ctl, cbcr, ovr;
+
+	/* Skip if cluster L2 is already powered on */
+	if (mmio_read_32(base + L2_PWR_STATUS) & L2_PWR_STATUS_L2_HS_STS) {
+		VERBOSE("PSCI: L2 cache @ 0x%08lx is already powered on\n", base);
+		return;
+	}
+
+	VERBOSE("PSCI: Powering on L2 cache @ 0x%08lx\n", base);
+
+	pwr_ctl = L2_PWR_CTL_L2_HS_CLAMP | L2_PWR_CTL_L2_HS_EN |
+		  L2_PWR_CTL_L2_HS_RST | L2_PWR_CTL_SYS_RESET |
+		  L2_PWR_CTL_SCU_ARRAY_HS_CLAMP | L2_PWR_CTL_L2_ARRAY_HS_CLAMP |
+		  L2_PWR_CTL_L2_HS_CNT(16);
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+
+	ovr = PWR_CTL_OVERRIDE_PRESETDBG;
+	mmio_write_32(base + PWR_CTL_OVERRIDE, ovr);
+	dsb();
+	udelay(2);
+
+	pwr_ctl &= ~(L2_PWR_CTL_SCU_ARRAY_HS_CLAMP |
+		     L2_PWR_CTL_L2_ARRAY_HS_CLAMP);
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+
+	pwr_ctl |= (L2_PWR_CTL_L2_ARRAY_HS | L2_PWR_CTL_SCU_ARRAY_HS);
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+	dsb();
+	udelay(2);
+
+	cbcr = CORE_CBCR_CLK_ENABLE;
+	mmio_write_32(base + CORE_CBCR, cbcr);
+
+	pwr_ctl &= ~L2_PWR_CTL_L2_HS_CLAMP;
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+	dsb();
+	udelay(2);
+
+	ovr &= ~PWR_CTL_OVERRIDE_PRESETDBG;
+	mmio_write_32(base + PWR_CTL_OVERRIDE, ovr);
+
+	pwr_ctl &= ~(L2_PWR_CTL_L2_HS_RST | L2_PWR_CTL_SYS_RESET);
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+	dsb();
+	udelay(54);
+
+	pwr_ctl |= L2_PWR_CTL_PMIC_APC_ON;
+	mmio_write_32(base + L2_PWR_CTL, pwr_ctl);
+
+	cbcr |= CORE_CBCR_HW_CTL;
+	mmio_write_32(base + CORE_CBCR, cbcr);
+	dsb();
+}
diff --git a/plat/qti/msm8916/msm8916_pm.c b/plat/qti/msm8916/msm8916_pm.c
index 792a096..fd44f04 100644
--- a/plat/qti/msm8916/msm8916_pm.c
+++ b/plat/qti/msm8916/msm8916_pm.c
@@ -4,9 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/cci.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
@@ -16,18 +19,51 @@
 #include <msm8916_mmap.h>
 #include "msm8916_pm.h"
 
+/*
+ * On platforms with two clusters the index of the APCS memory region is swapped
+ * compared to the MPIDR cluster affinity level: APCS cluster 0 manages CPUs
+ * with cluster affinity level 1, while APCS cluster 1 manages CPUs with level 0.
+ *
+ * On platforms with a single cluster there is only one APCS memory region.
+ */
+#if PLATFORM_CLUSTER_COUNT == 2
+#define MPIDR_APCS_CLUSTER(mpidr)	!MPIDR_AFFLVL1_VAL(mpidr)
+#else
+#define MPIDR_APCS_CLUSTER(mpidr)	0
+#endif
+
+#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+
 static int msm8916_pwr_domain_on(u_register_t mpidr)
 {
-	unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
+	/* Should be never called on single-core platforms */
+	if (PLATFORM_CORE_COUNT == 1) {
+		assert(false);
+		return PSCI_E_ALREADY_ON;
+	}
 
-	VERBOSE("PSCI: Booting CPU %d\n", core);
-	msm8916_cpu_boot(core);
-
+	/* Power on L2 cache and secondary CPU core for the first time */
+	if (PLATFORM_CLUSTER_COUNT > 1) {
+		msm8916_l2_boot(APCS_GLB(MPIDR_APCS_CLUSTER(mpidr)));
+	}
+	msm8916_cpu_boot(APCS_ALIAS_ACS(MPIDR_APCS_CLUSTER(mpidr),
+					MPIDR_AFFLVL0_VAL(mpidr)));
 	return PSCI_E_SUCCESS;
 }
 
 static void msm8916_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
+	/* Should be never called on single-core platforms */
+	if (PLATFORM_CORE_COUNT == 1) {
+		assert(false);
+		return;
+	}
+
+	if (PLATFORM_CLUSTER_COUNT > 1 &&
+	    CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
+		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+	}
+
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
 }
diff --git a/plat/qti/msm8916/msm8916_pm.h b/plat/qti/msm8916/msm8916_pm.h
index 5473bfa..f301d3c 100644
--- a/plat/qti/msm8916/msm8916_pm.h
+++ b/plat/qti/msm8916/msm8916_pm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2022, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef MSM8916_PM_H
 #define MSM8916_PM_H
 
-void msm8916_cpu_boot(unsigned int core);
+void msm8916_cpu_boot(uintptr_t acs);
+void msm8916_l2_boot(uintptr_t base);
 
 #endif /* MSM8916_PM_H */
diff --git a/plat/qti/msm8916/msm8916_setup.c b/plat/qti/msm8916/msm8916_setup.c
index 26039a9..69c0d78 100644
--- a/plat/qti/msm8916/msm8916_setup.c
+++ b/plat/qti/msm8916/msm8916_setup.c
@@ -47,7 +47,14 @@
 };
 
 static const struct uartdm_gpios uartdm_gpio_map[] = {
+#if defined(PLAT_msm8909)
+	{4, 5, 0x2}, {20, 21, 0x3},
+#elif defined(PLAT_msm8916) || defined(PLAT_msm8939)
 	{0, 1, 0x2}, {4, 5, 0x2},
+#elif defined(PLAT_mdm9607)
+	{12, 13, 0x2}, {4, 5, 0x2}, {0, 1, 0x1},
+	{16, 17, 0x2}, {8, 9, 0x2}, {20, 21, 0x2},
+#endif
 };
 
 /*
@@ -69,13 +76,13 @@
 
 	/* Enable AHB clock */
 	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
-	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
-		;
+	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF) {
+	}
 
 	/* Enable BLSP UART clock */
 	mmio_setbits_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM), CLK_ENABLE);
-	while (mmio_read_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM)) & CLK_OFF)
-		;
+	while (mmio_read_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM)) & CLK_OFF) {
+	}
 }
 
 void msm8916_early_platform_setup(void)
diff --git a/plat/qti/msm8916/msm8916_topology.c b/plat/qti/msm8916/msm8916_topology.c
index 4d0ed8f..d8cdc0e 100644
--- a/plat/qti/msm8916/msm8916_topology.c
+++ b/plat/qti/msm8916/msm8916_topology.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2022, Stephan Gerhold <stephan@gerhold.net>
  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -9,24 +10,27 @@
 
 #include <platform_def.h>
 
-static const unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = {
+static const unsigned char plat_power_domain_tree_desc[] = {
 	PLATFORM_SYSTEM_COUNT,
 	PLATFORM_CLUSTER_COUNT,
-	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	PLATFORM_CPUS_PER_CLUSTER,
+#if PLATFORM_CLUSTER_COUNT > 1
+	PLATFORM_CPUS_PER_CLUSTER,
+#endif
 };
 
 int plat_core_pos_by_mpidr(u_register_t mpidr)
 {
+	unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
 	unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
 
 	if (MPIDR_AFFLVL3_VAL(mpidr) > 0 ||
 	    MPIDR_AFFLVL2_VAL(mpidr) > 0 ||
-	    MPIDR_AFFLVL1_VAL(mpidr) > 0 ||
-	    core >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+	    cluster >= PLATFORM_CLUSTER_COUNT ||
+	    core >= PLATFORM_CPUS_PER_CLUSTER) {
 		return -1;
 	}
-
-	return core;
+	return core | (cluster << PLATFORM_CPU_PER_CLUSTER_SHIFT);
 }
 
 const unsigned char *plat_get_power_domain_tree_desc(void)
diff --git a/plat/qti/msm8916/platform.mk b/plat/qti/msm8916/platform.mk
index 7e698fb..c71ad94 100644
--- a/plat/qti/msm8916/platform.mk
+++ b/plat/qti/msm8916/platform.mk
@@ -17,7 +17,9 @@
 				plat/qti/msm8916/${ARCH}/msm8916_helpers.S	\
 				plat/qti/msm8916/${ARCH}/uartdm_console.S
 
-MSM8916_PM_SOURCES	:=	lib/cpus/${ARCH}/cortex_a53.S			\
+MSM8916_CPU		:=	$(if ${ARM_CORTEX_A7},cortex_a7,cortex_a53)
+MSM8916_PM_SOURCES	:=	drivers/arm/cci/cci.c				\
+				lib/cpus/${ARCH}/${MSM8916_CPU}.S		\
 				plat/common/plat_psci_common.c			\
 				plat/qti/msm8916/msm8916_config.c		\
 				plat/qti/msm8916/msm8916_cpu_boot.c		\
@@ -48,11 +50,14 @@
 ENABLE_SPE_FOR_NS		:= 0
 ENABLE_SVE_FOR_NS		:= 0
 
-# Disable workarounds unnecessary for Cortex-A53
+# Disable workarounds unnecessary for Cortex-A7/A53
 WORKAROUND_CVE_2017_5715	:= 0
 WORKAROUND_CVE_2022_23960	:= 0
 
-# MSM8916 uses ARM Cortex-A53 r0p0 so likely all the errata apply
+ifeq (${MSM8916_CPU},cortex_a53)
+# The Cortex-A53 revision varies depending on the SoC revision.
+# msm8916 uses r0p0, msm8939 uses r0p1 or r0p4. Enable all errata
+# and rely on the runtime detection to apply them only if needed.
 ERRATA_A53_819472		:= 1
 ERRATA_A53_824069		:= 1
 ERRATA_A53_826319		:= 1
@@ -60,8 +65,9 @@
 ERRATA_A53_835769		:= 1
 ERRATA_A53_836870		:= 1
 ERRATA_A53_843419		:= 1
-ERRATA_A53_855873		:= 0	# Workaround works only for >= r0p3
+ERRATA_A53_855873		:= 1
 ERRATA_A53_1530924		:= 1
+endif
 
 # Build config flags
 # ------------------
@@ -69,11 +75,14 @@
 PRELOADED_BL33_BASE		?= 0x8f600000
 
 ifeq (${ARCH},aarch64)
-BL32_BASE			?= BL31_LIMIT
-$(eval $(call add_define,BL31_BASE))
+    BL32_BASE			?= BL31_LIMIT
+    $(eval $(call add_define,BL31_BASE))
 else
-# There is no BL31 on aarch32, so reuse its location for BL32
-BL32_BASE			?= $(BL31_BASE)
+    ifeq (${AARCH32_SP},none)
+	$(error Variable AARCH32_SP has to be set for AArch32)
+    endif
+    # There is no BL31 on aarch32, so reuse its location for BL32
+    BL32_BASE			?= $(BL31_BASE)
 endif
 $(eval $(call add_define,BL32_BASE))
 
diff --git a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
index 78ab0c7..3c93305 100644
--- a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
+++ b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
@@ -27,6 +27,7 @@
 				  u_register_t arg2, u_register_t arg3)
 {
 	msm8916_early_platform_setup();
+	msm8916_configure_early();
 }
 
 void sp_min_plat_arch_setup(void)
diff --git a/plat/qti/msm8939/platform.mk b/plat/qti/msm8939/platform.mk
new file mode 100644
index 0000000..9bf6d4d
--- /dev/null
+++ b/plat/qti/msm8939/platform.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Cache cannot be enabled early on MSM8939 because the CCI-400 must be
+# enabled before the CPUs in both clusters become cache-coherent.
+override WARMBOOT_ENABLE_DCACHE_EARLY := 0
+
+include plat/qti/msm8916/platform.mk
diff --git a/plat/qti/msm8939/sp_min/sp_min-msm8939.mk b/plat/qti/msm8939/sp_min/sp_min-msm8939.mk
new file mode 100644
index 0000000..28a6f01
--- /dev/null
+++ b/plat/qti/msm8939/sp_min/sp_min-msm8939.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qti/msm8916/sp_min/sp_min-msm8916.mk
diff --git a/plat/qti/msm8939/tsp/tsp-msm8939.mk b/plat/qti/msm8939/tsp/tsp-msm8939.mk
new file mode 100644
index 0000000..4eefc64
--- /dev/null
+++ b/plat/qti/msm8939/tsp/tsp-msm8939.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qti/msm8916/tsp/tsp-msm8916.mk
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 9ec4bcd..81ee93e 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -236,6 +236,56 @@
 	       mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no),
 	       mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no));
 }
+
+static int bl2_create_reserved_memory(void)
+{
+	int ret;
+
+	int fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory");
+	if (fcnlnode < 0) {
+		NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n",
+			fcnlnode);
+		panic();
+	}
+
+	ret = fdt_setprop(fdt, fcnlnode, "ranges", NULL, 0);
+	if (ret < 0) {
+		NOTICE("BL2: Cannot add FCNL ranges prop (ret=%i)\n", ret);
+		panic();
+	}
+
+	ret = fdt_setprop_u32(fdt, fcnlnode, "#address-cells", 2);
+	if (ret < 0) {
+		NOTICE("BL2: Cannot add FCNL #address-cells prop (ret=%i)\n", ret);
+		panic();
+	}
+
+	ret = fdt_setprop_u32(fdt, fcnlnode, "#size-cells", 2);
+	if (ret < 0) {
+		NOTICE("BL2: Cannot add FCNL #size-cells prop (ret=%i)\n", ret);
+		panic();
+	}
+
+	return fcnlnode;
+}
+
+static void bl2_create_fcnl_reserved_memory(void)
+{
+	int fcnlnode;
+
+	NOTICE("BL2: Lossy Decomp areas\n");
+
+	fcnlnode = bl2_create_reserved_memory();
+
+	bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0,
+			  LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode);
+	bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1,
+			  LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode);
+	bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2,
+			  LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode);
+}
+#else
+static void bl2_create_fcnl_reserved_memory(void) {}
 #endif
 
 void bl2_plat_flush_bl31_params(void)
@@ -820,9 +870,6 @@
 #else
 	const char *boot_hyper160 = "HyperFlash(160MHz)";
 #endif
-#if (RCAR_LOSSY_ENABLE == 1)
-	int fcnlnode;
-#endif
 
 	bl2_init_generic_timer();
 
@@ -1099,23 +1146,8 @@
 		reg &= ~((uint32_t) 1 << 12);
 		mmio_write_32(CPG_PLL0CR, reg);
 	}
-#if (RCAR_LOSSY_ENABLE == 1)
-	NOTICE("BL2: Lossy Decomp areas\n");
 
-	fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory");
-	if (fcnlnode < 0) {
-		NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n",
-			fcnlnode);
-		panic();
-	}
-
-	bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0,
-			  LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode);
-	bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1,
-			  LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode);
-	bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2,
-			  LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode);
-#endif
+	bl2_create_fcnl_reserved_memory();
 
 	fdt_pack(fdt);
 	NOTICE("BL2: FDT at %p\n", fdt);
diff --git a/plat/rockchip/rk3288/platform.mk b/plat/rockchip/rk3288/platform.mk
index b8dd195..e6f78cf 100644
--- a/plat/rockchip/rk3288/platform.mk
+++ b/plat/rockchip/rk3288/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -67,3 +67,7 @@
 ENABLE_SVE_FOR_NS	:=	0
 
 WORKAROUND_CVE_2017_5715	:=	0
+
+ifeq (${AARCH32_SP}, none)
+    $(error Variable AARCH32_SP has to be set for AArch32)
+endif
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index c935b7d..5b0a171 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -222,7 +222,7 @@
 static void boot_mmc(enum mmc_device_type mmc_dev_type,
 		     uint16_t boot_interface_instance)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 	struct stm32_sdmmc2_params params;
 
 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
@@ -294,7 +294,7 @@
 #if STM32MP_SPI_NOR
 static void boot_spi_nor(boot_api_context_t *boot_context)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 
 	io_result = stm32_qspi_init();
 	assert(io_result == 0);
@@ -313,7 +313,7 @@
 #if STM32MP_RAW_NAND
 static void boot_fmc2_nand(boot_api_context_t *boot_context)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 
 	io_result = stm32_fmc2_init();
 	assert(io_result == 0);
@@ -332,7 +332,7 @@
 #if STM32MP_SPI_NAND
 static void boot_spi_nand(boot_api_context_t *boot_context)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 
 	io_result = stm32_qspi_init();
 	assert(io_result == 0);
@@ -351,7 +351,7 @@
 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
 static void mmap_io_setup(void)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 
 	io_result = register_io_dev_memmap(&memmap_dev_con);
 	assert(io_result == 0);
@@ -364,7 +364,7 @@
 #if STM32MP_UART_PROGRAMMER
 static void stm32cubeprogrammer_uart(void)
 {
-	int ret __unused;
+	int ret __maybe_unused;
 	boot_api_context_t *boot_context =
 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
 	uintptr_t uart_base;
@@ -378,7 +378,7 @@
 #if STM32MP_USB_PROGRAMMER
 static void stm32cubeprogrammer_usb(void)
 {
-	int ret __unused;
+	int ret __maybe_unused;
 	struct usb_handle *pdev;
 
 	/* Init USB on platform */
@@ -390,10 +390,9 @@
 #endif
 #endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
 
-
 void stm32mp_io_setup(void)
 {
-	int io_result __unused;
+	int io_result __maybe_unused;
 	boot_api_context_t *boot_context =
 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
 
@@ -473,7 +472,7 @@
 
 int bl2_plat_handle_pre_image_load(unsigned int image_id)
 {
-	static bool gpt_init_done __unused;
+	static bool gpt_init_done __maybe_unused;
 	uint16_t boot_itf = stm32mp_get_boot_itf_selected();
 
 	switch (boot_itf) {
@@ -516,6 +515,7 @@
 			gpt_init_done = true;
 		} else {
 			bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
 			assert(bl_mem_params != NULL);
 
 			mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
@@ -538,7 +538,14 @@
 
 #if STM32MP_SPI_NOR
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+/*
+ * With FWU Multi Bank feature enabled, the selection of
+ * the image to boot will be done by fwu_init calling the
+ * platform hook, plat_fwu_set_images_source.
+ */
+#if !PSA_FWU_SUPPORT
 		image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
+#endif
 		break;
 #endif
 
@@ -591,7 +598,7 @@
 	return rc;
 }
 
-#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
 /*
  * In each boot in non-trial mode, we set the BKP register to
  * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
@@ -652,54 +659,108 @@
 {
 	unsigned int i;
 	uint32_t boot_idx;
-	const partition_entry_t *entry;
-	const uuid_t *img_type_uuid, *img_uuid;
+	const partition_entry_t *entry __maybe_unused;
+	const uuid_t *img_type_uuid;
+	const uuid_t *img_uuid __maybe_unused;
 	io_block_spec_t *image_spec;
+	const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
 
 	boot_idx = plat_fwu_get_boot_idx();
 	assert(boot_idx < NR_OF_FW_BANKS);
 
 	for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
 		img_type_uuid = &metadata->img_entry[i].img_type_uuid;
+
+		img_uuid = &metadata->img_entry[i].img_props[boot_idx].img_uuid;
+
 		image_spec = stm32_get_image_spec(img_type_uuid);
 		if (image_spec == NULL) {
 			ERROR("Unable to get image spec for the image in the metadata\n");
 			panic();
 		}
 
-		img_uuid =
-			&metadata->img_entry[i].img_props[boot_idx].img_uuid;
+		switch (boot_itf) {
+#if (STM32MP_SDMMC || STM32MP_EMMC)
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+			entry = get_partition_entry_by_uuid(img_uuid);
+			if (entry == NULL) {
+				ERROR("No partition with the uuid mentioned in metadata\n");
+				panic();
+			}
 
-		entry = get_partition_entry_by_uuid(img_uuid);
-		if (entry == NULL) {
-			ERROR("Unable to find the partition with the uuid mentioned in metadata\n");
+			image_spec->offset = entry->start;
+			image_spec->length = entry->length;
+			break;
+#endif
+#if STM32MP_SPI_NOR
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+			if (guidcmp(img_uuid, &STM32MP_NOR_FIP_A_GUID) == 0) {
+				image_spec->offset = STM32MP_NOR_FIP_A_OFFSET;
+			} else if (guidcmp(img_uuid, &STM32MP_NOR_FIP_B_GUID) == 0) {
+				image_spec->offset = STM32MP_NOR_FIP_B_OFFSET;
+			} else {
+				ERROR("Invalid uuid mentioned in metadata\n");
+				panic();
+			}
+			break;
+#endif
+		default:
 			panic();
+			break;
 		}
-
-		image_spec->offset = entry->start;
-		image_spec->length = entry->length;
 	}
 }
 
 static int plat_set_image_source(unsigned int image_id,
 				 uintptr_t *handle,
-				 uintptr_t *image_spec,
-				 const char *part_name)
+				 uintptr_t *image_spec)
 {
 	struct plat_io_policy *policy;
-	io_block_spec_t *spec;
-	const partition_entry_t *entry = get_partition_entry(part_name);
-
-	if (entry == NULL) {
-		ERROR("Unable to find the %s partition\n", part_name);
-		return -ENOENT;
-	}
+	io_block_spec_t *spec __maybe_unused;
+	const partition_entry_t *entry __maybe_unused;
+	const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
 
 	policy = &policies[image_id];
-
 	spec = (io_block_spec_t *)policy->image_spec;
-	spec->offset = entry->start;
-	spec->length = entry->length;
+
+	switch (boot_itf) {
+#if (STM32MP_SDMMC || STM32MP_EMMC)
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+		partition_init(GPT_IMAGE_ID);
+
+		if (image_id == FWU_METADATA_IMAGE_ID) {
+			entry = get_partition_entry(METADATA_PART_1);
+		} else {
+			entry = get_partition_entry(METADATA_PART_2);
+		}
+
+		if (entry == NULL) {
+			ERROR("Unable to find a metadata partition\n");
+			return -ENOENT;
+		}
+
+		spec->offset = entry->start;
+		spec->length = entry->length;
+		break;
+#endif
+
+#if STM32MP_SPI_NOR
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+		if (image_id == FWU_METADATA_IMAGE_ID) {
+			spec->offset = STM32MP_NOR_METADATA1_OFFSET;
+		} else {
+			spec->offset = STM32MP_NOR_METADATA2_OFFSET;
+		}
+
+		spec->length = sizeof(struct fwu_metadata);
+		break;
+#endif
+	default:
+		panic();
+		break;
+	}
 
 	*image_spec = policy->image_spec;
 	*handle = *policy->dev_handle;
@@ -711,20 +772,9 @@
 				       uintptr_t *handle,
 				       uintptr_t *image_spec)
 {
-	char *part_name;
-
 	assert((image_id == FWU_METADATA_IMAGE_ID) ||
 	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
 
-	partition_init(GPT_IMAGE_ID);
-
-	if (image_id == FWU_METADATA_IMAGE_ID) {
-		part_name = METADATA_PART_1;
-	} else {
-		part_name = METADATA_PART_2;
-	}
-
-	return plat_set_image_source(image_id, handle, image_spec,
-				     part_name);
+	return plat_set_image_source(image_id, handle, image_spec);
 }
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 1a59f0b..5514c09 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,12 +27,12 @@
 };
 #endif
 
-#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
 static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
 
 /* By default, STM32 platforms load images from the FIP */
 struct plat_io_policy policies[MAX_NUMBER_IDS] = {
@@ -58,7 +58,7 @@
 		.check = open_storage
 	},
 #endif
-#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
+#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
 	[FWU_METADATA_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
 		.image_spec = (uintptr_t)&metadata_block_spec,
@@ -71,7 +71,7 @@
 		.img_type_guid = NULL_GUID,
 		.check = open_storage
 	},
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
+#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
 };
 
 #define DEFAULT_UUID_NUMBER	U(7)
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index f5184e7..9695c9b 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -48,6 +48,3 @@
 BL32_SOURCES		+=	plat/st/stm32mp1/services/bsec_svc.c		\
 				plat/st/stm32mp1/services/stm32mp1_svc_setup.c	\
 				plat/st/stm32mp1/stm32mp1_scmi.c
-
-# Arm Archtecture services
-BL32_SOURCES		+=	services/arm_arch_svc/arm_arch_svc_setup.c
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 4098386..fa2d20e 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -128,11 +128,26 @@
  * STM32MP1 RAW partition offset for devices without GPT
  ******************************************************************************/
 #define STM32MP_EMMC_BOOT_FIP_OFFSET	U(0x00040000)
+#if PSA_FWU_SUPPORT
+#define STM32MP_NOR_METADATA1_OFFSET	U(0x00080000)
+#define STM32MP_NOR_METADATA2_OFFSET	U(0x000C0000)
+#define STM32MP_NOR_FIP_A_OFFSET	U(0x00100000)
+#define STM32MP_NOR_FIP_A_GUID		(const struct efi_guid)EFI_GUID(0x4fd84c93,  \
+					0x54ef, 0x463f, 0xa7, 0xef, 0xae, 0x25, 0xff,\
+					0x88, 0x70, 0x87)
+
+#define STM32MP_NOR_FIP_B_OFFSET	U(0x00500000)
+#define STM32MP_NOR_FIP_B_GUID		(const struct efi_guid)EFI_GUID(0x09c54952,  \
+					0xd5bf, 0x45af, 0xac, 0xee, 0x33, 0x53, 0x03,\
+					0x76, 0x6f, 0xb3)
+
+#else /* PSA_FWU_SUPPORT */
 #ifndef STM32MP_NOR_FIP_OFFSET
 #define STM32MP_NOR_FIP_OFFSET		U(0x00080000)
 #endif
 #ifndef STM32MP_NAND_FIP_OFFSET
 #define STM32MP_NAND_FIP_OFFSET		U(0x00200000)
 #endif
+#endif /* PSA_FWU_SUPPORT */
 
 #endif /* STM32MP1_FIP_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c
index 98585dc..625d01a 100644
--- a/plat/st/stm32mp1/stm32mp1_scmi.c
+++ b/plat/st/stm32mp1/stm32mp1_scmi.c
@@ -260,7 +260,8 @@
 }
 
 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
-				    unsigned long *array, size_t *nb_elts)
+				    unsigned long *array, size_t *nb_elts,
+				    uint32_t start_idx)
 {
 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
 
@@ -272,6 +273,10 @@
 		return SCMI_DENIED;
 	}
 
+	if (start_idx > 0) {
+		return SCMI_OUT_OF_RANGE;
+	}
+
 	if (array == NULL) {
 		*nb_elts = 1U;
 	} else if (*nb_elts == 1U) {
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 dacef74..495f0c7 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -413,7 +413,7 @@
 	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, 0,
 				    &req, sizeof(req),
 				    NULL, 0,
 				    &xfer);
@@ -1389,7 +1389,7 @@
 	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+	ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, 0,
 				    &req, sizeof(req),
 				    NULL, 0,
 				    &xfer);
@@ -1623,7 +1623,7 @@
 	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+	ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, 0,
 				    &req, sizeof(req),
 				    NULL, 0,
 				    &xfer);
@@ -1669,7 +1669,7 @@
 	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_ENTER_SLEEP, 0,
 				    &req, sizeof(req),
 				    NULL, 0,
 				    &xfer);
diff --git a/plat/xilinx/common/include/plat_fdt.h b/plat/xilinx/common/include/plat_fdt.h
new file mode 100644
index 0000000..a1ee1e1
--- /dev/null
+++ b/plat/xilinx/common/include/plat_fdt.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef PLAT_FDT_H
+#define PLAT_FDT_H
+
+void prepare_dtb(void);
+
+#endif /* PLAT_FDT_H */
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index d1c5303..5270e13 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -10,34 +10,34 @@
 
 #include <common/bl_common.h>
 
-/* For FSBL handover */
-enum fsbl_handoff {
-	FSBL_HANDOFF_SUCCESS = 0,
-	FSBL_HANDOFF_NO_STRUCT,
-	FSBL_HANDOFF_INVAL_STRUCT,
-	FSBL_HANDOFF_TOO_MANY_PARTS
+/* For Xilinx bootloader XBL handover */
+enum xbl_handoff {
+	XBL_HANDOFF_SUCCESS = 0,
+	XBL_HANDOFF_NO_STRUCT,
+	XBL_HANDOFF_INVAL_STRUCT,
+	XBL_HANDOFF_TOO_MANY_PARTS
 };
 
-#define FSBL_MAX_PARTITIONS		8U
+#define XBL_MAX_PARTITIONS		8U
 
 /* Structure corresponding to each partition entry */
-struct xfsbl_partition {
+struct xbl_partition {
 	uint64_t entry_point;
 	uint64_t flags;
 };
 
 /* Structure for handoff parameters to TrustedFirmware-A (TF-A) */
-struct xfsbl_tfa_handoff_params {
+struct xbl_handoff_params {
 	uint8_t magic[4];
 	uint32_t num_entries;
-	struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
+	struct xbl_partition partition[XBL_MAX_PARTITIONS];
 };
 
-#define TFA_HANDOFF_PARAMS_MAX_SIZE	sizeof(struct xfsbl_tfa_handoff_params)
+#define HANDOFF_PARAMS_MAX_SIZE	 sizeof(struct xbl_handoff_params)
 
-enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
+enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t tfa_handoff_addr);
+					uint64_t handoff_addr);
 
 /* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
 #define JEDEC_XILINX_MFID	U(0x49)
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index b80cf45..72ba107 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -174,9 +174,7 @@
 	PM_CLOCK_GETSTATE,
 	PM_CLOCK_SETDIVIDER,
 	PM_CLOCK_GETDIVIDER,
-	PM_CLOCK_SETRATE,
-	PM_CLOCK_GETRATE,
-	PM_CLOCK_SETPARENT,
+	PM_CLOCK_SETPARENT = 43,
 	PM_CLOCK_GETPARENT,
 	PM_SECURE_IMAGE,
 	/* FPGA PL Readback */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 27fab7f..976abd6 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -9,8 +9,9 @@
 #ifndef PM_IPI_H
 #define PM_IPI_H
 
-#include <plat_ipi.h>
 #include <stddef.h>
+
+#include <plat_ipi.h>
 #include "pm_common.h"
 
 #define IPI_BLOCKING		1
diff --git a/plat/xilinx/common/include/pm_node.h b/plat/xilinx/common/include/pm_node.h
index b6c2d81..46f6bcf 100644
--- a/plat/xilinx/common/include/pm_node.h
+++ b/plat/xilinx/common/include/pm_node.h
@@ -188,54 +188,54 @@
 	XPM_NODEIDX_DEV_GT_10 = 0x53,
 
 #if defined(PLAT_versal_net)
-	XPM_NODEIDX_DEV_ACPU_0_0 = 0x54,
-	XPM_NODEIDX_DEV_ACPU_0_1 = 0x55,
-	XPM_NODEIDX_DEV_ACPU_0_2 = 0x56,
-	XPM_NODEIDX_DEV_ACPU_0_3 = 0x57,
-	XPM_NODEIDX_DEV_ACPU_1_0 = 0x58,
-	XPM_NODEIDX_DEV_ACPU_1_1 = 0x59,
-	XPM_NODEIDX_DEV_ACPU_1_2 = 0x5A,
-	XPM_NODEIDX_DEV_ACPU_1_3 = 0x5B,
-	XPM_NODEIDX_DEV_ACPU_2_0 = 0x5C,
-	XPM_NODEIDX_DEV_ACPU_2_1 = 0x5D,
-	XPM_NODEIDX_DEV_ACPU_2_2 = 0x5E,
-	XPM_NODEIDX_DEV_ACPU_2_3 = 0x5F,
-	XPM_NODEIDX_DEV_ACPU_3_0 = 0x60,
-	XPM_NODEIDX_DEV_ACPU_3_1 = 0x61,
-	XPM_NODEIDX_DEV_ACPU_3_2 = 0x62,
-	XPM_NODEIDX_DEV_ACPU_3_3 = 0x63,
-	XPM_NODEIDX_DEV_RPU_A_0 = 0x64,
-	XPM_NODEIDX_DEV_RPU_A_1 = 0x65,
-	XPM_NODEIDX_DEV_RPU_B_0 = 0x66,
-	XPM_NODEIDX_DEV_RPU_B_1 = 0x67,
-	XPM_NODEIDX_DEV_OCM_0_0 = 0x68,
-	XPM_NODEIDX_DEV_OCM_0_1 = 0x69,
-	XPM_NODEIDX_DEV_OCM_0_2 = 0x6A,
-	XPM_NODEIDX_DEV_OCM_0_3 = 0x6B,
-	XPM_NODEIDX_DEV_OCM_1_0 = 0x6C,
-	XPM_NODEIDX_DEV_OCM_1_1 = 0x6D,
-	XPM_NODEIDX_DEV_OCM_1_2 = 0x6E,
-	XPM_NODEIDX_DEV_OCM_1_3 = 0x6F,
-	XPM_NODEIDX_DEV_TCM_A_0A = 0x70,
-	XPM_NODEIDX_DEV_TCM_A_0B = 0x71,
-	XPM_NODEIDX_DEV_TCM_A_0C = 0x72,
-	XPM_NODEIDX_DEV_TCM_A_1A = 0x73,
-	XPM_NODEIDX_DEV_TCM_A_1B = 0x74,
-	XPM_NODEIDX_DEV_TCM_A_1C = 0x75,
-	XPM_NODEIDX_DEV_TCM_B_0A = 0x76,
-	XPM_NODEIDX_DEV_TCM_B_0B = 0x77,
-	XPM_NODEIDX_DEV_TCM_B_0C = 0x78,
-	XPM_NODEIDX_DEV_TCM_B_1A = 0x79,
-	XPM_NODEIDX_DEV_TCM_B_1B = 0x7A,
-	XPM_NODEIDX_DEV_TCM_B_1C = 0x7B,
-	XPM_NODEIDX_DEV_USB_1 = 0x7C,
-	XPM_NODEIDX_DEV_PMC_WWDT = 0x7D,
-	XPM_NODEIDX_DEV_LPD_SWDT_0 = 0x7E,
-	XPM_NODEIDX_DEV_LPD_SWDT_1 = 0x7F,
-	XPM_NODEIDX_DEV_FPD_SWDT_0 = 0x80,
-	XPM_NODEIDX_DEV_FPD_SWDT_1 = 0x81,
-	XPM_NODEIDX_DEV_FPD_SWDT_2 = 0x82,
-	XPM_NODEIDX_DEV_FPD_SWDT_3 = 0x83,
+	XPM_NODEIDX_DEV_ACPU_0_0 = 0xAF,
+	XPM_NODEIDX_DEV_ACPU_0_1 = 0xB0,
+	XPM_NODEIDX_DEV_ACPU_0_2 = 0xB1,
+	XPM_NODEIDX_DEV_ACPU_0_3 = 0xB2,
+	XPM_NODEIDX_DEV_ACPU_1_0 = 0xB3,
+	XPM_NODEIDX_DEV_ACPU_1_1 = 0xB4,
+	XPM_NODEIDX_DEV_ACPU_1_2 = 0xB5,
+	XPM_NODEIDX_DEV_ACPU_1_3 = 0xB6,
+	XPM_NODEIDX_DEV_ACPU_2_0 = 0xB7,
+	XPM_NODEIDX_DEV_ACPU_2_1 = 0xB8,
+	XPM_NODEIDX_DEV_ACPU_2_2 = 0xB9,
+	XPM_NODEIDX_DEV_ACPU_2_3 = 0xBA,
+	XPM_NODEIDX_DEV_ACPU_3_0 = 0xBB,
+	XPM_NODEIDX_DEV_ACPU_3_1 = 0xBC,
+	XPM_NODEIDX_DEV_ACPU_3_2 = 0xBD,
+	XPM_NODEIDX_DEV_ACPU_3_3 = 0xBE,
+	XPM_NODEIDX_DEV_RPU_A_0 = 0xBF,
+	XPM_NODEIDX_DEV_RPU_A_1 = 0xC0,
+	XPM_NODEIDX_DEV_RPU_B_0 = 0xC1,
+	XPM_NODEIDX_DEV_RPU_B_1 = 0xC2,
+	XPM_NODEIDX_DEV_OCM_0_0 = 0xC3,
+	XPM_NODEIDX_DEV_OCM_0_1 = 0xC4,
+	XPM_NODEIDX_DEV_OCM_0_2 = 0xC5,
+	XPM_NODEIDX_DEV_OCM_0_3 = 0xC6,
+	XPM_NODEIDX_DEV_OCM_1_0 = 0xC7,
+	XPM_NODEIDX_DEV_OCM_1_1 = 0xC8,
+	XPM_NODEIDX_DEV_OCM_1_2 = 0xC9,
+	XPM_NODEIDX_DEV_OCM_1_3 = 0xCA,
+	XPM_NODEIDX_DEV_TCM_A_0A = 0xCB,
+	XPM_NODEIDX_DEV_TCM_A_0B = 0xCC,
+	XPM_NODEIDX_DEV_TCM_A_0C = 0xCD,
+	XPM_NODEIDX_DEV_TCM_A_1A = 0xCE,
+	XPM_NODEIDX_DEV_TCM_A_1B = 0xCF,
+	XPM_NODEIDX_DEV_TCM_A_1C = 0xD0,
+	XPM_NODEIDX_DEV_TCM_B_0A = 0xD1,
+	XPM_NODEIDX_DEV_TCM_B_0B = 0xD2,
+	XPM_NODEIDX_DEV_TCM_B_0C = 0xD3,
+	XPM_NODEIDX_DEV_TCM_B_1A = 0xD4,
+	XPM_NODEIDX_DEV_TCM_B_1B = 0xD5,
+	XPM_NODEIDX_DEV_TCM_B_1C = 0xD6,
+	XPM_NODEIDX_DEV_USB_1 = 0xD7,
+	XPM_NODEIDX_DEV_PMC_WWDT = 0xD8,
+	XPM_NODEIDX_DEV_LPD_SWDT_0 = 0xD9,
+	XPM_NODEIDX_DEV_LPD_SWDT_1 = 0xDA,
+	XPM_NODEIDX_DEV_FPD_SWDT_0 = 0xDB,
+	XPM_NODEIDX_DEV_FPD_SWDT_1 = 0xDC,
+	XPM_NODEIDX_DEV_FPD_SWDT_2 = 0xDD,
+	XPM_NODEIDX_DEV_FPD_SWDT_3 = 0xDE,
 #endif
 	XPM_NODEIDX_DEV_MAX,
 };
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 1a27bdf..4cf7727 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -10,6 +10,26 @@
 
 #include <pm_common.h>
 
+/******************************************************************************/
+/**
+ * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
+ *			     avoid glitches which can skip a function call
+ *			     and cause altering of the code flow in security
+ *			     critical functions.
+ * @status: Variable which holds the return value of function executed
+ * @status_tmp: Variable which holds the return value of redundant function
+ *		call executed
+ * @function: Function to be executed
+ *
+ * Return: None
+ *
+ ******************************************************************************/
+#define SECURE_REDUNDANT_CALL(status, status_tmp, function, ...)   \
+	{ \
+		status = function(__VA_ARGS__); \
+		status_tmp = function(__VA_ARGS__); \
+	}
+
 int32_t pm_setup(void);
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle,
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 6c060d5..434cd88 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -18,11 +18,10 @@
 #include <lib/mmio.h>
 
 #include <ipi.h>
+#include "ipi_mailbox_svc.h"
 #include <plat_ipi.h>
 #include <plat_private.h>
 
-#include "ipi_mailbox_svc.h"
-
 /*********************************************************************
  * Macros definitions
  ********************************************************************/
diff --git a/plat/xilinx/common/plat_fdt.c b/plat/xilinx/common/plat_fdt.c
new file mode 100644
index 0000000..012aaa6
--- /dev/null
+++ b/plat/xilinx/common/plat_fdt.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+
+#include <plat_fdt.h>
+#include <platform_def.h>
+
+void prepare_dtb(void)
+{
+	void *dtb;
+	int ret;
+#if !defined(XILINX_OF_BOARD_DTB_ADDR)
+	return;
+#else
+	dtb = (void *)XILINX_OF_BOARD_DTB_ADDR;
+#endif
+	if (IS_TFA_IN_OCM(BL31_BASE))
+		return;
+
+	/* Return if no device tree is detected */
+	if (fdt_check_header(dtb) != 0) {
+		NOTICE("Can't read DT at %p\n", dtb);
+		return;
+	}
+
+	ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
+	if (ret < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
+		return;
+	}
+
+	/* Reserve memory used by Trusted Firmware. */
+	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE, BL31_LIMIT - BL31_BASE)) {
+		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
+		return;
+	}
+
+	ret = fdt_pack(dtb);
+	if (ret < 0) {
+		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
+		return;
+	}
+
+	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
+	INFO("Changed device tree to advertise PSCI and reserved memories.\n");
+}
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index d034e00..5beb765 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -15,7 +15,7 @@
 
 
 /*
- * TFAHandoffParams
+ * HandoffParams
  * Parameter		bitfield	encoding
  * -----------------------------------------------------------------------------
  * Exec State		0		0 -> Aarch64, 1-> Aarch32
@@ -23,94 +23,104 @@
  * secure (TZ)		2		0 -> Non secure, 1 -> secure
  * EL			3:4		00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
  * CPU#			5:6		00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
+ * Reserved		7:10		Reserved
+ * Cluster#		11:12		00 -> Cluster 0, 01 -> Cluster 1, 10 -> Cluster 2,
+ *					11 -> Cluster (Applicable for Versal NET only).
+ * Reserved		13:16		Reserved
  */
 
-#define FSBL_FLAGS_ESTATE_SHIFT		0U
-#define FSBL_FLAGS_ESTATE_MASK		(1U << FSBL_FLAGS_ESTATE_SHIFT)
-#define FSBL_FLAGS_ESTATE_A64		0U
-#define FSBL_FLAGS_ESTATE_A32		1U
+#define XBL_FLAGS_ESTATE_SHIFT		0U
+#define XBL_FLAGS_ESTATE_MASK		(1U << XBL_FLAGS_ESTATE_SHIFT)
+#define XBL_FLAGS_ESTATE_A64		0U
+#define XBL_FLAGS_ESTATE_A32		1U
 
-#define FSBL_FLAGS_ENDIAN_SHIFT		1U
-#define FSBL_FLAGS_ENDIAN_MASK		(1U << FSBL_FLAGS_ENDIAN_SHIFT)
-#define FSBL_FLAGS_ENDIAN_LE		0U
-#define FSBL_FLAGS_ENDIAN_BE		1U
+#define XBL_FLAGS_ENDIAN_SHIFT		1U
+#define XBL_FLAGS_ENDIAN_MASK		(1U << XBL_FLAGS_ENDIAN_SHIFT)
+#define XBL_FLAGS_ENDIAN_LE		0U
+#define XBL_FLAGS_ENDIAN_BE		1U
 
-#define FSBL_FLAGS_TZ_SHIFT		2U
-#define FSBL_FLAGS_TZ_MASK		(1U << FSBL_FLAGS_TZ_SHIFT)
-#define FSBL_FLAGS_NON_SECURE		0U
-#define FSBL_FLAGS_SECURE		1U
+#define XBL_FLAGS_TZ_SHIFT		2U
+#define XBL_FLAGS_TZ_MASK		(1U << XBL_FLAGS_TZ_SHIFT)
+#define XBL_FLAGS_NON_SECURE		0U
+#define XBL_FLAGS_SECURE		1U
 
-#define FSBL_FLAGS_EL_SHIFT		3U
-#define FSBL_FLAGS_EL_MASK		(3U << FSBL_FLAGS_EL_SHIFT)
-#define FSBL_FLAGS_EL0			0U
-#define FSBL_FLAGS_EL1			1U
-#define FSBL_FLAGS_EL2			2U
-#define FSBL_FLAGS_EL3			3U
+#define XBL_FLAGS_EL_SHIFT		3U
+#define XBL_FLAGS_EL_MASK		(3U << XBL_FLAGS_EL_SHIFT)
+#define XBL_FLAGS_EL0			0U
+#define XBL_FLAGS_EL1			1U
+#define XBL_FLAGS_EL2			2U
+#define XBL_FLAGS_EL3			3U
 
-#define FSBL_FLAGS_CPU_SHIFT		5U
-#define FSBL_FLAGS_CPU_MASK		(3U << FSBL_FLAGS_CPU_SHIFT)
-#define FSBL_FLAGS_A53_0		0U
-#define FSBL_FLAGS_A53_1		1U
-#define FSBL_FLAGS_A53_2		2U
-#define FSBL_FLAGS_A53_3		3U
+#define XBL_FLAGS_CPU_SHIFT		5U
+#define XBL_FLAGS_CPU_MASK		(3U << XBL_FLAGS_CPU_SHIFT)
+#define XBL_FLAGS_A53_0		0U
+#define XBL_FLAGS_A53_1		1U
+#define XBL_FLAGS_A53_2		2U
+#define XBL_FLAGS_A53_3		3U
+
+#if defined(PLAT_versal_net)
+#define XBL_FLAGS_CLUSTER_SHIFT		11U
+#define XBL_FLAGS_CLUSTER_MASK		GENMASK(11, 12)
+
+#define XBL_FLAGS_CLUSTER_0		0U
+#endif /* PLAT_versal_net */
 
 /**
- * get_fsbl_cpu() - Get the target CPU for partition.
+ * get_xbl_cpu() - Get the target CPU for partition.
  * @partition: Pointer to partition struct.
  *
- * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or
- *         FSBL_FLAGS_A53_3.
+ * Return: XBL_FLAGS_A53_0, XBL_FLAGS_A53_1, XBL_FLAGS_A53_2 or XBL_FLAGS_A53_3.
  *
  */
-static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
+static int32_t get_xbl_cpu(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_CPU_MASK;
 
-	return flags >> FSBL_FLAGS_CPU_SHIFT;
+	return flags >> XBL_FLAGS_CPU_SHIFT;
 }
 
 /**
- * get_fsbl_el() - Get the target exception level for partition.
+ * get_xbl_el() - Get the target exception level for partition.
  * @partition: Pointer to partition struct.
  *
- * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3.
+ * Return: XBL_FLAGS_EL0, XBL_FLAGS_EL1, XBL_FLAGS_EL2 or XBL_FLAGS_EL3.
  *
  */
-static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
+static int32_t get_xbl_el(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_EL_MASK;
 
-	return flags >> FSBL_FLAGS_EL_SHIFT;
+	return flags >> XBL_FLAGS_EL_SHIFT;
 }
 
 /**
- * get_fsbl_ss() - Get the target security state for partition.
+ * get_xbl_ss() - Get the target security state for partition.
  * @partition: Pointer to partition struct.
  *
- * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE.
+ * Return: XBL_FLAGS_NON_SECURE or XBL_FLAGS_SECURE.
  *
  */
-static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
+static int32_t get_xbl_ss(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_TZ_MASK;
 
-	return flags >> FSBL_FLAGS_TZ_SHIFT;
+	return flags >> XBL_FLAGS_TZ_SHIFT;
 }
 
 /**
- * get_fsbl_endian() - Get the target endianness for partition.
+ * get_xbl_endian() - Get the target endianness for partition.
  * @partition: Pointer to partition struct.
  *
  * Return: SPSR_E_LITTLE or SPSR_E_BIG.
  *
  */
-static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
+static int32_t get_xbl_endian(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_ENDIAN_MASK;
 
-	flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
+	flags >>= XBL_FLAGS_ENDIAN_SHIFT;
 
-	if (flags == FSBL_FLAGS_ENDIAN_BE) {
+	if (flags == XBL_FLAGS_ENDIAN_BE) {
 		return SPSR_E_BIG;
 	} else {
 		return SPSR_E_LITTLE;
@@ -118,58 +128,73 @@
 }
 
 /**
- * get_fsbl_estate() - Get the target execution state for partition.
+ * get_xbl_estate() - Get the target execution state for partition.
  * @partition: Pointer to partition struct.
  *
- * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64.
+ * Return: XBL_FLAGS_ESTATE_A32 or XBL_FLAGS_ESTATE_A64.
+ *
+ */
+static int32_t get_xbl_estate(const struct xbl_partition *partition)
+{
+	uint64_t flags = partition->flags & XBL_FLAGS_ESTATE_MASK;
+
+	return flags >> XBL_FLAGS_ESTATE_SHIFT;
+}
+
+#if defined(PLAT_versal_net)
+/**
+ * get_xbl_cluster - Get the cluster number
+ * @partition: pointer to the partition structure.
  *
+ * Return: cluster number for the partition.
  */
-static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
+static int32_t get_xbl_cluster(const struct xbl_partition *partition)
 {
-	uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
+	uint64_t flags = partition->flags & XBL_FLAGS_CLUSTER_MASK;
 
-	return flags >> FSBL_FLAGS_ESTATE_SHIFT;
+	return (int32_t)(flags >> XBL_FLAGS_CLUSTER_SHIFT);
 }
+#endif /* PLAT_versal_net */
 
 /**
- * fsbl_tfa_handover() - Populates the bl32 and bl33 image info structures.
+ * xbl_handover() - Populates the bl32 and bl33 image info structures.
  * @bl32: BL32 image info structure.
  * @bl33: BL33 image info structure.
- * @tfa_handoff_addr: TF-A handoff address.
+ * @handoff_addr: TF-A handoff address.
  *
- * Process the handoff parameters from the FSBL and populate the BL32 and BL33
+ * Process the handoff parameters from the XBL and populate the BL32 and BL33
  * image info structures accordingly.
  *
  * Return: Return the status of the handoff. The value will be from the
- *         fsbl_handoff enum.
+ *         xbl_handoff enum.
  *
  */
-enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
+enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
-					uint64_t tfa_handoff_addr)
+					uint64_t handoff_addr)
 {
-	const struct xfsbl_tfa_handoff_params *TFAHandoffParams;
-	if (!tfa_handoff_addr) {
-		WARN("BL31: No TFA handoff structure passed\n");
-		return FSBL_HANDOFF_NO_STRUCT;
+	const struct xbl_handoff_params *HandoffParams;
+
+	if (!handoff_addr) {
+		WARN("BL31: No handoff structure passed\n");
+		return XBL_HANDOFF_NO_STRUCT;
 	}
 
-	TFAHandoffParams = (struct xfsbl_tfa_handoff_params *)tfa_handoff_addr;
-	if ((TFAHandoffParams->magic[0] != 'X') ||
-	    (TFAHandoffParams->magic[1] != 'L') ||
-	    (TFAHandoffParams->magic[2] != 'N') ||
-	    (TFAHandoffParams->magic[3] != 'X')) {
-		ERROR("BL31: invalid TF-A handoff structure at %" PRIx64 "\n",
-		      tfa_handoff_addr);
-		return FSBL_HANDOFF_INVAL_STRUCT;
+	HandoffParams = (struct xbl_handoff_params *)handoff_addr;
+	if ((HandoffParams->magic[0] != 'X') ||
+	    (HandoffParams->magic[1] != 'L') ||
+	    (HandoffParams->magic[2] != 'N') ||
+	    (HandoffParams->magic[3] != 'X')) {
+		ERROR("BL31: invalid handoff structure at %" PRIx64 "\n", handoff_addr);
+		return XBL_HANDOFF_INVAL_STRUCT;
 	}
 
 	VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
-		tfa_handoff_addr, TFAHandoffParams->num_entries);
-	if (TFAHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
+		handoff_addr, HandoffParams->num_entries);
+	if (HandoffParams->num_entries > XBL_MAX_PARTITIONS) {
 		ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
-		      TFAHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
-		return FSBL_HANDOFF_TOO_MANY_PARTS;
+		      HandoffParams->num_entries, XBL_MAX_PARTITIONS);
+		return XBL_HANDOFF_TOO_MANY_PARTS;
 	}
 
 	/*
@@ -177,43 +202,55 @@
 	 * (bl32, bl33). I.e. the last applicable images in the handoff
 	 * structure will be used for the hand off
 	 */
-	for (size_t i = 0; i < TFAHandoffParams->num_entries; i++) {
+	for (size_t i = 0; i < HandoffParams->num_entries; i++) {
 		entry_point_info_t *image;
 		int32_t target_estate, target_secure, target_cpu;
 		uint32_t target_endianness, target_el;
 
 		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
-			TFAHandoffParams->partition[i].entry_point,
-			TFAHandoffParams->partition[i].flags);
+			HandoffParams->partition[i].entry_point,
+			HandoffParams->partition[i].flags);
+
+#if defined(PLAT_versal_net)
+		uint32_t target_cluster;
 
-		target_cpu = get_fsbl_cpu(&TFAHandoffParams->partition[i]);
-		if (target_cpu != FSBL_FLAGS_A53_0) {
+		target_cluster = get_xbl_cluster(&HandoffParams->partition[i]);
+		if (target_cluster != XBL_FLAGS_CLUSTER_0) {
+			WARN("BL31: invalid target Cluster (%i)\n",
+			     target_cluster);
+			continue;
+		}
+#endif /* PLAT_versal_net */
+
+		target_cpu = get_xbl_cpu(&HandoffParams->partition[i]);
+		if (target_cpu != XBL_FLAGS_A53_0) {
 			WARN("BL31: invalid target CPU (%i)\n", target_cpu);
 			continue;
 		}
 
-		target_el = get_fsbl_el(&TFAHandoffParams->partition[i]);
-		if ((target_el == FSBL_FLAGS_EL3) ||
-		    (target_el == FSBL_FLAGS_EL0)) {
-			WARN("BL31: invalid exception level (%i)\n", target_el);
+		target_el = get_xbl_el(&HandoffParams->partition[i]);
+		if ((target_el == XBL_FLAGS_EL3) ||
+		    (target_el == XBL_FLAGS_EL0)) {
+			WARN("BL31: invalid target exception level(%i)\n",
+			     target_el);
 			continue;
 		}
 
-		target_secure = get_fsbl_ss(&TFAHandoffParams->partition[i]);
-		if (target_secure == FSBL_FLAGS_SECURE &&
-		    target_el == FSBL_FLAGS_EL2) {
+		target_secure = get_xbl_ss(&HandoffParams->partition[i]);
+		if (target_secure == XBL_FLAGS_SECURE &&
+		    target_el == XBL_FLAGS_EL2) {
 			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
 			     target_secure, target_el);
 			continue;
 		}
 
-		target_estate = get_fsbl_estate(&TFAHandoffParams->partition[i]);
-		target_endianness = get_fsbl_endian(&TFAHandoffParams->partition[i]);
+		target_estate = get_xbl_estate(&HandoffParams->partition[i]);
+		target_endianness = get_xbl_endian(&HandoffParams->partition[i]);
 
-		if (target_secure == FSBL_FLAGS_SECURE) {
+		if (target_secure == XBL_FLAGS_SECURE) {
 			image = bl32;
 
-			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
+			if (target_estate == XBL_FLAGS_ESTATE_A32) {
 				bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
@@ -224,8 +261,8 @@
 		} else {
 			image = bl33;
 
-			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
-				if (target_el == FSBL_FLAGS_EL2) {
+			if (target_estate == XBL_FLAGS_ESTATE_A32) {
+				if (target_el == XBL_FLAGS_EL2) {
 					target_el = MODE32_hyp;
 				} else {
 					target_el = MODE32_sys;
@@ -235,7 +272,7 @@
 							 target_endianness,
 							 DISABLE_ALL_EXCEPTIONS);
 			} else {
-				if (target_el == FSBL_FLAGS_EL2) {
+				if (target_el == XBL_FLAGS_EL2) {
 					target_el = MODE_EL2;
 				} else {
 					target_el = MODE_EL1;
@@ -247,10 +284,10 @@
 		}
 
 		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
-			target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
-			TFAHandoffParams->partition[i].entry_point,
+			target_secure == XBL_FLAGS_SECURE ? "BL32" : "BL33",
+			HandoffParams->partition[i].entry_point,
 			target_el);
-		image->pc = TFAHandoffParams->partition[i].entry_point;
+		image->pc = HandoffParams->partition[i].entry_point;
 
 		if (target_endianness == SPSR_E_BIG) {
 			EP_SET_EE(image->h.attr, EP_EE_BIG);
@@ -259,5 +296,5 @@
 		}
 	}
 
-	return FSBL_HANDOFF_SUCCESS;
+	return XBL_HANDOFF_SUCCESS;
 }
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 5e59559..56567dd 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -11,11 +11,11 @@
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
 #include <ipi.h>
 #include <plat_ipi.h>
 #include <plat_private.h>
-#include <plat/common/platform.h>
-
 #include "pm_defs.h"
 #include "pm_ipi.h"
 
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index bae369e..1e5808c 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -11,15 +11,19 @@
  */
 
 #include <errno.h>
-#include <plat_private.h>
 #include <stdbool.h>
+
+#include "../drivers/arm/gic/v3/gicv3_private.h"
+
 #include <common/runtime_svc.h>
+#include <drivers/arm/gicv3.h>
 #include <plat/common/platform.h>
+
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
-#include <drivers/arm/gicv3.h>
-#include "../drivers/arm/gic/v3/gicv3_private.h"
+#include "pm_svc_main.h"
 
 #define MODE				0x80000000U
 
@@ -396,8 +400,9 @@
 {
 	uintptr_t ret;
 	uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
-	uint32_t security_flag = SECURE_FLAG;
+	uint32_t security_flag = NON_SECURE_FLAG;
 	uint32_t api_id;
+	bool status = false, status_tmp = false;
 
 	/* Handle case where PM wasn't initialized properly */
 	if (pm_up == false) {
@@ -405,11 +410,14 @@
 	}
 
 	/*
-	 * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
-	 * if smc called is non secure
+	 * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as secure (0)
+	 * if smc called is secure
+	 *
+	 * Add redundant macro call to immune the code from glitches
 	 */
-	if (is_caller_non_secure(flags) != 0) {
-		security_flag = NON_SECURE_FLAG;
+	SECURE_REDUNDANT_CALL(status, status_tmp, is_caller_secure, flags);
+	if ((status != false) && (status_tmp != false)) {
+		security_flag = SECURE_FLAG;
 	}
 
 	pm_arg[0] = (uint32_t)x1;
diff --git a/plat/xilinx/versal/aarch64/versal_helpers.S b/plat/xilinx/versal/aarch64/versal_helpers.S
index 30bbfb4..350ddc4 100644
--- a/plat/xilinx/versal/aarch64/versal_helpers.S
+++ b/plat/xilinx/versal/aarch64/versal_helpers.S
@@ -4,9 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <drivers/arm/gicv3.h>
+
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index e5e095a..6cb529b 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -8,8 +8,7 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <plat_arm.h>
-#include <plat_private.h>
+
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -19,12 +18,15 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
-#include <versal_def.h>
+#include <plat_arm.h>
+
+#include <plat_fdt.h>
 #include <plat_private.h>
 #include <plat_startup.h>
-#include <pm_ipi.h>
-#include "pm_client.h"
 #include "pm_api_sys.h"
+#include "pm_client.h"
+#include <pm_ipi.h>
+#include <versal_def.h>
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -68,9 +70,9 @@
 				u_register_t arg2, u_register_t arg3)
 {
 	uint64_t tfa_handoff_addr;
-	uint32_t payload[PAYLOAD_ARG_CNT], max_size = TFA_HANDOFF_PARAMS_MAX_SIZE;
+	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
-	uint64_t addr[TFA_HANDOFF_PARAMS_MAX_SIZE];
+	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
 	if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
 		static console_t versal_runtime_console;
@@ -125,14 +127,14 @@
 		tfa_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4);
 	}
 
-	enum fsbl_handoff ret = fsbl_tfa_handover(&bl32_image_ep_info,
+	enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 						  &bl33_image_ep_info,
 						  tfa_handoff_addr);
-	if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) {
+	if (ret == XBL_HANDOFF_NO_STRUCT || ret == XBL_HANDOFF_INVAL_STRUCT) {
 		bl31_set_default_config();
-	} else if (ret == FSBL_HANDOFF_TOO_MANY_PARTS) {
+	} else if (ret == XBL_HANDOFF_TOO_MANY_PARTS) {
 		ERROR("BL31: Error too many partitions %u\n", ret);
-	} else if (ret != FSBL_HANDOFF_SUCCESS) {
+	} else if (ret != XBL_HANDOFF_SUCCESS) {
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
@@ -190,8 +192,11 @@
 
 	return 0;
 }
+
 void bl31_platform_setup(void)
 {
+	prepare_dtb();
+
 	/* Initialize the gic cpu and distributor interfaces */
 	plat_versal_gic_driver_init();
 	plat_versal_gic_init();
@@ -219,6 +224,10 @@
 	plat_arm_interconnect_enter_coherency();
 
 	const mmap_region_t bl_regions[] = {
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+		MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
+				MT_MEMORY | MT_RW | MT_NS),
+#endif
 		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
 			MT_MEMORY | MT_RW | MT_SECURE),
 		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
diff --git a/plat/xilinx/versal/include/plat_ipi.h b/plat/xilinx/versal/include/plat_ipi.h
index e4922e4..4f7cb5f 100644
--- a/plat/xilinx/versal/include/plat_ipi.h
+++ b/plat/xilinx/versal/include/plat_ipi.h
@@ -10,9 +10,10 @@
 #ifndef PLAT_IPI_H
 #define PLAT_IPI_H
 
-#include <ipi.h>
 #include <stdint.h>
 
+#include <ipi.h>
+
 /*********************************************************************
  * IPI agent IDs macros
  ********************************************************************/
diff --git a/plat/xilinx/versal/include/plat_pm_common.h b/plat/xilinx/versal/include/plat_pm_common.h
index 4c057b8..0b4a115 100644
--- a/plat/xilinx/versal/include/plat_pm_common.h
+++ b/plat/xilinx/versal/include/plat_pm_common.h
@@ -12,8 +12,10 @@
 #ifndef PLAT_PM_COMMON_H
 #define PLAT_PM_COMMON_H
 
-#include <common/debug.h>
 #include <stdint.h>
+
+#include <common/debug.h>
+
 #include "pm_defs.h"
 
 #define NON_SECURE_FLAG		1U
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index b3f6aca..48f64ea 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -9,8 +9,8 @@
 #ifndef PLAT_PRIVATE_H
 #define PLAT_PRIVATE_H
 
-#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 typedef struct versal_intr_info_type_el3 {
 	uint32_t id;
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 6c1d8b6..4c02402 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -76,8 +76,29 @@
  ******************************************************************************/
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+
+#define PLAT_OCM_BASE			U(0xFFFE0000)
+#define PLAT_OCM_LIMIT			U(0xFFFFFFFF)
+
+#define IS_TFA_IN_OCM(x)	((x >= PLAT_OCM_BASE) && (x < PLAT_OCM_LIMIT))
+
+#ifndef MAX_MMAP_REGIONS
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+#define MAX_MMAP_REGIONS		9
+#else
 #define MAX_MMAP_REGIONS		8
-#define MAX_XLAT_TABLES			5
+#endif
+#endif
+
+#ifndef MAX_XLAT_TABLES
+#if !IS_TFA_IN_OCM(BL31_BASE)
+#define MAX_XLAT_TABLES		9
+#else
+#define MAX_XLAT_TABLES		5
+#endif
+#endif
 
 #define CACHE_WRITEBACK_SHIFT	6
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 1bc30f1..56d98f7 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -6,17 +6,18 @@
  */
 
 #include <assert.h>
-#include <plat_arm.h>
-#include <plat_private.h>
-#include <pm_common.h>
+
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
-#include <plat/common/platform.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
 
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
+#include <pm_common.h>
 
 static uintptr_t versal_sec_entry;
 
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index e561048..ba17b1d 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -4,9 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 0b6aea0..c936220 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -45,12 +45,17 @@
 VERSAL_PLATFORM ?= silicon
 $(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM}))
 
+ifdef XILINX_OF_BOARD_DTB_ADDR
+$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
+endif
+
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/common/ipi_mailbox_service/	\
 				-Iplat/xilinx/versal/include/			\
 				-Iplat/xilinx/versal/pm_service/
 
+include lib/libfdt/libfdt.mk
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 include lib/xlat_tables_v2/xlat_tables.mk
@@ -80,6 +85,7 @@
 				lib/cpus/aarch64/cortex_a72.S			\
 				plat/common/plat_psci_common.c			\
 				plat/xilinx/common/ipi.c			\
+				plat/xilinx/common/plat_fdt.c			\
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/pm_service/pm_ipi.c		\
@@ -93,7 +99,9 @@
 				plat/xilinx/versal/sip_svc_setup.c		\
 				plat/xilinx/versal/versal_gicv3.c		\
 				plat/xilinx/versal/versal_ipi.c			\
-				plat/xilinx/versal/pm_service/pm_client.c
+				plat/xilinx/versal/pm_service/pm_client.c	\
+				common/fdt_fixup.c				\
+				${LIBFDT_SRCS}
 
 ifeq ($(HARDEN_SLS_ALL), 1)
 TF_CFLAGS_aarch64      +=      -mharden-sls=all
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 9ad21a1..ccbfe77 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -11,18 +11,20 @@
  */
 
 #include <assert.h>
-#include <plat_ipi.h>
-#include <platform_def.h>
-#include <versal_def.h>
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-#include <drivers/arm/gicv3.h>
-#include <drivers/arm/gic_common.h>
 #include <plat/common/platform.h>
+
+#include <plat_ipi.h>
+#include <platform_def.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_defs.h"
+#include <versal_def.h>
 
 #define UNDEFINED_CPUID		(~0)
 
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 33d3d35..197d047 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -5,14 +5,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
-#include <platform_def.h>
-
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+#include <platform_def.h>
+
+
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv3 driver is initialised and used.
diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c
index 80a2e83..74b082d 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -10,6 +10,7 @@
  */
 
 #include <lib/utils_def.h>
+
 #include <ipi.h>
 #include <plat_ipi.h>
 
@@ -19,7 +20,7 @@
 	[IPI_ID_PMC] = {
 		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
 		.ipi_reg_base = PMC_REG_BASE,
-		.secure_only = 0U,
+		.secure_only = IPI_SECURE_MASK,
 	},
 
 	/* A72 IPI */
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index e1e2317..ccebff2 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -9,6 +9,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <drivers/arm/gicv3.h>
+
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index ae9dfe8..d2b6c7b 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -12,19 +12,20 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
-#include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
 #include <drivers/arm/dcc.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-#include <libfdt.h>
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 
+#include <plat_fdt.h>
 #include <plat_private.h>
 #include <plat_startup.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+#include <pm_ipi.h>
 #include <versal_net_def.h>
 
 static entry_point_info_t bl32_image_ep_info;
@@ -70,6 +71,11 @@
 {
 	uint32_t uart_clock;
 	int32_t rc;
+#if !(TFA_NO_PM)
+	uint64_t tfa_handoff_addr, buff[HANDOFF_PARAMS_MAX_SIZE] = {0};
+	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
+	enum pm_ret_status ret_status;
+#endif /* !(TFA_NO_PM) */
 
 	board_detection();
 
@@ -136,8 +142,32 @@
 	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if !(TFA_NO_PM)
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+			 (uintptr_t)buff >> 32U, (uintptr_t)buff, max_size);
 
+	ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	if (ret_status == PM_RET_SUCCESS) {
+		enum xbl_handoff xbl_ret;
+
+		tfa_handoff_addr = (uintptr_t)&buff;
+
+		xbl_ret = xbl_handover(&bl32_image_ep_info, &bl33_image_ep_info,
+				       tfa_handoff_addr);
+		if (xbl_ret != XBL_HANDOFF_SUCCESS) {
+			ERROR("BL31: PLM to TF-A handover failed %u\n", xbl_ret);
+			panic();
+		}
+
+		INFO("BL31: PLM to TF-A handover success\n");
+	} else {
+		INFO("BL31: setting up default configs\n");
+
+		bl31_set_default_config();
+	}
+#else
 	bl31_set_default_config();
+#endif /* !(TFA_NO_PM) */
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
 	NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
@@ -194,6 +224,8 @@
 
 void bl31_platform_setup(void)
 {
+	prepare_dtb();
+
 	/* Initialize the gic cpu and distributor interfaces */
 	plat_versal_net_gic_driver_init();
 	plat_versal_net_gic_init();
@@ -218,6 +250,10 @@
 void bl31_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+		MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
+				MT_MEMORY | MT_RW | MT_NS),
+#endif
 		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
 			MT_MEMORY | MT_RW | MT_SECURE),
 		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index b256b05..872b6ee 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -84,13 +84,25 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
-#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
-#define MAX_MMAP_REGIONS		U(10)
+
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+
+#define PLAT_OCM_BASE			U(0xBBF00000)
+#define PLAT_OCM_LIMIT			U(0xBC000000)
+
+#define IS_TFA_IN_OCM(x)	((x >= PLAT_OCM_BASE) && (x < PLAT_OCM_LIMIT))
+
+#ifndef MAX_MMAP_REGIONS
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+#define MAX_MMAP_REGIONS		9
 #else
-#define MAX_MMAP_REGIONS		U(9)
+#define MAX_MMAP_REGIONS		8
+#endif
 #endif
 
-#define MAX_XLAT_TABLES			U(8)
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES			U(9)
+#endif
 
 #define CACHE_WRITEBACK_SHIFT	U(6)
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 398ef85..9c4cfa0 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -65,6 +65,10 @@
 
 $(eval $(call add_define_val,VERSAL_NET_CONSOLE,VERSAL_NET_CONSOLE_ID_${VERSAL_NET_CONSOLE}))
 
+ifdef XILINX_OF_BOARD_DTB_ADDR
+$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
+endif
+
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/common/ipi_mailbox_service/	\
@@ -101,7 +105,8 @@
 else
 BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
 endif
-BL31_SOURCES		+=	plat/xilinx/common/plat_startup.c		\
+BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
+				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/versal.c			\
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index d09c927..cff400c 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -16,9 +16,8 @@
 #include <drivers/arm/gicv3.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
-#include <lib/mmio.h>
-#include <lib/utils.h>
 #include <lib/spinlock.h>
+#include <lib/utils.h>
 #include <plat/common/platform.h>
 
 #include <plat_ipi.h>
@@ -322,15 +321,9 @@
 
 	isb();
 
-	/* Clear power down interrupt status before enabling */
-	mmio_write_32(APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id),
-		      APU_PCIL_CORE_X_ISR_POWER_MASK);
 	/* Enable power down interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
 		      APU_PCIL_CORE_X_IEN_POWER_MASK);
-	/* Clear wakeup interrupt status before enabling */
-	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id),
-		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
 	/* Enable wake interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
 		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
@@ -384,9 +377,6 @@
 	/* Disabled power down interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid),
 			APU_PCIL_CORE_X_IDS_POWER_MASK);
-	/* Clear wakeup interrupt status before disabling */
-	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpuid),
-		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
 	/* Disable wake interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
 		      APU_PCIL_CORE_X_IDS_WAKE_MASK);
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
index 0943c62..e8d8fb7 100644
--- a/plat/xilinx/versal_net/versal_net_ipi.c
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -26,7 +26,7 @@
 	[IPI_ID_PMC] = {
 		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
 		.ipi_reg_base = IPI0_REG_BASE,
-		.secure_only = 0,
+		.secure_only = IPI_SECURE_MASK,
 	},
 
 	/* RPU0 IPI */
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 18ccafd..b584031 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -13,11 +13,12 @@
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
+
 #include <plat_ipi.h>
 #include <plat_private.h>
 #include <plat_startup.h>
-#include <plat/common/platform.h>
-#include <services/arm_arch_svc.h>
 
 #include "zynqmp_pm_api_sys.h"
 
@@ -228,20 +229,9 @@
 	size_t i, j, len;
 	const char *name = "EG/EV";
 
-#ifdef IMAGE_BL32
-	/*
-	 * For BL32, get the chip id info directly by reading corresponding
-	 * registers instead of making pm call. This has limitation
-	 * that these registers should be configured to have access
-	 * from APU which is default case.
-	 */
-	chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
-	chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
-#else
 	if (pm_get_chipid(chipid) != PM_RET_SUCCESS) {
 		return "XCZUUNKN";
 	}
-#endif
 
 	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
 			  ZYNQMP_CSU_IDCODE_SVD_MASK);
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index b00513e..56d402f 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -11,20 +11,20 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/dcc.h>
 #include <drivers/console.h>
+#include <lib/mmio.h>
+#include <libfdt.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <lib/mmio.h>
 
 #include <custom_svc.h>
-#include <plat_startup.h>
 #include <plat_private.h>
+#include <plat_startup.h>
 #include <zynqmp_def.h>
 
-#include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
-#include <libfdt.h>
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -112,11 +112,11 @@
 	if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) {
 		bl31_set_default_config();
 	} else {
-		/* use parameters from FSBL */
-		enum fsbl_handoff ret = fsbl_tfa_handover(&bl32_image_ep_info,
+		/* use parameters from XBL */
+		enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 							  &bl33_image_ep_info,
 							  tfa_handoff_addr);
-		if (ret != FSBL_HANDOFF_SUCCESS) {
+		if (ret != XBL_HANDOFF_SUCCESS) {
 			panic();
 		}
 	}
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 7b9f41d..e3a979e 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -4,9 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_private.h>
 #include <plat/common/platform.h>
 
+#include <plat_private.h>
+
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if (mpidr & MPIDR_CLUSTER_MASK) {
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 36fa0f8..9c79855 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -20,7 +20,7 @@
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
 # pncd SPD requires secure SGI to be handled at EL1
-ifeq (${SPD},pncd)
+ifeq (${SPD}, $(filter ${SPD},pncd tspd))
 ifeq (${ZYNQMP_WDT_RESTART},1)
 $(error "Error: ZYNQMP_WDT_RESTART and SPD=pncd are incompatible")
 endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 2041541..9682e59 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2458,7 +2458,7 @@
 	if (clock_id == CLK_MAX) {
 		memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
 					 CLK_NAME_LEN : sizeof(END_OF_CLK));
-	} else if (!pm_clock_valid(clock_id)) {
+	} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
 		memset(name, 0, CLK_NAME_LEN);
 	} else if (clock_id < CLK_MAX_OUTPUT_CLK) {
 		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 1880d9b..e812ad6 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -13,13 +13,13 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
-#include <zynqmp_def.h>
 
 #include "pm_api_clock.h"
 #include "pm_api_ioctl.h"
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
+#include <zynqmp_def.h>
 #include "zynqmp_pm_api_sys.h"
 
 /**
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 8cf29f0..4afa01d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -21,9 +21,9 @@
 #include <lib/utils.h>
 
 #include <plat_ipi.h>
-#include <zynqmp_def.h>
 #include "pm_client.h"
 #include "pm_ipi.h"
+#include <zynqmp_def.h>
 #include "zynqmp_pm_api_sys.h"
 
 #define IRQ_MAX		84U
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 ece5954..0199597 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1321,39 +1321,6 @@
 }
 
 /**
- * pm_clock_setrate - Set the clock rate for given id.
- * @clock_id: Id of the clock.
- * @rate: rate value in hz.
- *
- * This function is used by master to set rate for any clock.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
-				    uint64_t rate)
-{
-	return PM_RET_ERROR_NOTSUPPORTED;
-}
-
-/**
- * pm_clock_getrate - Get the clock rate for given id.
- * @clock_id: Id of the clock.
- * @rate: rate value in hz.
- *
- * This function is used by master to get rate
- * for any clock.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
-				    uint64_t *rate)
-{
-	return PM_RET_ERROR_NOTSUPPORTED;
-}
-
-/**
  * pm_clock_setparent - Set the clock parent for given id.
  * @clock_id: Id of the clock.
  * @parent_index: Index of the parent clock into clock's parents array.
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
index a2597bc..f69a3e7 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
@@ -143,10 +143,6 @@
 				       uint32_t divider);
 enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
 				       uint32_t *divider);
-enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
-				    uint64_t rate);
-enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
-				    uint64_t *rate);
 enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
 				      uint32_t parent_index);
 enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index fc9290c..5a6a9f8 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -12,14 +12,12 @@
 
 #include <errno.h>
 
-#include <common/runtime_svc.h>
-#if ZYNQMP_WDT_RESTART
 #include <arch_helpers.h>
+#include <common/runtime_svc.h>
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/spinlock.h>
 #include <plat/common/platform.h>
-#endif
 
 #include <plat_private.h>
 #include "pm_client.h"
@@ -437,23 +435,6 @@
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
 	}
 
-	case PM_CLOCK_SETRATE:
-		ret = pm_clock_setrate(pm_arg[0],
-		       ((uint64_t)pm_arg[2]) << 32 | pm_arg[1]);
-
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_CLOCK_GETRATE:
-	{
-		uint64_t value = 0;
-
-		ret = pm_clock_getrate(pm_arg[0], &value);
-		SMC_RET2(handle, (uint64_t)ret |
-				  (((uint64_t)value & 0xFFFFFFFFU) << 32U),
-			 (value >> 32U) & 0xFFFFFFFFU);
-
-	}
-
 	case PM_CLOCK_SETPARENT:
 		ret = pm_clock_setparent(pm_arg[0], pm_arg[1]);
 		SMC_RET1(handle, (uint64_t)ret);
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index eaecb89..02d0b23 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -8,9 +8,10 @@
 #include <common/debug.h>
 #include <drivers/console.h>
 #include <plat/arm/common/plat_arm.h>
-#include <plat_private.h>
 #include <platform_tsp.h>
 
+#include <plat_private.h>
+
 /*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
@@ -27,9 +28,6 @@
 				       &tsp_boot_console);
 	console_set_scope(&tsp_boot_console,
 			  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
-
-	/* Initialize the platform config for future decision making */
-	zynqmp_config_setup();
 }
 
 /*******************************************************************************
diff --git a/plat/xilinx/zynqmp/zynqmp_ehf.c b/plat/xilinx/zynqmp/zynqmp_ehf.c
index 56dc79c..18c3749 100644
--- a/plat/xilinx/zynqmp/zynqmp_ehf.c
+++ b/plat/xilinx/zynqmp/zynqmp_ehf.c
@@ -5,10 +5,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
-
 #include <bl31/ehf.h>
 
+#include <platform_def.h>
+
 /*
  * Enumeration of priority levels on ARM platforms.
  */
diff --git a/plat/xilinx/zynqmp/zynqmp_sdei.c b/plat/xilinx/zynqmp/zynqmp_sdei.c
index 984252e..ce68e6a 100644
--- a/plat/xilinx/zynqmp/zynqmp_sdei.c
+++ b/plat/xilinx/zynqmp/zynqmp_sdei.c
@@ -9,9 +9,9 @@
 
 #include <bl31/ehf.h>
 #include <common/debug.h>
+#include <plat/common/platform.h>
 #include <services/sdei.h>
 
-#include <plat/common/platform.h>
 #include <platform_def.h>
 
 int arm_validate_ns_entrypoint(uintptr_t entrypoint)
diff --git a/poetry.lock b/poetry.lock
index 07cd572..08b2b37 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
@@ -68,13 +68,13 @@
 
 [[package]]
 name = "certifi"
-version = "2022.12.7"
+version = "2023.7.22"
 description = "Python package for providing Mozilla's CA Bundle."
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
-    {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
+    {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
+    {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
 ]
 
 [[package]]
@@ -556,13 +556,13 @@
 
 [[package]]
 name = "requests"
-version = "2.30.0"
+version = "2.31.0"
 description = "Python HTTP for Humans."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"},
-    {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"},
+    {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
+    {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
 ]
 
 [package.dependencies]
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index bb042c7..57d211e 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,6 +28,8 @@
 		return SMC_ARCH_CALL_SUCCESS;
 	case SMCCC_ARCH_SOC_ID:
 		return plat_is_smccc_feature_available(arg1);
+#ifdef __aarch64__
+	/* Workaround checks are currently only implemented for aarch64 */
 #if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
 		if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES)
@@ -88,6 +90,7 @@
 		}
 		return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
 #endif
+#endif /* __aarch64__ */
 
 	/* Fallthrough */
 
@@ -128,6 +131,7 @@
 		SMC_RET1(handle, smccc_arch_features(x1));
 	case SMCCC_ARCH_SOC_ID:
 		SMC_RET1(handle, smccc_arch_id(x1));
+#ifdef __aarch64__
 #if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
 		/*
@@ -156,6 +160,7 @@
 		 */
 		SMC_RET0(handle);
 #endif
+#endif /* __aarch64__ */
 	default:
 		WARN("Unimplemented Arm Architecture Service Call: 0x%x \n",
 			smc_fid);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 00a3b73..e24a621 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -28,6 +28,7 @@
 #include <cortex_a715.h>
 #include <cortex_x1.h>
 #include <cortex_x2.h>
+#include <cortex_x3.h>
 #include <neoverse_n1.h>
 #include <neoverse_n2.h>
 #include <neoverse_v1.h>
@@ -39,7 +40,7 @@
 #include <cortex_a9.h>
 #endif
 
-#define MAX_ERRATA_ENTRIES	16
+#define MAX_ERRATA_ENTRIES	32
 
 #define ERRATA_LIST_END		(MAX_ERRATA_ENTRIES - 1)
 
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index bc176c6..8fee6ac 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -332,22 +332,25 @@
 	.cpu_partnumber = NEOVERSE_N2_MIDR,
 	.cpu_errata_list = {
 		[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
-		[1] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
-		[2] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
-		[3] = {2138953, 0x00, 0x00, ERRATA_N2_2138953},
-		[4] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
-		[5] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
-		[6] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
-		[7] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
-		[8] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
-		[9] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
-		[10] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
-		[11] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
-		[12] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
-		[13] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
+		[1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478},
+		[2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
+		[3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
+		[4] = {2138953, 0x00, 0x00, ERRATA_N2_2138953},
+		[5] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
+		[6] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
+		[7] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
+		[8] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
+		[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
+		[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
+		[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
+		[12] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+		[13] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
+		[14] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[14] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
-		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[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,
 	}
 },
 #endif /* NEOVERSE_N2_H_INC */
@@ -399,7 +402,8 @@
 	.cpu_errata_list = {
 		[0] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[1] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V2_H_INC */
@@ -414,6 +418,18 @@
 	}
 },
 #endif /* CORTEX_A715_H_INC */
+
+#if CORTEX_X3_H_INC
+{
+	.cpu_partnumber = CORTEX_X3_MIDR,
+	.cpu_errata_list = {
+		[0] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
+		[1] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
+		[2] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
+		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X3_H_INC */
 };
 
 /*
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index c80b524..a929ea2 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -128,6 +128,11 @@
 		sve_enable(ctx);
 	}
 
+	/* NS can access this but Realm shouldn't */
+	if (is_feat_sys_reg_trace_supported()) {
+		sys_reg_trace_disable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 }
 
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 13875b9..48644ac 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -213,30 +213,6 @@
 	uint32_t ffa_version;
 };
 
-/**
- * Holds information returned for each partition by the FFA_PARTITION_INFO_GET
- * interface.
- */
-struct ffa_partition_info_v1_0 {
-	uint16_t ep_id;
-	uint16_t execution_ctx_count;
-	uint32_t properties;
-};
-
-/* Extended structure for v1.1. */
-struct ffa_partition_info_v1_1 {
-	uint16_t ep_id;
-	uint16_t execution_ctx_count;
-	uint32_t properties;
-	uint32_t uuid[4];
-};
-
-/* FF-A Partition Info Get related macros. */
-#define FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK	U(0x7)
-#define FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT 	U(8)
-#define FFA_PARTITION_INFO_GET_AARCH32_STATE 		U(0)
-#define FFA_PARTITION_INFO_GET_AARCH64_STATE 		U(1)
-
 /* Reference to power management hooks */
 extern const spd_pm_ops_t spmc_pm;
 
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
index 5c3d580..5263c04 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -743,10 +743,12 @@
 	/*
 	 * Overflow is impossible: the arithmetic happens in at least 64-bit
 	 * precision, but all of the operands are bounded by UINT32_MAX, and
-	 * ((2^32 - 1)^2 + (2^32 - 1) + (2^32 - 1)) = ((2^32 - 1) * (2^32 + 1))
+	 *   ((2^32 - 1) * (2^32 - 1) + (2^32 - 1) + (2^32 - 1))
+	 * = ((2^32 - 1) * ((2^32 - 1) + 1 + 1))
+	 * = ((2^32 - 1) * (2^32 + 1))
 	 * = (2^64 - 1).
 	 */
-	CASSERT(sizeof(desc->emad_count == 4), assert_emad_count_max_too_large);
+	CASSERT(sizeof(desc->emad_count) == 4, assert_emad_count_max_too_large);
 	emad_end = (desc->emad_count * (unsigned long long)emad_size) +
 		   (unsigned long long)sizeof(struct ffa_comp_mrd) +
 		   (unsigned long long)emad_offset;
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 6f451c8..72376f7 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -15,7 +15,18 @@
 SPMD_SOURCES	+=	$(addprefix services/std_svc/spmd/,	\
 			${ARCH}/spmd_helpers.S			\
 			spmd_pm.c				\
-			spmd_main.c)
+			spmd_main.c				\
+			spmd_logical_sp.c)
+
+# Specify platform specific SPMD logical partition implementation.
+SPMD_LP_SOURCES  := $(wildcard $(addprefix ${PLAT_DIR}/, \
+					${PLAT}_spmd_logical_sp*.c))
+
+ifeq (${ENABLE_SPMD_LP}, 1)
+ifneq ($(wildcard $(SPMD_LP_SOURCES)),)
+SPMD_SOURCES += $(SPMD_LP_SOURCES)
+endif
+endif
 
 # Let the top-level Makefile know that we intend to include a BL32 image
 NEED_BL32		:=	yes
diff --git a/services/std_svc/spmd/spmd_logical_sp.c b/services/std_svc/spmd/spmd_logical_sp.c
new file mode 100644
index 0000000..964b36b
--- /dev/null
+++ b/services/std_svc/spmd/spmd_logical_sp.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include "spmd_private.h"
+
+#include <common/debug.h>
+#include <common/uuid.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <services/el3_spmd_logical_sp.h>
+#include <services/spmc_svc.h>
+#include <smccc_helpers.h>
+
+
+/*
+ * Maximum ffa_partition_info entries that can be returned by an invocation
+ * of FFA_PARTITION_INFO_GET_REGS_64 is size in bytes, of available
+ * registers/args in struct ffa_value divided by size of struct
+ * ffa_partition_info. For this ABI, arg3-arg17 in ffa_value can be used, i.e.
+ * 15 uint64_t fields. For FF-A v1.1, this value should be 5.
+ */
+#define MAX_INFO_REGS_ENTRIES_PER_CALL \
+	(uint8_t)((15 * sizeof(uint64_t)) / \
+		  sizeof(struct ffa_partition_info_v1_1))
+CASSERT(MAX_INFO_REGS_ENTRIES_PER_CALL == 5, assert_too_many_info_reg_entries);
+
+#if ENABLE_SPMD_LP
+static bool is_spmd_lp_inited;
+static bool is_spmc_inited;
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * SPMD Logical Partition descriptors.
+ */
+static struct spmd_lp_desc *get_spmd_el3_lp_array(void)
+{
+	return (struct spmd_lp_desc *) SPMD_LP_DESCS_START;
+}
+
+/*******************************************************************************
+ * Validate any logical partition descriptors before we initialize.
+ * Initialization of said partitions will be taken care of during SPMD boot.
+ ******************************************************************************/
+static int el3_spmd_sp_desc_validate(struct spmd_lp_desc *lp_array)
+{
+	/* Check the array bounds are valid. */
+	assert(SPMD_LP_DESCS_END > SPMD_LP_DESCS_START);
+
+	/*
+	 * No support for SPMD logical partitions when SPMC is at EL3.
+	 */
+	assert(!is_spmc_at_el3());
+
+	/* If no SPMD logical partitions are implemented then simply bail out. */
+	if (SPMD_LP_DESCS_COUNT == 0U) {
+		return -1;
+	}
+
+	for (uint32_t index = 0U; index < SPMD_LP_DESCS_COUNT; index++) {
+		struct spmd_lp_desc *lp_desc = &lp_array[index];
+
+		/* Validate our logical partition descriptors. */
+		if (lp_desc == NULL) {
+			ERROR("Invalid SPMD Logical SP Descriptor\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * Ensure the ID follows the convention to indicate it resides
+		 * in the secure world.
+		 */
+		if (!ffa_is_secure_world_id(lp_desc->sp_id)) {
+			ERROR("Invalid SPMD Logical SP ID (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure SPMD logical partition is in valid range. */
+		if (!is_spmd_lp_id(lp_desc->sp_id)) {
+			ERROR("Invalid SPMD Logical Partition ID (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure the UUID is not the NULL UUID. */
+		if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 &&
+		    lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) {
+			ERROR("Invalid UUID for SPMD Logical SP (0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure init function callback is registered. */
+		if (lp_desc->init == NULL) {
+			ERROR("Missing init function for Logical SP(0x%x)\n",
+			      lp_desc->sp_id);
+			return -EINVAL;
+		}
+
+		/* Ensure that SPMD LP only supports sending direct requests. */
+		if (lp_desc->properties != FFA_PARTITION_DIRECT_REQ_SEND) {
+			ERROR("Invalid SPMD logical partition properties (0x%x)\n",
+			      lp_desc->properties);
+			return -EINVAL;
+		}
+
+		/* Ensure that all partition IDs are unique. */
+		for (uint32_t inner_idx = index + 1;
+		     inner_idx < SPMD_LP_DESCS_COUNT; inner_idx++) {
+			if (lp_desc->sp_id == lp_array[inner_idx].sp_id) {
+				ERROR("Duplicate SPMD logical SP ID Detected (0x%x)\n",
+				      lp_desc->sp_id);
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
+
+static void spmd_encode_ffa_error(struct ffa_value *retval, int32_t error_code)
+{
+	retval->func = FFA_ERROR;
+	retval->arg1 = FFA_TARGET_INFO_MBZ;
+	retval->arg2 = (uint32_t)error_code;
+	retval->arg3 = FFA_TARGET_INFO_MBZ;
+	retval->arg4 = FFA_TARGET_INFO_MBZ;
+	retval->arg5 = FFA_TARGET_INFO_MBZ;
+	retval->arg6 = FFA_TARGET_INFO_MBZ;
+	retval->arg7 = FFA_TARGET_INFO_MBZ;
+}
+
+static void spmd_build_direct_message_req(spmd_spm_core_context_t *ctx,
+					  uint64_t x1, uint64_t x2,
+					  uint64_t x3, uint64_t x4)
+{
+	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+
+	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
+	write_ctx_reg(gpregs, CTX_GPREG_X1, x1);
+	write_ctx_reg(gpregs, CTX_GPREG_X2, x2);
+	write_ctx_reg(gpregs, CTX_GPREG_X3, x3);
+	write_ctx_reg(gpregs, CTX_GPREG_X4, x4);
+	write_ctx_reg(gpregs, CTX_GPREG_X5, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X6, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X7, 0U);
+}
+
+static void spmd_encode_ctx_to_ffa_value(spmd_spm_core_context_t *ctx,
+					 struct ffa_value *retval)
+{
+	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+
+	retval->func = read_ctx_reg(gpregs, CTX_GPREG_X0);
+	retval->arg1 = read_ctx_reg(gpregs, CTX_GPREG_X1);
+	retval->arg2 = read_ctx_reg(gpregs, CTX_GPREG_X2);
+	retval->arg3 = read_ctx_reg(gpregs, CTX_GPREG_X3);
+	retval->arg4 = read_ctx_reg(gpregs, CTX_GPREG_X4);
+	retval->arg5 = read_ctx_reg(gpregs, CTX_GPREG_X5);
+	retval->arg6 = read_ctx_reg(gpregs, CTX_GPREG_X6);
+	retval->arg7 = read_ctx_reg(gpregs, CTX_GPREG_X7);
+	retval->arg8 = read_ctx_reg(gpregs, CTX_GPREG_X8);
+	retval->arg9 = read_ctx_reg(gpregs, CTX_GPREG_X9);
+	retval->arg10 = read_ctx_reg(gpregs, CTX_GPREG_X10);
+	retval->arg11 = read_ctx_reg(gpregs, CTX_GPREG_X11);
+	retval->arg12 = read_ctx_reg(gpregs, CTX_GPREG_X12);
+	retval->arg13 = read_ctx_reg(gpregs, CTX_GPREG_X13);
+	retval->arg14 = read_ctx_reg(gpregs, CTX_GPREG_X14);
+	retval->arg15 = read_ctx_reg(gpregs, CTX_GPREG_X15);
+	retval->arg16 = read_ctx_reg(gpregs, CTX_GPREG_X16);
+	retval->arg17 = read_ctx_reg(gpregs, CTX_GPREG_X17);
+}
+
+static void spmd_logical_sp_set_dir_req_ongoing(spmd_spm_core_context_t *ctx)
+{
+	ctx->spmd_lp_sync_req_ongoing |= SPMD_LP_FFA_DIR_REQ_ONGOING;
+}
+
+static void spmd_logical_sp_reset_dir_req_ongoing(spmd_spm_core_context_t *ctx)
+{
+	ctx->spmd_lp_sync_req_ongoing &= ~SPMD_LP_FFA_DIR_REQ_ONGOING;
+}
+
+static void spmd_build_ffa_info_get_regs(spmd_spm_core_context_t *ctx,
+					 const uint32_t uuid[4],
+					 const uint16_t start_index,
+					 const uint16_t tag)
+{
+	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+
+	uint64_t arg1 = (uint64_t)uuid[1] << 32 | uuid[0];
+	uint64_t arg2 = (uint64_t)uuid[3] << 32 | uuid[2];
+	uint64_t arg3 = start_index | (uint64_t)tag << 16;
+
+	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_PARTITION_INFO_GET_REGS_SMC64);
+	write_ctx_reg(gpregs, CTX_GPREG_X1, arg1);
+	write_ctx_reg(gpregs, CTX_GPREG_X2, arg2);
+	write_ctx_reg(gpregs, CTX_GPREG_X3, arg3);
+	write_ctx_reg(gpregs, CTX_GPREG_X4, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X5, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X6, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X7, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X8, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X9, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X10, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X11, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X12, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X13, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X14, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X15, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X16, 0U);
+	write_ctx_reg(gpregs, CTX_GPREG_X17, 0U);
+}
+
+static void spmd_logical_sp_set_info_regs_ongoing(spmd_spm_core_context_t *ctx)
+{
+	ctx->spmd_lp_sync_req_ongoing |= SPMD_LP_FFA_INFO_GET_REG_ONGOING;
+}
+
+static void spmd_logical_sp_reset_info_regs_ongoing(
+		spmd_spm_core_context_t *ctx)
+{
+	ctx->spmd_lp_sync_req_ongoing &= ~SPMD_LP_FFA_INFO_GET_REG_ONGOING;
+}
+
+static void spmd_fill_lp_info_array(
+	struct ffa_partition_info_v1_1 (*partitions)[EL3_SPMD_MAX_NUM_LP],
+	uint32_t uuid[4], uint16_t *lp_count_out)
+{
+	uint16_t lp_count = 0;
+	struct spmd_lp_desc *lp_array;
+	bool uuid_is_null = is_null_uuid(uuid);
+
+	if (SPMD_LP_DESCS_COUNT == 0U) {
+		*lp_count_out = 0;
+		return;
+	}
+
+	lp_array = get_spmd_el3_lp_array();
+	for (uint16_t index = 0; index < SPMD_LP_DESCS_COUNT; ++index) {
+		struct spmd_lp_desc *lp = &lp_array[index];
+
+		if (uuid_is_null || uuid_match(uuid, lp->uuid)) {
+			uint16_t array_index = lp_count;
+
+			++lp_count;
+
+			(*partitions)[array_index].ep_id = lp->sp_id;
+			(*partitions)[array_index].execution_ctx_count = 1;
+			(*partitions)[array_index].properties = lp->properties;
+			(*partitions)[array_index].properties |=
+				(FFA_PARTITION_INFO_GET_AARCH64_STATE <<
+				 FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT);
+			if (uuid_is_null) {
+				memcpy(&((*partitions)[array_index].uuid),
+					  &lp->uuid, sizeof(lp->uuid));
+			}
+		}
+	}
+
+	*lp_count_out = lp_count;
+}
+
+static inline void spmd_pack_lp_count_props(
+	uint64_t *xn, uint16_t ep_id, uint16_t vcpu_count,
+	uint32_t properties)
+{
+	*xn = (uint64_t)ep_id;
+	*xn |= (uint64_t)vcpu_count << 16;
+	*xn |= (uint64_t)properties << 32;
+}
+
+static inline void spmd_pack_lp_uuid(uint64_t *xn_1, uint64_t *xn_2,
+				     uint32_t uuid[4])
+{
+	*xn_1 = (uint64_t)uuid[0];
+	*xn_1 |= (uint64_t)uuid[1] << 32;
+	*xn_2 = (uint64_t)uuid[2];
+	*xn_2 |= (uint64_t)uuid[3] << 32;
+}
+#endif
+
+/*
+ * Initialize SPMD logical partitions. This function assumes that it is called
+ * only after the SPMC has successfully initialized.
+ */
+int32_t spmd_logical_sp_init(void)
+{
+#if ENABLE_SPMD_LP
+	int32_t rc = 0;
+	struct spmd_lp_desc *spmd_lp_descs;
+
+	assert(SPMD_LP_DESCS_COUNT <= EL3_SPMD_MAX_NUM_LP);
+
+	if (is_spmd_lp_inited == true) {
+		return 0;
+	}
+
+	if (is_spmc_inited == false) {
+		return -1;
+	}
+
+	spmd_lp_descs = get_spmd_el3_lp_array();
+
+	/* Perform initial validation of the SPMD Logical Partitions. */
+	rc = el3_spmd_sp_desc_validate(spmd_lp_descs);
+	if (rc != 0) {
+		ERROR("Logical SPMD Partition validation failed!\n");
+		return rc;
+	}
+
+	VERBOSE("SPMD Logical Secure Partition init start.\n");
+	for (unsigned int i = 0U; i < SPMD_LP_DESCS_COUNT; i++) {
+		rc = spmd_lp_descs[i].init();
+		if (rc != 0) {
+			ERROR("SPMD Logical SP (0x%x) failed to initialize\n",
+			      spmd_lp_descs[i].sp_id);
+			return rc;
+		}
+		VERBOSE("SPMD Logical SP (0x%x) Initialized\n",
+			spmd_lp_descs[i].sp_id);
+	}
+
+	INFO("SPMD Logical Secure Partition init completed.\n");
+	if (rc == 0) {
+		is_spmd_lp_inited = true;
+	}
+	return rc;
+#else
+	return 0;
+#endif
+}
+
+void spmd_logical_sp_set_spmc_initialized(void)
+{
+#if ENABLE_SPMD_LP
+	is_spmc_inited = true;
+#endif
+}
+
+void spmd_logical_sp_set_spmc_failure(void)
+{
+#if ENABLE_SPMD_LP
+	is_spmc_inited = false;
+#endif
+}
+
+/*
+ * This function takes an ffa_value structure populated with partition
+ * information from an FFA_PARTITION_INFO_GET_REGS ABI call, extracts
+ * the values and writes it into a ffa_partition_info_v1_1 structure for
+ * other code to consume.
+ */
+bool ffa_partition_info_regs_get_part_info(
+	struct ffa_value args, uint8_t idx,
+	struct ffa_partition_info_v1_1 *partition_info)
+{
+	uint64_t *arg_ptrs;
+	uint64_t info, uuid_lo, uuid_high;
+
+	/*
+	 * Each partition information is encoded in 3 registers, so there can be
+	 * a maximum of 5 entries.
+	 */
+	if (idx >= 5 || partition_info == NULL) {
+		return false;
+	}
+
+	/*
+	 * List of pointers to args in return value. arg0/func encodes ff-a
+	 * function, arg1 is reserved, arg2 encodes indices. arg3 and greater
+	 * values reflect partition properties.
+	 */
+	arg_ptrs = (uint64_t *)&args + ((idx * 3) + 3);
+	info = *arg_ptrs;
+
+	arg_ptrs++;
+	uuid_lo = *arg_ptrs;
+
+	arg_ptrs++;
+	uuid_high = *arg_ptrs;
+
+	partition_info->ep_id = (uint16_t)(info & 0xFFFFU);
+	partition_info->execution_ctx_count = (uint16_t)((info >> 16) & 0xFFFFU);
+	partition_info->properties = (uint32_t)(info >> 32);
+	partition_info->uuid[0] = (uint32_t)(uuid_lo & 0xFFFFFFFFU);
+	partition_info->uuid[1] = (uint32_t)((uuid_lo >> 32) & 0xFFFFFFFFU);
+	partition_info->uuid[2] = (uint32_t)(uuid_high & 0xFFFFFFFFU);
+	partition_info->uuid[3] = (uint32_t)((uuid_high >> 32) & 0xFFFFFFFFU);
+
+	return true;
+}
+
+/*
+ * This function is called by the SPMD in response to
+ * an FFA_PARTITION_INFO_GET_REG ABI invocation by the SPMC. Secure partitions
+ * are allowed to discover the presence of EL3 SPMD logical partitions by
+ * invoking the aforementioned ABI and this function populates the required
+ * information about EL3 SPMD logical partitions.
+ */
+uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
+						  uint64_t x2, uint64_t x3)
+{
+#if ENABLE_SPMD_LP
+	uint32_t target_uuid[4] = { 0 };
+	uint32_t w0;
+	uint32_t w1;
+	uint32_t w2;
+	uint32_t w3;
+	uint16_t start_index;
+	uint16_t tag;
+	static struct ffa_partition_info_v1_1 partitions[EL3_SPMD_MAX_NUM_LP];
+	uint16_t lp_count = 0;
+	uint16_t max_idx = 0;
+	uint16_t curr_idx = 0;
+	uint8_t num_entries_to_ret = 0;
+	struct ffa_value ret = { 0 };
+	uint64_t *arg_ptrs = (uint64_t *)&ret + 3;
+
+	w0 = (uint32_t)(x1 & 0xFFFFFFFFU);
+	w1 = (uint32_t)(x1 >> 32);
+	w2 = (uint32_t)(x2 & 0xFFFFFFFFU);
+	w3 = (uint32_t)(x2 >> 32);
+
+	target_uuid[0] = w0;
+	target_uuid[1] = w1;
+	target_uuid[2] = w2;
+	target_uuid[3] = w3;
+
+	start_index = (uint16_t)(x3 & 0xFFFFU);
+	tag = (uint16_t)((x3 >> 16) & 0xFFFFU);
+
+	assert(handle == cm_get_context(SECURE));
+
+	if (tag != 0) {
+		VERBOSE("Tag is not 0. Cannot return partition info.\n");
+		return spmd_ffa_error_return(handle, FFA_ERROR_RETRY);
+	}
+
+	memset(&partitions, 0, sizeof(partitions));
+
+	spmd_fill_lp_info_array(&partitions, target_uuid, &lp_count);
+
+	if (lp_count == 0) {
+		VERBOSE("No SPDM EL3 logical partitions exist.\n");
+		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	if (start_index >= lp_count) {
+		VERBOSE("start_index = %d, lp_count = %d (start index must be"
+			" less than partition count.\n",
+			start_index, lp_count);
+		return spmd_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	max_idx = lp_count - 1;
+	num_entries_to_ret = (max_idx - start_index) + 1;
+	num_entries_to_ret =
+		MIN(num_entries_to_ret, MAX_INFO_REGS_ENTRIES_PER_CALL);
+	curr_idx = start_index + num_entries_to_ret - 1;
+	assert(curr_idx <= max_idx);
+
+	ret.func = FFA_SUCCESS_SMC64;
+	ret.arg2 = (uint64_t)((sizeof(struct ffa_partition_info_v1_1) & 0xFFFFU) << 48);
+	ret.arg2 |= (uint64_t)(curr_idx << 16);
+	ret.arg2 |= (uint64_t)max_idx;
+
+	for (uint16_t idx = start_index; idx <= curr_idx; ++idx) {
+		spmd_pack_lp_count_props(arg_ptrs, partitions[idx].ep_id,
+					 partitions[idx].execution_ctx_count,
+					 partitions[idx].properties);
+		arg_ptrs++;
+		if (is_null_uuid(target_uuid)) {
+			spmd_pack_lp_uuid(arg_ptrs, (arg_ptrs + 1),
+					  partitions[idx].uuid);
+		}
+		arg_ptrs += 2;
+	}
+
+	SMC_RET18(handle, ret.func, ret.arg1, ret.arg2, ret.arg3, ret.arg4,
+		  ret.arg5, ret.arg6, ret.arg7, ret.arg8, ret.arg9, ret.arg10,
+		  ret.arg11, ret.arg12, ret.arg13, ret.arg14, ret.arg15,
+		  ret.arg16, ret.arg17);
+#else
+	return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+#endif
+}
+
+/* This function can be used by an SPMD logical partition to invoke the
+ * FFA_PARTITION_INFO_GET_REGS ABI to the SPMC, to discover the secure
+ * partitions in the system. The function takes a UUID, start index and
+ * tag and the partition information are returned in an ffa_value structure
+ * and can be consumed by using appropriate helper functions.
+ */
+bool spmd_el3_invoke_partition_info_get(
+				const uint32_t target_uuid[4],
+				const uint16_t start_index,
+				const uint16_t tag,
+				struct ffa_value *retval)
+{
+#if ENABLE_SPMD_LP
+	uint64_t rc = UINT64_MAX;
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+
+	if (retval == NULL) {
+		return false;
+	}
+
+	memset(retval, 0, sizeof(*retval));
+
+	if (!is_spmc_inited) {
+		VERBOSE("Cannot discover partition before,"
+			" SPMC is initialized.\n");
+			spmd_encode_ffa_error(retval, FFA_ERROR_DENIED);
+		return true;
+	}
+
+	if (tag != 0) {
+		VERBOSE("Tag must be zero. other tags unsupported\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	/* Save the non-secure context before entering SPMC */
+	cm_el1_sysregs_context_save(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_save(NON_SECURE);
+#endif
+
+	spmd_build_ffa_info_get_regs(ctx, target_uuid, start_index, tag);
+	spmd_logical_sp_set_info_regs_ongoing(ctx);
+
+	rc = spmd_spm_core_sync_entry(ctx);
+	if (rc != 0ULL) {
+		ERROR("%s failed (%lx) on CPU%u\n", __func__, rc,
+		      plat_my_core_pos());
+		panic();
+	}
+
+	spmd_logical_sp_reset_info_regs_ongoing(ctx);
+	spmd_encode_ctx_to_ffa_value(ctx, retval);
+
+	assert(is_ffa_error(retval) || is_ffa_success(retval));
+
+	cm_el1_sysregs_context_restore(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_restore(NON_SECURE);
+#endif
+	cm_set_next_eret_context(NON_SECURE);
+	return true;
+#else
+	return false;
+#endif
+}
+
+/*******************************************************************************
+ * This function sends an FF-A Direct Request from a partition in EL3 to a
+ * partition that may reside under an SPMC (only lower ELs supported). The main
+ * use of this API is for SPMD logical partitions.
+ * The API is expected to be used when there are platform specific SMCs that
+ * need to be routed to a secure partition that is FF-A compliant or when
+ * there are group 0 interrupts that need to be handled first in EL3 and then
+ * forwarded to an FF-A compliant secure partition. Therefore, it is expected
+ * that the handle to the context provided belongs to the non-secure context.
+ * This also means that interrupts/SMCs that trap to EL3 during secure execution
+ * cannot use this API.
+ * x1, x2, x3 and x4 are encoded as specified in the FF-A specification.
+ * retval is used to pass the direct response values to the caller.
+ * The function returns true if retval has valid values, and false otherwise.
+ ******************************************************************************/
+bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
+				 uint64_t x2,
+				 uint64_t x3,
+				 uint64_t x4,
+				 void *handle,
+				 struct ffa_value *retval)
+{
+#if ENABLE_SPMD_LP
+
+	uint64_t rc = UINT64_MAX;
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+
+	if (retval == NULL) {
+		return false;
+	}
+
+	memset(retval, 0, sizeof(*retval));
+
+	if (!is_spmd_lp_inited || !is_spmc_inited) {
+		VERBOSE("Cannot send SPMD logical partition direct message,"
+			" Partitions not initialized or SPMC not initialized.\n");
+			spmd_encode_ffa_error(retval, FFA_ERROR_DENIED);
+		return true;
+	}
+
+	/*
+	 * x2 must be zero, since there is no support for framework message via
+	 * an SPMD logical partition. This is sort of a useless check and it is
+	 * possible to not take parameter. However, as the framework extends it
+	 * may be useful to have x2 and extend this function later with
+	 * functionality based on x2.
+	 */
+	if (x2 != 0) {
+		VERBOSE("x2 must be zero. Cannot send framework message.\n");
+			spmd_encode_ffa_error(retval, FFA_ERROR_DENIED);
+		return true;
+	}
+
+	/*
+	 * Current context must be non-secure. API is expected to be used
+	 * when entry into EL3 and the SPMD logical partition is via an
+	 * interrupt that occurs when execution is in normal world and
+	 * SMCs from normal world. FF-A compliant SPMCs are expected to
+	 * trap interrupts during secure execution in lower ELs since they
+	 * are usually not re-entrant and SMCs from secure world can be
+	 * handled synchronously. There is no known use case for an SPMD
+	 * logical partition to send a direct message to another partition
+	 * in response to a secure interrupt or SMCs from secure world.
+	 */
+	if (handle != cm_get_context(NON_SECURE)) {
+		VERBOSE("Handle must be for the non-secure context.\n");
+			spmd_encode_ffa_error(retval, FFA_ERROR_DENIED);
+		return true;
+	}
+
+	if (!is_spmd_lp_id(ffa_endpoint_source(x1))) {
+		VERBOSE("Source ID must be valid SPMD logical partition"
+			" ID.\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	if (is_spmd_lp_id(ffa_endpoint_destination(x1))) {
+		VERBOSE("Destination ID must not be SPMD logical partition"
+			" ID.\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	if (!ffa_is_secure_world_id(ffa_endpoint_destination(x1))) {
+		VERBOSE("Destination ID must be secure world ID.\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	if (ffa_endpoint_destination(x1) == SPMD_DIRECT_MSG_ENDPOINT_ID) {
+		VERBOSE("Destination ID must not be SPMD ID.\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	if (ffa_endpoint_destination(x1) == spmd_spmc_id_get()) {
+		VERBOSE("Destination ID must not be SPMC ID.\n");
+			spmd_encode_ffa_error(retval,
+					      FFA_ERROR_INVALID_PARAMETER);
+		return true;
+	}
+
+	/* Save the non-secure context before entering SPMC */
+	cm_el1_sysregs_context_save(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_save(NON_SECURE);
+#endif
+
+	/*
+	 * Perform synchronous entry into the SPMC. Synchronous entry is
+	 * required because the spec requires that a direct message request
+	 * from an SPMD LP look like a function call from it's perspective.
+	 */
+	spmd_build_direct_message_req(ctx, x1, x2, x3, x4);
+	spmd_logical_sp_set_dir_req_ongoing(ctx);
+
+	rc = spmd_spm_core_sync_entry(ctx);
+
+	spmd_logical_sp_reset_dir_req_ongoing(ctx);
+
+	if (rc != 0ULL) {
+		ERROR("%s failed (%lx) on CPU%u\n", __func__, rc,
+		      plat_my_core_pos());
+		panic();
+	} else {
+		spmd_encode_ctx_to_ffa_value(ctx, retval);
+
+		/*
+		 * Only expect error or direct response,
+		 * spmd_spm_core_sync_exit should not be called on other paths.
+		 * Checks are asserts since the LSP can fail gracefully if the
+		 * source or destination ids are not the same. Panic'ing would
+		 * not provide any benefit.
+		 */
+		assert(is_ffa_error(retval) || is_ffa_direct_msg_resp(retval));
+		assert(is_ffa_error(retval) ||
+			(ffa_endpoint_destination(retval->arg1) ==
+				ffa_endpoint_source(x1)));
+		assert(is_ffa_error(retval) ||
+			(ffa_endpoint_source(retval->arg1) ==
+				ffa_endpoint_destination(x1)));
+	}
+
+	cm_el1_sysregs_context_restore(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_restore(NON_SECURE);
+#endif
+	cm_set_next_eret_context(NON_SECURE);
+
+	return true;
+#else
+	return false;
+#endif
+}
+
+bool is_spmd_logical_sp_info_regs_req_in_progress(
+		spmd_spm_core_context_t *ctx)
+{
+#if ENABLE_SPMD_LP
+	return ((ctx->spmd_lp_sync_req_ongoing & SPMD_LP_FFA_INFO_GET_REG_ONGOING)
+			== SPMD_LP_FFA_INFO_GET_REG_ONGOING);
+#else
+	return false;
+#endif
+}
+
+bool is_spmd_logical_sp_dir_req_in_progress(
+		spmd_spm_core_context_t *ctx)
+{
+#if ENABLE_SPMD_LP
+	return ((ctx->spmd_lp_sync_req_ongoing & SPMD_LP_FFA_DIR_REQ_ONGOING)
+		== SPMD_LP_FFA_DIR_REQ_ONGOING);
+#else
+	return false;
+#endif
+}
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 6b16373..d830403 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -27,6 +27,7 @@
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
+#include <services/el3_spmd_logical_sp.h>
 #include <services/ffa_svc.h>
 #include <services/spmc_svc.h>
 #include <services/spmd_svc.h>
@@ -86,8 +87,7 @@
  ******************************************************************************/
 static int32_t spmd_init(void);
 static int spmd_spmc_init(void *pm_addr);
-static uint64_t spmd_ffa_error_return(void *handle,
-				       int error_code);
+
 static uint64_t spmd_smc_forward(uint32_t smc_fid,
 				 bool secure_origin,
 				 uint64_t x1,
@@ -190,6 +190,12 @@
 
 	VERBOSE("SPM Core init end.\n");
 
+	spmd_logical_sp_set_spmc_initialized();
+	rc = spmd_logical_sp_init();
+	if (rc != 0) {
+		WARN("SPMD Logical partitions failed init.\n");
+	}
+
 	return 1;
 }
 
@@ -273,13 +279,16 @@
 
 	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
 
-	intid = plat_ic_get_pending_interrupt_id();
+	intid = plat_ic_acknowledge_interrupt();
 
 	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
 		ERROR("Group0 interrupt %u not handled\n", intid);
 		panic();
 	}
 
+	/* Deactivate the corresponding Group0 interrupt. */
+	plat_ic_end_of_interrupt(intid);
+
 	return 0U;
 }
 #endif
@@ -300,7 +309,7 @@
 
 	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
 
-	intid = plat_ic_get_pending_interrupt_id();
+	intid = plat_ic_acknowledge_interrupt();
 
 	/*
 	 * TODO: Currently due to a limitation in SPMD implementation, the
@@ -313,6 +322,9 @@
 		panic();
 	}
 
+	/* Deactivate the corresponding Group0 interrupt. */
+	plat_ic_end_of_interrupt(intid);
+
 	/* Return success. */
 	SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
 		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
@@ -736,7 +748,7 @@
 /*******************************************************************************
  * Return FFA_ERROR with specified error code
  ******************************************************************************/
-static uint64_t spmd_ffa_error_return(void *handle, int error_code)
+uint64_t spmd_ffa_error_return(void *handle, int error_code)
 {
 	SMC_RET8(handle, (uint32_t) FFA_ERROR,
 		 FFA_TARGET_INFO_MBZ, (uint32_t)error_code,
@@ -839,6 +851,16 @@
 		    SMC_GET_GP(handle, CTX_GPREG_X6),
 		    SMC_GET_GP(handle, CTX_GPREG_X7));
 
+	/*
+	 * If there is an on-going info regs from EL3 SPMD LP, unconditionally
+	 * return, we don't expect any other FF-A ABIs to be called between
+	 * calls to FFA_PARTITION_INFO_GET_REGS.
+	 */
+	if (is_spmd_logical_sp_info_regs_req_in_progress(ctx)) {
+		assert(secure_origin);
+		spmd_spm_core_sync_exit(0ULL);
+	}
+
 	switch (smc_fid) {
 	case FFA_ERROR:
 		/*
@@ -850,6 +872,16 @@
 			spmd_spm_core_sync_exit(x2);
 		}
 
+		/*
+		 * If there was an SPMD logical partition direct request on-going,
+		 * return back to the SPMD logical partition so the error can be
+		 * consumed.
+		 */
+		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
+			assert(secure_origin);
+			spmd_spm_core_sync_exit(0ULL);
+		}
+
 		return spmd_smc_forward(smc_fid, secure_origin,
 					x1, x2, x3, x4, cookie,
 					handle, flags);
@@ -1039,6 +1071,31 @@
 
 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+		/*
+		 * Regardless of secure_origin, SPMD logical partitions cannot
+		 * handle direct messages. They can only initiate direct
+		 * messages and consume direct responses or errors.
+		 */
+		if (is_spmd_lp_id(ffa_endpoint_source(x1)) ||
+				  is_spmd_lp_id(ffa_endpoint_destination(x1))) {
+			return spmd_ffa_error_return(handle,
+						     FFA_ERROR_INVALID_PARAMETER
+						     );
+		}
+
+		/*
+		 * When there is an ongoing SPMD logical partition direct
+		 * request, there cannot be another direct request. Return
+		 * error in this case. Panic'ing is an option but that does
+		 * not provide the opportunity for caller to abort based on
+		 * error codes.
+		 */
+		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
+			assert(secure_origin);
+			return spmd_ffa_error_return(handle,
+						     FFA_ERROR_DENIED);
+		}
+
 		if (!secure_origin) {
 			/* Validate source endpoint is non-secure for non-secure caller. */
 			if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
@@ -1066,7 +1123,9 @@
 		break; /* Not reached */
 
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
-		if (secure_origin && spmd_is_spmc_message(x1)) {
+	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+		if (secure_origin && (spmd_is_spmc_message(x1) ||
+		    is_spmd_logical_sp_dir_req_in_progress(ctx))) {
 			spmd_spm_core_sync_exit(0ULL);
 		} else {
 			/* Forward direct message to the other world */
@@ -1106,7 +1165,6 @@
 		/* Forward the call to the other world */
 		/* fallthrough */
 	case FFA_MSG_SEND:
-	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 	case FFA_MEM_DONATE_SMC32:
 	case FFA_MEM_DONATE_SMC64:
 	case FFA_MEM_LEND_SMC32:
@@ -1123,11 +1181,14 @@
 	case FFA_SUCCESS_SMC32:
 	case FFA_SUCCESS_SMC64:
 		/*
-		 * TODO: Assume that no requests originate from EL3 at the
-		 * moment. This will change if a SP service is required in
-		 * response to secure interrupts targeted to EL3. Until then
-		 * simply forward the call to the Normal world.
+		 * If there is an ongoing direct request from an SPMD logical
+		 * partition, return an error.
 		 */
+		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
+			assert(secure_origin);
+			return spmd_ffa_error_return(handle,
+					FFA_ERROR_DENIED);
+		}
 
 		return spmd_smc_forward(smc_fid, secure_origin,
 					x1, x2, x3, x4, cookie,
@@ -1154,6 +1215,12 @@
 						      FFA_ERROR_NOT_SUPPORTED);
 		}
 
+		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
+			assert(secure_origin);
+			return spmd_ffa_error_return(handle,
+					FFA_ERROR_DENIED);
+		}
+
 		return spmd_smc_forward(smc_fid, secure_origin,
 					x1, x2, x3, x4, cookie,
 					handle, flags);
@@ -1169,8 +1236,8 @@
 #if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
 	case FFA_PARTITION_INFO_GET_REGS_SMC64:
 		if (secure_origin) {
-			/* TODO: Future patches to enable support for this */
-			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+			return spmd_el3_populate_logical_partition_info(handle, x1,
+								   x2, x3);
 		}
 
 		/* Call only supported with SMCCC 1.2+ */
@@ -1187,7 +1254,7 @@
 		if (secure_origin) {
 			return spmd_handle_group0_intr_swd(handle);
 		} else {
-			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
+			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
 		}
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index ff6942e..fef7ef6 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -52,8 +52,15 @@
 	cpu_context_t cpu_ctx;
 	spmc_state_t state;
 	bool secure_interrupt_ongoing;
+#if ENABLE_SPMD_LP
+	uint8_t spmd_lp_sync_req_ongoing;
+#endif
 } spmd_spm_core_context_t;
 
+/* Flags to indicate ongoing requests for SPMD EL3 logical partitions */
+#define SPMD_LP_FFA_DIR_REQ_ONGOING		U(0x1)
+#define SPMD_LP_FFA_INFO_GET_REG_ONGOING	U(0x2)
+
 /*
  * Reserve ID for NS physical FFA Endpoint.
  */
@@ -100,6 +107,9 @@
  *  otherwise it returns a negative value
  */
 int plat_spmd_handle_group0_interrupt(uint32_t id);
+
+uint64_t spmd_ffa_error_return(void *handle, int error_code);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_PRIVATE_H */
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 042e844..b911d19 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -85,9 +85,9 @@
 
 .PHONY: all clean realclean --openssl
 
-all: ${BINARY}
+all: --openssl ${BINARY}
 
-${BINARY}: --openssl ${OBJECTS} Makefile
+${BINARY}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
                 const char platform_msg[] = "${PLAT_MSG}";' | \
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 2939b14..924e5fe 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -65,9 +65,9 @@
 
 .PHONY: all clean realclean --openssl
 
-all: ${BINARY}
+all: --openssl ${BINARY}
 
-${BINARY}: --openssl ${OBJECTS} Makefile
+${BINARY}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
                 ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 2ebee33..4bdebd9 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -68,9 +68,9 @@
 
 .PHONY: all clean distclean --openssl
 
-all: ${PROJECT}
+all: --openssl ${PROJECT}
 
-${PROJECT}: --openssl ${OBJECTS} Makefile
+${PROJECT}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
 	@${ECHO_BLANK_LINE}
diff --git a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
index 46b5179..fef2116 100644
--- a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
@@ -8,8 +8,8 @@
 
 ifeq (${PLAT_DEF_UUID}, yes)
 HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
-ifeq (${ARM_ETHOSN_NPU_TZMP1},1)
-HOSTCCFLAGS += -DARM_ETHOSN_NPU_TZMP1
+ifeq (${ETHOSN_NPU_TZMP1},1)
+HOSTCCFLAGS += -DETHOSN_NPU_TZMP1
 endif
 INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/
 OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 4067331..c69e0a7 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python3
-# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -21,6 +21,7 @@
 param2: "SP_LAYOUT_FILE", json file containing platform provided information
 param3: plat out directory
 param4: CoT parameter
+param5: Generated dts file "sp_list_fragment.dts"
 
 Generated "sp_gen.mk" file contains triplet of following information for each
 Secure Partition entry
@@ -112,6 +113,34 @@
     ''' Helper to fetch pm offset from sp_layout.json '''
     return get_offset_from_layout(node["pm"])
 
+def get_uuid(sp_layout, sp, args :dict):
+    ''' Helper to fetch uuid from pm file listed in sp_layout.json'''
+    if "uuid" in sp_layout[sp]:
+        # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
+        uuid_std = uuid.UUID(sp_layout[sp]['uuid'])
+    else:
+        with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
+            uuid_lines = [l for l in pm_f if 'uuid' in l]
+        assert(len(uuid_lines) == 1)
+        # The uuid field in SP manifest is the little endian representation
+        # mapped to arguments as described in SMCCC section 5.3.
+        # Convert each unsigned integer value to a big endian representation
+        # required by fiptool.
+        uuid_parsed = re.findall("0x([0-9a-f]+)", uuid_lines[0])
+        y = list(map(bytearray.fromhex, uuid_parsed))
+        z = [int.from_bytes(i, byteorder='little', signed=False) for i in y]
+        uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+    return uuid_std
+
+def get_load_address(sp_layout, sp, args :dict):
+    ''' Helper to fetch load-address from pm file listed in sp_layout.json'''
+    with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
+        load_address_lines = [l for l in pm_f if 'load-address' in l]
+    assert(len(load_address_lines) == 1)
+    load_address_parsed = re.search("(0x[0-9a-f]+)", load_address_lines[0])
+    return load_address_parsed.group(0)
+
+
 @SpSetupActions.sp_action(global_action=True)
 def check_max_sps(sp_layout, _, args :dict):
     ''' Check validate the maximum number of SPs is respected. '''
@@ -195,37 +224,53 @@
 @SpSetupActions.sp_action
 def gen_fiptool_args(sp_layout, sp, args :dict):
     ''' Generate arguments for the FIP Tool. '''
-    if "uuid" in sp_layout[sp]:
-        # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
-        uuid_std = uuid.UUID(sp_layout[sp]['uuid'])
-    else:
-        with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
-            uuid_lines = [l for l in pm_f if 'uuid' in l]
-        assert(len(uuid_lines) == 1)
-        # The uuid field in SP manifest is the little endian representation
-        # mapped to arguments as described in SMCCC section 5.3.
-        # Convert each unsigned integer value to a big endian representation
-        # required by fiptool.
-        uuid_parsed = re.findall("0x([0-9a-f]+)", uuid_lines[0])
-        y = list(map(bytearray.fromhex, uuid_parsed))
-        z = [int.from_bytes(i, byteorder='little', signed=False) for i in y]
-        uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+    uuid_std = get_uuid(sp_layout, sp, args)
     write_to_sp_mk_gen(f"FIP_ARGS += --blob uuid={str(uuid_std)},file={get_sp_pkg(sp, args)}\n", args)
     return args
 
+@SpSetupActions.sp_action
+def gen_fconf_fragment(sp_layout, sp, args: dict):
+    ''' Generate the fconf fragment file'''
+    with open(args["fconf_fragment"], "a") as f:
+        uuid = get_uuid(sp_layout, sp, args)
+        owner = "Plat" if sp_layout[sp].get("owner") == "Plat" else "SiP"
+
+        if "physical-load-address" in sp_layout[sp].keys():
+            load_address = sp_layout[sp]["physical-load-address"]
+        else:
+            load_address = get_load_address(sp_layout, sp, args)
+
+        f.write(
+f'''\
+{sp} {{
+    uuid = "{uuid}";
+    load-address = <{load_address}>;
+    owner = "{owner}";
+}};
+
+''')
+    return args
+
 def init_sp_actions(sys):
-    sp_layout_file = os.path.abspath(sys.argv[2])
-    with open(sp_layout_file) as json_file:
-        sp_layout = json.load(json_file)
     # Initialize arguments for the SP actions framework
     args = {}
     args["sp_gen_mk"] = os.path.abspath(sys.argv[1])
+    sp_layout_file = os.path.abspath(sys.argv[2])
     args["sp_layout_dir"] = os.path.dirname(sp_layout_file)
     args["out_dir"] = os.path.abspath(sys.argv[3])
     args["dualroot"] = sys.argv[4] == "dualroot"
+    args["fconf_fragment"] = os.path.abspath(sys.argv[5])
+
+
+    with open(sp_layout_file) as json_file:
+        sp_layout = json.load(json_file)
     #Clear content of file "sp_gen.mk".
     with open(args["sp_gen_mk"], "w"):
         None
+    #Clear content of file "fconf_fragment".
+    with open(args["fconf_fragment"], "w"):
+        None
+
     return args, sp_layout
 
 if __name__ == "__main__":